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

📄 parser.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        
        // USN header
        if (Result->Headers[SSDP_USN] == NULL || Result->Headers[SSDP_USN][0] == '\x0')
        {
            TraceTag(ttidSsdpParser, "USN header missing or empty for ssdp:alive NOTIFY message.");
            return FALSE;
        }

        // ssdp:alive
        if (Result->Headers[SSDP_NTS] != NULL && 0 == _stricmp(Result->Headers[SSDP_NTS], "ssdp:alive"))
        {
            // CACHE-CONTROL header
            if (Result->Headers[SSDP_CACHECONTROL] == NULL || Result->Headers[SSDP_CACHECONTROL][0] == '\x0')
            {
                TraceTag(ttidSsdpParser, "CACHE-CONTROL header missing or empty for ssdp:alive NOTIFY message.");
                return FALSE;
            }
            
            // LOCATION header
            if (Result->Headers[SSDP_LOCATION] == NULL || Result->Headers[SSDP_LOCATION][0] == '\x0')
            {
                TraceTag(ttidSsdpParser, "LOCATION header missing or empty for ssdp:alive NOTIFY message.");
                return FALSE;
            }
            
            // SERVER header
            if (Result->Headers[SSDP_SERVER] == NULL || Result->Headers[SSDP_SERVER][0] == '\x0')
            {
                TraceTag(ttidSsdpParser, "SERVER header missing or empty for ssdp:alive NOTIFY message.");
                return FALSE;
            }
        }
        else
            // ssdp:byebye
            if (Result->Headers[SSDP_NTS] == NULL || 0 != _stricmp(Result->Headers[SSDP_NTS], "ssdp:byebye"))
            {
                TraceTag(ttidSsdpParser, "NTS header must be one of ssdp:alive, ssdp:byebye for a SSDP NOTIFY message.");
                return FALSE;
            }
    }
    
    return TRUE; 
}


// VerifySsdpResponseHeaders
BOOL VerifySsdpResponseHeaders(SSDP_REQUEST *Result)
{
    // CACHE-CONTROL header
    if (Result->Headers[SSDP_CACHECONTROL] == NULL || Result->Headers[SSDP_CACHECONTROL][0] == '\x0')
    {
        TraceTag(ttidSsdpParser, "CACHE-CONTROL header missing or empty for ssdp response.");
        return FALSE;
    }
    
    // EXT header
    if (Result->Headers[SSDP_EXT] == NULL)
    {
        TraceTag(ttidSsdpParser, "EXT header missing in SSDP response.");
        return FALSE;
    }
    
    // LOCATION header
    if (Result->Headers[SSDP_LOCATION] == NULL || Result->Headers[SSDP_LOCATION][0] == '\x0')
    {
        TraceTag(ttidSsdpParser, "LOCATION header missing or empty for ssdp response.");
        return FALSE;
    }
    
    // SERVER header
    if (Result->Headers[SSDP_SERVER] == NULL || Result->Headers[SSDP_SERVER][0] == '\x0')
    {
        TraceTag(ttidSsdpParser, "SERVER header missing or empty for ssdp response.");
        return FALSE;
    }
    
    // ST header
    if(Result->Headers[SSDP_ST] == NULL || Result->Headers[SSDP_ST][0] == '\x0')
    {
        TraceTag(ttidSsdpParser, "ST header missing or empty for ssdp response");
        return FALSE;
    }
    
    // USN header
    if (Result->Headers[SSDP_USN] == NULL || Result->Headers[SSDP_USN][0] == '\x0')
    {
        TraceTag(ttidSsdpParser, "USN header missing or empty for ssdp response.");
        return FALSE;
    }
    
    return TRUE;
}


BOOL HasContentBody(PSSDP_REQUEST Result)
{
    return (Result->Headers[CONTENT_LENGTH] != NULL); 
}

