Revert "Imported Upstream version 7.53.1"
[platform/upstream/curl.git] / lib / rtsp.c
index 029738d..ed3fd64 100644 (file)
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.haxx.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
 #include "progress.h"
 #include "rtsp.h"
 #include "rawstr.h"
-#include "curl_memory.h"
 #include "select.h"
 #include "connect.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /*
@@ -76,7 +73,7 @@ static int rtsp_getsock_do(struct connectdata *conn,
  *        data is parsed and k->str is moved up
  * readmore: whether or not the RTP parser needs more data right away
  */
-static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
                                    struct connectdata *conn,
                                    ssize_t *nread,
                                    bool *readmore);
@@ -161,7 +158,7 @@ bool Curl_rtsp_connisdead(struct connectdata *check)
   }
   else if((sval & CURL_CSELECT_IN) && check->data) {
     /* readable with no error. could be closed or could be alive but we can
-       only check if we have a proper SessionHandle for the connection */
+       only check if we have a proper Curl_easy for the connection */
     curl_socket_t connectinfo = Curl_getconnectinfo(check->data, &check);
     if(connectinfo != CURL_SOCKET_BAD)
       ret_val = FALSE;
@@ -173,7 +170,7 @@ bool Curl_rtsp_connisdead(struct connectdata *check)
 static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
 {
   CURLcode httpStatus;
-  struct SessionHandle *data = conn->data;
+  struct Curl_easy *data = conn->data;
 
   httpStatus = Curl_http_connect(conn, done);
 
@@ -199,7 +196,7 @@ static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
 static CURLcode rtsp_done(struct connectdata *conn,
                           CURLcode status, bool premature)
 {
-  struct SessionHandle *data = conn->data;
+  struct Curl_easy *data = conn->data;
   struct RTSP *rtsp = data->req.protop;
   CURLcode httpStatus;
   long CSeq_sent;
@@ -233,7 +230,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
 
 static CURLcode rtsp_do(struct connectdata *conn, bool *done)
 {
-  struct SessionHandle *data = conn->data;
+  struct Curl_easy *data = conn->data;
   CURLcode result=CURLE_OK;
   Curl_RtspReq rtspreq = data->set.rtspreq;
   struct RTSP *rtsp = data->req.protop;
@@ -251,6 +248,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
   const char *p_stream_uri = NULL;
   const char *p_transport = NULL;
   const char *p_uagent = NULL;
+  const char *p_proxyuserpwd = NULL;
+  const char *p_userpwd = NULL;
 
   *done = TRUE;
 
@@ -265,11 +264,10 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
    * Since all RTSP requests are included here, there is no need to
    * support custom requests like HTTP.
    **/
-  DEBUGASSERT((rtspreq > RTSPREQ_NONE && rtspreq < RTSPREQ_LAST));
   data->set.opt_no_body = TRUE; /* most requests don't contain a body */
   switch(rtspreq) {
-  case RTSPREQ_NONE:
-    failf(data, "Got invalid RTSP request: RTSPREQ_NONE");
+  default:
+    failf(data, "Got invalid RTSP request");
     return CURLE_BAD_FUNCTION_ARGUMENT;
   case RTSPREQ_OPTIONS:
     p_request = "OPTIONS";
@@ -325,11 +323,10 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
   if(!p_session_id &&
      (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
     failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
-          p_request ? p_request : "");
+          p_request);
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
 
-  /* TODO: auth? */
   /* TODO: proxy? */
 
   /* Stream URI. Default to server '*' if not specified */
@@ -395,6 +392,14 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
     p_uagent = conn->allocptr.uagent;
   }
 
+  /* setup the authentication headers */
+  result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE);
+  if(result)
+    return result;
+
+  p_proxyuserpwd = conn->allocptr.proxyuserpwd;
+  p_userpwd = conn->allocptr.userpwd;
+
   /* Referrer */
   Curl_safefree(conn->allocptr.ref);
   if(data->change.referer && !Curl_checkheaders(conn, "Referer:"))
@@ -443,8 +448,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
     Curl_add_bufferf(req_buffer,
                      "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
                      "CSeq: %ld\r\n", /* CSeq */
-                     (p_request ? p_request : ""), p_stream_uri,
-                     rtsp->CSeq_sent);
+                     p_request, p_stream_uri, rtsp->CSeq_sent);
   if(result)
     return result;
 
@@ -468,13 +472,25 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
                             "%s" /* range */
                             "%s" /* referrer */
                             "%s" /* user-agent */
+                            "%s" /* proxyuserpwd */
+                            "%s" /* userpwd */
                             ,
                             p_transport ? p_transport : "",
                             p_accept ? p_accept : "",
                             p_accept_encoding ? p_accept_encoding : "",
                             p_range ? p_range : "",
                             p_referrer ? p_referrer : "",
-                            p_uagent ? p_uagent : "");
+                            p_uagent ? p_uagent : "",
+                            p_proxyuserpwd ? p_proxyuserpwd : "",
+                            p_userpwd ? p_userpwd : "");
+
+  /*
+   * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
+   * with basic and digest, it will be freed anyway by the next request
+   */
+  Curl_safefree (conn->allocptr.userpwd);
+  conn->allocptr.userpwd = NULL;
+
   if(result)
     return result;
 
@@ -498,8 +514,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
 
     }
     else {
-      postsize = (data->set.postfieldsize != -1)?
-        data->set.postfieldsize:
+      postsize = (data->state.infilesize != -1)?
+        data->state.infilesize:
         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
       data->set.httpreq = HTTPREQ_POST;
     }
@@ -584,7 +600,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
 }
 
 
-static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
                                    struct connectdata *conn,
                                    ssize_t *nread,
                                    bool *readmore) {
@@ -715,7 +731,7 @@ static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
 static
 CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len)
 {
-  struct SessionHandle *data = conn->data;
+  struct Curl_easy *data = conn->data;
   size_t wrote;
   curl_write_callback writeit;
 
@@ -743,7 +759,7 @@ CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len)
 CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
                                char *header)
 {
-  struct SessionHandle *data = conn->data;
+  struct Curl_easy *data = conn->data;
   long CSeq = 0;
 
   if(checkprefix("CSeq:", header)) {
@@ -780,19 +796,15 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
       }
     }
     else {
-      /* If the Session ID is not set, and we find it in a response, then
-         set it */
-
-      /* The session ID can be an alphanumeric or a 'safe' character
+      /* If the Session ID is not set, and we find it in a response, then set
+       * it.
        *
-       * RFC 2326 15.1 Base Syntax:
-       * safe =  "\$" | "-" | "_" | "." | "+"
-       * */
+       * Allow any non whitespace content, up to the field seperator or end of
+       * line. RFC 2326 isn't 100% clear on the session ID and for example
+       * gstreamer does url-encoded session ID's not covered by the standard.
+       */
       char *end = start;
-      while(*end &&
-            (ISALNUM(*end) || *end == '-' || *end == '_' || *end == '.' ||
-             *end == '+' ||
-             (*end == '\\' && *(end + 1) && *(end + 1) == '$' && (++end, 1))))
+      while(*end && *end != ';' && !ISSPACE(*end))
         end++;
 
       /* Copy the id substring into a new buffer */