⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpparser.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 5 页
字号:
            if( ret == UPNP_E_OUTOF_MEMORY ) {                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                return PARSE_FAILURE;            }        } else if( hdr_value.length > 0 ) {            //            // append value to existing header            //            // append space            ret = membuffer_append_str( &orig_header->value, ", " );            // append continuation of header value            ret2 = membuffer_append( &orig_header->value,                                     hdr_value.buf, hdr_value.length );            if( ret == UPNP_E_OUTOF_MEMORY || ret2 == UPNP_E_OUTOF_MEMORY ) {                // not enuf mem                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                return PARSE_FAILURE;            }        }    }                           // end while}////////////////////////////////////////////////////////////////////////#ifdef HIGHLY_UNLIKELY// **************static parse_status_tparser_parse_headers_old( INOUT http_parser_t * parser ){    parse_status_t status;    memptr token;    memptr hdr_value;    token_type_t tok_type;    scanner_t *scanner = &parser->scanner;    size_t save_pos;    http_header_t *header;    int header_id;    int ret = 0;    int index;    http_header_t *orig_header;    char save_char;    int ret2,      ret3;    assert( parser->position == POS_HEADERS ||            parser->ent_position == ENTREAD_CHUNKY_HEADERS );    while( TRUE ) {        save_pos = scanner->cursor;        //        // check end of headers        //        status = scanner_get_token( scanner, &token, &tok_type );        if( status != PARSE_OK ) {            return status;        }        if( tok_type == TT_CRLF ) {            // end of headers            parser->position = POS_ENTITY;  // read entity next            return PARSE_OK;        }        //        // not end; read header        //        if( tok_type != TT_IDENTIFIER ) {            return PARSE_FAILURE;   // didn't see header name        }        status = match( scanner, " : %R%c", &hdr_value );        if( status != PARSE_OK ) {            // pushback tokens; useful only on INCOMPLETE error            scanner->cursor = save_pos;            return status;        }        //        // add header        //        // find header        index = map_str_to_int( token.buf, token.length, Http_Header_Names,                                NUM_HTTP_HEADER_NAMES, FALSE );        if( index != -1 ) {            header_id = Http_Header_Names[index].id;            orig_header =                httpmsg_find_hdr( &parser->msg, header_id, NULL );        } else {            header_id = HDR_UNKNOWN;            save_char = token.buf[token.length];            token.buf[token.length] = '\0';            orig_header = httpmsg_find_hdr_str( &parser->msg, token.buf );            token.buf[token.length] = save_char;    // restore        }        if( orig_header == NULL ) {            //            // add new header            //            header = ( http_header_t * ) malloc( sizeof( http_header_t ) );            if( header == NULL ) {                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                return PARSE_FAILURE;            }            membuffer_init( &header->multi_hdr_buf );            header->name = token;            header->value = hdr_value;            header->name_id = header_id;            ret = dlist_append( &parser->msg.headers, header );            if( ret == UPNP_E_OUTOF_MEMORY ) {                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                return PARSE_FAILURE;            }        } else if( hdr_value.length > 0 ) {            //            // append value to existing header            //            if( orig_header->multi_hdr_buf.buf == NULL ) {                // store in buffer                ret = membuffer_append( &orig_header->multi_hdr_buf,                                        orig_header->value.buf,                                        orig_header->value.length );            }            // append space            ret2 =                membuffer_append( &orig_header->multi_hdr_buf, ", ", 2 );            // append continuation of header value            ret3 = membuffer_append( &orig_header->multi_hdr_buf,                                     hdr_value.buf, hdr_value.length );            if( ret == UPNP_E_OUTOF_MEMORY ||                ret2 == UPNP_E_OUTOF_MEMORY ||                ret3 == UPNP_E_OUTOF_MEMORY ) {                // not enuf mem                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                return PARSE_FAILURE;            }            // header value points to allocated buf            orig_header->value.buf = orig_header->multi_hdr_buf.buf;            orig_header->value.length = orig_header->multi_hdr_buf.length;        }    }                           // end while}#endif// ******************************/************************************************************************* Function: parser_parse_entity_using_clen								*																		* Parameters:															*	INOUT http_parser_t* parser ; HTTP Parser object*																		* Description: reads entity using content-length						*																		* Returns:																*	 PARSE_INCOMPLETE													*	 PARSE_FAILURE -- entity length > content-length value				*	 PARSE_SUCCESS														************************************************************************/static XINLINE parse_status_tparser_parse_entity_using_clen( INOUT http_parser_t * parser ){    //int entity_length;    assert( parser->ent_position == ENTREAD_USING_CLEN );    // determine entity (i.e. body) length so far    //entity_length = parser->msg.msg.length - parser->entity_start_position;    parser->msg.entity.length =        parser->msg.msg.length - parser->entity_start_position;    if( parser->msg.entity.length < parser->content_length ) {        // more data to be read        return PARSE_INCOMPLETE;    } else {        if( parser->msg.entity.length > parser->content_length ) {            // silently discard extra data            parser->msg.msg.buf[parser->entity_start_position +                                parser->content_length] = '\0';        }        // save entity length        parser->msg.entity.length = parser->content_length;        // save entity start ptr; (the very last thing to do)        parser->msg.entity.buf = parser->msg.msg.buf +            parser->entity_start_position;        // done reading entity        parser->position = POS_COMPLETE;        return PARSE_SUCCESS;    }}/************************************************************************* Function: parser_parse_chunky_body									*																		* Parameters:															*	INOUT http_parser_t* parser	; HTTP Parser object*																		* Description: Read data in the chunks									*																		* Returns:																*	 PARSE_INCOMPLETE													*	 PARSE_FAILURE -- entity length > content-length value				*	 PARSE_SUCCESS														************************************************************************/static XINLINE parse_status_tparser_parse_chunky_body( INOUT http_parser_t * parser ){    parse_status_t status;    size_t save_pos;    // if 'chunk_size' of bytes have been read; read next chunk    if( ( int )( parser->msg.msg.length - parser->scanner.cursor ) >=        parser->chunk_size ) {        // move to next chunk        parser->scanner.cursor += parser->chunk_size;        save_pos = parser->scanner.cursor;        //discard CRLF        status = match( &parser->scanner, "%c" );        if( status != PARSE_OK ) {            parser->scanner.cursor -= parser->chunk_size;   //move back            //parser->scanner.cursor = save_pos;            return status;        }        membuffer_delete( &parser->msg.msg, save_pos,                          ( parser->scanner.cursor - save_pos ) );        parser->scanner.cursor = save_pos;        parser->msg.entity.length += parser->chunk_size;    //update temp         parser->ent_position = ENTREAD_USING_CHUNKED;        return PARSE_CONTINUE_1;    } else {        return PARSE_INCOMPLETE;    // need more data for chunk    }}/************************************************************************* Function: parser_parse_chunky_headers									*																		* Parameters:															*	INOUT http_parser_t* parser	; HTTP Parser object						*																		* Description: Read headers at the end of the chunked entity			*																		* Returns:																*	 PARSE_INCOMPLETE													*	 PARSE_FAILURE -- entity length > content-length value				*	 PARSE_SUCCESS														************************************************************************/static XINLINE parse_status_tparser_parse_chunky_headers( INOUT http_parser_t * parser ){    parse_status_t status;    size_t save_pos;    save_pos = parser->scanner.cursor;    status = parser_parse_headers( parser );    if( status == PARSE_OK ) {        // finally, done with the whole msg        parser->position = POS_COMPLETE;        // save entity start ptr as the very last thing to do        parser->msg.entity.buf = parser->msg.msg.buf +            parser->entity_start_position;        membuffer_delete( &parser->msg.msg, save_pos,                          ( parser->scanner.cursor - save_pos ) );        parser->scanner.cursor = save_pos;        return PARSE_SUCCESS;    } else {        return status;    }}/************************************************************************* Function: parser_parse_chunky_entity									*																		* Parameters:															*	INOUT http_parser_t* parser	- HTTP Parser Object									*																		* Description: Read headers at the end of the chunked entity			*																		* Returns:																*	 PARSE_INCOMPLETE													*	 PARSE_FAILURE -- entity length > content-length value				*	 PARSE_SUCCESS														*	 PARSE_CONTINUE_1													************************************************************************/static XINLINE parse_status_tparser_parse_chunky_entity( INOUT http_parser_t * parser ){    scanner_t *scanner = &parser->scanner;    parse_status_t status;    size_t save_pos;    memptr dummy;    assert( parser->ent_position == ENTREAD_USING_CHUNKED );    save_pos = scanner->cursor;    // get size of chunk, discard extension, discard CRLF    status = match( scanner, "%x%L%c", &parser->chunk_size, &dummy );    if( status != PARSE_OK ) {        scanner->cursor = save_pos;        DBGONLY( UpnpPrintf                 ( UPNP_INFO, HTTP, __FILE__, __LINE__,                   "CHUNK COULD NOT BE PARSED\n" ); )            return status;    }    // remove chunk info just matched; just retain data    membuffer_delete( &parser->msg.msg, save_pos,                      ( scanner->cursor - save_pos ) );    scanner->cursor = save_pos; // adjust scanner too    if( parser->chunk_size == 0 ) {        // done reading entity; determine length of entity        parser->msg.entity.length = parser->scanner.cursor -            parser->entity_start_position;        // read entity headers        parser->ent_position = ENTREAD_CHUNKY_HEADERS;    } else {        // read chunk body        parser->ent_position = ENTREAD_CHUNKY_BODY;    }    return PARSE_CONTINUE_1;    // continue to reading body}/************************************************************************* Function: parser_parse_entity_until_close								*																		* Parameters:															*	INOUT http_parser_t* parser	; HTTP Parser object*																		* Description: Read headers at the end of the chunked entity			*																		* Returns:																*	 PARSE_INCOMPLETE_ENTITY											************************************************************************/static XINLINE parse_status_tparser_parse_entity_until_close( INOUT http_parser_t * parser ){    size_t cursor;    assert( parser->ent_position == ENTREAD_UNTIL_CLOSE );    // eat any and all data    cursor = parser->msg.msg.length;    // update entity length    parser->msg.entity.length = cursor - parser->entity_start_position;    // update pointer    parser->msg.entity.buf =        parser->msg.msg.buf + parser->entity_start_position;    parser->scanner.cursor = cursor;    return PARSE_INCOMPLETE_ENTITY; // add anything}/************************************************************************* Function: parser_get_entity_read_method								*																		* Parameters:															*	INOUT http_parser_t* parser	; HTTP Parser object					*																		* Description: Determines method to read entity							*																		* Returns:																*	 PARSE_OK															* 	 PARSE_FAILURE														*	 PARSE_COMPLETE	-- no more reading to do							************************************************************************/XINLINE parse_status_tparser_get_entity_read_method( INOUT http_parser_t * parser ){    http_message_t *hmsg = &parser->msg;    int response_code;    memptr hdr_value;    assert( parser->ent_position == ENTREAD_DETERMINE_READ_METHOD );    // entity points to start of msg body    parser->msg.entity.buf = scanner_get_str( &parser->scanner );    parser->msg.entity.length = 0;    // remember start of body    parser->entity_start_position = parser->scanner.cursor;    // std http rules for determining content length    // * no body for 1xx, 204, 304 and HEAD, GET,    //      SUBSCRIBE, UNSUBSCRIBE    if( hmsg->is_request ) {        switch ( hmsg->method ) {            case HTTPMETHOD_HEAD:            case HTTPMETHOD_GET:                //case HTTPMETHOD_POST:            case HTTPMETHOD_SUBSCRIBE:            case HTTPMETHOD_UNSUBSCRIBE:            case HTTPMETHOD_MSEARCH:                // no body; mark as done                parser->position 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -