]> git.sesse.net Git - vlc/blobdiff - modules/access/http.c
Used uint64_t for access_t::info.i_size/i_pos and access_t::pf_seek().
[vlc] / modules / access / http.c
index 4fac39cacca1d62b367910410513b7d5cf2fa689..384a58c19f100a8eac5029f1277412c4590ad4eb 100644 (file)
 #ifdef HAVE_LIBPROXY
 #    include <proxy.h>
 #endif
+
+#ifdef WIN32
+#   include <windows.h>
+#endif
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -99,6 +104,11 @@ static void Close( vlc_object_t * );
 #define MAX_REDIRECT_TEXT N_("Max number of redirection")
 #define MAX_REDIRECT_LONGTEXT N_("Limit the number of redirection to follow.")
 
+#define USE_IE_PROXY_TEXT N_("Use Internet Explorer entered HTTP proxy server")
+#define USE_IE_PROXY_LONGTEXT N_("Use Internet Explorer entered HTTP proxy " \
+    "server for all URL. Don't take into account bypasses settings and auto " \
+    "configuration scripts.")
+
 vlc_module_begin ()
     set_description( N_("HTTP input") )
     set_capability( "access", 0 )
@@ -125,6 +135,10 @@ vlc_module_begin ()
               FORWARD_COOKIES_LONGTEXT, true )
     add_integer( "http-max-redirect", 5, NULL, MAX_REDIRECT_TEXT,
                  MAX_REDIRECT_LONGTEXT, true )
+#ifdef WIN32
+    add_bool( "http-use-IE-proxy", false, NULL, USE_IE_PROXY_TEXT,
+              USE_IE_PROXY_LONGTEXT, true )
+#endif
     add_obsolete_string("http-user")
     add_obsolete_string("http-pwd")
     add_shortcut( "http" )
@@ -180,18 +194,19 @@ struct access_sys_t
     int64_t    i_chunk;
 
     int        i_icy_meta;
-    int64_t    i_icy_offset;
+    uint64_t   i_icy_offset;
     char       *psz_icy_name;
     char       *psz_icy_genre;
     char       *psz_icy_title;
 
-    int64_t i_remaining;
+    uint64_t i_remaining;
 
     bool b_seekable;
     bool b_reconnect;
     bool b_continuous;
     bool b_pace_control;
     bool b_persist;
+    bool b_has_size;
 
     vlc_array_t * cookies;
 };
@@ -204,12 +219,12 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
 /* */
 static ssize_t Read( access_t *, uint8_t *, size_t );
 static ssize_t ReadCompressed( access_t *, uint8_t *, size_t );
-static int Seek( access_t *, int64_t );
+static int Seek( access_t *, uint64_t );
 static int Control( access_t *, int, va_list );
 
 /* */
-static int Connect( access_t *, int64_t );
-static int Request( access_t *p_access, int64_t i_tell );
+static int Connect( access_t *, uint64_t );
+static int Request( access_t *p_access, uint64_t i_tell );
 static void Disconnect( access_t * );
 
 /* Small Cookie utilities. Cookies support is partial. */
@@ -293,7 +308,8 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
     p_sys->psz_icy_title = NULL;
     p_sys->i_remaining = 0;
     p_sys->b_persist = false;
-    p_access->info.i_size = -1;
+    p_sys->b_has_size = false;
+    p_access->info.i_size = 0;
     p_access->info.i_pos  = 0;
     p_access->info.b_eof  = false;
 
@@ -371,6 +387,67 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
             msg_Err(p_access, "Allocating memory for libproxy failed");
         }
     }
