Implemented http proxy for mmsh (close #629)
authorLaurent Aimar <fenrir@videolan.org>
Sat, 24 Mar 2007 00:24:22 +0000 (00:24 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 24 Mar 2007 00:24:22 +0000 (00:24 +0000)
It uses --mmsh-proxy=xxx or http_proxy environment variable (basic
authentication has not been tested).
We may want to reuse --http-proxy from http instead (and so we will have to
move the option out of http.c)

modules/access/mms/mms.c
modules/access/mms/mmsh.c
modules/access/mms/mmsh.h

index abdecb8..ccc29a4 100644 (file)
@@ -57,6 +57,12 @@ static void Close( vlc_object_t * );
 #define BITRATE_LONGTEXT N_( \
     "Select the stream with the maximum bitrate under that limit."  )
 
+#define PROXY_TEXT N_("HTTP proxy")
+#define PROXY_LONGTEXT N_( \
+    "HTTP proxy to be used It must be of the form " \
+    "http://[user[:pass]@]myproxy.mydomain:myport/ ; " \
+    "if empty, the http_proxy environment variable will be tried." )
+
 vlc_module_begin();
     set_shortname( "MMS" );
     set_description( _("Microsoft Media Server (MMS) input") );
@@ -70,6 +76,8 @@ vlc_module_begin();
     add_bool( "mms-all", 0, NULL, ALL_TEXT, ALL_LONGTEXT, VLC_TRUE );
     add_integer( "mms-maxbitrate", 0, NULL, BITRATE_TEXT, BITRATE_LONGTEXT ,
                  VLC_FALSE );
+    add_string( "mmsh-proxy", NULL, NULL, PROXY_TEXT, PROXY_LONGTEXT,
+                    VLC_FALSE );
 
     add_shortcut( "mms" );
     add_shortcut( "mmsu" );
index 18d1c73..6ca4ad6 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#define _GNU_SOURCE
 #include <stdlib.h>
 
 #include <vlc/vlc.h>
 #include <vlc_access.h>
 #include "vlc_playlist.h"
+#include "vlc_strings.h"
 
 #include <vlc_network.h>
 #include "vlc_url.h"
@@ -74,6 +76,7 @@ int E_(MMSHOpen)( access_t *p_access )
 {
     access_sys_t    *p_sys;
     char            *psz_location = NULL;
+    char            *psz_proxy;
 
     /* init p_sys */
 
@@ -94,6 +97,46 @@ int E_(MMSHOpen)( access_t *p_access )
     p_sys->fd     = -1;
     p_sys->i_start= 0;
 
+    /* Handle proxy */
+    p_sys->b_proxy = VLC_FALSE;
+    memset( &p_sys->proxy, 0, sizeof(p_sys->proxy) );
+
+    /* Check proxy */
+    /* TODO reuse instead http-proxy from http access ? */
+    psz_proxy = var_CreateGetString( p_access, "mmsh-proxy" );
+    if( *psz_proxy )
+    {
+        p_sys->b_proxy = VLC_TRUE;
+        vlc_UrlParse( &p_sys->proxy, psz_proxy, 0 );
+    }
+#ifdef HAVE_GETENV
+    else
+    {
+        char *psz_proxy = getenv( "http_proxy" );
+        if( psz_proxy && *psz_proxy )
+        {
+            p_sys->b_proxy = VLC_TRUE;
+            vlc_UrlParse( &p_sys->proxy, psz_proxy, 0 );
+        }
+    }
+#endif
+    free( psz_proxy );
+
+    if( p_sys->b_proxy )
+    {
+       if( p_sys->proxy.psz_host == NULL || *p_sys->proxy.psz_host == '\0' )
+        {
+            msg_Warn( p_access, "invalid proxy host" );
+            vlc_UrlClean( &p_sys->proxy );
+            free( p_sys );
+            return VLC_EGENERIC;
+        }
+        if( p_sys->proxy.i_port <= 0 )
+            p_sys->proxy.i_port = 80;
+        msg_Dbg( p_access, "Using http proxy %s:%d",
+                 p_sys->proxy.psz_host, p_sys->proxy.i_port );
+    }
+
     /* open a tcp connection */
     vlc_UrlParse( &p_sys->url, p_access->psz_path, 0 );
     if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
@@ -433,6 +476,55 @@ static int Reset( access_t *p_access )
     p_sys->i_packet_length = 0;
     return 0;
 }
