[vlc-commits] Fixed ICY metadata support when HTTP chunked transfer is used.
Laurent Aimar
git at videolan.org
Sat Jan 7 01:29:55 CET 2012
vlc/vlc-1.2 | branch: master | Laurent Aimar <fenrir at videolan.org> | Fri Jan 6 22:43:18 2012 +0100| [49ee431b88845b540e5fcfac88d365d601669b07] | committer: Jean-Baptiste Kempf
Fixed ICY metadata support when HTTP chunked transfer is used.
It closes #5628.
(cherry picked from commit 94d21282e56fb9ccd8e2e98e058b24909d63839c)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-1.2.git/?a=commit;h=49ee431b88845b540e5fcfac88d365d601669b07
---
modules/access/http.c | 120 ++++++++++++++++++++++++++----------------------
1 files changed, 65 insertions(+), 55 deletions(-)
diff --git a/modules/access/http.c b/modules/access/http.c
index d8e56a4..1389810 100644
--- a/modules/access/http.c
+++ b/modules/access/http.c
@@ -745,35 +745,15 @@ static void Close( vlc_object_t *p_this )
free( p_sys );
}
-/*****************************************************************************
- * Read: Read up to i_len bytes from the http connection and place in
- * p_buffer. Return the actual number of bytes read
- *****************************************************************************/
-static int ReadICYMeta( access_t *p_access );
-static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
+/* Read data from the socket taking care of chunked transfer if needed */
+static int ReadData( access_t *p_access, int *pi_read,
+ uint8_t *p_buffer, size_t i_len )
{
access_sys_t *p_sys = p_access->p_sys;
- int i_read;
-
- if( p_sys->fd == -1 )
- goto fatal;
-
- if( p_sys->b_has_size )
- {
- /* Remaining bytes in the file */
- uint64_t remainder = p_access->info.i_size - p_access->info.i_pos;
- if( remainder < i_len )
- i_len = remainder;
-
- /* Remaining bytes in the response */
- if( p_sys->i_remaining < i_len )
- i_len = p_sys->i_remaining;
- }
-
if( p_sys->b_chunked )
{
if( p_sys->i_chunk < 0 )
- goto fatal;
+ return VLC_EGENERIC;
if( p_sys->i_chunk <= 0 )
{
@@ -783,7 +763,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
{
/* fatal error - end of file */
msg_Dbg( p_access, "failed reading chunk-header line" );
- goto fatal;
+ return VLC_EGENERIC;
}
p_sys->i_chunk = strtoll( psz, NULL, 16 );
free( psz );
@@ -791,14 +771,54 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( p_sys->i_chunk <= 0 ) /* eof */
{
p_sys->i_chunk = -1;
- goto fatal;
+ return VLC_EGENERIC;
}
}
if( i_len > p_sys->i_chunk )
i_len = p_sys->i_chunk;
}
+ *pi_read = net_Read( p_access, p_sys->fd, p_sys->p_vs, p_buffer, i_len, false );
+ if( *pi_read <= 0 )
+ return VLC_SUCCESS;
+ if( p_sys->b_chunked )
+ {
+ p_sys->i_chunk -= *pi_read;
+ if( p_sys->i_chunk <= 0 )
+ {
+ /* read the empty line */
+ char *psz = net_Gets( p_access, p_sys->fd, p_sys->p_vs );
+ free( psz );
+ }
+ }
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Read: Read up to i_len bytes from the http connection and place in
+ * p_buffer. Return the actual number of bytes read
+ *****************************************************************************/
+static int ReadICYMeta( access_t *p_access );
+static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
+{
+ access_sys_t *p_sys = p_access->p_sys;
+ int i_read;
+
+ if( p_sys->fd == -1 )
+ goto fatal;
+
+ if( p_sys->b_has_size )
+ {
+ /* Remaining bytes in the file */
+ uint64_t remainder = p_access->info.i_size - p_access->info.i_pos;
+ if( remainder < i_len )
+ i_len = remainder;
+
+ /* Remaining bytes in the response */
+ if( p_sys->i_remaining < i_len )
+ i_len = p_sys->i_remaining;
+ }
if( i_len == 0 )
goto fatal;
@@ -816,22 +836,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
i_len = i_next;
}
- i_read = net_Read( p_access, p_sys->fd, p_sys->p_vs, p_buffer, i_len, false );
+ if( ReadData( p_access, &i_read, p_buffer, i_len ) )
+ goto fatal;
- if( i_read > 0 )
- {
- if( p_sys->b_chunked )
- {
- p_sys->i_chunk -= i_read;
- if( p_sys->i_chunk <= 0 )
- {
- /* read the empty line */
- char *psz = net_Gets( p_access, p_sys->fd, p_sys->p_vs );
- free( psz );
- }
- }
- }
- else
+ if( i_read <= 0 )
{
/*
* I very much doubt that this will work.
@@ -897,24 +905,26 @@ static int ReadICYMeta( access_t *p_access )
int i_read;
/* Read meta data length */
- i_read = net_Read( p_access, p_sys->fd, p_sys->p_vs, &buffer, 1,
- true );
- if( i_read <= 0 )
+ if( ReadData( p_access, &i_read, &buffer, 1 ) )
return VLC_EGENERIC;
- if( buffer == 0 )
- return VLC_SUCCESS;
-
- i_read = buffer << 4;
- /* msg_Dbg( p_access, "ICY meta size=%u", i_read); */
+ if( i_read != 1 )
+ return VLC_EGENERIC;
+ const int i_size = buffer << 4;
+ /* msg_Dbg( p_access, "ICY meta size=%u", i_size); */
- psz_meta = malloc( i_read + 1 );
- if( net_Read( p_access, p_sys->fd, p_sys->p_vs,
- (uint8_t *)psz_meta, i_read, true ) != i_read )
+ psz_meta = malloc( i_size + 1 );
+ for( i_read = 0; i_read < i_size; )
{
- free( psz_meta );
- return VLC_EGENERIC;
+ int i_tmp;
+ if( ReadData( p_access, &i_tmp, (uint8_t *)&psz_meta[i_read], i_size - i_read ) )
+ {
+ free( psz_meta );
+ return VLC_EGENERIC;
+ }
+ if( i_tmp <= 0 )
+ return VLC_EGENERIC;
+ i_read += i_tmp;
}
-
psz_meta[i_read] = '\0'; /* Just in case */
/* msg_Dbg( p_access, "icy-meta=%s", psz_meta ); */
More information about the vlc-commits
mailing list