📄 httpparser.c
字号:
* void* param1 ; * void* param2 ; ** Description : Compares name id in the http headers.** Return : int ;** Note :************************************************************************/static inthttpmsg_compare( void *param1, void *param2 ){ assert( param1 != NULL ); assert( param2 != NULL ); return ( ( http_header_t * ) param1 )->name_id == ( ( http_header_t * ) param2 )->name_id;}/************************************************************************* Function : httpheader_free** Parameters :* void *msg ; ** Description : Free memory allocated for the http header** Return : void ;** Note :************************************************************************/static voidhttpheader_free( void *msg ){ http_header_t *hdr = ( http_header_t * ) msg; membuffer_destroy( &hdr->name_buf ); membuffer_destroy( &hdr->value ); free( hdr );}/************************************************************************* Function : httpmsg_init** Parameters :* INOUT http_message_t* msg ; HTTP Message Object** Description : Initialize and allocate memory for http message** Return : void ;** Note :************************************************************************/voidhttpmsg_init( INOUT http_message_t * msg ){ msg->initialized = 1; msg->entity.buf = NULL; msg->entity.length = 0; ListInit( &msg->headers, httpmsg_compare, httpheader_free ); membuffer_init( &msg->msg ); membuffer_init( &msg->status_msg );}/************************************************************************* Function : httpmsg_destroy** Parameters :* INOUT http_message_t* msg ; HTTP Message Object** Description : Free memory allocated for the http message** Return : void ;** Note :************************************************************************/voidhttpmsg_destroy( INOUT http_message_t * msg ){ assert( msg != NULL ); if( msg->initialized == 1 ) { ListDestroy( &msg->headers, 1 ); membuffer_destroy( &msg->msg ); membuffer_destroy( &msg->status_msg ); free( msg->urlbuf ); msg->initialized = 0; }}/************************************************************************* Function : httpmsg_find_hdr_str** Parameters :* IN http_message_t* msg ; HTTP Message Object* IN const char* header_name ; Header name to be compared with ** Description : Compares the header name with the header names stored * in the linked list of messages** Return : http_header_t* - Pointer to a header on success;* NULL on failure ** Note :************************************************************************/http_header_t *httpmsg_find_hdr_str( IN http_message_t * msg, IN const char *header_name ){ http_header_t *header; ListNode *node; node = ListHead( &msg->headers ); while( node != NULL ) { header = ( http_header_t * ) node->item; if( memptr_cmp_nocase( &header->name, header_name ) == 0 ) { return header; } node = ListNext( &msg->headers, node ); } return NULL;}/************************************************************************* Function : httpmsg_find_hdr** Parameters :* IN http_message_t* msg ; HTTP Message Object* IN int header_name_id ; Header Name ID to be compared with* OUT memptr* value ; Buffer to get the ouput to.** Description : Finds header from a list, with the given 'name_id'.** Return : http_header_t* - Pointer to a header on success; ** NULL on failure ** Note :************************************************************************/http_header_t *httpmsg_find_hdr( IN http_message_t * msg, IN int header_name_id, OUT memptr * value ){ http_header_t header; // temp header for searching ListNode *node; http_header_t *data; header.name_id = header_name_id; node = ListFind( &msg->headers, NULL, &header ); if( node == NULL ) { return NULL; } data = ( http_header_t * ) node->item; if( value != NULL ) { value->buf = data->value.buf; value->length = data->value.length; } return data;}/***********************************************************************//************* http_parser_t **************//***********************************************************************//************************************************************************* Function : skip_blank_lines** Parameters :* INOUT scanner_t* scanner ; Scanner Object** Description : skips blank lines at the start of a msg.** Return : int ;** Note :************************************************************************/static XINLINE intskip_blank_lines( INOUT scanner_t * scanner ){ memptr token; token_type_t tok_type; parse_status_t status; // skip ws, crlf do { status = scanner_get_token( scanner, &token, &tok_type ); } while( status == PARSE_OK && ( tok_type == TT_WHITESPACE || tok_type == TT_CRLF ) ); if( status == PARSE_OK ) { // pushback a non-whitespace token scanner->cursor -= token.length; //scanner_pushback( scanner, token.length ); } return status;}/************************************************************************* Function : skip_lws** Parameters :* INOUT scanner_t* scanner ; Scanner Object** Description : skip linear whitespace.** Return : int ;* PARSE_OK: (LWS)* removed from input * PARSE_FAILURE: bad input * PARSE_INCOMPLETE: incomplete input ** Note :************************************************************************/static XINLINE intskip_lws( INOUT scanner_t * scanner ){ memptr token; token_type_t tok_type; parse_status_t status; size_t save_pos; xboolean matched; do { save_pos = scanner->cursor; matched = FALSE; // get CRLF or WS status = scanner_get_token( scanner, &token, &tok_type ); if( status == PARSE_OK ) { if( tok_type == TT_CRLF ) { // get WS status = scanner_get_token( scanner, &token, &tok_type ); } if( status == PARSE_OK && tok_type == TT_WHITESPACE ) { matched = TRUE; } else { // did not match LWS; pushback token(s) scanner->cursor = save_pos; } } } while( matched ); // if entire msg is loaded, ignore an 'incomplete' warning if( status == PARSE_INCOMPLETE && scanner->entire_msg_loaded ) { status = PARSE_OK; } return status;}/************************************************************************* Function : match_non_ws_string** Parameters :* INOUT scanner_t* scanner ; Scanner Object* OUT memptr* str ; Buffer to get the scanner buffer contents.** Description : Match a string without whitespace or CRLF (%S)** Return : XINLINE parse_status_t ;* PARSE_OK * PARSE_NO_MATCH * PARSE_FAILURE * PARSE_INCOMPLETE ** Note :************************************************************************/static XINLINE parse_status_tmatch_non_ws_string( INOUT scanner_t * scanner, OUT memptr * str ){ memptr token; token_type_t tok_type; parse_status_t status; xboolean done = FALSE; size_t save_cursor; save_cursor = scanner->cursor; str->length = 0; str->buf = scanner_get_str( scanner ); // point to next char in input while( !done ) { status = scanner_get_token( scanner, &token, &tok_type ); if( status == PARSE_OK && tok_type != TT_WHITESPACE && tok_type != TT_CRLF ) { // append non-ws token str->length += token.length; } else { done = TRUE; } } if( status == PARSE_OK ) { // last token was WS; push it back in scanner->cursor -= token.length; } // tolerate 'incomplete' msg if( status == PARSE_OK || ( status == PARSE_INCOMPLETE && scanner->entire_msg_loaded ) ) { if( str->length == 0 ) { // no strings found return PARSE_NO_MATCH; } else { return PARSE_OK; } } else { // error -- pushback tokens scanner->cursor = save_cursor; return status; }}/************************************************************************* Function : match_raw_value** Parameters :* INOUT scanner_t* scanner ; Scanner Object* OUT memptr* raw_value ; Buffer to get the scanner buffer * contents** Description : Matches a raw value in a the input; value's length * can be 0 or more. Whitespace after value is trimmed. On success,* scanner points the CRLF that ended the value ** Return : parse_status_t ;* PARSE_OK * PARSE_INCOMPLETE * PARSE_FAILURE ** Note :************************************************************************/static XINLINE parse_status_tmatch_raw_value( INOUT scanner_t * scanner, OUT memptr * raw_value ){ memptr token; token_type_t tok_type; parse_status_t status; xboolean done = FALSE; xboolean saw_crlf = FALSE; size_t pos_at_crlf = 0; size_t save_pos; char c; save_pos = scanner->cursor; // value points to start of input raw_value->buf = scanner_get_str( scanner ); raw_value->length = 0; while( !done ) { status = scanner_get_token( scanner, &token, &tok_type ); if( status == PARSE_OK ) { if( !saw_crlf ) { if( tok_type == TT_CRLF ) { // CRLF could end value saw_crlf = TRUE; // save input position at start of CRLF pos_at_crlf = scanner->cursor - token.length; } // keep appending value raw_value->length += token.length; } else // already seen CRLF { if( tok_type == TT_WHITESPACE ) { // start again; forget CRLF saw_crlf = FALSE; raw_value->length += token.length; } else { // non-ws means value ended just before CRLF done = TRUE; // point to the crlf which ended the value scanner->cursor = pos_at_crlf; } } } else { // some kind of error; restore scanner position scanner->cursor = save_pos; done = TRUE; } } if( status == PARSE_OK ) { // trim whitespace on right side of value while( raw_value->length > 0 ) { // get last char c = raw_value->buf[raw_value->length - 1]; if( c != ' ' && c != '\t' && c != TOKCHAR_CR && c != TOKCHAR_LF ) { // done; no more whitespace break; } // remove whitespace raw_value->length--; } } return status;}/************************************************************************* Function: match_int * * Parameters:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -