Ejemplo n.º 1
0
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);
        }
    }
}
Ejemplo n.º 2
0
//Parses the request
QTSS_Error HTTPRequest::Parse()
{
	Assert(fRequestHeader.Ptr != NULL);
	StringParser parser(&fRequestHeader);

	// Store the request line (used for logging) 
	// (ex: GET /index.html HTTP/1.0)
	StringParser requestLineParser(&fRequestHeader);
	requestLineParser.ConsumeUntil(&fRequestLine, StringParser::sEOLMask);

	// Parse request line returns an error if there is an error in the
	// request URI or the formatting of the request line. 
	// If the method or version are not found, they are set
	// to httpIllegalMethod or httpIllegalVersion respectively, 
	// and QTSS_NoErr is returned.
	QTSS_Error err = QTSS_NoErr;
	do {
		err = parseRequestLine(&parser);
		if (err != QTSS_NoErr)
			return err;
	} while (fHTTPType == httpIllegalType);

	// Parse headers and set values of headers into fFieldValues array
	err = parseHeaders(&parser);
	if (err != QTSS_NoErr)
		return err;

	return QTSS_NoErr;
}
Ejemplo n.º 3
0
/**
 * @brief Parse socket data.
 * @param [in] s The socket from which to retrieve data.
 */
void HttpParser::parse(Socket s) {
	std::string line;
	line = s.readToDelim(lineTerminator);
	parseRequestLine(line);
	line = s.readToDelim(lineTerminator);
	while(!line.empty()) {
		m_headers.insert(parseHeader(line));
		line = s.readToDelim(lineTerminator);
	}
	// Only PUT and POST requests have a body
	if (getMethod() != "POST" && getMethod() != "PUT") {
		return;
	}

	// We have now parsed up to and including the separator ... we are now at the point where we
	// want to read the body.  There are two stories here.  The first is that we know the exact length
	// of the body or we read until we can't read anymore.
	if (hasHeader(HttpRequest::HTTP_HEADER_CONTENT_LENGTH)) {
		std::string val = getHeader(HttpRequest::HTTP_HEADER_CONTENT_LENGTH);
		int length = std::atoi(val.c_str());
		uint8_t data[length];
		s.receive_cpp(data, length, true);
		m_body = std::string((char *)data, length);
	} else {
		uint8_t data[512];
		int rc = s.receive_cpp(data, sizeof(data));
		m_body = std::string((char *)data, rc);
	}
	ESP_LOGD(LOG_TAG, "Size of body: %d", m_body.length());
} // parse
Ejemplo n.º 4
0
HttpParser::status_t
HttpParser::addBytes( const char* bytes, unsigned len )
{
    if ( _status != Incomplete ) {
        return _status;
    }

    // append the bytes to data.
    _data.append( bytes, len );

    if ( _state < p_content ) {
        parseHeader();
    }

    if ( _state == p_error ) {
        _status = Error;
    } else if ( _state == p_content ) {
        if ( _contentLength == 0 || _data.length() - _contentStart >= _contentLength ) {
            if ( parseRequestLine() ) {
                _status = Done;
            } else {
                _status = Error;
            }
        }
    }

    return _status;
}
Ejemplo n.º 5
0
/**
 * Process http request headers (until CRLFCRLF)
 * Check request line and parse headers
 * @param input lines that form the request line and headers
 */
