#1278 librtmp needs the #-fragment part of the URL to be kept

closed-fixed
None
5
2015-02-18
2013-09-11
No

Steps to reproduce:

$curl "rtmp://live.iguide.to/edge swfUrl=http://player.ilive.to/player_ilive_2.swf pageUrl=http://www.ilive.to playpath=nz7l9vc5nv1og7b token=#e87JDUJD264YED687 live=1"

Output:

ERROR: RTMP_ReadPacket, failed to read RTMP packet header
curl: (2) Failed initialization

The error happens due to not parsing the correct token because of "#" character. To test that I just put a printf in rtmp_setup like this:

static CURLcode rtmp_setup(struct connectdata *conn)
{
  RTMP *r = RTMP_Alloc();

  if(!r)
    return CURLE_OUT_OF_MEMORY;

  RTMP_Init(r);
  RTMP_SetBufferMS(r, DEF_BUFTIME);
  printf(
            "CURLcode rtmp_setup %s \n", conn->data->change.url);
  if(!RTMP_SetupURL(r, conn->data->change.url)) {
    RTMP_Free(r);
    return CURLE_URL_MALFORMAT;
  }
  conn->proto.generic = r;
  return CURLE_OK;
}

The output is:

CURLcode rtmp_setup rtmp://live.iguide.to/edge swfUrl=http://player.ilive.to/player_ilive_2.swf pageUrl=http://www.ilive.to playpath=nz7l9vc5nv1og7b token=
ERROR: RTMP_ReadPacket, failed to read RTMP packet header
curl: (2) Failed initialization

If no "#" it's present the token it's parsed correctly:

$curl "rtmp://live.iguide.to/edge swfUrl=http://player.ilive.to/player_ilive_2.swf pageUrl=http://www.ilive.to playpath=nz7l9vc5nv1og7b token=e87JDUJD264YED687 live=1"

Although the rtmp response fails as it's normal:

CURLcode rtmp_setup rtmp://live.iguide.to/edge swfUrl=http://player.ilive.to/player_ilive_2.swf pageUrl=http://www.ilive.to playpath=nz7l9vc5nv1og7b token=e87JDUJD264YED687 live=1: 
ERROR: RTMP_ReadPacket, failed to read RTMP packet header
curl: (2) Failed initialization

Discussion

  • Gorilla Maguila

    Gorilla Maguila - 2013-09-11

    The problem it's in:

    ~~~~~~~~
    static CURLcode parseurlandfillconn(struct SessionHandle data,
    struct connectdata
    conn,
    bool prot_missing,
    char
    user, char passwd, char options)

    ........

    fragment = strchr(path, '#');
    if(fragment) {
    *fragment = 0;

    /* we know the path part ended with a fragment, so we know the full URL
       string does too and we need to cut it off from there so it isn't used
       over proxy */
    fragment = strchr(data->change.url, '#');
    if(fragment)
      *fragment = 0;
    

    .......

    ~~~~~~~~~

    Maybe we can put something like:

    ~~~~~~~~~~

    ........

    if(!strstr(protop, "rtmp")){
    fragment = strchr(path, '#');
    if(fragment) {
    *fragment = 0;

    /* we know the path part ended with a fragment, so we know the full URL
       string does too and we need to cut it off from there so it isn't used
       over proxy */
    fragment = strchr(data->change.url, '#');
    if(fragment)
      *fragment = 0;
    

    }
    }

    .......

     
    Last edit: Gorilla Maguila 2013-09-11
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-11
    • assigned_to: Daniel Stenberg
     
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-11

    1 - a URL cannot legally contain white spaces so your input is wrong.

    2 - a '#' character in a URL is a fragment and is not supposed to be sent to a server. If you need the "literal" # letter you can pass it in as %23.

     
  • Gorilla Maguila

    Gorilla Maguila - 2013-09-11

    What do you mean my input it's wrong?

    I'm using librtmp so parsing (this is linux command line):

    $curl "rtmp://live.iguide.to/edge swfUrl=http://player.ilive.to/player_ilive_2.swf pageUrl=http://www.ilive.to playpath=nz7l9vc5nv1og7b token=#e87JDUJD264YED687 live=1"

    It's perfectly ok.

    And no I shouldn't substitute # with url encode format because the token changes,

     
    Last edit: Gorilla Maguila 2013-09-11
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-11

    Wrong as in not a valid URL (or actually a URI as the specs say).

    Spaces aren't part of URIs, they should either not be there at all or be encoded as %20.

    '#' marks a "fragment". RFC3986 details how they work, chapter 3.5 mentions fragments and they say "Fragment identifier semantics are independent of the URI scheme and thus cannot be redefined by scheme specifications."

    curl is very liberal in what it accepts so don't expect that to be a very good judge of what's a "legal" URL and what isn't. If the code treats %23 wrongly, then I suspect that's an error since a URL should be able to use letters url encoded fine

     
  • Gorilla Maguila

    Gorilla Maguila - 2013-09-11

    Well being true that it's not a valid URL, curl supports librtmp and in librtmp parameters internally are passed with white spaces.

    So in the end you are telling me that that librtmp should handle url encoded characters? what if the token or another paramater actually need %23 characters instead of # for example token=%23abc instead of token=#abc ?

     
    Last edit: Gorilla Maguila 2013-09-11
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-12

    Urgh. How annoying.

    Yes, a URL should only require valid URL characters to be part of the string and spaces and #-letters are not. I claim librtmp is broken in this aspect. But I also acknowledge that me saying this doesn't help you with this problem one bit.

    I first considered that perhaps the bug is in libcurl and perhaps we should url-decode the URL string before we pass it to RTMP_SetupURL() but I'm not convinced that is the correct route either as for example http://rtmpdump.mplayerhq.hu/librtmp.3.html shows how to use the function and it encourages an illegal URL to be used. I'm a bit concerned that URL-decoding before passing it to librtmp may have some other side-effects I haven't really thought about even if it would allow %23 to be used instead of the literal #...

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-12
    • summary: Parse rtmp token utf-8 character --> librtmp needs the #-fragment part of the URL to be kept
    • status: open --> open-confirmed
     
  • Gorilla Maguila

    Gorilla Maguila - 2013-09-12

    Don't get annoyed.

    I'm just trying to help ;)

    May be my bad after all. It seems that using hexadecimal representation works on librtmp ex: token=\23abc works as token=#abc

    Sorry for the disturbance

     
    Last edit: Gorilla Maguila 2013-09-12
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-13

    That's still not very URL like, but at least it is a way to work around this problem so I'm glad you figured this out.

    I've now pushed a documentation update for curl_easy_setopt and its section where it mentions special stuff about the URL for various protocols. This update is present in commit 8a6dba520bfc.

    I believe we can consider this case closed. Unless someone objects I'll close this soonish.

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-09-13
    • labels: rtmp token utf-8 character -->
    • status: open-confirmed --> closed-fixed
     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks