[vlc-devel] [PATCH] access/http: Persist cookies in the libvlc instance

Antti Ajanki antti.ajanki at iki.fi
Mon Aug 11 17:58:21 CEST 2014


Cookies are shared between all HTTP requests in a libvlc session.
Sharing of cookies is required, for example, by certain HDS and HLS
streams that set a cookie when the manifest is read and expect it to be
sent back on fragment requests.
---
 NEWS                         |    3 ++-
 modules/access/http.c        |   25 +++++++++--------------
 modules/access/httpcookies.c |   46 ++++++++++++++++++++++++++++++++----------
 modules/access/httpcookies.h |    2 +-
 src/Makefile.am              |    1 +
 src/libvlc.c                 |    5 +++++
 6 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/NEWS b/NEWS
index f1e6256..5c3f092 100644
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,8 @@ Access:
  * Support HDS (Http Dynamic Streaming) from Adobe (f4m, f4v, etc.)
  * New SMB access module using libdsm
  * Support decompression and extraction through libarchive (tar, zip, rar...)
- * Improvements of cookie handling (domain / path matching, Secure cookies)
+ * Improvements of HTTP cookie handling (persist cookies during a libvlc
+   session, domain / path matching, Secure cookies)
 
 Decoder:
  * OMX GPU-zerocopy support for decoding and display on Android using OpenMax IL
diff --git a/modules/access/http.c b/modules/access/http.c
index 8b0b305..3ed16be 100644
--- a/modules/access/http.c
+++ b/modules/access/http.c
@@ -179,19 +179,19 @@ struct access_sys_t
     uint64_t i_remaining;
     uint64_t size;
 
+    http_cookie_jar_t *cookies;
+
     bool b_seekable;
     bool b_reconnect;
     bool b_continuous;
     bool b_pace_control;
     bool b_persist;
     bool b_has_size;
-
-    http_cookie_jar_t * cookies;
 };
 
 /* */
-static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
-                            unsigned i_redirect, http_cookie_jar_t *cookies );
+static int OpenWithRedirects( vlc_object_t *p_this, const char *psz_access,
+                              unsigned i_redirect );
 
 /* */
 static ssize_t Read( access_t *, uint8_t *, size_t );
@@ -216,7 +216,7 @@ static int AuthCheckReply( access_t *p_access, const char *psz_header,
 static int Open( vlc_object_t *p_this )
 {
     access_t *p_access = (access_t*)p_this;
-    return OpenWithCookies( p_this, p_access->psz_access, 5, NULL );
+    return OpenWithRedirects( p_this, p_access->psz_access, 5 );
 }
 
 /**
@@ -225,11 +225,10 @@ static int Open( vlc_object_t *p_this )
  * @psz_access: the acces to use (http, https, ...) (this value must be used
  *              instead of p_access->psz_access)
  * @i_redirect: number of redirections remaining
- * @cookies: the available cookies
  * @return vlc error codes
  */
-static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
-                            unsigned i_redirect, http_cookie_jar_t *cookies )
+static int OpenWithRedirects( vlc_object_t *p_this, const char *psz_access,
+                              unsigned i_redirect )
 {
     access_t     *p_access = (access_t*)p_this;
     access_sys_t *p_sys;
@@ -279,7 +278,7 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
 
     /* Only forward an store cookies if the corresponding option is activated */
     if( var_CreateGetBool( p_access, "http-forward-cookies" ) )
-        p_sys->cookies = (cookies != NULL) ? cookies : http_cookies_new();
+        p_sys->cookies = var_GetAddress( p_access->p_libvlc, "http-cookies" );
     else
         p_sys->cookies = NULL;
 
@@ -510,15 +509,13 @@ connect:
 
         Disconnect( p_access );
         vlc_tls_Delete( p_sys->p_creds );
-        cookies = p_sys->cookies;
 #ifdef HAVE_ZLIB_H
         inflateEnd( &p_sys->inflate.stream );
 #endif
         free( p_sys );
 
         /* Do new Open() run with new data */
-        return OpenWithCookies( p_this, psz_protocol, i_redirect - 1,
-                                cookies );
+        return OpenWithRedirects( p_this, psz_protocol, i_redirect - 1 );
     }
 
     if( p_sys->b_mms )