void Socket::processHeaders(const string &input){
	string line;
	size_t offset=0;
	syslog(LOG_DEBUG,"processHeaders: %s",input.c_str());
	do
		line=Util::getLine(input,offset);
	while(line.size()==0 && offset< input.size());
	parseRequestLine(line);
	while((line=Util::getLine(input,offset)).size()){
		parseHeader(line);
	}
}
Ejemplo n.º 6
0
ApiMock::RequestData ApiMock::RequestParser::parse(const std::string& requestBuffer) {
	std::vector<std::string> r = projectToCollection(requestBuffer);
	RequestData request;
	parseRequestLine(&request, r[0]);

	for (unsigned i = 1; i < r.size(); ++i) {
		if (r[i] == "") {
			parseRequestBody(&request, r, i + 1);
			break;
		}

		parseHeader(&request, r[i]);
	}

	return request;
}
Ejemplo n.º 7
0
Http_t Parse_parse (int fd)
{
  http400 = generate400();
  getToken(fd, 1);

  ReqLine_t reqline;
  Http_t http = 0;

  reqline = parseRequestLine (fd);
  parseHeaders(fd);
  if (token.kind!=TOKEN_CRLF)
    parseError(fd);
  parseBody(fd);
  http = Http_new (HTTP_KIND_REQUEST
		   , reqline
		   , 0
		   , 0
		   , 0);

  if (DEBUG)
    Http_print (1, http);
  return http;
}
Ejemplo n.º 8
0
abyss_bool
RequestRead(TSession * const sessionP) {
    uint16_t httpErrorCode;  /* zero for no error */
    char * requestLine;

    readRequestLine(sessionP, &requestLine, &httpErrorCode);
    if (!httpErrorCode) {
        TMethod httpMethod;
        const char * host;
        const char * path;
        const char * query;
        unsigned short port;
        abyss_bool moreHeaders=false;

        parseRequestLine(requestLine, &httpMethod, &sessionP->version,
                         &host, &port, &path, &query,
                         &moreHeaders, &httpErrorCode);

        if (!httpErrorCode)
            initRequestInfo(&sessionP->request_info, sessionP->version,
                            strdup(requestLine),
                            httpMethod, host, port, path, query);

        while (moreHeaders && !httpErrorCode) {
            char * p;
            abyss_bool succeeded;
            succeeded = ConnReadHeader(sessionP->conn, &p);
            if (!succeeded)
                httpErrorCode = 408;  /* Request Timeout */
            else {
                if (!*p)
                    /* We have reached the empty line so all the request
                       was read.
                    */
                    moreHeaders = FALSE;
                else {
                    char * fieldName;
                    getFieldNameToken(&p, &fieldName, &httpErrorCode);
                    if (!httpErrorCode) {
                        char * fieldValue;

                        NextToken((const char **)&p);
                        
                        fieldValue = p;
                        
                        TableAdd(&sessionP->request_headers,
                                 fieldName, fieldValue);
                        
                        processHeader(fieldName, fieldValue, sessionP,
                                      &httpErrorCode);
                    }
                }
            }
        }
    }
    if (httpErrorCode)
        ResponseStatus(sessionP, httpErrorCode);
    else
        sessionP->validRequest = true;

    return !httpErrorCode;
}
Ejemplo n.º 9
0
// received a character from UART
void GSwifi::parseByte(uint8_t dat) {
    static uint8_t  next_token; // split each byte into tokens (cid,ip,port,length,data)
    static bool     escape = false;
    char temp[GS_MAX_PATH_LENGTH+1];

    if (dat == ESCAPE) {
        // 0x1B : Escape
        GSLOG_PRINT("e< ");
    }
    else { // if (next_token != NEXT_TOKEN_DATA) {
        GSLOG_WRITE(dat);
    }

    if (gs_mode_ == GSMODE_COMMAND) {
        if (escape) {
            // esc
            switch (dat) {
            case 'O':
            case 'F':
                // ignore
                break;
            case 'Z':
            case 'H':
                gs_mode_   = GSMODE_DATA_RX_BULK;
                next_token = NEXT_TOKEN_CID;
                break;
            default:
                // GSLOG_PRINT("!E1 "); GSLOG_PRINTLN2(dat,HEX);
                break;
            }
            escape = false;
        }
        else {
            if (dat == ESCAPE) {
                escape = true;
            }
            else if (dat == '\n') {
                // end of line
                parseLine();
            }
            else if (dat != '\r') {
                if ( ! ring_isfull(_buf_cmd) ) {
                    ring_put(_buf_cmd, dat);
                }
                else {
                    GSLOG_PRINTLN("!E2");
                }
            }
        }
        return;
    }
    else if (gs_mode_ != GSMODE_DATA_RX_BULK) {
        return;
    }

    static uint16_t       len;
    static char           len_chars[5];
    static int8_t         current_cid;
    static GSREQUESTSTATE request_state;

    if (next_token == NEXT_TOKEN_CID) {
        // dat is cid
        current_cid = x2i(dat);
        ASSERT((0 <= current_cid) && (current_cid <= 16));

        next_token  = NEXT_TOKEN_LENGTH;
        len         = 0;
    }
    else if (next_token == NEXT_TOKEN_LENGTH) {
        // Data Length is 4 ascii char represents decimal value i.e. 1400 byte (0x31 0x34 0x30 0x30)
        len_chars[ len ++ ] = dat;
        if (len >= 4) {
            len_chars[ len ] = 0;
            len        = atoi(len_chars); // length of data
            next_token = NEXT_TOKEN_DATA;

            if (content_lengths_[ current_cid ] > 0) {
                // this is our 2nd bulk message from GS for this response
                // we already swallowed HTTP response headers,
                // following should be body
                request_state = GSREQUESTSTATE_BODY;
            }
            else {
                request_state = GSREQUESTSTATE_HEAD1;
            }
            ring_clear( _buf_cmd ); // reuse _buf_cmd to store HTTP request
        }
    }
    else if (next_token == NEXT_TOKEN_DATA) {
        len --;

        if (cidIsRequest(current_cid)) { // request against us
            static uint16_t error_code;
            static int8_t   routeid;

            switch (request_state) {
            case GSREQUESTSTATE_HEAD1:
                if (dat != '\n') {
                    if ( ! ring_isfull(_buf_cmd) ) {
                        ring_put( _buf_cmd, dat );
                    }
                    // ignore overflowed
                }
                else {
                    // end of request line

                    // reuse "temp" buffer to parse method and path
                    int8_t  result  = parseRequestLine((char*)temp, 7);
                    GSMETHOD method = GSMETHOD_UNKNOWN;
                    if ( result == 0 ) {
                        method = x2method(temp);
                        result = parseRequestLine((char*)temp, GS_MAX_PATH_LENGTH);
                    }
                    if ( result != 0 ) {
                        // couldn't detect method or path
                        request_state = GSREQUESTSTATE_ERROR;
                        error_code    = 400;
                        ring_clear(_buf_cmd);
                        break;
                    }

                    routeid = router(method, temp);
                    if ( routeid < 0 ) {
                        request_state = GSREQUESTSTATE_ERROR;
                        error_code    = 404;
                        ring_clear(_buf_cmd);
                        break;
                    }
                    request_state                   = GSREQUESTSTATE_HEAD2;
                    continuous_newlines_            = 0;
                    content_lengths_[ current_cid ] = 0;
                    has_requested_with_             = false;
                    ring_clear(_buf_cmd);
                }
                break;
            case GSREQUESTSTATE_HEAD2:
                if(0 == parseHead2(dat, current_cid)) {
                    request_state = GSREQUESTSTATE_BODY;
                    // dispatched once, at start of body
                    dispatchRequestHandler(current_cid, routeid, GSREQUESTSTATE_BODY_START);
                }
                break;
            case GSREQUESTSTATE_BODY:
                if (content_lengths_[ current_cid ] > 0) {
                    content_lengths_[ current_cid ] --;
                }
                if (ring_isfull(_buf_cmd)) {
                    dispatchRequestHandler(current_cid, routeid, request_state); // POST, user callback should write()
                }
                ring_put(_buf_cmd, dat);
                break;
            case GSREQUESTSTATE_ERROR:
                // skip until received whole request
                break;
            case GSREQUESTSTATE_RECEIVED:
            default:
                break;
            }

            // end of bulk transfered data
            if (len == 0) {
                gs_mode_ = GSMODE_COMMAND;

                if ( request_state == GSREQUESTSTATE_ERROR ) {
                    writeHead( current_cid, error_code );
                    writeEnd();
                    ring_put( &commands, COMMAND_CLOSE );
                    ring_put( &commands, current_cid );
                }
                else {
                    if (content_lengths_[ current_cid ] == 0) {
                        // if Content-Length header was longer than <ESC>Z length,
                        // we wait til next bulk transfer
                        request_state = GSREQUESTSTATE_RECEIVED;
                    }
                    // user callback should write(), writeEnd() and close()
                    dispatchRequestHandler(current_cid, routeid, request_state);
                }
                ring_clear(_buf_cmd);
            }
        }
        else {
            // is request from us
            static uint16_t status_code;

            switch (request_state) {
            case GSREQUESTSTATE_HEAD1:
                if (dat != '\n') {
                    if ( ! ring_isfull(_buf_cmd) ) {
                        // ignore if overflowed
                        ring_put( _buf_cmd, dat );
                    }
                }
                else {
                    uint8_t i=0;

                    // skip 9 characters "HTTP/1.1 "
                    while (i++ < 9) {
                        ring_get( _buf_cmd, &temp[0], 1 );
                    }

                    // copy 3 numbers representing status code into temp buffer
                    temp[ 3 ] = 0;
                    int8_t count = ring_get( _buf_cmd, temp, 3 );
                    if (count != 3) {
                        // protocol error
                        // we should receive something like: "200 OK", "401 Unauthorized"
                        status_code   = 999;
                        request_state = GSREQUESTSTATE_ERROR;
                        break;
                    }
                    status_code                     = atoi(temp);
                    request_state                   = GSREQUESTSTATE_HEAD2;
                    continuous_newlines_            = 0;
                    content_lengths_[ current_cid ] = 0;
                    ring_clear(_buf_cmd);
                }
                break;
            case GSREQUESTSTATE_HEAD2:
                if(0 == parseHead2(dat, current_cid)) {
                    request_state = GSREQUESTSTATE_BODY;
                    // dispatched once, at start of body
                    dispatchResponseHandler(current_cid, status_code, GSREQUESTSTATE_BODY_START);
                }
                break;
            case GSREQUESTSTATE_BODY:
                if (content_lengths_[ current_cid ] > 0) {
                    content_lengths_[ current_cid ] --;
                }
                if (ring_isfull(_buf_cmd)) {
                    dispatchResponseHandler(current_cid, status_code, GSREQUESTSTATE_BODY);
                }
                ring_put(_buf_cmd, dat);
                break;
            case GSREQUESTSTATE_ERROR:
            case GSREQUESTSTATE_RECEIVED:
            default:
                break;
            }

            if (len == 0) {
                gs_mode_ = GSMODE_COMMAND;

                if ( request_state == GSREQUESTSTATE_ERROR ) {
                    dispatchResponseHandler(current_cid, status_code, request_state);
                }
                else {
                    if (content_lengths_[ current_cid ] == 0) {
                        // if Content-Length header was longer than <ESC>Z length,
                        // we wait til all response body received.
                        // we need to close our clientRequest before handling it.
                        // GS often locks when closing 2 connections in a row
                        // ex: POST /keys from iPhone (cid:1) -> POST /keys to server (cid:2)
                        //     response from server arrives -> close(1) -> close(2) -> lock!!
                        // the other way around: close(2) -> close(1) doesn't lock :(
                        request_state = GSREQUESTSTATE_RECEIVED;
                    }
                    dispatchResponseHandler(current_cid, status_code, request_state);
                }
                ring_clear( _buf_cmd );
            }
        } // is response
    } // (next_token == NEXT_TOKEN_DATA)
}