[vlc-devel] [PATCH] access/http: Inherit cookies from a parent HTTP access

Rémi Denis-Courmont remi at remlab.net
Sun Aug 3 11:21:56 CEST 2014


Le dimanche 3 août 2014, 11:13:16 Antti Ajanki a écrit :
> 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.

There are other situations than HLS and HDS where an access object may be 
parented to another access object now (e.g. via the vobsub demux), and there 
may be other in the future. Basically, this breaks encapsulation unless we are 
certain that it is always acceptable and safe to inherit cookies.

Also life cycle management of an object with VLC_VAR_ADDRESS may be hazardous 
- regardless of the mutex to protect internal state. This would at the very 
least need a clear set of access and ownership rules.

> ---
>  modules/access/http.c        |   58
> +++++++++++++++++++++++++----------------- modules4/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;

Keep the pointer and don't fetch the variable all the time.

> +    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 );

-- 
Rémi Denis-Courmont
http://www.remlab.net/




More information about the vlc-devel mailing list