Commit 94d21282 authored by Laurent Aimar's avatar Laurent Aimar

Fixed ICY metadata support when HTTP chunked transfer is used.

It closes #5628.
parent c16b17c6
...@@ -745,35 +745,15 @@ static void Close( vlc_object_t *p_this ) ...@@ -745,35 +745,15 @@ static void Close( vlc_object_t *p_this )
free( p_sys ); free( p_sys );
} }
/***************************************************************************** /* Read data from the socket taking care of chunked transfer if needed */
* Read: Read up to i_len bytes from the http connection and place in static int ReadData( access_t *p_access, int *pi_read,
* p_buffer. Return the actual number of bytes read uint8_t *p_buffer, size_t i_len )
*****************************************************************************/
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; 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->b_chunked )
{ {
if( p_sys->i_chunk < 0 ) if( p_sys->i_chunk < 0 )
goto fatal; return VLC_EGENERIC;
if( p_sys->i_chunk <= 0 ) 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 ) ...@@ -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 */ /* fatal error - end of file */
msg_Dbg( p_access, "failed reading chunk-header line" ); msg_Dbg( p_access, "failed reading chunk-header line" );
goto fatal; return VLC_EGENERIC;
} }
p_sys->i_chunk = strtoll( psz, NULL, 16 ); p_sys->i_chunk = strtoll( psz, NULL, 16 );
free( psz ); free( psz );
...@@ -791,14 +771,54 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -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 */ if( p_sys->i_chunk <= 0 ) /* eof */
{ {
p_sys->i_chunk = -1; p_sys->i_chunk = -1;
goto fatal; return VLC_EGENERIC;
} }
} }
if( i_len > p_sys->i_chunk ) if( i_len > p_sys->i_chunk )
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 ) if( i_len == 0 )
goto fatal; goto fatal;
...@@ -816,22 +836,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -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_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( 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
{ {
/* /*
* I very much doubt that this will work. * I very much doubt that this will work.
...@@ -897,24 +905,26 @@ static int ReadICYMeta( access_t *p_access ) ...@@ -897,24 +905,26 @@ static int ReadICYMeta( access_t *p_access )
int i_read; int i_read;
/* Read meta data length */ /* Read meta data length */
i_read = net_Read( p_access, p_sys->fd, p_sys->p_vs, &buffer, 1, if( ReadData( p_access, &i_read, &buffer, 1 ) )
true );
if( i_read <= 0 )
return VLC_EGENERIC; return VLC_EGENERIC;
if( buffer == 0 ) if( i_read != 1 )
return VLC_SUCCESS; return VLC_EGENERIC;
const int i_size = buffer << 4;
i_read = buffer << 4; /* msg_Dbg( p_access, "ICY meta size=%u", i_size); */
/* msg_Dbg( p_access, "ICY meta size=%u", i_read); */
psz_meta = malloc( i_read + 1 ); psz_meta = malloc( i_size + 1 );
if( net_Read( p_access, p_sys->fd, p_sys->p_vs, for( i_read = 0; i_read < i_size; )
(uint8_t *)psz_meta, i_read, true ) != i_read )
{ {
free( psz_meta ); int i_tmp;
return VLC_EGENERIC; 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 */ psz_meta[i_read] = '\0'; /* Just in case */
/* msg_Dbg( p_access, "icy-meta=%s", psz_meta ); */ /* msg_Dbg( p_access, "icy-meta=%s", psz_meta ); */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment