[hxprotocol] CR: handle ',' in URL of RTP-Info

[hxprotocol] CR: handle ',' in URL of RTP-Info

Henry Ping ping at real.com
Mon Jul 28 17:01:51 PDT 2003


Here is my 2nd attempt to address this issue, it's tricky given both ';' 
and ',' can exist in URL and they are also valid attribute's and entry's 
separators.

I'd like to check this in before 12pm tonight if no objection, so the fix 
will be in tonight's daily build.

-->Henry

At 12:48 PM 7/28/2003 -0700, Tom Marshall wrote:
>On Mon, Jul 28, 2003 at 11:49:31AM -0700, Henry Ping wrote:
> > In RTP-Info header from PLAY response, ',' is allowed in URL such as the
> > port separator for cloaking("?cloakport=7070, 80, 554") but the client
> > currently only treats ',' as the field separator of control streams.
>
>This is a problem in the RTSP spec and fixing the issue is bound to be
>tricky.
>
>What happens if an url contains a semicolon?  This is common in HTTP urls,
>especially for Java based servlets that maintain session state.  A quick
>tcpdump shows that the Mozilla web browser sends semicolons unescaped but
>RealPlayer (8.0 for Linux) does not.  I don't have another RTSP client handy
>to test with, but I think a better parser could protect us from future
>reincarnations of this same bug with third party clients.  Something that
>looks for an initial "url=" after the semicolon to recognize the start of a
>new stream-url would probably be more robust.
>
>Client-side behavior parameters (cloakport, start, end, etc.) would probably
>be better encoded differently.  The query should be reserved for dynamic
>content on the server.  Using queries to signal client-side behavior has
>other undesirable consequences, such as caching issues.  One alternative
>could be using an url fragment.  Fragments are handled at the client and not
>transmitted on the wire.
>
>Coincidentally, I just had a discussion regarding encoding temporal
>parameters in URIs at the last IETF meeting.  Temporal parameters differ
>from HTTP fragments because they indicate a range to be used for the PLAY
>request in RTSP so that only part of the document is not retrieved, but the
>HTTP client retrieves the entire document.  There may be enough interest in
>this issue to begin discussion in the IETF for updating the URI spec to
>include an official syntax for encoding temporal parameters in fragments.
>
>--
>Logic is a systematic method of coming to the wrong conclusion with
>confidence.
-------------- next part --------------
? Umakefil.upp
? Makefile
? protocol_rtsp.dsp
? protocol_rtsp.dsw
? dbg32
? a
? logfile.txt
Index: rtsppars.cpp
===================================================================
RCS file: /cvs/protocol/rtsp/rtsppars.cpp,v
retrieving revision 1.1.1.1.10.1
diff -u -w -4 -r1.1.1.1.10.1 rtsppars.cpp
--- rtsppars.cpp	13 Jun 2003 00:21:45 -0000	1.1.1.1.10.1
+++ rtsppars.cpp	28 Jul 2003 23:52:33 -0000
@@ -246,8 +246,148 @@
     return 0;
 }
 
 int
