From bc77ed15963fda782402c4f37dd3b16a1e720a92 Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sat, 19 Jan 2008 00:06:18 +0000 Subject: [PATCH] Add gzip support to the http access. We never request it, we just know how to handle it if the server forces us to use it (for example Pierre's test page http://www.canalplus.fr/index.php?pid=1784) --- configure.ac | 4 ++ modules/access/http.c | 91 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 0b0835c5f4..50bb0454f0 100644 --- a/configure.ac +++ b/configure.ac @@ -521,6 +521,10 @@ AC_CHECK_FUNCS(gethostbyname,,[ ]) ]) +AC_CHECK_HEADERS(zlib.h, [ + VLC_ADD_LIBS([access_http],[-lz]) +]) + dnl Check for socklen_t AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, [AC_TRY_COMPILE( diff --git a/modules/access/http.c b/modules/access/http.c index b055f6704c..403392b576 100644 --- a/modules/access/http.c +++ b/modules/access/http.c @@ -39,6 +39,10 @@ #include #include +#ifdef HAVE_ZLIB_H +# include +#endif + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -130,6 +134,14 @@ struct access_sys_t vlc_bool_t b_mms; vlc_bool_t b_icecast; vlc_bool_t b_ssl; +#ifdef HAVE_ZLIB_H + vlc_bool_t b_compressed; + struct + { + z_stream stream; + uint8_t *p_buffer; + } inflate; +#endif vlc_bool_t b_chunked; int64_t i_chunk; @@ -154,6 +166,7 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies ); /* */ 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 Control( access_t *, int, va_list ); @@ -187,6 +200,9 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies ) /* Set up p_access */ STANDARD_READ_ACCESS_INIT; +#ifdef HAVE_ZLIB_H + p_access->pf_read = ReadCompressed; +#endif p_sys->fd = -1; p_sys->b_proxy = VLC_FALSE; p_sys->i_version = 1; @@ -199,6 +215,16 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies ) p_sys->psz_user_agent = NULL; p_sys->b_pace_control = VLC_TRUE; p_sys->b_ssl = VLC_FALSE; +#ifdef HAVE_ZLIB_H + p_sys->b_compressed = VLC_FALSE; + /* 15 is the max windowBits, +32 to enable optional gzip decoding */ + if( inflateInit2( &p_sys->inflate.stream, 32+15 ) != Z_OK ) + msg_Warn( p_access, "Error during zlib initialisation: %s", + p_sys->inflate.stream.msg ); + if( zlibCompileFlags() & (1<<17) ) + msg_Warn( p_access, "Your zlib was compiled without gzip support." ); + p_sys->inflate.p_buffer = NULL; +#endif p_sys->p_tls = NULL; p_sys->p_vs = NULL; p_sys->i_icy_meta = 0; @@ -474,6 +500,11 @@ static void Close( vlc_object_t *p_this ) vlc_array_destroy( p_sys->cookies ); } +#ifdef HAVE_ZLIB_H + inflateEnd( &p_sys->inflate.stream ); + free( p_sys->inflate.p_buffer ); +#endif + free( p_sys ); } @@ -538,7 +569,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) } } - if( p_sys->b_continuous && i_len > p_sys->i_remaining ) + if( p_sys->b_continuous && (ssize_t)i_len > p_sys->i_remaining ) { /* Only ask for the remaining length */ int i_new_len = p_sys->i_remaining; @@ -692,6 +723,42 @@ static int ReadICYMeta( access_t *p_access ) return VLC_SUCCESS; } +#ifdef HAVE_ZLIB_H +static ssize_t ReadCompressed( access_t *p_access, uint8_t *p_buffer, + size_t i_len ) +{ + access_sys_t *p_sys = p_access->p_sys; + + if( p_sys->b_compressed ) + { + int i_ret; + + if( !p_sys->inflate.p_buffer ) + p_sys->inflate.p_buffer = malloc( 256 * 1024 ); + + if( p_sys->inflate.stream.avail_in == 0 ) + { + ssize_t i_read = Read( p_access, p_sys->inflate.p_buffer + p_sys->inflate.stream.avail_in, 256 * 1024 ); + if( i_read <= 0 ) return i_read; + p_sys->inflate.stream.next_in = p_sys->inflate.p_buffer; + p_sys->inflate.stream.avail_in = i_read; + } + + p_sys->inflate.stream.avail_out = i_len; + p_sys->inflate.stream.next_out = p_buffer; + + i_ret = inflate( &p_sys->inflate.stream, Z_SYNC_FLUSH ); + msg_Warn( p_access, "inflate return value: %d, %s", i_ret, p_sys->inflate.stream.msg ); + + return i_len - p_sys->inflate.stream.avail_out; + } + else + { + return Read( p_access, p_buffer, i_len ); + } +} +#endif + /***************************************************************************** * Seek: close and re-open a connection at the right place *****************************************************************************/ @@ -967,7 +1034,7 @@ static int Request( access_t *p_access, int64_t i_tell ) const char * cookie = vlc_array_item_at_index( p_sys->cookies, i ); char * psz_cookie_content = cookie_get_content( cookie ); char * psz_cookie_domain = cookie_get_domain( cookie ); - + assert( psz_cookie_content ); /* FIXME: This is clearly not conforming to the rfc */ @@ -1145,13 +1212,15 @@ static int Request( access_t *p_access, int64_t i_tell ) if( p_sys->url.i_port == ( p_sys->b_ssl ? 443 : 80 ) ) { - asprintf(&psz_new_loc, "http%s://%s%s", psz_http_ext, - p_sys->url.psz_host, p); + if( asprintf(&psz_new_loc, "http%s://%s%s", psz_http_ext, + p_sys->url.psz_host, p) < 0 ) + goto error; } else { - asprintf(&psz_new_loc, "http%s://%s:%d%s", psz_http_ext, - p_sys->url.psz_host, p_sys->url.i_port, p); + if( asprintf(&psz_new_loc, "http%s://%s:%d%s", psz_http_ext, + p_sys->url.psz_host, p_sys->url.i_port, p) < 0 ) + goto error; } } else @@ -1168,6 +1237,16 @@ static int Request( access_t *p_access, int64_t i_tell ) p_sys->psz_mime = strdup( p ); msg_Dbg( p_access, "Content-Type: %s", p_sys->psz_mime ); } + else if( !strcasecmp( psz, "Content-Encoding" ) ) + { + msg_Dbg( p_access, "Content-Encoding: %s", p ); + if( strcasecmp( p, "identity" ) ) +#ifdef HAVE_ZLIB_H + p_sys->b_compressed = VLC_TRUE; +#else + msg_Warn( p_access, "Compressed content not supported. Rebuild with zlib support." ); +#endif + } else if( !strcasecmp( psz, "Pragma" ) ) { if( !strcasecmp( psz, "Pragma: features" ) ) -- 2.39.5