@@ -597,8 +594,6 @@ error:
     Disconnect( p_access );
     vlc_tls_Delete( p_sys->p_creds );
 
-    http_cookies_destroy( p_sys->cookies );
-
 #ifdef HAVE_ZLIB_H
     inflateEnd( &p_sys->inflate.stream );
 #endif
@@ -633,8 +628,6 @@ static void Close( vlc_object_t *p_this )
     Disconnect( p_access );
     vlc_tls_Delete( p_sys->p_creds );
 
-    http_cookies_destroy( p_sys->cookies );
-
 #ifdef HAVE_ZLIB_H
     inflateEnd( &p_sys->inflate.stream );
     free( p_sys->inflate.p_buffer );
diff --git a/modules/access/httpcookies.c b/modules/access/httpcookies.c
index 2dc0a6b..dcef50d 100644
--- a/modules/access/httpcookies.c
+++ b/modules/access/httpcookies.c
@@ -45,6 +45,12 @@ typedef struct http_cookie_t
     bool b_secure;
 } http_cookie_t;
 
+struct http_cookie_jar_t
+{
+    vlc_array_t cookies;
+    vlc_mutex_t lock;
+};
+
 static http_cookie_t * cookie_parse( const char * cookie_header, const vlc_url_t * url );
 static void cookie_destroy( http_cookie_t * p_cookie );
 static char * cookie_get_content( const char * cookie );
@@ -60,7 +66,14 @@ static char * cookie_default_path( const char *request_path );
 
 http_cookie_jar_t * http_cookies_new()
 {
-    return vlc_array_new();
+    http_cookie_jar_t * jar = malloc( sizeof( http_cookie_jar_t ) );
+    if ( !jar )
+        return NULL;
+
+    vlc_array_init( &jar->cookies );
+    vlc_mutex_init( &jar->lock );
+
+    return jar;
 }
 
 void http_cookies_destroy( http_cookie_jar_t * p_jar )
@@ -69,9 +82,11 @@ void http_cookies_destroy( http_cookie_jar_t * p_jar )
         return;
 
     int i;
-    for( i = 0; i < vlc_array_count( p_jar ); i++ )
-        cookie_destroy( vlc_array_item_at_index( p_jar, i ) );
-    vlc_array_destroy( p_jar );
+    for( i = 0; i < vlc_array_count( &p_jar->cookies ); i++ )
+        cookie_destroy( vlc_array_item_at_index( &p_jar->cookies, i ) );
+
+    vlc_array_clear( &p_jar->cookies );
+    vlc_mutex_destroy( &p_jar->lock );
 }
 
 bool http_cookies_append( http_cookie_jar_t * p_jar, const char * psz_cookie_header, const vlc_url_t *p_url )
@@ -85,9 +100,11 @@ bool http_cookies_append( http_cookie_jar_t * p_jar, const char * psz_cookie_hea
         return false;
     }
 
-    for( i = 0; i < vlc_array_count( p_jar ); i++ )
+    vlc_mutex_lock( &p_jar->lock );
+
+    for( i = 0; i < vlc_array_count( &p_jar->cookies ); i++ )
     {
-        http_cookie_t *iter = vlc_array_item_at_index( p_jar, i );
+        http_cookie_t *iter = vlc_array_item_at_index( &p_jar->cookies, i );
 
         assert( iter->psz_name );
         assert( iter->psz_domain );
@@ -100,24 +117,28 @@ bool http_cookies_append( http_cookie_jar_t * p_jar, const char * psz_cookie_hea
         if( domains_match && paths_match && names_match )
         {
             /* Remove previous value for this cookie */
-            vlc_array_remove( p_jar, i );
+            vlc_array_remove( &p_jar->cookies, i );
             cookie_destroy(iter);
             break;
         }
     }
-    vlc_array_append( p_jar, cookie );
+    vlc_array_append( &p_jar->cookies, cookie );
+
+    vlc_mutex_unlock( &p_jar->lock );
 
     return true;
 }
 
