(file) Return to HTTPConnection.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/HTTPConnection.cpp between version 1.125.4.15 and 1.126

version 1.125.4.15, 2008/02/01 17:50:16 version 1.126, 2007/01/11 16:21:54
Line 148 
Line 148 
     const char *file , Uint32 line)     const char *file , Uint32 line)
 { {
     String message = status + httpDetailDelimiter + detail;     String message = status + httpDetailDelimiter + detail;
     PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, message);      Tracer::trace(file, line, TRC_HTTP, Tracer::LEVEL2, message);
     if (status == httpStatusInternal)     if (status == httpStatusInternal)
         throw AssertionFailureException(file, line, message);         throw AssertionFailureException(file, line, message);
     else throw Exception(message);     else throw Exception(message);
Line 163 
Line 163 
 #define _socketWriteError()                                                   \ #define _socketWriteError()                                                   \
     do                                                                        \     do                                                                        \
     {                                                                         \     {                                                                         \
         PEG_TRACE((__FILE__, __LINE__, TRC_DISCARDED_DATA, Tracer::LEVEL2,     \          Tracer::trace(__FILE__, __LINE__, TRC_DISCARDED_DATA, Tracer::LEVEL2, \
             "Socket write failed with error %d; could not write response "    \             "Socket write failed with error %d; could not write response "    \
                 "to client.  (Client may have timed out.)",                   \                 "to client.  (Client may have timed out.)",                   \
             getSocketError()));                                                \              getSocketError());                                                \
         throw Exception("socket write error");                                \         throw Exception("socket write error");                                \
     }                                                                         \     }                                                                         \
     while (0)     while (0)
Line 176 
Line 176 
     return x < y ? x : y;     return x < y ? x : y;
 } }
  
   static char* _FindSeparator(const char* data, Uint32 size)
   {
       const char* p = data;
       const char* end = p + size;
   
       while (p != end)
       {
           if (*p == '\r')
           {
               size_t n = end - p;
   
               if (n >= 2 && p[1] == '\n')
                   return (char*)p;
           }
           else if (*p == '\n')
               return (char*)p;
   
           p++;
       }
   
       return 0;
   }
   
 // Used to test signal handling // Used to test signal handling
 void * sigabrt_generator(void * parm) void * sigabrt_generator(void * parm)
 { {
Line 206 
Line 229 
     _contentOffset(-1),     _contentOffset(-1),
     _contentLength(-1),     _contentLength(-1),
     _connectionClosePending(false),     _connectionClosePending(false),
     _acceptPending(false),      _acceptPending(false)
     _firstRead(true),  
     _idleConnectionTimeoutSeconds(0)  
 { {
     PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::HTTPConnection");     PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::HTTPConnection");
  
       _socket->disableBlocking();
     _authInfo.reset(new AuthenticationInfo(true));     _authInfo.reset(new AuthenticationInfo(true));
  
     // Add SSL verification information to the authentication information     // Add SSL verification information to the authentication information
Line 221 
Line 243 
         if (_socket->isPeerVerificationEnabled() &&         if (_socket->isPeerVerificationEnabled() &&
             _socket->isCertificateVerified())             _socket->isCertificateVerified())
         {         {
             _authInfo->setConnectionAuthenticated(true);              _authInfo->setAuthStatus(AuthenticationInfoRep::AUTHENTICATED);
             _authInfo->setAuthType(AuthenticationInfoRep::AUTH_TYPE_SSL);             _authInfo->setAuthType(AuthenticationInfoRep::AUTH_TYPE_SSL);
             _authInfo->setClientCertificateChain(             _authInfo->setClientCertificateChain(
                 _socket->getPeerCertificateChain());                 _socket->getPeerCertificateChain());
Line 229 
Line 251 
 #else #else
         if (_socket->isClientAuthenticated())         if (_socket->isClientAuthenticated())
         {         {
             _authInfo->setConnectionAuthenticated(true);              _authInfo->setAuthStatus(AuthenticationInfoRep::AUTHENTICATED);
             _authInfo->setAuthenticatedUser(_socket->getAuthenticatedUser());             _authInfo->setAuthenticatedUser(_socket->getAuthenticatedUser());
         }         }
 #endif #endif
Line 252 
Line 274 
 { {
     PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::~HTTPConnection");     PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::~HTTPConnection");
  
     // We need to acquire this mutex in order to give handleEnqueue()  
     // a chance to finish processing. If we don't, we may run into a  
     // situation where the connection is marked to be closed by the  
     // idle connection timeout mechanism and there are no pending  
     // responses (the _responsePending flag is cleared in  
     // _handleWriteEvent()). This causes the monitor to clean up the  
     // connection. But if processing is not out of  
     // HTTPConnection::handleEnqueue(), we are running a risk of  
     // accessing a deleted object and crashing cimserver.  
     AutoMutex connectionLock(_connection_mut);  
      _socket->close();      _socket->close();
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
Line 288 
Line 300 
     {     {
         case SOCKET_MESSAGE:         case SOCKET_MESSAGE:
         {         {
             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,              Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                 "HTTPConnection::handleEnqueue - SOCKET_MESSAGE");                 "HTTPConnection::handleEnqueue - SOCKET_MESSAGE");
             SocketMessage* socketMessage = (SocketMessage*)message;             SocketMessage* socketMessage = (SocketMessage*)message;
             if (socketMessage->events & SocketMessage::READ)             if (socketMessage->events & SocketMessage::READ)
Line 298 
Line 310 
  
         case HTTP_MESSAGE:         case HTTP_MESSAGE:
         {         {
             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,              Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                 "HTTPConnection::handleEnqueue - HTTP_MESSAGE");                 "HTTPConnection::handleEnqueue - HTTP_MESSAGE");
  
             _handleWriteEvent(*message);             _handleWriteEvent(*message);
Line 316 
Line 328 
 } }
  
 /* /*
  * Used on Server side to close outstanding connections waiting for SSL  
  * handshake to complete if timeout expired or to close idle connections if  
  * idleConnectionTimeout config property value has specified.  
  * Returns 'true' if connection is closed (or is closePending).  
  * timeNow will be updated to current time if connection's _idleStartTime  
  * is greater than timeNow.  
 */  
   
 Boolean HTTPConnection::closeConnectionOnTimeout(struct timeval* timeNow)  
 {  
     // if SSL Handshake is not complete.  
     if (_acceptPending)  
     {  
         PEGASUS_ASSERT(!_isClient());  
         if ((timeNow->tv_sec - _acceptPendingStartTime.tv_sec >  
                  PEGASUS_SSL_ACCEPT_TIMEOUT_SECONDS) &&  
             (timeNow->tv_sec > _acceptPendingStartTime.tv_sec))  
         {  
             PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                 "HTTPConnection: close acceptPending connection for timeout");  
             _closeConnection();  
             return true;  // return 'true' to indicate connection was closed  
         }  
     }  
     // else if connection timeout is active  
     else if (_idleConnectionTimeoutSeconds)  
     {  
         // For performance reasons timeNow is calculated only once in Monitor.  
         // Update timeNow if connection's _idleStartTime has more recent time.  
         if (timeNow->tv_sec < _idleStartTime.tv_sec)  
         {  
             Time::gettimeofday(timeNow);  
         }  
         else if ((Uint32)(timeNow->tv_sec - _idleStartTime.tv_sec) >  
             _idleConnectionTimeoutSeconds)  
         {  
             PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                 "HTTPConnection: close idle connection for timeout "  
                 "of %d seconds\n", _idleConnectionTimeoutSeconds));  
             _closeConnection();  
             return true;  // return 'true' to indicate connection was closed  
         }  
     }  
     return false;  // connection was not closed  
 }  
   
 /*  
  * handle the message coming down from the above. This is shared client and  * handle the message coming down from the above. This is shared client and
  * server code. If the message is coming in chunks, then validate the chunk  * server code. If the message is coming in chunks, then validate the chunk
  * sequence number. If the message is being processed on the server side,  * sequence number. If the message is being processed on the server side,
Line 380 
Line 345 
     Boolean isFirst = message.isFirst();     Boolean isFirst = message.isFirst();
     Boolean isLast = message.isComplete();     Boolean isLast = message.isComplete();
     Sint32 totalBytesWritten = 0;     Sint32 totalBytesWritten = 0;
     Uint32 messageLength = buffer.size();      Uint32 messageLength = (Uint32) buffer.size();
  
     try     try
     {     {
Line 403 
Line 368 
             buffer.reserveCapacity(messageLength + 1);             buffer.reserveCapacity(messageLength + 1);
             messageStart = (char *) buffer.getData();             messageStart = (char *) buffer.getData();
             messageStart[messageLength] = 0;             messageStart[messageLength] = 0;
             PEG_TRACE((TRC_XML_IO, Tracer::LEVEL2,              Tracer::trace(
                 "<!-- Response: queue id: %u -->\n%s",                  TRC_XML_IO,
                   Tracer::LEVEL2, "<!-- Response: queue id: %u -->\n%s",
                 getQueueId(),                 getQueueId(),
                 buffer.getData()));                  buffer.getData());
             if (isFirst == true)             if (isFirst == true)
             {             {
                 _incomingBuffer.clear();                 _incomingBuffer.clear();
Line 414 
Line 380 
                 _transferEncodingChunkOffset = 0;                 _transferEncodingChunkOffset = 0;
                 _mpostPrefix.clear();                 _mpostPrefix.clear();
                 cimException = CIMException();                 cimException = CIMException();
                   _responsePending = true;
             }             }
             else             else
             {             {
Line 474 
Line 441 
                         String httpStatus(s);                         String httpStatus(s);
                         Buffer message = XmlWriter::formatHttpErrorRspMessage                         Buffer message = XmlWriter::formatHttpErrorRspMessage
                             (httpStatus, String(), httpDetail);                             (httpStatus, String(), httpDetail);
                         messageLength = message.size();                          messageLength = (Uint32)message.size();
                         message.reserveCapacity(messageLength+1);                         message.reserveCapacity(messageLength+1);
                         messageStart = (char *) message.getData();                         messageStart = (char *) message.getData();
                         messageStart[messageLength] = 0;                         messageStart[messageLength] = 0;
Line 487 
Line 454 
                 {                 {
                     // subsequent chunks from the server, just append                     // subsequent chunks from the server, just append
  
                     messageLength += _incomingBuffer.size();                      messageLength += (Uint32)(_incomingBuffer.size());
                     _incomingBuffer.reserveCapacity(messageLength+1);                     _incomingBuffer.reserveCapacity(messageLength+1);
                     _incomingBuffer.append(buffer.getData(), buffer.size());                     _incomingBuffer.append(buffer.getData(), buffer.size());
                     buffer.clear();                     buffer.clear();
Line 515 
Line 482 
                         String messageS = cimException.getMessage();                         String messageS = cimException.getMessage();
                         CString messageC = messageS.getCString();                         CString messageC = messageS.getCString();
                         messageStart = (char *) (const char *) messageC;                         messageStart = (char *) (const char *) messageC;
                         messageLength = strlen(messageStart);                          messageLength = (Uint32)strlen(messageStart);
                         buffer.reserveCapacity(messageLength+1);                         buffer.reserveCapacity(messageLength+1);
                         buffer.append(messageStart, messageLength);                         buffer.append(messageStart, messageLength);
                         // null terminate                         // null terminate
Line 603 
Line 570 
                         headerNameTerminatorLength + numberAsStringLength;                         headerNameTerminatorLength + numberAsStringLength;
  
                     Uint32 contentLengthLineLengthFound =                     Uint32 contentLengthLineLengthFound =
                         contentLengthEnd - contentLengthStart;                          (Uint32)(contentLengthEnd - contentLengthStart);
  
                     if (isValid == false || ! contentLengthEnd ||                     if (isValid == false || ! contentLengthEnd ||
                             contentLengthLineLengthFound !=                             contentLengthLineLengthFound !=
Line 696 
Line 663 
                             Uint32 insertOffset =                             Uint32 insertOffset =
                                 headerLength - headerLineTerminatorLength;                                 headerLength - headerLineTerminatorLength;
                             messageLength =                             messageLength =
                                 contentLanguagesString.size() + buffer.size();                                  (Uint32)(contentLanguagesString.size() +
                                       buffer.size());
                             buffer.reserveCapacity(messageLength+1);                             buffer.reserveCapacity(messageLength+1);
                             messageLength = contentLanguagesString.size();                              messageLength =
                                   (Uint32)contentLanguagesString.size();
                             messageStart =                             messageStart =
                                 (char *)contentLanguagesString.getData();                                 (char *)contentLanguagesString.getData();
                             // insert the content language line before end                             // insert the content language line before end
Line 706 
Line 675 
                             // note: this can be expensive on large payloads                             // note: this can be expensive on large payloads
                             buffer.insert(                             buffer.insert(
                                 insertOffset, messageStart, messageLength);                                 insertOffset, messageStart, messageLength);
                             messageLength = buffer.size();                              messageLength = (Uint32)buffer.size();
                             // null terminate                             // null terminate
                             messageStart = (char *) buffer.getData();                             messageStart = (char *) buffer.getData();
                             messageStart[messageLength] = 0;                             messageStart[messageLength] = 0;
Line 776 
Line 745 
  
         } // if not a client         } // if not a client
  
         PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
                 "HTTPConnection::_handleWriteEvent: Server write event.");  
   
         SignalHandler::ignore(PEGASUS_SIGPIPE);         SignalHandler::ignore(PEGASUS_SIGPIPE);
  
         // use the next four lines to test the SIGABRT handler         // use the next four lines to test the SIGABRT handler
Line 797 
Line 763 
             // dont include header terminator yet             // dont include header terminator yet
             Uint32 headerLength = bytesToWrite;             Uint32 headerLength = bytesToWrite;
             bytesToWrite -= headerLineTerminatorLength;             bytesToWrite -= headerLineTerminatorLength;
             PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
               "HTTPConnection::_handleWriteEvent: "  
               "Sending header for chunked reponses.");  
  
             bytesWritten = _socket->write(sendStart, bytesToWrite);             bytesWritten = _socket->write(sendStart, bytesToWrite);
             if (bytesWritten < 0)             if (bytesWritten < 0)
Line 814 
Line 777 
                 _mpostPrefix << headerNameDescription << headerValueSeparator <<                 _mpostPrefix << headerNameDescription << headerValueSeparator <<
                 headerNameContentLanguage << headerLineTerminator;                 headerNameContentLanguage << headerLineTerminator;
             sendStart = (char *) trailer.getData();             sendStart = (char *) trailer.getData();
             bytesToWrite = trailer.size();              bytesToWrite = (Uint32)trailer.size();
   
             PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
                     "HTTPConnection::_handleWriteEvent: "  
                     "Sending trailer header for chunked responses.");  
   
             bytesWritten = _socket->write(sendStart, bytesToWrite);             bytesWritten = _socket->write(sendStart, bytesToWrite);
  
             if (bytesWritten < 0)             if (bytesWritten < 0)
Line 831 
Line 789 
             // now send header terminator             // now send header terminator
             bytesToWrite = headerLineTerminatorLength;             bytesToWrite = headerLineTerminatorLength;
             sendStart = messageStart + headerLength - bytesToWrite;             sendStart = messageStart + headerLength - bytesToWrite;
   
             PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
                     "HTTPConnection::_handleWriteEvent: "  
                     "Sending header terminator for chunked responses.");  
   
             bytesWritten = _socket->write(sendStart, bytesToWrite);             bytesWritten = _socket->write(sendStart, bytesToWrite);
             if (bytesWritten < 0)             if (bytesWritten < 0)
                 _socketWriteError();                 _socketWriteError();
Line 860 
Line 813 
                 // terminator                 // terminator
                 sprintf(chunkLine, "%x%s", bytesToWrite, chunkLineTerminator);                 sprintf(chunkLine, "%x%s", bytesToWrite, chunkLineTerminator);
                 sendStart = chunkLine;                 sendStart = chunkLine;
                 Sint32 chunkBytesToWrite = strlen(sendStart);                  Sint32 chunkBytesToWrite = (Sint32)strlen(sendStart);
   
                 PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
                         "HTTPConnection::_handleWriteEvent: "  
                         "Sending chunk with chunk line terminator.");  
   
                 bytesWritten = _socket->write(sendStart, chunkBytesToWrite);                 bytesWritten = _socket->write(sendStart, chunkBytesToWrite);
                 if (bytesWritten < 0)                 if (bytesWritten < 0)
                     _socketWriteError();                     _socketWriteError();
Line 887 
Line 835 
             {             {
               sendStart = messageStart + messageLength - bytesRemaining;               sendStart = messageStart + messageLength - bytesRemaining;
               bytesToWrite = _Min(httpTcpBufferSize, bytesRemaining);               bytesToWrite = _Min(httpTcpBufferSize, bytesRemaining);
   
               PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
                       "HTTPConnection::_handleWriteEvent: "  
                       "Sending non-chunked data.");  
   
               bytesWritten = _socket->write(sendStart, bytesToWrite);               bytesWritten = _socket->write(sendStart, bytesToWrite);
               if (bytesWritten < 0)               if (bytesWritten < 0)
                   _socketWriteError();                   _socketWriteError();
Line 953 
Line 896 
  
                 if (traceTrailer)                 if (traceTrailer)
                 {                 {
                     PEG_TRACE((TRC_XML_IO, Tracer::LEVEL2,                      Tracer::trace(TRC_XML_IO,Tracer::LEVEL2,
                         "<!-- Trailer: queue id: %u -->\n%s",                          "<!-- Trailer: queue id: %u -->\n%s \n",
                         getQueueId(),                         getQueueId(),
                         trailer.getData()));                          trailer.getData());
                 }                 }
                 sendStart = (char *) trailer.getData();                 sendStart = (char *) trailer.getData();
                 Sint32 chunkBytesToWrite = (Sint32) trailer.size();                 Sint32 chunkBytesToWrite = (Sint32) trailer.size();
   
                 PEG_TRACE_CSTRING(TRC_HTTP,Tracer::LEVEL4,  
                         "HTTPConnection::_handleWriteEvent: "  
                         "Sending the last chunk with chunk body terminator ");  
   
                 bytesWritten = _socket->write(sendStart, chunkBytesToWrite);                 bytesWritten = _socket->write(sendStart, chunkBytesToWrite);
                 if (bytesWritten < 0)                 if (bytesWritten < 0)
                     _socketWriteError();                     _socketWriteError();
Line 982 
Line 920 
     catch (...)     catch (...)
     {     {
         httpStatus = HTTP_STATUS_INTERNALSERVERERROR;         httpStatus = HTTP_STATUS_INTERNALSERVERERROR;
         PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, "Unknown internal error");          String message("Unknown internal error");
           Tracer::trace(__FILE__, __LINE__, TRC_HTTP, Tracer::LEVEL2, message);
     }     }
  
     if (isLast == true)     if (isLast == true)
Line 990 
Line 929 
         _incomingBuffer.clear();         _incomingBuffer.clear();
         _transferEncodingTEValues.clear();         _transferEncodingTEValues.clear();
  
         // Reset the transfer encoding chunk offset. If it is not reset here,  
         // then a request sent with chunked encoding may not be properly read  
         // off of a connection in which a chunked response has been sent.  
         _transferEncodingChunkOffset = 0;  
         //         //
         // decrement request count         // decrement request count
         //         //
  
         _requestCount--;         _requestCount--;
         _responsePending = false;  
  
         if (httpStatus.size() == 0)         if (httpStatus.size() == 0)
         {         {
Line 1009 
Line 943 
                 "A total of %d requests have been processed on this "                 "A total of %d requests have been processed on this "
                     "connection.";                     "connection.";
  
             PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, msg, totalBytesWritten,              Tracer::trace(TRC_HTTP, Tracer::LEVEL4, msg, totalBytesWritten,
                 messageLength, _requestCount.get(), _connectionRequestCount));                  messageLength, _requestCount.get(), _connectionRequestCount);
         }         }
  
         //         //
Line 1022 
Line 956 
             // Check for message to close             // Check for message to close
             if (message.getCloseConnect()== true)             if (message.getCloseConnect()== true)
             {             {
                 PEG_TRACE((                  Tracer::trace(
                     TRC_HTTP,                     TRC_HTTP,
                     Tracer::LEVEL3,                     Tracer::LEVEL3,
                     "HTTPConnection::_handleWriteEvent - Connection: Close "                     "HTTPConnection::_handleWriteEvent - Connection: Close "
                         "in client message."));                          "in client message.");
                 _closeConnection();                 _closeConnection();
             }             }
             else             else
             {             {
                 // Update the connection idle time.                  Tracer::trace (TRC_HTTP, Tracer::LEVEL2,
                 if (_idleConnectionTimeoutSeconds)                      "Now setting state to %d", _MonitorEntry::IDLE);
                 {  
                     Time::gettimeofday(&_idleStartTime);  
                 }  
                 PEG_TRACE((TRC_HTTP, Tracer::LEVEL2,  
                     "Now setting state to %d", _MonitorEntry::IDLE));  
                 _monitor->setState (_entry_index, _MonitorEntry::IDLE);                 _monitor->setState (_entry_index, _MonitorEntry::IDLE);
                 _monitor->tickle();                 _monitor->tickle();
             }             }
               _responsePending = false;
             cimException = CIMException();             cimException = CIMException();
         }         }
     }     }
Line 1095 
Line 1025 
  
     for (Uint32 i = 0; i < METHOD_NAMES_SIZE; i++)     for (Uint32 i = 0; i < METHOD_NAMES_SIZE; i++)
     {     {
         Uint32 n = strlen(METHOD_NAMES[i]);          Uint32 n = (Uint32)strlen(METHOD_NAMES[i]);
  
         if (strncmp(line, METHOD_NAMES[i], n) == 0 && isspace(line[n]))         if (strncmp(line, METHOD_NAMES[i], n) == 0 && isspace(line[n]))
             return true;             return true;
Line 1106 
Line 1036 
  
     for (Uint32 i = 0; i < RESPONSE_CODES_SIZE; i++)     for (Uint32 i = 0; i < RESPONSE_CODES_SIZE; i++)
     {     {
         Uint32 n = strlen(RESPONSE_CODES[i]);          Uint32 n = (Uint32)strlen(RESPONSE_CODES[i]);
  
         if (strncmp(line, RESPONSE_CODES[i], n - 2) == 0 && isspace(line[n]))         if (strncmp(line, RESPONSE_CODES[i], n - 2) == 0 && isspace(line[n]))
                 return true;                 return true;
Line 1155 
Line 1085 
 { {
     static const char func[] =     static const char func[] =
     "HTTPConnection::_getContentLengthAndContentOffset";     "HTTPConnection::_getContentLengthAndContentOffset";
     Uint32 size = _incomingBuffer.size();      Uint32 size = (Uint32)_incomingBuffer.size();
     if (size == 0)     if (size == 0)
         return;         return;
     char* data = (char*)_incomingBuffer.getData();     char* data = (char*)_incomingBuffer.getData();
Line 1168 
Line 1098 
     Boolean gotContentLanguage = false;     Boolean gotContentLanguage = false;
     Boolean gotTransferTE = false;     Boolean gotTransferTE = false;
  
     while ((sep = HTTPMessage::findSeparator(line, size - (line - data))))      while ((sep = _FindSeparator(line, (Uint32)(size - (line - data)))))
     {     {
         char save = *sep;         char save = *sep;
         *sep = '\0';         *sep = '\0';
Line 1179 
Line 1109 
         {         {
             *sep = save;             *sep = save;
             line = sep + ((save == '\r') ? 2 : 1);             line = sep + ((save == '\r') ? 2 : 1);
             _contentOffset = line - _incomingBuffer.getData();              _contentOffset = (Sint32)(line - _incomingBuffer.getData());
  
             // reserve space for entire non-chunked message             // reserve space for entire non-chunked message
             if (_contentLength > 0)             if (_contentLength > 0)
Line 1293 
Line 1223 
                     // note: if this is a chunked header, then this will be                     // note: if this is a chunked header, then this will be
                     // ignored later                     // ignored later
                     String contentLanguagesString(                     String contentLanguagesString(
                         valueStart, valueEnd - valueStart + 1);                          valueStart, (Uint32)(valueEnd - valueStart + 1));
                     try                     try
                     {                     {
                         ContentLanguageList contentLanguagesValue =                         ContentLanguageList contentLanguagesValue =
Line 1319 
Line 1249 
                     }                     }
                     catch (...)                     catch (...)
                     {                     {
                         PEG_TRACE((TRC_HTTP, Tracer::LEVEL2,                          Tracer::trace(TRC_HTTP, Tracer::LEVEL2,
                             "HTTPConnection: ERROR: contentLanguages had "                             "HTTPConnection: ERROR: contentLanguages had "
                                 "parsing failure. clearing languages. error "                                 "parsing failure. clearing languages. error "
                                 "data=%s",                                 "data=%s",
                             (const char *)contentLanguagesString.getCString()));                              (const char *)contentLanguagesString.getCString());
                         contentLanguages.clear();                         contentLanguages.clear();
                     }                     }
                 }                 }
Line 1421 
Line 1351 
     {     {
         if (_responsePending == true)         if (_responsePending == true)
         {         {
             PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,              Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "HTTPConnection::_closeConnection - Close connection "                 "HTTPConnection::_closeConnection - Close connection "
                     "requested while responses are still expected on this "                     "requested while responses are still expected on this "
                     "connection. connection=0x%p, socket=%d\n",                     "connection. connection=0x%p, socket=%d\n",
                 (void*)this, getSocket()));                  (void*)this, getSocket());
  
         }         }
  
         // still set to DYING         // still set to DYING
         PEG_TRACE((TRC_HTTP, Tracer::LEVEL2,          Tracer::trace(TRC_HTTP, Tracer::LEVEL2,
             "Now setting state to %d", _MonitorEntry::DYING));              "Now setting state to %d", _MonitorEntry::DYING);
         _monitor->setState (_entry_index, _MonitorEntry::DYING);         _monitor->setState (_entry_index, _MonitorEntry::DYING);
         _monitor->tickle();         _monitor->tickle();
     }     }
  
     if (_connectionRequestCount == 0)     if (_connectionRequestCount == 0)
     {     {
         PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,          Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
             "HTTPConnection::_closeConnection - Connection being closed "             "HTTPConnection::_closeConnection - Connection being closed "
                 "without receiving any requests.");                 "without receiving any requests.");
     }     }
Line 1502 
Line 1432 
         "HTTPConnection::_handleReadEventTransferEncoding";         "HTTPConnection::_handleReadEventTransferEncoding";
     PEG_METHOD_ENTER(TRC_HTTP, func);     PEG_METHOD_ENTER(TRC_HTTP, func);
  
     Uint32 messageLength = _incomingBuffer.size();      Uint32 messageLength = (Uint32)_incomingBuffer.size();
     Uint32 headerLength = (Uint32) _contentOffset;     Uint32 headerLength = (Uint32) _contentOffset;
  
     // return immediately under these conditions:     // return immediately under these conditions:
Line 1603 
Line 1533 
         }         }
  
         chunkLineEnd += chunkLineTerminatorLength;         chunkLineEnd += chunkLineTerminatorLength;
         Uint32 chunkLineLength = chunkLineEnd - chunkLineStart;          Uint32 chunkLineLength = (Uint32)(chunkLineEnd - chunkLineStart);
         Uint32 chunkMetaLength = chunkLineLength;         Uint32 chunkMetaLength = chunkLineLength;
         if (chunkLengthParsed > 0)         if (chunkLengthParsed > 0)
             chunkMetaLength += chunkTerminatorLength;             chunkMetaLength += chunkTerminatorLength;
Line 1636 
Line 1566 
  
         // remove the chunk length line         // remove the chunk length line
         _incomingBuffer.remove(_transferEncodingChunkOffset, chunkLineLength);         _incomingBuffer.remove(_transferEncodingChunkOffset, chunkLineLength);
         messageLength = _incomingBuffer.size();          messageLength = (Uint32)_incomingBuffer.size();
         // always keep the byte after the last data byte null for easy string         // always keep the byte after the last data byte null for easy string
         // processing.         // processing.
         messageStart[messageLength] = 0;         messageStart[messageLength] = 0;
Line 1685 
Line 1615 
                 trailerStart[trailerLength] = save;                 trailerStart[trailerLength] = save;
  
                 _incomingBuffer.remove(trailerOffset, trailerLength);                 _incomingBuffer.remove(trailerOffset, trailerLength);
                 messageLength = _incomingBuffer.size();                  messageLength = (Uint32)_incomingBuffer.size();
                 messageStart[messageLength] = 0;                 messageStart[messageLength] = 0;
                 remainderLength -= trailerLength;                 remainderLength -= trailerLength;
  
Line 1777 
Line 1707 
                         }                         }
                         catch (...)                         catch (...)
                         {                         {
                             PEG_TRACE((TRC_HTTP, Tracer::LEVEL2,                              Tracer::trace(TRC_HTTP, Tracer::LEVEL2,
                                 "HTTPConnection: ERROR: contentLanguages had "                                 "HTTPConnection: ERROR: contentLanguages had "
                                     "parsing failure. clearing languages. "                                     "parsing failure. clearing languages. "
                                     "error data=%s",                                     "error data=%s",
                                 (const char *)contentLanguagesString.                                 (const char *)contentLanguagesString.
                                     getCString()));                                      getCString());
                             contentLanguages.clear();                             contentLanguages.clear();
                         }                         }
                     }                     }
Line 1849 
Line 1779 
  
         // now remove the chunk terminator         // now remove the chunk terminator
         _incomingBuffer.remove(chunkTerminatorOffset, chunkTerminatorLength);         _incomingBuffer.remove(chunkTerminatorOffset, chunkTerminatorLength);
         messageLength = _incomingBuffer.size();          messageLength = (Uint32)_incomingBuffer.size();
         messageStart[messageLength] = 0;         messageStart[messageLength] = 0;
  
         // jump to the start of the next chunk (which may not have been         // jump to the start of the next chunk (which may not have been
Line 1881 
Line 1811 
             delimiterFound + httpDetailDelimiter.size());             delimiterFound + httpDetailDelimiter.size());
     }     }
  
     PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,      Tracer::trace(__FILE__, __LINE__, TRC_HTTP, Tracer::LEVEL2,
         httpStatus + httpDetailDelimiter + httpDetail +         httpStatus + httpDetailDelimiter + httpDetail +
             httpDetailDelimiter + cimError);             httpDetailDelimiter + cimError);
  
Line 1890 
Line 1820 
     message = XmlWriter::formatHttpErrorRspMessage(httpStatus, cimError,     message = XmlWriter::formatHttpErrorRspMessage(httpStatus, cimError,
         httpDetail);         httpDetail);
     HTTPMessage* httpMessage = new HTTPMessage(message);     HTTPMessage* httpMessage = new HTTPMessage(message);
       Tracer::traceBuffer(TRC_XML_IO, Tracer::LEVEL2,
           httpMessage->message.getData(),
           (Uint32)(httpMessage->message.size()));
  
     // this is common error code. If we are the server side, we want to send     // this is common error code. If we are the server side, we want to send
     // back the error to the client, but if we are the client side, then we     // back the error to the client, but if we are the client side, then we
Line 1908 
Line 1841 
     else     else
     {     {
         // else server side processing error - send back to client         // else server side processing error - send back to client
         PEG_TRACE((TRC_XML_IO, Tracer::LEVEL2,  
             "<!-- Error response: queue id: %u -->\n%s",  
             getQueueId(),  
             httpMessage->message.getData()));  
         handleEnqueue(httpMessage);         handleEnqueue(httpMessage);
     }     }
     _closeConnection();     _closeConnection();
Line 1930 
Line 1859 
  
         if (socketAcceptStatus < 0)         if (socketAcceptStatus < 0)
         {         {
             PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,              PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "HTTPConnection: SSL_accept() failed");                 "HTTPConnection: SSL_accept() failed");
             _closeConnection();             _closeConnection();
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
Line 1939 
Line 1868 
         else if (socketAcceptStatus == 0)         else if (socketAcceptStatus == 0)
         {         {
             // Not enough data yet to complete the SSL handshake             // Not enough data yet to complete the SSL handshake
             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,              PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
                 "HTTPConnection: SSL_accept() pending");                 "HTTPConnection: SSL_accept() pending");
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return;             return;
Line 1953 
Line 1882 
                 if (_socket->isPeerVerificationEnabled() &&                 if (_socket->isPeerVerificationEnabled() &&
                     _socket->isCertificateVerified())                     _socket->isCertificateVerified())
                 {                 {
                     _authInfo->setConnectionAuthenticated(true);                      _authInfo->setAuthStatus(
                           AuthenticationInfoRep::AUTHENTICATED);
                     _authInfo->setAuthType(                     _authInfo->setAuthType(
                         AuthenticationInfoRep::AUTH_TYPE_SSL);                         AuthenticationInfoRep::AUTH_TYPE_SSL);
                     _authInfo->setClientCertificateChain(                     _authInfo->setClientCertificateChain(
Line 1962 
Line 1892 
 #else #else
                 if (_socket->isClientAuthenticated())                 if (_socket->isClientAuthenticated())
                 {                 {
                     _authInfo->setConnectionAuthenticated(true);                      _authInfo->setAuthStatus(
                           AuthenticationInfoRep::AUTHENTICATED);
                     _authInfo->setAuthenticatedUser(                     _authInfo->setAuthenticatedUser(
                         _socket->getAuthenticatedUser());                         _socket->getAuthenticatedUser());
                 }                 }
Line 1978 
Line 1909 
  
     // -- Append all data waiting on socket to incoming buffer:     // -- Append all data waiting on socket to incoming buffer:
  
       String httpStatus;
     Sint32 bytesRead = 0;     Sint32 bytesRead = 0;
     Boolean incompleteSecureReadOccurred = false;     Boolean incompleteSecureReadOccurred = false;
  
     for (;;)     for (;;)
     {     {
         char buffer[httpTcpBufferSize];          // save one for null
           char buffer[httpTcpBufferSize+1];
           buffer[sizeof(buffer)-1] = 0;
  
         Sint32 n = _socket->read(buffer, sizeof(buffer)-1);         Sint32 n = _socket->read(buffer, sizeof(buffer)-1);
  
         // Check if this was the first read of a connection to the server.  
         // This has to happen inside the read loop, because there can be  
         // an incomplete SSL read.  
         if (_firstRead && n > 5 && !_isClient())  
         {  
             // The first bytes of a connection to the server have to contain  
             // a valid cim-over-http HTTP Method (M-POST or POST).  
             if ((strncmp(buffer, "POST", 4) != 0) &&  
                 (strncmp(buffer, "M-POST", 6) != 0))  
             {  
                 _clearIncoming();  
   
                 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,  
                       "This Request has non-valid CIM-HTTP Method: "  
                       "%02X %02X %02X %02X %02X %02X",  
                       buffer[0],buffer[1],buffer[2],  
                       buffer[3],buffer[4],buffer[5]));  
   
                 // Try to send message to client.  
                 // This function also closes the connection.  
                 _handleReadEventFailure(HTTP_STATUS_NOTIMPLEMENTED);  
   
                 PEG_METHOD_EXIT();  
                 return;  
             }  
             _firstRead = false;  
         }  
   
         if (n <= 0)         if (n <= 0)
         {         {
               if (_socket->isSecure())
               {
             // It is possible that SSL_read was not able to             // It is possible that SSL_read was not able to
             // read the entire SSL record.  This could happen             // read the entire SSL record.  This could happen
             // if the record was send in multiple packets             // if the record was send in multiple packets
Line 2031 
Line 1939 
             // disconnect and partial read of an SSL record.             // disconnect and partial read of an SSL record.
             //             //
             incompleteSecureReadOccurred =             incompleteSecureReadOccurred =
                 _socket->incompleteSecureReadOccurred(n);                      _socket->incompleteReadOccurred(n);
               }
             break;             break;
         }         }
  
         try         try
         {         {
             _incomingBuffer.reserveCapacity(_incomingBuffer.size() + n);              buffer[n] = 0;
               // important: always keep message buffer null terminated for easy
               // string parsing!
               Uint32 size = (Uint32)(_incomingBuffer.size() + n);
               _incomingBuffer.reserveCapacity(size + 1);
             _incomingBuffer.append(buffer, n);             _incomingBuffer.append(buffer, n);
               // put a null on it. This is safe sice we have reserved an
               // extra byte
               char *data = (char *)_incomingBuffer.getData();
               data[size] = 0;
         }         }
         catch (...)         catch (...)
         {         {
             static const char detailP[] =             static const char detailP[] =
                 "Unable to append the request to the input buffer";                 "Unable to append the request to the input buffer";
             String httpStatus =              httpStatus =
                 HTTP_STATUS_REQUEST_TOO_LARGE + httpDetailDelimiter + detailP;                 HTTP_STATUS_REQUEST_TOO_LARGE + httpDetailDelimiter + detailP;
             _handleReadEventFailure(httpStatus);             _handleReadEventFailure(httpStatus);
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
Line 2064 
Line 1981 
 #endif #endif
     }     }
  
     PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,      Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
         "Total bytesRead = %d; Bytes read this iteration = %d",         "Total bytesRead = %d; Bytes read this iteration = %d",
         _incomingBuffer.size(), bytesRead));          _incomingBuffer.size(), bytesRead);
  
     try     try
     {     {
Line 2076 
Line 1993 
     }     }
     catch (Exception& e)     catch (Exception& e)
     {     {
         _handleReadEventFailure(e.getMessage());          httpStatus = e.getMessage();
       }
   
       if (httpStatus.size() > 0)
       {
           _handleReadEventFailure(httpStatus);
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         return;         return;
     }     }
Line 2090 
Line 2012 
         (_contentLength != -1 && _contentOffset != -1 &&         (_contentLength != -1 && _contentOffset != -1 &&
         (Sint32(_incomingBuffer.size()) >= _contentLength + _contentOffset)))         (Sint32(_incomingBuffer.size()) >= _contentLength + _contentOffset)))
     {     {
         // If no message was received, just close the connection  
         if (_incomingBuffer.size() == 0)  
         {  
             _clearIncoming();  
   
             PEG_TRACE((TRC_XML_IO, Tracer::LEVEL2,  
                 "<!-- No request message received; connection closed: "  
                     "queue id: %u -->",  
                 getQueueId()));  
             _closeConnection();  
   
             PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,  
                 "_requestCount = %d", _requestCount.get()));  
   
             //  
             // If we are executing on the server side, the connection  
             // is closed, return. Do not forward an empty HTTP message.  
             //  
             if (!_isClient())  
             {  
                 PEG_METHOD_EXIT();  
                 return;  
             }  
         }  
   
         // If the connection was closed and we are executing on the client  
         // side send an empty HTTP message. Otherwise, a message was  
         // received, so process it.  
   
         HTTPMessage* message = new HTTPMessage(_incomingBuffer, getQueueId());         HTTPMessage* message = new HTTPMessage(_incomingBuffer, getQueueId());
         message->authInfo = _authInfo.get();         message->authInfo = _authInfo.get();
         message->ipAddress = _ipAddress;         message->ipAddress = _ipAddress;
         message->contentLanguages = contentLanguages;  
         message->dest = _outputMessageQueue->getQueueId();  
   
         //  
         // The _closeConnection method sets the _connectionClosePending flag.  
         // If we are executing on the client side and the  
         // _connectionClosePending flag is set, send an empty HTTP message.  
         //  
         if (_connectionClosePending)  
         {  
             _outputMessageQueue->enqueue(message);  
             PEG_METHOD_EXIT();  
             return;  
         }  
  
         if (_isClient() == false)          // add any content languages
         {          message->contentLanguages = contentLanguages;
 #ifndef PEGASUS_REMOVE_TRACE  
             if (Tracer::isTraceOn())  
             {  
                 AutoArrayPtr<char> requestTrace(  
                     Tracer::getHTTPRequestMessage(_incomingBuffer));  
                 PEG_TRACE((TRC_XML_IO, Tracer::LEVEL2,  
                     "<!-- Request: queue id: %u -->\n%s",  
                     getQueueId(),  
                     requestTrace.get()));  
             }  
 #endif  
         }  
  
         //         //
         // increment request count         // increment request count
         //         //
           if (bytesRead > 0)
           {
         _requestCount++;         _requestCount++;
         _connectionRequestCount++;         _connectionRequestCount++;
         _responsePending = true;          }
           Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
         PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,              "_requestCount = %d", _requestCount.get());
             "_requestCount = %d", _requestCount.get()));          message->dest = _outputMessageQueue->getQueueId();
   //        SendForget(message);
  
         //         //
         // Set the entry status to BUSY.         // Set the entry status to BUSY.
         //         //
         if (_isClient() == false)          if (_isClient() == false && !_connectionClosePending)
         {         {
             PEG_TRACE((TRC_HTTP, Tracer::LEVEL2,              Tracer::trace (TRC_HTTP, Tracer::LEVEL2,
                 "Now setting state to %d", _MonitorEntry::BUSY));                  "Now setting state to %d", _MonitorEntry::BUSY);
             _monitor->setState (_entry_index, _MonitorEntry::BUSY);             _monitor->setState (_entry_index, _MonitorEntry::BUSY);
             _monitor->tickle();             _monitor->tickle();
         }         }
   
         try         try
         {         {
             _outputMessageQueue->enqueue(message);             _outputMessageQueue->enqueue(message);
Line 2185 
Line 2054 
         }         }
  
         _clearIncoming();         _clearIncoming();
   
           if (bytesRead == 0)
           {
               Tracer::trace(TRC_HTTP, Tracer::LEVEL3,
                   "HTTPConnection::_handleReadEvent - bytesRead == 0 - "
                       "Connection being closed.");
               _closeConnection();
   
               //
               // decrement request count
               //
               Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                   "_requestCount = %d", _requestCount.get());
   
               PEG_METHOD_EXIT();
               return;
           }
     }     }
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
Line 2198 
Line 2084 
 { {
     Boolean handled_events = false;     Boolean handled_events = false;
     int events = 0;     int events = 0;
     fd_set fdread;      fd_set fdread; // , fdwrite;
     struct timeval tv = { 0, 1 };     struct timeval tv = { 0, 1 };
     FD_ZERO(&fdread);     FD_ZERO(&fdread);
     FD_SET(getSocket(), &fdread);     FD_SET(getSocket(), &fdread);
Line 2220 
Line 2106 
             }             }
             catch (...)             catch (...)
             {             {
                 PEG_TRACE_CSTRING(                  Tracer::trace(
                     TRC_DISCARDED_DATA,                     TRC_DISCARDED_DATA,
                     Tracer::LEVEL2,                     Tracer::LEVEL2,
                     "HTTPConnection::run handleEnqueue(msg) failure");                     "HTTPConnection::run handleEnqueue(msg) failure");


Legend:
Removed from v.1.125.4.15  
changed lines
  Added in v.1.126

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2