int parse_request(struct buf *bufp) { char *p; p = bufp->parse_p; //dbprintf("parse_request:\n\trbuf left to parse:\n%s\n", p); // count request number based on CRLF2 while ((p = strstr(p, CRLF2)) != NULL && p < bufp->rbuf_tail) { ++(bufp->rbuf_req_count); p += strlen(CRLF2); bufp->parse_p = p; } // parse every request while (bufp->rbuf_req_count != 0) { dbprintf("parse_request: request count %d\n", bufp->rbuf_req_count); // calloc http_req if (bufp->req_fully_received == 1) { //dbprintf("parse_request: start parsing new request\n"); bufp->http_req_p = (struct http_req *)calloc(1, sizeof(struct http_req)); bufp->req_fully_received = 0; bufp->req_line_header_received = 0; } // parse req parse_request_line(bufp); parse_request_headers(bufp); bufp->req_line_header_received = 1;// update parse_message_body(bufp); // set req_fully_received inside // if fully received, enqueue if (bufp->req_fully_received == 1) { dbprintf("parse_request: req fully received\n"); // update req_queue req_enqueue(bufp->req_queue_p, bufp->http_req_p); // update rbuf --(bufp->rbuf_req_count); bufp->rbuf_head = strstr(bufp->rbuf_head, CRLF2) + strlen(CRLF2); } else { // only POST can reach here dbprintf("parse_request: POST req not fully received yet, continue receiving\n"); break; // break out while loop } } return 0; }
void SessionImpl::parse_request( const asio::error_code& error, const shared_ptr< Session > session, const function< void ( const shared_ptr< Session > ) >& callback ) try { if ( error ) { throw runtime_error( error.message( ) ); } istream stream( m_buffer.get( ) ); const auto items = parse_request_line( stream ); const auto uri = Uri::parse( "http://localhost" + items.at( "path" ) ); m_request = make_shared< Request >( ); m_request->m_pimpl->m_path = Uri::decode( uri.get_path( ) ); m_request->m_pimpl->m_method = items.at( "method" ); m_request->m_pimpl->m_version = stod( items.at( "version" ) ); m_request->m_pimpl->m_headers = parse_request_headers( stream ); m_request->m_pimpl->m_query_parameters = uri.get_query_parameters( ); callback( session ); } catch ( const int status_code ) { runtime_error re( m_settings->get_status_message( status_code ) ); failure( session, status_code, re ); } catch ( const regex_error& re ) { failure( session, 500, re ); } catch ( const runtime_error& re ) { failure( session, 400, re ); } catch ( const exception& ex ) { failure( session, 500, ex ); } catch ( ... ) { auto cex = current_exception( ); if ( cex not_eq nullptr ) { try { rethrow_exception( cex ); } catch ( const exception& ex ) { failure( session, 500, ex ); } catch ( ... ) { runtime_error re( "Internal Server Error" ); failure( session, 500, re ); } } else { runtime_error re( "Internal Server Error" ); failure( session, 500, re ); } }