-
 char *http_cookies_for_url( http_cookie_jar_t * p_jar, const vlc_url_t * p_url )
 {
     int i;
     char *psz_cookiebuf = NULL;
-    for( i = 0; i < vlc_array_count( p_jar ); i++ )
+
+    vlc_mutex_lock( &p_jar->lock );
+
+    for( i = 0; i < vlc_array_count( &p_jar->cookies ); i++ )
     {
-        const http_cookie_t * cookie = vlc_array_item_at_index( p_jar, i );
+        const http_cookie_t * cookie = vlc_array_item_at_index( &p_jar->cookies, i );
         if ( cookie_should_be_sent( cookie, p_url ) )
         {
             char *psz_updated_buf = NULL;
@@ -129,6 +150,7 @@ char *http_cookies_for_url( http_cookie_jar_t * p_jar, const vlc_url_t * p_url )
             {
                 // TODO: report error
                 free( psz_cookiebuf );
+                vlc_mutex_unlock( &p_jar->lock );
                 return NULL;
             }
             free( psz_cookiebuf );
@@ -136,6 +158,8 @@ char *http_cookies_for_url( http_cookie_jar_t * p_jar, const vlc_url_t * p_url )
         }
     }
 
+    vlc_mutex_unlock( &p_jar->lock );
+
     return psz_cookiebuf;
 }
 
diff --git a/modules/access/httpcookies.h b/modules/access/httpcookies.h
index bf73191..21311d6 100644
--- a/modules/access/httpcookies.h
+++ b/modules/access/httpcookies.h
@@ -31,7 +31,7 @@ extern "C" {
 #include <vlc_url.h>
 #include <vlc_arrays.h>
 
-typedef struct vlc_array_t http_cookie_jar_t;
+typedef struct http_cookie_jar_t http_cookie_jar_t;
 
 http_cookie_jar_t * http_cookies_new( void );
 void http_cookies_destroy( http_cookie_jar_t * p_jar );
diff --git a/src/Makefile.am b/src/Makefile.am
index fbe7ec2..3f57bfe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -484,6 +484,7 @@ SOURCES_libvlc_common = \
 	misc/text_style.c \
 	misc/subpicture.c \
 	misc/subpicture.h \
+	../modules/access/httpcookies.c \
 	$(NULL)
 
 SOURCES_libvlc_httpd = \
diff --git a/src/libvlc.c b/src/libvlc.c
index 946ce2e..5751eb1 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -69,6 +69,7 @@
 #include "libvlc.h"
 #include "playlist/playlist_internal.h"
 #include "misc/variables.h"
+#include "../modules/access/httpcookies.h"
 
 #include <vlc_vlm.h>
 
@@ -389,6 +390,8 @@ dbus_out:
     var_Create( p_libvlc, "http-user-agent", VLC_VAR_STRING );
     var_SetString( p_libvlc, "http-user-agent",
                    "VLC/"PACKAGE_VERSION" LibVLC/"PACKAGE_VERSION );
+    var_Create( p_libvlc, "http-cookies", VLC_VAR_ADDRESS );
+    var_SetAddress( p_libvlc, "http-cookies", http_cookies_new() );
     var_Create( p_libvlc, "app-icon-name", VLC_VAR_STRING );
     var_SetString( p_libvlc, "app-icon-name", PACKAGE_NAME );
     var_Create( p_libvlc, "app-id", VLC_VAR_STRING );
@@ -547,6 +550,8 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
 
     vlc_DeinitActions( p_libvlc, priv->actions );
 
+    http_cookies_destroy( var_GetAddress( p_libvlc, "http-cookies" ) );
+
     /* Save the configuration */
     if( !var_InheritBool( p_libvlc, "ignore-config" ) )
         config_AutoSaveConfigFile( VLC_OBJECT(p_libvlc) );
-- 
1.7.10.4




More information about the vlc-devel mailing list