示例#1
0
//throws eHTTPNoMoreData and eHTTPOutOfBuffer
QTSS_Error RTSPRequest::ParseHeaders(StringParser& parser)
{
    StrPtrLen theKeyWord;
    Bool16 isStreamOK;
    
    //Repeat until we get a \r\n\r\n, which signals the end of the headers
    
    while ((parser.PeekFast() != '\r') && (parser.PeekFast() != '\n')) 
    {
        //First get the header identifier
        
        isStreamOK = parser.GetThru(&theKeyWord, ':');
        if (!isStreamOK)
            return QTSSModuleUtils::SendErrorResponse(this, qtssClientBadRequest, qtssMsgNoColonAfterHeader, this->GetValue(qtssRTSPReqFullRequest));
                            
         theKeyWord.TrimWhitespace();
        
        //Look up the proper header enumeration based on the header string.
        //Use the enumeration to look up the dictionary ID of this header,
        //and set that dictionary attribute to be whatever is in the body of the header
        
        UInt32 theHeader = RTSPProtocol::GetRequestHeader(theKeyWord);
        StrPtrLen theHeaderVal;
		parser.ConsumeUntil(&theHeaderVal, StringParser::sEOLMask);
	
		StrPtrLen theEOL;
		if ((parser.PeekFast() == '\r') || (parser.PeekFast() == '\n'))
		{
			isStreamOK = true;
			parser.ConsumeEOL(&theEOL);
		}
		else
			isStreamOK = false;
			
		while((parser.PeekFast() == ' ') || (parser.PeekFast() == '\t'))
		{
			theHeaderVal.Len += theEOL.Len;
			StrPtrLen temp;
			parser.ConsumeUntil(&temp, StringParser::sEOLMask);
			theHeaderVal.Len += temp.Len;
			
			if ((parser.PeekFast() == '\r') || (parser.PeekFast() == '\n'))
			{
				isStreamOK = true;
				parser.ConsumeEOL(&theEOL);
			}
			else
				isStreamOK = false;			
		}

        // If this is an unknown header, ignore it. Otherwise, set the proper
        // dictionary attribute
        if (theHeader != qtssIllegalHeader)
        {
            Assert(theHeader < qtssNumHeaders);
            theHeaderVal.TrimWhitespace();
            fHeaderDictionary.SetVal(theHeader, &theHeaderVal);
        }
        if (!isStreamOK)
            return QTSSModuleUtils::SendErrorResponse(this, qtssClientBadRequest, qtssMsgNoEOLAfterHeader);
        
        //some headers require some special processing. If this code begins
        //to get out of control, we made need to come up with a function pointer table
        switch (theHeader)
        {
            case qtssSessionHeader:             ParseSessionHeader(); break;
            case qtssTransportHeader:           ParseTransportHeader(); break;
            case qtssRangeHeader:               ParseRangeHeader();     break;
            case qtssIfModifiedSinceHeader:     ParseIfModSinceHeader();break;
            case qtssXRetransmitHeader:         ParseRetransmitHeader();break;
            case qtssContentLengthHeader:       ParseContentLengthHeader();break;
            case qtssSpeedHeader:               ParseSpeedHeader();     break;
            case qtssXTransportOptionsHeader:   ParseTransportOptionsHeader();break;
            case qtssXPreBufferHeader:          ParsePrebufferHeader();break;
			case qtssXDynamicRateHeader:		ParseDynamicRateHeader(); break;
			case qtssXRandomDataSizeHeader:		ParseRandomDataSizeHeader(); break;
			case qtss3GPPAdaptationHeader:      fRequest3GPP.ParseAdpationHeader(&fHeaderDictionary); break;
			case qtss3GPPLinkCharHeader:        fRequest3GPP.ParseLinkCharHeader(&fHeaderDictionary); break;
			case qtssBandwidthHeader:           ParseBandwidthHeader(); break;
            default:    break;
        }
    }

    // Tell the session what the request body length is for this request
    // so that it can prevent people from reading past the end of the request.
    StrPtrLen* theContentLengthBody = fHeaderDictionary.GetValue(qtssContentLengthHeader);
    if (theContentLengthBody->Len > 0)
    {
        StringParser theHeaderParser(fHeaderDictionary.GetValue(qtssContentLengthHeader));
        theHeaderParser.ConsumeWhitespace();
        this->GetSession()->SetRequestBodyLength(theHeaderParser.ConsumeInteger(NULL));
    }
    
    isStreamOK = parser.ExpectEOL();
    Assert(isStreamOK);
    return QTSS_NoErr;
}
示例#2
0
int RtspRequest::ParseRtspPackage(char Buf[], int Size) //bool bReq
{
    int ret = 0;
    StringArray_t saLine;
    StringPair_t spHeader;
    string Delim=CRLF;
    string sRequest(Buf, Size);
    U32 theHeader = 0;
    StringUtil::Trim(sRequest);
    StringUtil::Split(sRequest, Delim, saLine);
    //Request Line
    
    if(strncmp(saLine[0].c_str(), RTSPProtocol::GetVersionString(RTSPProtocol::k10Version).Ptr, RTSPProtocol::GetVersionString(RTSPProtocol::k10Version).Len) != 0) //bReq
    {    
        m_bIsRequest = true;
        ret = ParseRequestLine(saLine[0]);
        if(ret < 0)
        {
            return -1;
        }
    }
    else
    {
        m_bIsRequest = false;
        ret = ParseStatusLine(saLine[0]);
        if(ret < 0)
        {
            return -1;
        }    
    }
    //Parse Header
    for(int i=1; i<saLine.size(); i++)
    {           
        StringUtil::Split(saLine[i], ':', spHeader);
        theHeader = RTSPProtocol::GetRequestHeader(StrPtrLen((char*)spHeader.first.c_str()));
        if(qtssIllegalHeader != theHeader)
        {
            StringUtil::Trim(spHeader.second);
            m_HeaderDict[theHeader] = spHeader.second;
        }

        //some headers require some special processing. If this code begins
        //to get out of control, we made need to come up with a function pointer table
        switch (theHeader)
        {
            case qtssSessionHeader:             ParseSessionHeader(); break;
            case qtssCSeqHeader:                ParseCSeqHeader(); break;
            case qtssTransportHeader:           ParseTransportHeader(); break;
            case qtssRangeHeader:               ParseRangeHeader();     break;
            case qtssContentLengthHeader:       ParseContentLengthHeader();break;
            case qtssSpeedHeader:               ParseSpeedHeader();     break;
            case qtssScaleHeader:               ParseScaleHeader();     break;
            case qtssRequireHeader:             ParseRequireHeader();   break;
            case ngodNoticeHeader:              ParseNoticeHeader();    break;
            case ngodOnDemandSessionIdHeader:   ParseOnDemandSessionIdHeader(); break;
            case ngodReasonHeader:              ParseReasonHeader(); break;
            case ngodSessionGroupHeader:        ParseSessionGroupHeader(); break;
            default:    break;
        }

    }
    return 0;
}