+
+static int OpenConnection( access_t *p_access )
+{
+    access_sys_t *p_sys = p_access->p_sys;
+    vlc_url_t    srv = p_sys->b_proxy ? p_sys->proxy : p_sys->url;
+
+    if( ( p_sys->fd = net_ConnectTCP( p_access,
+                                      srv.psz_host, srv.i_port ) ) < 0 )
+    {
+        msg_Err( p_access, "cannot connect to %s:%d",
+                 srv.psz_host, srv.i_port );
+        return VLC_EGENERIC;
+    }
+
+    if( p_sys->b_proxy )
+    {
+        net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
+                    "GET http://%s:%d%s HTTP/1.0\r\n",
+                    p_sys->url.psz_host, p_sys->url.i_port,
+                    ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path );
+
+        /* Proxy Authentication */
+        if( p_sys->proxy.psz_username && *p_sys->proxy.psz_username )
+        {
+            char *buf;
+            char *b64;
+
+            asprintf( &buf, "%s:%s", p_sys->proxy.psz_username,
+                       p_sys->proxy.psz_password ? p_sys->proxy.psz_password : "" );
+
+            b64 = vlc_b64_encode( buf );
+            free( buf );
+
+            net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
+                        "Proxy-Authorization: Basic %s\r\n", b64 );
+            free( b64 );
+        }
+    }
+    else
+    {
+        net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
+                    "GET %s HTTP/1.0\r\n"
+                    "Host: %s:%d\r\n",
+                    ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,
+                    p_sys->url.psz_host, p_sys->url.i_port );
+    }
+    return VLC_SUCCESS;
+}
+
 /*****************************************************************************
  * Describe:
  *****************************************************************************/
@@ -452,25 +544,14 @@ static int Describe( access_t  *p_access, char **ppsz_location )
     p_sys->p_packet = NULL;
     E_( GenerateGuid )( &p_sys->guid );
 
-    if( ( p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host,
-                                            p_sys->url.i_port ) ) < 0 )
-    {
-        msg_Err( p_access, "cannot connect to %s:%d", p_sys->url.psz_host,
-                 p_sys->url.i_port );
-        goto error;
-    }
+    OpenConnection( p_access );
 
-    /* send first request */
     net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
-                "GET %s HTTP/1.0\r\n"
                 "Accept: */*\r\n"
                 "User-Agent: "MMSH_USER_AGENT"\r\n"
-                "Host: %s:%d\r\n"
                 "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%d,max-duration=0\r\n"
                 "Pragma: xClientGUID={"GUID_FMT"}\r\n"
                 "Connection: Close\r\n",
-                ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,
-                p_sys->url.psz_host, p_sys->url.i_port,
                 p_sys->i_request_context++,
                 GUID_PRINT( p_sys->guid ) );
 
@@ -646,14 +727,6 @@ static int Start( access_t *p_access, off_t i_pos )
 
     msg_Dbg( p_access, "starting stream" );
 
-    if( ( p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host,
-                                      p_sys->url.i_port ) ) < 0 )
-    {
-        /* should not occur */
-        msg_Err( p_access, "cannot connect to the server" );
-        return VLC_EGENERIC;
-    }
-
     for( i = 1; i < 128; i++ )
     {
         if( p_sys->asfh.stream[i].i_cat == ASF_STREAM_UNKNOWN )
@@ -662,19 +735,17 @@ static int Start( access_t *p_access, off_t i_pos )
         if( p_sys->asfh.stream[i].i_selected )
             i_streams_selected++;
     }
-
     if( i_streams_selected <= 0 )
     {
         msg_Err( p_access, "no stream selected" );
         return VLC_EGENERIC;
     }
+
+    OpenConnection( p_access );
+
     net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
-                "GET %s HTTP/1.0\r\n"
                 "Accept: */*\r\n"
-                "User-Agent: "MMSH_USER_AGENT"\r\n"
-                "Host: %s:%d\r\n",
-                ( p_sys->url.psz_path == NULL || *p_sys->url.psz_path == '\0' ) ? "/" : p_sys->url.psz_path,
-                p_sys->url.psz_host, p_sys->url.i_port );
+                "User-Agent: "MMSH_USER_AGENT"\r\n" );
     if( p_sys->b_broadcast )
     {
         net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
index dc29b4e..bf25ac0 100644 (file)
@@ -44,6 +44,9 @@ struct access_sys_t
     int             fd;
     vlc_url_t       url;
 
+    vlc_bool_t      b_proxy;
+    vlc_url_t       proxy;
+
     int             i_request_context;
 
     uint8_t         buffer[BUFFER_SIZE + 1];