+RTSPParser::parseRTPInfoHeaderValues(const char* pValue, MIMEHeader* pHeader)
+{
+    // Per RFC2326 "12.33 RTP-Info"
+    // We can't use token search on ',' & ';' since both can also be part of 
+    // the URL value. We will:
+    // 1. find stream URL entry based on "url="
+    // 2. read "url", "seq" and "rtptime" within the stream URL entry
+    if (!pValue || 0 == strlen(pValue))
+    {
+        return 0;
+    }
+
+    char*   pCurrentEntry = NULL;
+    char*   pNextEntry = NULL;
+    CHXString value = pValue;
+    CHXString entry;
+
+    pCurrentEntry = strstr(pValue, "url=");
+
+    while (pNextEntry = strstr(pCurrentEntry+4, "url="))
+    {
+        // retreive stream URL entry
+        entry = value.Mid(pCurrentEntry - pValue, pNextEntry - pCurrentEntry);
+
+        // retrieve "url", "seq" and "rtptime"
+        SetRTPInfoEntry(entry, pHeader);
+        
+        pCurrentEntry = pNextEntry;
+    }
+
+    entry = value.Mid(pCurrentEntry - pValue);
+    SetRTPInfoEntry(entry, pHeader);
+
+    return 0;
+}
+
+int 
+RTSPParser::ReadRTPInfoEntry(CHXString      in, 
+                             INT32          i,
+                             INT32          length,
+                             CHXString&     out)
+{
+    UINT32 ulLength = 0;
+    CHXString temp;
+
+    if (length > 0)
+    {
+        temp = in.Mid(i, length);
+    }
+    else
+    {
+        temp = in.Mid(i);
+    }
+
+    temp.TrimLeft();
+    temp.TrimRight();
+
+    ulLength = temp.GetLength();
+    // remove trailing ',' or ';' in case there is any
+    if (temp[ulLength-1] == ',' || temp[ulLength-1] == ';')
+    {
+        out = temp.Mid(0, ulLength-1);
+        out.TrimRight();
+    }
+    else
+    {
+        out = temp;
+    }
+
+    return 0;
+}
+
+int
+RTSPParser::SetRTPInfoEntry(CHXString in, MIMEHeader* pHeader)
+{
+    INT32 lURL, lSeq, lRTPTime;
+    CHXString URLValue, SeqValue, RTPTimeValue;
+    MIMEHeaderValue* pHeaderValue = new MIMEHeaderValue;
+
+    lURL = in.Find("url=");
+    lSeq = in.Find("seq=");
+    lRTPTime = in.Find("rtptime=");
+
+    // both seq and rtptime are present
+    if (lSeq > 0 && lRTPTime > 0)
+    {
+        // url;seq;rtptime
+        if (lRTPTime > lSeq)
+        {
+            ReadRTPInfoEntry(in, lURL+4, lSeq-lURL-5, URLValue);
+            ReadRTPInfoEntry(in, lSeq+4, lRTPTime-lSeq-5, SeqValue);
+            ReadRTPInfoEntry(in, lRTPTime+8, -1, RTPTimeValue);
+        }
+        // url;rtptime;seq
+        else
+        {
+            ReadRTPInfoEntry(in, lURL+4, lRTPTime-lURL-5, URLValue);
+            ReadRTPInfoEntry(in, lRTPTime+8, lSeq-lRTPTime-9, RTPTimeValue);
+            ReadRTPInfoEntry(in, lSeq+4, -1, SeqValue);
+        }
+    }
+    // url;seq
+    else if (lSeq > 0)
+    {
+        ReadRTPInfoEntry(in, lURL+4, lSeq-lURL-5, URLValue);
+        ReadRTPInfoEntry(in, lSeq+4, -1, SeqValue);
+    }
+    // url;rtptime
+    else if (lRTPTime > 0)
+    {
+        ReadRTPInfoEntry(in, lURL+4, lRTPTime-lURL-5, URLValue);
+        ReadRTPInfoEntry(in, lRTPTime+8, -1, RTPTimeValue);
+    }
+    // invalid case, either seq or rtptime has to be present
+    else
+    {
+        HX_ASSERT(FALSE);
+    }
+
+    if (!URLValue.IsEmpty())
+    {
+        pHeaderValue->addParameter("url", URLValue);
+    }
+
+    if (!SeqValue.IsEmpty())
+    {
+        pHeaderValue->addParameter("seq", SeqValue);
+    }
+
+    if (!RTPTimeValue.IsEmpty())
+    {
+        pHeaderValue->addParameter("rtptime", RTPTimeValue);
+    }
+
+    pHeader->addHeaderValue(pHeaderValue);
+
+    return 0;
+}
+
+int
 RTSPParser::parseBackChannelValue(const char* pValue, MIMEHeader* pHeader)
 {
     MIMEInputStream input(pValue, strlen(pValue));
     MIMEScanner scanner(input);
@@ -375,8 +515,12 @@
 	        (strcasecmp(pHeader->name(), "C-PEP-Info") == 0))
 	{
 	    parsePEPInfoHeaderValues(nextTok.value(), pHeader);
 	}
+        else if(strcasecmp(pHeader->name(), "RTP-Info") == 0)
+        {
+            parseRTPInfoHeaderValues(nextTok.value(), pHeader);
+        }
 	else if(strcasecmp(pHeader->name(), "BackChannel") == 0)
 	{
 	    parseBackChannelValue(nextTok.value(), pHeader);
 	}
Index: pub/rtsppars.h
===================================================================
RCS file: /cvs/protocol/rtsp/pub/rtsppars.h,v
retrieving revision 1.1.1.1
diff -u -w -4 -r1.1.1.1 rtsppars.h
--- pub/rtsppars.h	18 Oct 2002 01:57:52 -0000	1.1.1.1
+++ pub/rtsppars.h	28 Jul 2003 23:52:33 -0000
@@ -68,8 +68,11 @@
 					 MIMEHeader* pHeader);
     int parseDigestAuthorizationHeaderValues(const char* pValue,
 					 MIMEHeader* pHeader);
     int parsePEPInfoHeaderValues(const char* pValue, MIMEHeader* pHeader);
+    int parseRTPInfoHeaderValues(const char* pValue, MIMEHeader* pHeader);
+    int ReadRTPInfoEntry(CHXString in, INT32 i, INT32 length, CHXString& out);
+    int SetRTPInfoEntry(CHXString in, MIMEHeader* pHeader);
     int parseBackChannelValue(const char* pValue, MIMEHeader* pHeader);
     int parseAlertValue(const char* pValue, MIMEHeader* pHeader);
     int defaultParseHeaderValues(const char* pValue, MIMEHeader* pHeader);
     int parseProtocolVersion(const CHXString& prot, int& major, int& minor);

-------------- next part --------------
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe at protocol.helixcommunity.org
For additional commands, e-mail: dev-help at protocol.helixcommunity.org


More information about the Protocol-dev mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.