BOOL ParseSsdpRequest(CHAR * szMessage, PSSDP_REQUEST Result)
{
    CHAR *szHeaders;
    CHAR pszHeaderPrefix[100] = {0};
        
    szHeaders = ParseRequestLine(szMessage, Result); 

    if (szHeaders == NULL)
    {
        return FALSE; 
    }
    else
    {
        if(VerifyRequestLine(Result) == FALSE)
            return FALSE;
    }
    
    {
        // make a copy of headers and parse them to get value of OPT header
        CHAR* pszHeadersCopy;
        
        pszHeadersCopy = (CHAR*)malloc(strlen(szHeaders) + 1);
        
        if(pszHeadersCopy)
        {
            SSDP_REQUEST Temp;
            
            memset(&Temp, 0, sizeof(Temp));
            strcpy(pszHeadersCopy, szHeaders);
            
            if(ParseHeaders(pszHeadersCopy, &Temp))
            {
                if(Temp.Headers[SSDP_OPT] && strlen(Temp.Headers[SSDP_OPT]) < sizeof(pszHeaderPrefix) - 2)
                {
                    strcpy(pszHeaderPrefix, Temp.Headers[SSDP_OPT]);
                    strcat(pszHeaderPrefix, DASH);
                }
            }
            
            FreeSsdpRequest(&Temp);
            free(pszHeadersCopy);
        }
    }
    
    char *pContent = ParseHeaders(szHeaders, Result, pszHeaderPrefix);
    if ( pContent == NULL)
    {
        return FALSE;
    }
    else
    {
        if (VerifySsdpHeaders(Result) == FALSE)
        {
            return FALSE; 
        }

        // Headers are OK. 
        
        if (Result->Headers[CONTENT_LENGTH] != NULL)
        {
            // To-Do: Maybe we can share the this routine with those 
            // in ProcessTcpReceiveData(); 
            // In that case, we need catch the return value of ParseContent
            // and probably return a more meaningful error code. 
            ParseContent(pContent, Result);
        }
        return TRUE;
    }
}


// Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
// Returns a pointer to the first CHAR after the status line
// Returns NULL if fail to parse status line

BOOL ParseSsdpResponse(CHAR *szMessage, SSDP_REQUEST *Result)
{
    CHAR *token;
    CHAR *szHeaders;
    CHAR pszHeaderPrefix[100] = {0};

    //  get the version
    token = strtok(szMessage," \t\n");
    if (token == NULL)
    {
        TraceTag(ttidSsdpParser, "Response: Parser could not locate the "
                 "seperator, space, tab or eol");
        return FALSE;
    }

    if (_stricmp(token, "HTTP/1.1") != 0)
    {
        TraceTag(ttidSsdpParser, "The version specified in the response "
                 "message is not HTTP/1.1");
        return FALSE;
    }

    // get the response code
    token = strtok(NULL," ");
    if (token == NULL)
    {
        TraceTag(ttidSsdpParser, "Parser could not find response code in the "
                 "message.");
        return FALSE;
    }

    if (_stricmp(token, "200") != 0)
    {
        TraceTag(ttidSsdpParser, "The response code in the response message "
                 "is not HTTP/1.1");
        return FALSE;
    }


    // get the response message, no need for now.
    token = strtok(NULL,"  \t\r");

    if (token == NULL)
    {
        TraceTag(ttidSsdpParser, "Response: Parser could not locate the "
                 "seperator, space, tab or eol");
        return FALSE;
    }

    szHeaders = token + strlen(token) + 1;
    
    {
        // make a copy of headers and parse them to get value of OPT header
        CHAR* pszHeadersCopy;
        
        pszHeadersCopy = (CHAR*)malloc(strlen(szHeaders) + 1);
        
        if(pszHeadersCopy)
        {
            SSDP_REQUEST Temp;
            
            memset(&Temp, 0, sizeof(Temp));
            strcpy(pszHeadersCopy, szHeaders);
            
            if(ParseHeaders(pszHeadersCopy, &Temp))
            {
                if(Temp.Headers[SSDP_OPT] && strlen(Temp.Headers[SSDP_OPT]) < sizeof(pszHeaderPrefix) - 2)
                {
                    strcpy(pszHeaderPrefix, Temp.Headers[SSDP_OPT]);
                    strcat(pszHeaderPrefix, DASH);
                }
            }
            
            FreeSsdpRequest(&Temp);
            free(pszHeadersCopy);
        }
    }
    
    char *pContent = ParseHeaders(szHeaders, Result, pszHeaderPrefix);

    if (pContent == NULL || Result->Headers[SSDP_USN] == NULL)
    {
        return FALSE;
    }
    else
    {
        if (VerifySsdpResponseHeaders(Result) == FALSE)
        {
            return FALSE; 
        }
        
        if (Result->Headers[CONTENT_LENGTH] != NULL)
        {
            ParseContent(pContent, Result);
        }
        return TRUE;
    }
}

