void RequestRead(TSession * const sessionP, uint32_t const timeout, const char ** const errorP, uint16_t * const httpErrorCodeP) { /*---------------------------------------------------------------------------- Read the headers of a new HTTP request (assuming nothing has yet been read on the session). Update *sessionP with the information from the headers. Leave the connection positioned to the body of the request, ready to be read by an HTTP request handler (via SessionRefillBuffer() and SessionGetReadData()). -----------------------------------------------------------------------------*/ time_t const deadline = time(NULL) + timeout; uint16_t httpErrorCode; /* zero for no error */ char * requestLine; /* In connection;s internal buffer */ readRequestHeader(sessionP, deadline, &requestLine, &httpErrorCode); if (httpErrorCode) { xmlrpc_asprintf(errorP, "Problem getting the request header"); *httpErrorCodeP = httpErrorCode; } else { TMethod httpMethod; const char * host; const char * path; const char * query; unsigned short port; bool moreHeaders; parseRequestLine(requestLine, &httpMethod, &sessionP->version, &host, &port, &path, &query, &moreHeaders, &httpErrorCode); if (httpErrorCode) { xmlrpc_asprintf(errorP, "Unable to parse the request header " "'%s'", requestLine); *httpErrorCodeP = httpErrorCode; } else { initRequestInfo(&sessionP->requestInfo, sessionP->version, requestLine, httpMethod, host, port, path, query); if (moreHeaders) { readAndProcessHeaders(sessionP, deadline, errorP, httpErrorCodeP); } else *errorP = NULL; if (!*errorP) sessionP->validRequest = true; xmlrpc_strfreenull(host); xmlrpc_strfree(path); xmlrpc_strfreenull(query); } } }
void HttpServer::slotReadyRead() { #ifdef DEBUG_XMLRPC qDebug() << this << "slotReadyRead():" << socket->bytesAvailable() << "bytes available"; #endif if( !socket->bytesAvailable() ) return; switch( state ) { case ReadingHeader: // если заголовок прочитан if( readRequestHeader() ) { // если судя по заголовку есть тело, меняем статус на чтение тела // и попадаем в следующий case if( requestContainsBody() ) state = ReadingBody; } else { // тела нет, бросаем сигнал, что заголовок получен Q_ASSERT( !socket->bytesAvailable() ); state = WaitingReply; #ifdef DEBUG_XMLRPC qDebug() << this << "slotReadyRead(): emit requestReceived()"; #endif emit requestReceived( this, requestHeader, requestBody ); break; } case ReadingBody: if( readRequestBody() ) { // тело прочитано, бросаем сигнал, что запрос получен Q_ASSERT( !socket->bytesAvailable() ); state = WaitingReply; #ifdef DEBUG_XMLRPC qDebug() << this << "slotReadyRead(): emit requestReceived()"; #endif emit requestReceived( this, requestHeader, requestBody ); } break; case WaitingReply: qCritical() << this << "slotReadyRead(): got data in WaitingReply state, emit parseError()"; emit parseError( this ); break; case SendingReply: qCritical() << this << "slotReadyRead(): got data in SendingHeader state, emit parseError()"; emit parseError( this ); break; case Done: qCritical() << this << "slotReadyRead(): got data in Done state, emit parseError()"; emit parseError( this ); break; default: qCritical() << this << "slotReadyRead(): unknown state"; qFatal( "programming error" ); } }