[vlc-devel] [PATCH] access/http: Inherit cookies from a parent HTTP access
Antti Ajanki
antti.ajanki at iki.fi
Sun Aug 3 10:13:16 CEST 2014
This allows stream filters such as HDS and HLS to share cookies between
HTTP requests. Enables playing streams that set a cookie when the
manifest is read and expect it to be sent back on fragment requests.
---
modules/access/http.c | 58 +++++++++++++++++++++++++-----------------
modules/access/httpcookies.c | 46 +++++++++++++++++++++++++--------
modules/access/httpcookies.h | 2 +-
3 files changed, 70 insertions(+), 36 deletions(-)
diff --git a/modules/access/http.c b/modules/access/http.c
index 8b0b305..1db9034 100644
--- a/modules/access/http.c
+++ b/modules/access/http.c
@@ -185,13 +185,12 @@ struct access_sys_t
bool b_pace_control;
bool b_persist;
bool b_has_size;
-
- http_cookie_jar_t * cookies;
+ bool b_free_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 +215,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 +224,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;
@@ -274,14 +272,22 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
p_sys->b_persist = false;
p_sys->b_has_size = false;
p_sys->size = 0;
+ p_sys->b_free_cookies = false;
p_access->info.i_pos = 0;
p_access->info.b_eof = false;
/* 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();
- else
- p_sys->cookies = NULL;
+ if( var_CreateGetBool( p_access, "http-forward-cookies" ) &&
+ ( var_CreateGetAddress( p_access, "http-cookies" ) == NULL ) )
+ {
+ http_cookie_jar_t *cookies = http_cookies_new();
+ if ( likely( cookies ) ) {
+ var_SetAddress( p_access, "http-cookies", cookies );
+ p_sys->b_free_cookies = true;
+ } else {
+ var_Destroy( p_access, "http-cookies" );
+ }
+ }
http_auth_Init( &p_sys->auth );
http_auth_Init( &p_sys->proxy_auth );
@@ -510,15 +516,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,7 +601,9 @@ error:
Disconnect( p_access );
vlc_tls_Delete( p_sys->p_creds );
- http_cookies_destroy( p_sys->cookies );
+ if ( p_sys->b_free_cookies )
+ http_cookies_destroy( var_GetAddress( p_access, "http-cookies" ) );
+ var_Destroy( p_access, "http-cookies" );
#ifdef HAVE_ZLIB_H
inflateEnd( &p_sys->inflate.stream );
@@ -633,7 +639,9 @@ static void Close( vlc_object_t *p_this )
Disconnect( p_access );
vlc_tls_Delete( p_sys->p_creds );
- http_cookies_destroy( p_sys->cookies );
+ if ( p_sys->b_free_cookies )
+ http_cookies_destroy( var_GetAddress( p_access, "http-cookies" ) );
+ var_Destroy( p_access, "http-cookies" );
#ifdef HAVE_ZLIB_H
inflateEnd( &p_sys->inflate.stream );
@@ -1126,9 +1134,10 @@ static int Connect( access_t *p_access, uint64_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 ;
- v_socket_t *pvs = p_sys->p_vs;
+ access_sys_t *p_sys = p_access->p_sys;
+ char *psz ;
+ v_socket_t *pvs = p_sys->p_vs;
+ http_cookie_jar_t *cookies;
p_sys->b_persist = false;
p_sys->i_remaining = 0;
@@ -1169,9 +1178,10 @@ static int Request( access_t *p_access, uint64_t i_tell )
}
/* Cookies */
- if( p_sys->cookies )
+ cookies = var_GetAddress( p_access, "http-cookies" );
+ if( cookies )
{
- char * psz_cookiestring = http_cookies_for_url( p_sys->cookies, &p_sys->url );
+ char * psz_cookiestring = http_cookies_for_url( cookies, &p_sys->url );
if ( psz_cookiestring )
{
msg_Dbg( p_access, "Sending Cookie %s", psz_cookiestring );
@@ -1472,9 +1482,9 @@ static int Request( access_t *p_access, uint64_t i_tell )
}
else if( !strcasecmp( psz, "Set-Cookie" ) )
{
- if( p_sys->cookies )
+ if( cookies )
{
- if ( http_cookies_append( p_sys->cookies, p, &p_sys->url ) )
+ if ( http_cookies_append( cookies, p, &p_sys->url ) )
msg_Dbg( p_access, "Accepting Cookie: %s", p );
else
msg_Dbg( p_access, "Rejected Cookie: %s", p );
diff --git a/modules/access/httpcookies.c b/modules/access/httpcookies.c
index 2dc0a6b..2bdd774 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_destroy( &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 );
--
1.7.10.4
More information about the vlc-devel
mailing list