char * ParseHeaders(CHAR *szMessage, SSDP_REQUEST *Result, CHAR* pszHeaderPrefix/* = NULL*/)
{
    CHAR *token;
    INT i;
    INT nHeaderPrefix = 0;

    if(pszHeaderPrefix && *pszHeaderPrefix)
    {
        nHeaderPrefix = strlen(pszHeaderPrefix);
        
        ASSERT(pszHeaderPrefix[nHeaderPrefix - 1] == '-');
    }
    
    // Get the next header
    token = strtok(szMessage, "\r\n");

    while (token != NULL)
    {
        CHAR * pHeaderSep; // points to the ':' that seperates the header and its content.
        CHAR * pBeyondTokenEnd;

        pBeyondTokenEnd = token + strlen(token) + 1;

        pHeaderSep = strchr( token, ':' );
        if (pHeaderSep == NULL)
        {
            TraceTag(ttidSsdpParser, "Token %s does not have a ':', ignored.",
                     token);
        }
        else
        {
            *pHeaderSep = '\0';

            strtrim(&token);

            for (i = 0; i < NUM_OF_HEADERS; i++)
            {
                CHAR* pszHeader = token;
                
                // if we have a recognized extension skip the headr prefix
                PREFAST_SUPPRESS(387, "if pszHeaderPrefix == NULL then nHeaderPrefix == 0");
                if(0 == _strnicmp(pszHeaderPrefix, pszHeader, nHeaderPrefix))
                    pszHeader += nHeaderPrefix;
                
                if (_stricmp(SsdpHeaderStr[i], pszHeader) == 0)
                {
                    CHAR *szValue;

                    szValue = pHeaderSep + 1;
                    strtrim(&szValue);

                    if (SSDP_CACHECONTROL == i)
                    {
                        // Further parse the cache-control header
                        //
                        szValue = strstr(szValue, c_szMaxAge);
                        if (szValue)
                        {
                            CHAR *  szTemp = szValue + c_cchMaxAge;

                            strtrim(&szTemp);
                            if (*szTemp != '=')
                            {
                                TraceTag(ttidSsdpParser, "Invalid max-age directive"
                                         " in cache-control header.");
                                break;
                            }
                            else
                            {
                                szTemp++;
                                strtrim(&szTemp);
                                while (isdigit(*szTemp))
                                {
                                    szTemp++;
                                }

                                // Nul term the string so the cache-control
                                // header should now be "max-age=398733" and
                                // nothing more or less
                                *szTemp = 0;
                            }
                        }
                        else
                        {
                            TraceTag(ttidSsdpParser, "Cache-control header"
                                     "did not include max-age directive.");
                            break;
                        }
                    }

                    if(SSDP_OPT == i)
                    {
                        // check if we recognize this extension
                        if(0 != _strnicmp(szValue, g_pszExtensionURI, strlen(g_pszExtensionURI)))
                            break;
                            
                        if(!(szValue = strstr(szValue, "ns")))
                            break;
                            
                        szValue += 2; // skip ns
                        
                        while(*szValue && (*szValue == ' ' || *szValue == '=')) // skip white spaces and =
                            szValue++;
                                    
                        if(*szValue == '\x0')
                            break;
                    }
                    
                    Result->Headers[i] = (CHAR *) SsdpAlloc(
                        sizeof(CHAR) * (strlen(szValue) + 1));
                    if (Result->Headers[i] == NULL)
                    {
                        TraceTag(ttidSsdpParser, "Failed to allocate memory "
                                 "for szValue %s",szValue);
                        FreeSsdpRequest(Result);
                        Result->status = HTTP_STATUS_SERVER_ERROR;
                        return NULL;
                    }
                    strcpy(Result->Headers[i], szValue);
                    break;
                }
            }

            if (i == NUM_OF_HEADERS && pszHeaderPrefix != NULL) // don't display trace if pszHeaderPrefix because it is pre-pass to get extension prefix
            {
                // Ignore not recognized header

⌨️ 快捷键说明

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