+#elif defined( WIN32 )
+    else
+    {
+        if( var_CreateGetBool( p_access, "http-use-IE-proxy" ) )
+        {
+            /* Try to get the proxy server address from Windows internet settings using registry. */
+            HKEY h_key;
+            /* Open the key */
+            if( RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Microsoft" \
+                              "\\Windows\\CurrentVersion\\Internet Settings",
+                              0, KEY_READ, &h_key ) == ERROR_SUCCESS )
+            {
+                DWORD i_dataReadSize = 4; /* sizeof( DWORD ); */
+                DWORD proxyEnable = 0;
+                /* Get the proxy enable value */
+                if( RegQueryValueEx( h_key, "ProxyEnable", NULL, NULL,
+                                     (char *)&proxyEnable, &i_dataReadSize )
+                                     == ERROR_SUCCESS )
+                {
+                    if( proxyEnable )
+                    {
+                        /* Proxy is enable */
+                        char psz_key[256];
+                        i_dataReadSize = 256;
+                        if( RegQueryValueEx( h_key, "ProxyServer",
+                                             NULL, NULL, psz_key,
+                                             &i_dataReadSize )
+                                             == ERROR_SUCCESS )
+                        {
+                            /* Get the proxy URL :
+                            Proxy server value in the registry can be something like "address:port"
+                            or "ftp=adress1:port1;http=adress2:port2 ..." depending of the
+                            confirguration. */
+                            char *psz_proxy;
+                            psz_proxy = strstr( psz_key, "http=" );
+                            if( psz_proxy != NULL )
+                            {
+                                psz_proxy += strlen( "http=" );
+                                char *psz_endUrl = strchr( psz_proxy, ';' );
+                                if( psz_endUrl != NULL )
+                                    *psz_endUrl = '\0';
+                            }
+                            else
+                                psz_proxy = psz_key;
+                            /* Set proxy enable for this connection. */
+                            p_sys->b_proxy = true;
+                            vlc_UrlParse( &p_sys->proxy, psz_proxy, 0 );
+                        }
+                        msg_Warn( p_access, "Couldn't read in registry " \
+                                  "the proxy server address." );
+                    }
+                }
+                else
+                    msg_Warn( p_access, "Couldn't read in registry if the " \
+                              "proxy is enable or not." );
+            }
+            else
+                msg_Warn( p_access, "Couldn't open internet settings key " \
+                          "in registry." );
+        }
+    }
 #elif HAVE_GETENV
     else
     {
@@ -382,6 +459,7 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
         }
     }
 #endif
+
     if( psz ) /* No, this is NOT a use-after-free error */
     {
         psz = var_CreateGetNonEmptyString( p_access, "http-proxy-pwd" );
@@ -682,7 +760,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
         return 0;
     }
 
-    if( p_access->info.i_size >= 0 &&
+    if( p_sys->b_has_size &&
         i_len + p_access->info.i_pos > p_access->info.i_size )
     {
         if( ( i_len = p_access->info.i_size - p_access->info.i_pos ) == 0 )
@@ -726,9 +804,9 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
             i_len = p_sys->i_chunk;
         }
     }
