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);
        }
    }
}
Exemple #2
0
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" );
      }
}