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

📄 parseutil.cpp

📁 这是公司移植的UPNP协议
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000 Intel Corporation// All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met://// * Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above copyright notice,// this list of conditions and the following disclaimer in the documentation// and/or other materials provided with the distribution.// * Neither name of the Intel Corporation nor the names of its contributors// may be used to endorse or promote products derived from this software// without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE./////////////////////////////////////////////////////////////////////////////// $Revision: 1.1.1.1 $// $Date: 2004/10/19 11:54:08 $#include "../../inc/tools/config.h"#ifdef INTERNAL_WEB_SERVER#if EXCLUDE_WEB_SERVER == 0#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <genlib/net/netexception.h>#include <genlib/net/http/tokenizer.h>#include <genlib/net/http/parseutil.h>#include <genlib/net/http/statuscodes.h>#include <genlib/util/utilall.h>#include <genlib/util/util.h>#include <genlib/util/gmtdate.h>#include <genlib/file/fileexceptions.h>#include <genlib/util/memreader.h>// HttpParseExceptionHttpParseException::HttpParseException( const char* s, int lineNumber )    : BasicException(""){    if ( lineNumber != -1 )    {        char buf[100];                sprintf( buf, "line %d: ", lineNumber );        appendMessage( buf );    }    appendMessage( s );}//////// callback used to read a HttpHeader value from a scannertypedef HttpHeaderValue* (*ReadHttpValueCallback)    ( Tokenizer& scanner );    typedef void (*AddValueToListCallback)    ( HttpHeaderValueList& list, HttpHeaderValue* value );// module vars ////////////////////// static -- to do: determine os/version on the flystatic const char* gServerDesc = "Linux/6.0 UPnP/1.0 Intel UPnP/0.9";static const char* gUserAgentDesc = "Intel UPnP/0.9";///////////////////////////////////    // ******** CREATE callback functions ****static HttpHeaderValue* CreateIdentifierValue(){    return new IdentifierValue;}static HttpHeaderValue* CreateIdentifierQValue(){    return new IdentifierQValue;}static HttpHeaderValue* CreateMediaRange(){    return new MediaRange;}static HttpHeaderValue* CreateLanguageTag(){    return new LanguageTag;}static HttpHeaderValue* CreateCacheDirective(){    return new CacheDirective;}// *********** endstruct SortedTableEntry{    char* name;    int   id;};#define NUM_HEADERS 52// table _must_ be sorted by header namestatic SortedTableEntry HeaderNameTable[NUM_HEADERS] ={    { "ACCEPT",             HDR_ACCEPT },    { "ACCEPT-CHARSET",     HDR_ACCEPT_CHARSET },    { "ACCEPT-ENCODING",    HDR_ACCEPT_ENCODING },    { "ACCEPT-LANGUAGE",    HDR_ACCEPT_LANGUAGE },    { "ACCEPT-RANGES",      HDR_ACCEPT_RANGES },    { "AGE",                HDR_AGE },    { "ALLOW",              HDR_ALLOW },    { "AUTHORIZATION",      HDR_AUTHORIZATION },        { "CACHE-CONTROL",      HDR_CACHE_CONTROL },    { "CALLBACK",           HDR_UPNP_CALLBACK },    { "CONNECTION",         HDR_CONNECTION },    { "CONTENT-ENCODING",   HDR_CONTENT_ENCODING },    { "CONTENT-LANGUAGE",   HDR_CONTENT_LANGUAGE },    { "CONTENT-LENGTH",     HDR_CONTENT_LENGTH },    { "CONTENT-LOCATION",   HDR_CONTENT_LOCATION },    { "CONTENT-MD5",        HDR_CONTENT_MD5 },    { "CONTENT-TYPE",       HDR_CONTENT_TYPE },        { "DATE",               HDR_DATE },        { "ETAG",               HDR_ETAG },    { "EXPECT",             HDR_EXPECT },    { "EXPIRES",            HDR_EXPIRES },        { "FROM",               HDR_FROM },        { "HOST",               HDR_HOST },        { "IF-MATCH",           HDR_IF_MATCH },    { "IF-MODIFIED-SINCE",  HDR_IF_MODIFIED_SINCE },    { "IF-NONE-MATCH",      HDR_IF_NONE_MATCH },    { "IF-RANGE",           HDR_IF_RANGE },    { "IF-UNMODIFIED-SINCE",HDR_IF_UNMODIFIED_SINCE },        { "LAST-MODIFIED",      HDR_LAST_MODIFIED },    { "LOCATION",           HDR_LOCATION },        { "MAN",                HDR_UPNP_MAN },    { "MAX-FORWARDS",       HDR_MAX_FORWARDS },        { "NT",                 HDR_UPNP_NT },    { "NTS",                HDR_UPNP_NTS },        { "PRAGMA",             HDR_PRAGMA },    { "PROXY-AUTHENTICATE", HDR_PROXY_AUTHENTICATE },    { "PROXY-AUTHORIZATION",HDR_PROXY_AUTHORIZATION },        { "RANGE",              HDR_RANGE },    { "REFERER",            HDR_REFERER },        { "SERVER",             HDR_SERVER },    { "SID",                HDR_UPNP_SID },    { "SOAPACTION",         HDR_UPNP_SOAPACTION },    { "ST",                 HDR_UPNP_ST },        { "TE",                 HDR_TE },    { "TRAILER",            HDR_TRAILER },    { "TRANSFER-ENCODING",  HDR_TRANSFER_ENCODING },        { "USER-AGENT",         HDR_USER_AGENT },    { "USN",                HDR_UPNP_USN },        { "VARY",               HDR_VARY },    { "VIA",                HDR_VIA },        { "WARNING",            HDR_WARNING },    { "WWW-AUTHENTICATE",   HDR_WWW_AUTHENTICATE },};// returns header ID; or -1 on errorint NameToID( const char* name,    SortedTableEntry* table, int size, bool caseSensitive = true ){    int top, mid, bot;    int cmp;        top = 0;    bot = size - 1;        while ( top <= bot )    {        mid = (top + bot) / 2;        if ( caseSensitive )        {            cmp = strcmp( name, table[mid].name );        }        else        {            cmp = strcasecmp( name, table[mid].name );        }                if ( cmp > 0 )        {            top = mid + 1;      // look below mid        }        else if ( cmp < 0 )        {            bot = mid - 1;      // look above mid        }        else    // cmp == 0        {            return table[mid].id;   // match        }    }            return -1;  // header name not found}// returns textual representation of id in table;//   NULL if id is invalid or missing from tableconst char* IDToName( int id,    SortedTableEntry* table, int size ){    if ( id < 0 )        return NULL;        for ( int i = 0; i < size; i++ )    {        if ( id == table[i].id )        {            return table[i].name;        }    }    return NULL;}// skips all blank lines (lines with crlf + optional whitespace);// removes leading whitespace from first non-blank linestatic void SkipBlankLines( IN Tokenizer& scanner ){    Token *token;        while ( true )    {        token = scanner.getToken();        if ( !(token->tokType == Token::CRLF ||               token->tokType == Token::WHITESPACE) )        {            // not whitespace or crlf; restore and done            scanner.pushBack();            return;        }    }}// reads and discards LWS// returns true if matched; false if not matched LWSbool SkipLWS( IN Tokenizer& scanner ){    Token* token;    bool crlfMatch = true;        // skip optional CRLF    token = scanner.getToken();    if ( token->tokType != Token::CRLF )    {        // not CRLF        scanner.pushBack();        crlfMatch = false;    }        // match whitespace    token = scanner.getToken();    if ( token->tokType != Token::WHITESPACE )    {        // no match        scanner.pushBack();                // put back crlf as well, if read        if ( crlfMatch )            scanner.pushBack();        return false;   // input does not match LWS    }        return true;    // match}// skips *LWSvoid SkipOptionalLWS( IN Tokenizer& scanner ){    // skip LWS until no match    while ( SkipLWS(scanner) )    {    }}static void SkipOptionalWhitespace( IN Tokenizer& scanner ){    Token* token;        token = scanner.getToken();    if ( token->tokType != Token::WHITESPACE )    {        scanner.pushBack();    }}// reads and discards a header from input streamstatic void SkipHeader( IN Tokenizer& scanner ){    Token* token;        // skip all lines that are continuation of the header    while ( true )    {        // skip until eol        do        {            token = scanner.getToken();                        // handle incomplete or bad input            if ( token->tokType == Token::END_OF_STREAM )            {                scanner.pushBack();                return;            }        } while ( token->tokType != Token::CRLF );                // header continues or ends?        token = scanner.getToken();        if ( token->tokType != Token::WHITESPACE )        {            // possibly, new header starts here            scanner.pushBack();            break;        }    }}/*// returns a string that matches the pattern//// pattern should not have Token::END_OF_STREAM,// last pattern should be null, (0) and//   patternSize excludes this nullstatic int MatchPattern( IN Tokenizer& scanner,    IN char* pattern, IN int patternSize,    OUT xstring& match ){    assert( pattern != NULL );    assert( patternSize > 0 );    match = "";    scanner.getToken();    for ( i = 0; i < patternSize; i++ )    {        token = scanner.getToken();        if ( token.tokType != pattern[i] )        {            return -1;        }        match += token->s;    }    return 0;}*/// reads header name from input// call when scanning start of line// header ::= headername : value//// throws ParseFailException if header identifier not foundstatic void ParseHeaderName( IN Tokenizer& scanner, OUT xstring& hdrName ){    Token *token;        token = scanner.getToken();    if ( token->tokType != Token::IDENTIFIER )    {        scanner.pushBack();     // put token back in stream        // not an identifier        throw HttpParseException(            "ParseHeaderName()", scanner.getLineNum() );    }        hdrName = token->s;}// skips the ':' after header name and the all whitespace//  surrounding it// precond: cursor pointing after headerNamestatic void SkipColonLWS( IN Tokenizer& scanner ){    Token *token;    SkipOptionalLWS( scanner );        token = scanner.getToken();    if ( token->s != ':' )    {        scanner.pushBack();        throw HttpParseException( "SkipColonLWS(): expecting colon",            scanner.getLineNum() );    }        SkipOptionalLWS( scanner ); }// header ::= name : value// returns value of a header// called when currToken is pointing to a non-whitespace token//   after colon// NOTE: value can be blank; "" (len = 0)static void ParseHeaderValue( IN Tokenizer& scanner, OUT xstring& value ){    Token* token;    value = "";    //SkipOptionalLWS( scanner ); // no leading whitespace    // precond: next token is not whitespace    while ( true )    {        // add all str till eol or end of stream        while ( true )        {            token = scanner.getToken();            if ( token->tokType == Token::END_OF_STREAM )            {                scanner.pushBack();                throw HttpParseException(                    "ParseHeaderValue(): unexpected end" );            }            if ( token->tokType == Token::CRLF )            {                break;  // end of value?            }            value += token->s;        }        token = scanner.getToken();                    // header continued on new line?        if ( token->tokType != Token::WHITESPACE )        {            // no; header done            scanner.pushBack();            scanner.pushBack(); // return CRLF too            break;        }        else        {            // header value continued            value += ' ';        }    }    // precond:    // value is either empty "", or has one at least one    //   non-whitespace char; also, no whitespace on left    if ( value.length() > 0 )    {        const char *start_ptr, *eptr;        int sublen;        start_ptr = value.c_str();        eptr = start_ptr + value.length() - 1;  // start at last char        while ( *eptr == ' ' || *eptr == '\t' )        {            eptr--;        }        sublen = eptr - start_ptr + 1;        if ( value.length() != sublen )        {            // trim right whitespace            value.deleteSubstring( eptr - start_ptr + 1,                value.length() - sublen );        }    }    else    {        value = "";    }}#ifdef no_such_deff// ************************************************// no special parsing performed for value//  throws://    ParseNoMatchException: if error reading header name//    ParseNoMatchException(PARSERR_COLON_NOT_FOUND) ://          if colon following parse is not found//         & scanner points non-colon tokenstatic void ParseSimpleHeader( IN Tokenizer& scanner,    OUT xstring& name, OUT xstring& value ){    // get header name    ParseHeaderValue( scanner, name );        // skip colon    SkipOptionalLWS( scanner );        Token *token = scanner.getToken();    if ( token->s != ":" )    {        scanner.pushBack();                HttpParseException e( "ParseSimpleHeader()", scanner.getLineNum() );        e.setErrorCode( PARSERR_COLON_NOT_FOUND );        throw e;    }        SkipOptionalLWS( scanner );        // get header value    ParseHeaderValue( scanner, name );}// Reads a request line// throws ParseNoMatchException : code PARSERR_BAD_REQUEST_LINE//    if request line is unacceptablestatic void ParseRequestLine( IN Tokenizer& scanner,    OUT xstring& method, OUT xstring& uri, OUT xstring& httpVers ){    Token* token;    ParseNoMatchException e( "ParseSimpleHeader()" );    e.setErrorCode( PARSERR_BAD_REQUEST_LINE );        // get method    token = scanner.getToken();    if ( token->tokType != Token::IDENTIFIER )    {        scanner.pushBack();        throw e;    }    method = token->s;        // skip spaces    token = scanner.getToken();    if ( token->tokType != Token::WHITESPACE )    {        scanner.pushBack();        throw e;    }        // get uri    int count = 0;    uri = "";    while ( true )

⌨️ 快捷键说明

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