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

📄 httpparser.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************* Function: matchstr													*																		* Parameters:															*	IN char *str ;		 String to be matched														*	IN size_t slen ;     Length of the string														*	IN const char* fmt ; Pattern format												*	...																	*																		* Description: Matches a variable parameter list with a string			*	and takes actions based on the data type specified.					*																		* Returns:																*   PARSE_OK															*   PARSE_NO_MATCH -- failure to match pattern 'fmt'					*   PARSE_FAILURE	-- 'str' is bad input							************************************************************************/intmatchstr( IN char *str,          IN size_t slen,          IN const char *fmt,          ... ){    int ret_code;    char save_char;    scanner_t scanner;    membuffer buf;    va_list arg_list;    // null terminate str    save_char = str[slen];    str[slen] = '\0';    membuffer_init( &buf );    // under no circumstances should this buffer be modifed because its memory    //  might have not come from malloc()    membuffer_attach( &buf, str, slen );    scanner_init( &scanner, &buf );    scanner.entire_msg_loaded = TRUE;    va_start( arg_list, fmt );    ret_code = vfmatch( &scanner, fmt, arg_list );    va_end( arg_list );    // restore str    str[slen] = save_char;    // don't destroy buf    return ret_code;}/************************************************************************* Function: parser_init													*																		* Parameters:															*	OUT http_parser_t* parser ; HTTP Parser object*																		* Description: Initializes the parser object.							*																		* Returns:																*	void																************************************************************************/static XINLINE voidparser_init( OUT http_parser_t * parser ){    memset( parser, 0, sizeof( http_parser_t ) );    parser->http_error_code = HTTP_BAD_REQUEST; // err msg by default    parser->ent_position = ENTREAD_DETERMINE_READ_METHOD;    parser->valid_ssdp_notify_hack = FALSE;    httpmsg_init( &parser->msg );    scanner_init( &parser->scanner, &parser->msg.msg );}/************************************************************************* Function: parser_parse_requestline									*																		* Parameters:															*	INOUT http_parser_t* parser ; HTTP Parser  object						*																		* Description: Get HTTP Method, URL location and version information.	*																		* Returns:																*	PARSE_OK															*	PARSE_SUCCESS														*	PARSE_FAILURE														************************************************************************/static parse_status_tparser_parse_requestline( INOUT http_parser_t * parser ){    parse_status_t status;    http_message_t *hmsg = &parser->msg;    memptr method_str;    memptr version_str;    int index;    char save_char;    int num_scanned;    memptr url_str;    assert( parser->position == POS_REQUEST_LINE );    status = skip_blank_lines( &parser->scanner );    if( status != PARSE_OK ) {        return status;    }    //simple get http 0.9 as described in http 1.0 spec    status =        match( &parser->scanner, "%s\t%S%w%c", &method_str, &url_str );    if( status == PARSE_OK ) {        index =            map_str_to_int( method_str.buf, method_str.length,                            Http_Method_Table, NUM_HTTP_METHODS, TRUE );        if( index < 0 ) {            // error; method not found            parser->http_error_code = HTTP_NOT_IMPLEMENTED;            return PARSE_FAILURE;        }        if( Http_Method_Table[index].id != HTTPMETHOD_GET ) {            parser->http_error_code = HTTP_BAD_REQUEST;            return PARSE_FAILURE;        }        hmsg->method = HTTPMETHOD_SIMPLEGET;        // store url        hmsg->urlbuf = str_alloc( url_str.buf, url_str.length );        if( hmsg->urlbuf == NULL ) {            // out of mem            parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;            return PARSE_FAILURE;        }        if( parse_uri( hmsg->urlbuf, url_str.length, &hmsg->uri ) !=            HTTP_SUCCESS ) {            return PARSE_FAILURE;        }        parser->position = POS_COMPLETE;    // move to headers        return PARSE_SUCCESS;    }    status = match( &parser->scanner,                    "%s\t%S\t%ihttp%w/%w%L%c", &method_str, &url_str,                    &version_str );    if( status != PARSE_OK ) {        return status;    }    // store url    hmsg->urlbuf = str_alloc( url_str.buf, url_str.length );    if( hmsg->urlbuf == NULL ) {        // out of mem        parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;        return PARSE_FAILURE;    }    if( parse_uri( hmsg->urlbuf, url_str.length, &hmsg->uri ) !=        HTTP_SUCCESS ) {        return PARSE_FAILURE;    }    // scan version    save_char = version_str.buf[version_str.length];    version_str.buf[version_str.length] = '\0'; // null-terminate    num_scanned = sscanf( version_str.buf, "%d . %d",                          &hmsg->major_version, &hmsg->minor_version );    version_str.buf[version_str.length] = save_char;    // restore    if( num_scanned != 2 ||        hmsg->major_version < 0 || hmsg->minor_version < 0 ) {        // error; bad http version        return PARSE_FAILURE;    }    index =        map_str_to_int( method_str.buf, method_str.length,                        Http_Method_Table, NUM_HTTP_METHODS, TRUE );    if( index < 0 ) {        // error; method not found        parser->http_error_code = HTTP_NOT_IMPLEMENTED;        return PARSE_FAILURE;    }    hmsg->method = Http_Method_Table[index].id;    parser->position = POS_HEADERS; // move to headers    return PARSE_OK;}/************************************************************************* Function: parser_parse_responseline									*																		* Parameters:															*	INOUT http_parser_t* parser	; HTTP Parser object					*																		* Description: Get HTTP Method, URL location and version information.	*																		* Returns:																*	PARSE_OK															*	PARSE_SUCCESS														*	PARSE_FAILURE														************************************************************************/parse_status_tparser_parse_responseline( INOUT http_parser_t * parser ){    parse_status_t status;    http_message_t *hmsg = &parser->msg;    memptr line;    char save_char;    int num_scanned;    int i;    char *p;    assert( parser->position == POS_RESPONSE_LINE );    status = skip_blank_lines( &parser->scanner );    if( status != PARSE_OK ) {        return status;    }    // response line    //status = match( &parser->scanner, "%ihttp%w/%w%d\t.\t%d\t%d\t%L%c",    //  &hmsg->major_version, &hmsg->minor_version,    //  &hmsg->status_code, &hmsg->status_msg );    status = match( &parser->scanner, "%ihttp%w/%w%L%c", &line );    if( status != PARSE_OK ) {        return status;    }    save_char = line.buf[line.length];    line.buf[line.length] = '\0';   // null-terminate    // scan http version and ret code    num_scanned = sscanf( line.buf, "%d . %d %d",                          &hmsg->major_version, &hmsg->minor_version,                          &hmsg->status_code );    line.buf[line.length] = save_char;  // restore    if( num_scanned != 3 ||        hmsg->major_version < 0 ||        hmsg->minor_version < 0 || hmsg->status_code < 0 ) {        // bad response line        return PARSE_FAILURE;    }    //    // point to status msg    //    p = line.buf;    // skip 3 ints    for( i = 0; i < 3; i++ ) {        // go to start of num        while( !isdigit( *p ) ) {            p++;        }        // skip int        while( isdigit( *p ) ) {            p++;        }    }    // whitespace must exist after status code    if( *p != ' ' && *p != '\t' ) {        return PARSE_FAILURE;    }    // skip whitespace    while( *p == ' ' || *p == '\t' ) {        p++;    }    // now, p is at start of status msg    if( membuffer_assign( &hmsg->status_msg, p,                          line.length - ( p - line.buf ) ) != 0 ) {        // out of mem        parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;        return PARSE_FAILURE;    }    parser->position = POS_HEADERS; // move to headers    return PARSE_OK;}/************************************************************************* Function: parser_parse_headers									*																		* Parameters:															*	INOUT http_parser_t* parser	; HTTP Parser object										*													* Description: Get HTTP Method, URL location and version information.	*																		* Returns:																*	PARSE_OK															*	PARSE_SUCCESS														*	PARSE_FAILURE														************************************************************************/parse_status_tparser_parse_headers( 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;    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            if( ( parser->msg.is_request )                && ( parser->msg.method == HTTPMETHOD_POST ) ) {                parser->position = POS_COMPLETE;    //post entity parsing                //is handled separately                 return PARSE_SUCCESS;            }            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 ) {            //Check if it is a soap header            if( Http_Header_Names[index].id == HDR_SOAPACTION ) {                parser->msg.method = SOAPMETHOD_POST;            }            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->name_buf );            membuffer_init( &header->value );            // value can be 0 length            if( hdr_value.length == 0 ) {                hdr_value.buf = "\0";                hdr_value.length = 1;            }            // save in header in buffers            if( membuffer_assign                ( &header->name_buf, token.buf, token.length ) != 0                || membuffer_assign( &header->value, hdr_value.buf,                                     hdr_value.length ) != 0 ) {                // not enuf mem                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                return PARSE_FAILURE;            }            header->name.buf = header->name_buf.buf;            header->name.length = header->name_buf.length;            header->name_id = header_id;            ListAddTail( &parser->msg.headers, header );            //NNS:          ret = dlist_append( &parser->msg.headers, header );

⌨️ 快捷键说明

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