-    else if( p_access->info.i_size != -1 && (int64_t)i_len > p_sys->i_remaining) {
+    else if( p_sys->b_has_size && i_len > p_sys->i_remaining) {
         /* Only ask for the remaining length */
-        i_len = (size_t)p_sys->i_remaining;
+        i_len = p_sys->i_remaining;
         if(i_len == 0) {
             p_access->info.b_eof = true;
             return 0;
@@ -807,8 +885,9 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
             p_access->b_error = true;
     }
 
-    if( p_access->info.i_size != -1 )
+    if( p_sys->b_has_size )
     {
+        assert( i_read <= p_sys->i_remaining );
         p_sys->i_remaining -= i_read;
     }
 
@@ -924,14 +1003,14 @@ static ssize_t ReadCompressed( access_t *p_access, uint8_t *p_buffer,
 /*****************************************************************************
  * Seek: close and re-open a connection at the right place
  *****************************************************************************/
-static int Seek( access_t *p_access, int64_t i_pos )
+static int Seek( access_t *p_access, uint64_t i_pos )
 {
     msg_Dbg( p_access, "trying to seek to %"PRId64, i_pos );
 
     Disconnect( p_access );
 
     if( p_access->info.i_size
-     && (uint64_t)i_pos >= (uint64_t)p_access->info.i_size ) {
+     && i_pos >= p_access->info.i_size ) {
         msg_Err( p_access, "seek to far" );
         int retval = Seek( p_access, p_access->info.i_size - 1 );
         if( retval == VLC_SUCCESS ) {
@@ -1025,7 +1104,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
 /*****************************************************************************
  * Connect:
  *****************************************************************************/
-static int Connect( access_t *p_access, int64_t i_tell )
+static int Connect( access_t *p_access, uint64_t i_tell )
 {
     access_sys_t   *p_sys = p_access->p_sys;
     vlc_url_t      srv = p_sys->b_proxy ? p_sys->proxy : p_sys->url;
@@ -1053,8 +1132,8 @@ static int Connect( access_t *p_access, int64_t i_tell )
     p_sys->psz_icy_title = NULL;
     p_sys->i_remaining = 0;
     p_sys->b_persist = false;
-
-    p_access->info.i_size = -1;
+    p_sys->b_has_size = false;
+    p_access->info.i_size = 0;
     p_access->info.i_pos  = i_tell;
     p_access->info.b_eof  = false;
 
@@ -1148,7 +1227,7 @@ static int Connect( access_t *p_access, int64_t i_tell )
 }
 
 
-static int Request( access_t *p_access, int64_t i_tell )
+static int Request( access_t *p_access, uint64_t i_tell )
 {
     access_sys_t   *p_sys = p_access->p_sys;
     char           *psz ;
@@ -1332,25 +1411,28 @@ static int Request( access_t *p_access, int64_t i_tell )
 
         if( !strcasecmp( psz, "Content-Length" ) )
         {
-            int64_t i_size = i_tell + (p_sys->i_remaining = atoll( p ));
+            uint64_t i_size = i_tell + (p_sys->i_remaining = (uint64_t)atoll( p ));
             if(i_size > p_access->info.i_size) {
+                p_sys->b_has_size = true;
                 p_access->info.i_size = i_size;
             }
-            msg_Dbg( p_access, "this frame size=%"PRId64, p_sys->i_remaining );
+            msg_Dbg( p_access, "this frame size=%"PRIu64, p_sys->i_remaining );
         }
         else if( !strcasecmp( psz, "Content-Range" ) ) {
-            int64_t i_ntell = i_tell;
-            int64_t i_nend = (p_access->info.i_size > 0)?(p_access->info.i_size - 1):i_tell;
-            int64_t i_nsize = p_access->info.i_size;
-            sscanf(p,"bytes %"PRId64"-%"PRId64"/%"PRId64,&i_ntell,&i_nend,&i_nsize);
+            uint64_t i_ntell = i_tell;
+            uint64_t i_nend = (p_access->info.i_size > 0)?(p_access->info.i_size - 1):i_tell;
+            uint64_t i_nsize = p_access->info.i_size;
+            sscanf(p,"bytes %"SCNu64"-%"SCNu64"/%"SCNu64,&i_ntell,&i_nend,&i_nsize);
             if(i_nend > i_ntell ) {
                 p_access->info.i_pos = i_ntell;
                 p_sys->i_remaining = i_nend+1-i_ntell;
                 int64_t i_size = (i_nsize > i_nend) ? i_nsize : (i_nend + 1);
                 if(i_size > p_access->info.i_size) {
+                    p_sys->b_has_size = true;
                     p_access->info.i_size = i_size;
                 }
-                msg_Dbg( p_access, "stream size=%"PRId64",pos=%"PRId64",remaining=%"PRId64,i_nsize,i_ntell,p_sys->i_remaining);
+                msg_Dbg( p_access, "stream size=%"PRIu64",pos=%"PRIu64",remaining=%"PRIu64,
+                         i_nsize, i_ntell, p_sys->i_remaining);
             }
         }
         else if( !strcasecmp( psz, "Connection" ) ) {
@@ -1401,12 +1483,14 @@ static int Request( access_t *p_access, int64_t i_tell )
         else if( !strcasecmp( psz, "Content-Encoding" ) )
         {
             msg_Dbg( p_access, "Content-Encoding: %s", p );
-            if( strcasecmp( p, "identity" ) )
+            if( !strcasecmp( p, "identity" ) )
+                ;
 #ifdef HAVE_ZLIB_H
+            else if( !strcasecmp( p, "gzip" ) || !strcasecmp( p, "deflate" ) )
                 p_sys->b_compressed = true;
-#else
-                msg_Warn( p_access, "Compressed content not supported. Rebuild with zlib support." );
 #endif
+            else
+                msg_Warn( p_access, "Unknown content coding: %s", p );
         }
         else if( !strcasecmp( psz, "Pragma" ) )
         {
@@ -1525,7 +1609,7 @@ static int Request( access_t *p_access, int64_t i_tell )
     /* We close the stream for zero length data, unless of course the
      * server has already promised to do this for us.
      */
-    if( p_access->info.i_size != -1 && p_sys->i_remaining == 0 && p_sys->b_persist ) {
+    if( p_sys->b_has_size && p_sys->i_remaining == 0 && p_sys->b_persist ) {
         Disconnect( p_access );
     }
     return VLC_SUCCESS;