Commit 82e174bc authored by Laurent Aimar's avatar Laurent Aimar

* access2: support for demuxer access provided.

 * http: converted to access2.
parent 58cdead8
...@@ -37,9 +37,10 @@ static void Access2Close( vlc_object_t * ); ...@@ -37,9 +37,10 @@ static void Access2Close( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("Access2 adaptation layer" ) ); set_description( _("Access2 adaptation layer" ) );
set_capability( "access", 2 ); set_capability( "access", 0 );
set_callbacks( Access2Open, Access2Close ); set_callbacks( Access2Open, Access2Close );
add_shortcut( "access2" ); add_shortcut( "access2" );
add_shortcut( "http" );
/* Hack */ /* Hack */
//add_shortcut( "file" ); //add_shortcut( "file" );
...@@ -110,6 +111,12 @@ static int Access2Open( vlc_object_t * p_this ) ...@@ -110,6 +111,12 @@ static int Access2Open( vlc_object_t * p_this )
access2_Control( p_access, ACCESS_GET_PTS_DELAY, &i_64 ); access2_Control( p_access, ACCESS_GET_PTS_DELAY, &i_64 );
p_input->i_pts_delay = i_64; p_input->i_pts_delay = i_64;
if( p_access->psz_demux && *p_access->psz_demux )
{
if( !p_input->psz_demux || *p_input->psz_demux == '\0' )
p_input->psz_demux = strdup( p_access->psz_demux );
}
/* Init p_input->stream.* */ /* Init p_input->stream.* */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
/* size */ /* size */
...@@ -219,7 +226,14 @@ static void Access2Seek( input_thread_t *p_input, off_t i_pos ) ...@@ -219,7 +226,14 @@ static void Access2Seek( input_thread_t *p_input, off_t i_pos )
access_t *p_access = p_sys->p_access; access_t *p_access = p_sys->p_access;
if( p_access->pf_seek != NULL && p_input->stream.b_seekable ) if( p_access->pf_seek != NULL && p_input->stream.b_seekable )
p_access->pf_seek( p_access, i_pos ); {
if( p_access->pf_seek( p_access, i_pos ) )
{
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell = i_pos;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
}
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -64,7 +64,7 @@ static void Close( vlc_object_t * ); ...@@ -64,7 +64,7 @@ static void Close( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("HTTP input") ); set_description( _("HTTP input") );
set_capability( "access", 0 ); set_capability( "access2", 0 );
add_string( "http-proxy", NULL, NULL, PROXY_TEXT, PROXY_LONGTEXT, add_string( "http-proxy", NULL, NULL, PROXY_TEXT, PROXY_LONGTEXT,
VLC_FALSE ); VLC_FALSE );
...@@ -110,14 +110,19 @@ struct access_sys_t ...@@ -110,14 +110,19 @@ struct access_sys_t
int64_t i_chunk; int64_t i_chunk;
int64_t i_tell; int64_t i_tell;
int64_t i_size; int64_t i_size;
};
static void Seek( input_thread_t *, off_t ); vlc_bool_t b_seekable;
static ssize_t Read( input_thread_t *, byte_t *, size_t ); vlc_bool_t b_eof;
};
static void ParseURL( access_sys_t *, char *psz_url ); /* */
static int Connect( input_thread_t *, vlc_bool_t *, off_t *, off_t ); static int Read( access_t *, uint8_t *, int );
static int Seek( access_t *, int64_t );
static int Control( access_t *, int, va_list );
/* */
static void ParseURL( access_sys_t *, char *psz_url );
static int Connect( access_t *, int64_t );
static char *b64_encode( unsigned char *src ); static char *b64_encode( unsigned char *src );
/***************************************************************************** /*****************************************************************************
...@@ -125,50 +130,55 @@ static char *b64_encode( unsigned char *src ); ...@@ -125,50 +130,55 @@ static char *b64_encode( unsigned char *src );
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t *p_this ) static int Open ( vlc_object_t *p_this )
{ {
input_thread_t *p_input = (input_thread_t*)p_this; access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys; access_sys_t *p_sys;
vlc_value_t val; vlc_value_t val;
/* Create private struct */ /* Create private struct */
p_sys = p_input->p_access_data = malloc( sizeof( access_sys_t ) ); p_sys = malloc( sizeof( access_sys_t ) );
memset( p_sys, 0, sizeof( access_sys_t ) ); memset( p_sys, 0, sizeof( access_sys_t ) );
p_sys->fd = -1; p_sys->fd = -1;
p_sys->b_proxy = VLC_FALSE; p_sys->b_proxy = VLC_FALSE;
p_sys->i_version = 1; p_sys->i_version = 1;
p_sys->b_seekable = VLC_TRUE;
p_sys->psz_mime = NULL; p_sys->psz_mime = NULL;
p_sys->psz_location = NULL; p_sys->psz_location = NULL;
p_sys->psz_user_agent = NULL; p_sys->psz_user_agent = NULL;
p_sys->b_eof = VLC_FALSE;
/* First set ipv4/ipv6 */ /* First set ipv4/ipv6 */
var_Create( p_input, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_access, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_access, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
if( *p_input->psz_access ) if( *p_access->psz_access )
{ {
/* Find out which shortcut was used */ /* Find out which shortcut was used */
if( !strncmp( p_input->psz_access, "http4", 6 ) ) if( !strncmp( p_access->psz_access, "http4", 6 ) )
{ {
val.b_bool = VLC_TRUE; val.b_bool = VLC_TRUE;
var_Set( p_input, "ipv4", val ); var_Set( p_access, "ipv4", val );
val.b_bool = VLC_FALSE; val.b_bool = VLC_FALSE;
var_Set( p_input, "ipv6", val ); var_Set( p_access, "ipv6", val );
} }
else if( !strncmp( p_input->psz_access, "http6", 6 ) ) else if( !strncmp( p_access->psz_access, "http6", 6 ) )
{ {
val.b_bool = VLC_TRUE; val.b_bool = VLC_TRUE;
var_Set( p_input, "ipv6", val ); var_Set( p_access, "ipv6", val );
val.b_bool = VLC_FALSE; val.b_bool = VLC_FALSE;
var_Set( p_input, "ipv4", val ); var_Set( p_access, "ipv4", val );
} }
} }
/* Pts delay */
var_Create( p_access, "http-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
/* Parse URI */ /* Parse URI */
ParseURL( p_sys, p_input->psz_name ); ParseURL( p_sys, p_access->psz_path );
if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' ) if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
{ {
msg_Warn( p_input, "invalid host" ); msg_Warn( p_access, "invalid host" );
goto error; goto error;
} }
if( p_sys->url.i_port <= 0 ) if( p_sys->url.i_port <= 0 )
...@@ -177,23 +187,23 @@ static int Open ( vlc_object_t *p_this ) ...@@ -177,23 +187,23 @@ static int Open ( vlc_object_t *p_this )
} }
if( !p_sys->psz_user || *p_sys->psz_user == '\0' ) if( !p_sys->psz_user || *p_sys->psz_user == '\0' )
{ {
var_Create( p_input, "http-user", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_access, "http-user", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Get( p_input, "http-user", &val ); var_Get( p_access, "http-user", &val );
p_sys->psz_user = val.psz_string; p_sys->psz_user = val.psz_string;
var_Create( p_input, "http-pwd", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_access, "http-pwd", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Get( p_input, "http-pwd", &val ); var_Get( p_access, "http-pwd", &val );
p_sys->psz_passwd = val.psz_string; p_sys->psz_passwd = val.psz_string;
} }
/* Do user agent */ /* Do user agent */
var_Create( p_input, "http-user-agent", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_access, "http-user-agent", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Get( p_input, "http-user-agent", &val ); var_Get( p_access, "http-user-agent", &val );
p_sys->psz_user_agent = val.psz_string; p_sys->psz_user_agent = val.psz_string;
/* Check proxy */ /* Check proxy */
var_Create( p_input, "http-proxy", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_access, "http-proxy", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Get( p_input, "http-proxy", &val ); var_Get( p_access, "http-proxy", &val );
if( val.psz_string && *val.psz_string ) if( val.psz_string && *val.psz_string )
{ {
p_sys->b_proxy = VLC_TRUE; p_sys->b_proxy = VLC_TRUE;
...@@ -221,7 +231,7 @@ static int Open ( vlc_object_t *p_this ) ...@@ -221,7 +231,7 @@ static int Open ( vlc_object_t *p_this )
{ {
if( p_sys->proxy.psz_host == NULL || *p_sys->proxy.psz_host == '\0' ) if( p_sys->proxy.psz_host == NULL || *p_sys->proxy.psz_host == '\0' )
{ {
msg_Warn( p_input, "invalid proxy host" ); msg_Warn( p_access, "invalid proxy host" );
goto error; goto error;
} }
if( p_sys->proxy.i_port <= 0 ) if( p_sys->proxy.i_port <= 0 )
...@@ -230,29 +240,28 @@ static int Open ( vlc_object_t *p_this ) ...@@ -230,29 +240,28 @@ static int Open ( vlc_object_t *p_this )
} }
} }
msg_Dbg( p_input, "http: server='%s' port=%d file='%s", msg_Dbg( p_access, "http: server='%s' port=%d file='%s",
p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path ); p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path );
if( p_sys->b_proxy ) if( p_sys->b_proxy )
{ {
msg_Dbg( p_input, " proxy %s:%d", p_sys->proxy.psz_host, msg_Dbg( p_access, " proxy %s:%d", p_sys->proxy.psz_host,
p_sys->proxy.i_port ); p_sys->proxy.i_port );
} }
if( p_sys->psz_user && *p_sys->psz_user ) if( p_sys->psz_user && *p_sys->psz_user )
{ {
msg_Dbg( p_input, " user='%s', pwd='%s'", msg_Dbg( p_access, " user='%s', pwd='%s'",
p_sys->psz_user, p_sys->psz_passwd ); p_sys->psz_user, p_sys->psz_passwd );
} }
/* Connect */ /* Connect */
if( Connect( p_input, &p_input->stream.b_seekable, p_access->p_sys = p_sys;
&p_input->stream.p_selected_area->i_size, 0 ) ) if( Connect( p_access, 0 ) )
{ {
/* Retry with http 1.0 */ /* Retry with http 1.0 */
p_sys->i_version = 0; p_sys->i_version = 0;
if( p_input->b_die || if( p_access->b_die ||
Connect( p_input, &p_input->stream.b_seekable, Connect( p_access, 0 ) )
&p_input->stream.p_selected_area->i_size, 0 ) )
{ {
goto error; goto error;
} }
...@@ -264,12 +273,12 @@ static int Open ( vlc_object_t *p_this ) ...@@ -264,12 +273,12 @@ static int Open ( vlc_object_t *p_this )
{ {
playlist_t * p_playlist; playlist_t * p_playlist;
msg_Dbg( p_input, "redirection to %s", p_sys->psz_location ); msg_Dbg( p_access, "redirection to %s", p_sys->psz_location );
p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_PARENT ); p_playlist = vlc_object_find( p_access, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( !p_playlist ) if( !p_playlist )
{ {
msg_Err( p_input, "redirection failed: can't find playlist" ); msg_Err( p_access, "redirection failed: can't find playlist" );
goto error; goto error;
} }
p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE; p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
...@@ -281,38 +290,22 @@ static int Open ( vlc_object_t *p_this ) ...@@ -281,38 +290,22 @@ static int Open ( vlc_object_t *p_this )
p_sys->i_size = 0; /* Force to stop reading */ p_sys->i_size = 0; /* Force to stop reading */
} }
/* Finish to set up p_input */ /* Set up p_access */
p_input->pf_read = Read; p_access->pf_read = Read;
p_input->pf_set_program = input_SetProgram; p_access->pf_block = NULL;
p_input->pf_set_area = NULL; p_access->pf_control = Control;
p_input->pf_seek = Seek; p_access->pf_seek = Seek;
p_access->p_sys = p_sys;
vlc_mutex_lock( &p_input->stream.stream_lock ); if( !strcmp( p_sys->psz_protocol, "ICY" ) )
p_input->stream.b_pace_control = VLC_TRUE;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_input->i_mtu = 0;
if( !strcmp( p_sys->psz_protocol, "ICY" ) &&
( !p_input->psz_demux || !*p_input->psz_demux ) )
{ {
if( p_sys->psz_mime && !strcasecmp( p_sys->psz_mime, "video/nsv" ) ) if( p_sys->psz_mime && !strcasecmp( p_sys->psz_mime, "video/nsv" ) )
{ p_access->psz_demux = strdup( "nsv" );
p_input->psz_demux = strdup( "nsv" );
}
else else
{ p_access->psz_demux = strdup( "mp3" );
p_input->psz_demux = strdup( "mp3" );
}
msg_Info( p_input, "ICY server found, %s demuxer selected",
p_input->psz_demux );
}
/* Update default_pts to a suitable value for http access */
var_Create( p_input, "http-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_input, "http-caching", &val );
p_input->i_pts_delay = val.i_int * 1000;
msg_Info( p_access, "ICY server found, %s demuxer selected",
p_access->psz_demux );
}
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
...@@ -337,8 +330,8 @@ error: ...@@ -337,8 +330,8 @@ error:
*****************************************************************************/ *****************************************************************************/
static void Close( vlc_object_t *p_this ) static void Close( vlc_object_t *p_this )
{ {
input_thread_t *p_input = (input_thread_t*)p_this; access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys = p_input->p_access_data; access_sys_t *p_sys = p_access->p_sys;
vlc_UrlClean( &p_sys->url ); vlc_UrlClean( &p_sys->url );
vlc_UrlClean( &p_sys->proxy ); vlc_UrlClean( &p_sys->proxy );
...@@ -358,45 +351,26 @@ static void Close( vlc_object_t *p_this ) ...@@ -358,45 +351,26 @@ static void Close( vlc_object_t *p_this )
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* Seek: close and re-open a connection at the right place
*****************************************************************************/
static void Seek( input_thread_t * p_input, off_t i_pos )
{
access_sys_t *p_sys = p_input->p_access_data;
msg_Dbg( p_input, "trying to seek to "I64Fd, i_pos );
net_Close( p_sys->fd ); p_sys->fd = -1;
if( Connect( p_input, &p_input->stream.b_seekable,
&p_input->stream.p_selected_area->i_size, i_pos ) )
{
msg_Err( p_input, "seek failed" );
}
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell = i_pos;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
/***************************************************************************** /*****************************************************************************
* Read: Read up to i_len bytes from the http connection and place in * Read: Read up to i_len bytes from the http connection and place in
* p_buffer. Return the actual number of bytes read * p_buffer. Return the actual number of bytes read
*****************************************************************************/ *****************************************************************************/
static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
{ {
access_sys_t *p_sys = p_input->p_access_data; access_sys_t *p_sys = p_access->p_sys;
int i_read; int i_read;
if( p_sys->fd < 0 ) if( p_sys->fd < 0 )
{ {
return -1; p_sys->b_eof = VLC_TRUE;
return 0;
} }
if( p_sys->i_size > 0 && i_len + p_sys->i_tell > p_sys->i_size ) if( p_sys->i_size > 0 && i_len + p_sys->i_tell > p_sys->i_size )
{ {
if( ( i_len = p_sys->i_size - p_sys->i_tell ) == 0 ) if( ( i_len = p_sys->i_size - p_sys->i_tell ) == 0 )
{ {
p_sys->b_eof = VLC_TRUE;
return 0; return 0;
} }
} }
...@@ -404,16 +378,17 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) ...@@ -404,16 +378,17 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
{ {
if( p_sys->i_chunk < 0 ) if( p_sys->i_chunk < 0 )
{ {
p_sys->b_eof = VLC_TRUE;
return 0; return 0;
} }
if( p_sys->i_chunk <= 0 ) if( p_sys->i_chunk <= 0 )
{ {
char *psz = net_Gets( VLC_OBJECT(p_input), p_sys->fd ); char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd );
/* read the chunk header */ /* read the chunk header */
if( psz == NULL ) if( psz == NULL )
{ {
msg_Dbg( p_input, "failed reading chunk-header line" ); msg_Dbg( p_access, "failed reading chunk-header line" );
return -1; return -1;
} }
p_sys->i_chunk = strtoll( psz, NULL, 16 ); p_sys->i_chunk = strtoll( psz, NULL, 16 );
...@@ -422,6 +397,7 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) ...@@ -422,6 +397,7 @@ static ssize_t Read( input_thread_t * p_input, byte_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;
p_sys->b_eof = VLC_TRUE;
return 0; return 0;
} }
} }
...@@ -433,7 +409,7 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) ...@@ -433,7 +409,7 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
} }
i_read = net_Read( p_input, p_sys->fd, p_buffer, i_len, VLC_FALSE ); i_read = net_Read( p_access, p_sys->fd, p_buffer, i_len, VLC_FALSE );
if( i_read > 0 ) if( i_read > 0 )
{ {
p_sys->i_tell += i_read; p_sys->i_tell += i_read;
...@@ -444,7 +420,7 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) ...@@ -444,7 +420,7 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
if( p_sys->i_chunk <= 0 ) if( p_sys->i_chunk <= 0 )
{ {
/* read the empty line */ /* read the empty line */
char *psz = net_Gets( VLC_OBJECT(p_input), p_sys->fd ); char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd );
if( psz ) if( psz )
{ {
free( psz ); free( psz );
...@@ -452,9 +428,101 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) ...@@ -452,9 +428,101 @@ static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
} }
} }
} }
else if( i_read == 0 )
{
p_sys->b_eof = VLC_TRUE;
}
return i_read; return i_read;
} }
/*****************************************************************************
* Seek: close and re-open a connection at the right place
*****************************************************************************/
static int Seek( access_t *p_access, int64_t i_pos )
{
access_sys_t *p_sys = p_access->p_sys;
msg_Dbg( p_access, "trying to seek to "I64Fd, i_pos );
net_Close( p_sys->fd ); p_sys->fd = -1;
if( Connect( p_access, i_pos ) )
{
msg_Err( p_access, "seek failed" );
p_sys->b_eof = VLC_TRUE;
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
/*****************************************************************************
* Control:
*****************************************************************************/
static int Control( access_t *p_access, int i_query, va_list args )
{
access_sys_t *p_sys = p_access->p_sys;
vlc_bool_t *pb_bool;
int *pi_int;
int64_t *pi_64;
vlc_value_t val;
switch( i_query )
{
/* */
case ACCESS_CAN_SEEK:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = p_sys->b_seekable;
break;
case ACCESS_CAN_FASTSEEK:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = VLC_FALSE;
break;
case ACCESS_CAN_PAUSE:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = VLC_TRUE; /* FIXME */
break;
case ACCESS_CAN_CONTROL_PACE:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = VLC_TRUE; /* FIXME */
break;
/* */
case ACCESS_GET_MTU:
pi_int = (int*)va_arg( args, int * );
*pi_int = 0;
break;
case ACCESS_GET_SIZE:
pi_64 = (int64_t*)va_arg( args, int64_t * );
*pi_64 = p_sys->i_size > 0 ? p_sys->i_size : 0;
break;
case ACCESS_GET_POS:
pi_64 = (int64_t*)va_arg( args, int64_t * );
*pi_64 = p_sys->i_tell;
break;
case ACCESS_GET_EOF:
pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
*pb_bool = p_sys->b_eof;
break;
case ACCESS_GET_PTS_DELAY:
pi_64 = (int64_t*)va_arg( args, int64_t * );
var_Get( p_access, "http-caching", &val );
*pi_64 = val.i_int * 1000;
break;
/* */
case ACCESS_SET_PAUSE_STATE:
/* Nothing to do */
break;
default:
msg_Err( p_access, "unimplemented query in control" );
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* ParseURL: extract user:password * ParseURL: extract user:password
*****************************************************************************/ *****************************************************************************/
...@@ -506,10 +574,9 @@ static void ParseURL( access_sys_t *p_sys, char *psz_url ) ...@@ -506,10 +574,9 @@ static void ParseURL( access_sys_t *p_sys, char *psz_url )
/***************************************************************************** /*****************************************************************************
* Connect: * Connect:
*****************************************************************************/ *****************************************************************************/
static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, static int Connect( access_t *p_access, int64_t i_tell )
off_t *pi_size, off_t i_tell )
{ {
access_sys_t *p_sys = p_input->p_access_data; access_sys_t *p_sys = p_access->p_sys;
vlc_url_t srv = p_sys->b_proxy ? p_sys->proxy : p_sys->url; vlc_url_t srv = p_sys->b_proxy ? p_sys->proxy : p_sys->url;
char *psz; char *psz;
...@@ -526,16 +593,16 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -526,16 +593,16 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
/* Open connection */ /* Open connection */
p_sys->fd = net_OpenTCP( p_input, srv.psz_host, srv.i_port ); p_sys->fd = net_OpenTCP( p_access, srv.psz_host, srv.i_port );
if( p_sys->fd < 0 ) if( p_sys->fd < 0 )
{ {
msg_Err( p_input, "cannot connect to %s:%d", srv.psz_host, srv.i_port ); msg_Err( p_access, "cannot connect to %s:%d", srv.psz_host, srv.i_port );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( p_sys->b_proxy ) if( p_sys->b_proxy )
{ {
net_Printf( VLC_OBJECT(p_input), p_sys->fd, net_Printf( VLC_OBJECT(p_access), p_sys->fd,
"GET http://%s:%d/%s HTTP/1.%d\r\n", "GET http://%s:%d/%s HTTP/1.%d\r\n",
p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_host, p_sys->url.i_port,
p_sys->url.psz_path, p_sys->i_version ); p_sys->url.psz_path, p_sys->i_version );
...@@ -547,17 +614,17 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -547,17 +614,17 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
{ {
psz_path = "/"; psz_path = "/";
} }
net_Printf( VLC_OBJECT(p_input), p_sys->fd, net_Printf( VLC_OBJECT(p_access), p_sys->fd,
"GET %s HTTP/1.%d\r\nHost: %s\r\n", "GET %s HTTP/1.%d\r\nHost: %s\r\n",
psz_path, p_sys->i_version, p_sys->url.psz_host ); psz_path, p_sys->i_version, p_sys->url.psz_host );
} }
/* User Agent */ /* User Agent */
net_Printf( VLC_OBJECT(p_input), p_sys->fd, "User-Agent: %s\r\n", net_Printf( VLC_OBJECT(p_access), p_sys->fd, "User-Agent: %s\r\n",
p_sys->psz_user_agent ); p_sys->psz_user_agent );
/* Offset */ /* Offset */
if( p_sys->i_version == 1 ) if( p_sys->i_version == 1 )
{ {
net_Printf( VLC_OBJECT(p_input), p_sys->fd, net_Printf( VLC_OBJECT(p_access), p_sys->fd,
"Range: bytes="I64Fd"-\r\n", i_tell ); "Range: bytes="I64Fd"-\r\n", i_tell );
} }
/* Authentification */ /* Authentification */
...@@ -571,27 +638,23 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -571,27 +638,23 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
b64 = b64_encode( buf ); b64 = b64_encode( buf );
net_Printf( VLC_OBJECT(p_input), p_sys->fd, net_Printf( VLC_OBJECT(p_access), p_sys->fd,
"Authorization: Basic %s\r\n", b64 ); "Authorization: Basic %s\r\n", b64 );
free( b64 ); free( b64 );
} }
net_Printf( VLC_OBJECT(p_input), p_sys->fd, "Connection: Close\r\n" ); net_Printf( VLC_OBJECT(p_access), p_sys->fd, "Connection: Close\r\n" );
if( net_Printf( VLC_OBJECT(p_input), p_sys->fd, "\r\n" ) < 0 ) if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, "\r\n" ) < 0 )
{ {
msg_Err( p_input, "failed to send request" ); msg_Err( p_access, "failed to send request" );
net_Close( p_sys->fd ); p_sys->fd = -1; net_Close( p_sys->fd ); p_sys->fd = -1;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Set values */
*pb_seekable = p_sys->i_version == 1 ? VLC_TRUE : VLC_FALSE;
*pi_size = 0;
/* Read Answer */ /* Read Answer */
if( ( psz = net_Gets( VLC_OBJECT(p_input), p_sys->fd ) ) == NULL ) if( ( psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd ) ) == NULL )
{ {
msg_Err( p_input, "failed to read answer" ); msg_Err( p_access, "failed to read answer" );
goto error; goto error;
} }
if( !strncmp( psz, "HTTP/1.", 7 ) ) if( !strncmp( psz, "HTTP/1.", 7 ) )
...@@ -606,23 +669,23 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -606,23 +669,23 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
} }
else else
{ {
msg_Err( p_input, "invalid HTTP reply '%s'", psz ); msg_Err( p_access, "invalid HTTP reply '%s'", psz );
free( psz ); free( psz );
goto error; goto error;
} }
msg_Dbg( p_input, "protocol '%s' answer code %d", msg_Dbg( p_access, "protocol '%s' answer code %d",
p_sys->psz_protocol, p_sys->i_code ); p_sys->psz_protocol, p_sys->i_code );
if( !strcmp( p_sys->psz_protocol, "ICY" ) ) if( !strcmp( p_sys->psz_protocol, "ICY" ) )
{ {
*pb_seekable = VLC_FALSE; p_sys->b_seekable = VLC_FALSE;
} }
if( p_sys->i_code != 206 ) if( p_sys->i_code != 206 )
{ {
*pb_seekable = VLC_FALSE; p_sys->b_seekable = VLC_FALSE;
} }
if( p_sys->i_code >= 400 ) if( p_sys->i_code >= 400 )
{ {
msg_Err( p_input, "error: %s", psz ); msg_Err( p_access, "error: %s", psz );
free( psz ); free( psz );
goto error; goto error;
} }
...@@ -630,12 +693,12 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -630,12 +693,12 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
for( ;; ) for( ;; )
{ {
char *psz = net_Gets( VLC_OBJECT(p_input), p_sys->fd ); char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd );
char *p; char *p;
if( psz == NULL ) if( psz == NULL )
{ {
msg_Err( p_input, "failed to read answer" ); msg_Err( p_access, "failed to read answer" );
goto error; goto error;
} }
...@@ -649,7 +712,7 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -649,7 +712,7 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
if( ( p = strchr( psz, ':' ) ) == NULL ) if( ( p = strchr( psz, ':' ) ) == NULL )
{ {
msg_Err( p_input, "malformed header line: %s", psz ); msg_Err( p_access, "malformed header line: %s", psz );
free( psz ); free( psz );
goto error; goto error;
} }
...@@ -658,8 +721,8 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -658,8 +721,8 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
if( !strcasecmp( psz, "Content-Length" ) ) if( !strcasecmp( psz, "Content-Length" ) )
{ {
*pi_size = p_sys->i_size = i_tell + atoll( p ); p_sys->i_size = i_tell + atoll( p );
msg_Dbg( p_input, "stream size="I64Fd, p_sys->i_size ); msg_Dbg( p_access, "stream size="I64Fd, p_sys->i_size );
} }
else if( !strcasecmp( psz, "Location" ) ) else if( !strcasecmp( psz, "Location" ) )
{ {
...@@ -670,11 +733,11 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable, ...@@ -670,11 +733,11 @@ static int Connect( input_thread_t *p_input, vlc_bool_t *pb_seekable,
{ {
if( p_sys->psz_mime ) free( p_sys->psz_mime ); if( p_sys->psz_mime ) free( p_sys->psz_mime );
p_sys->psz_mime = strdup( p ); p_sys->psz_mime = strdup( p );
msg_Dbg( p_input, "Content-Type: %s", p_sys->psz_mime ); msg_Dbg( p_access, "Content-Type: %s", p_sys->psz_mime );
} }
else if( !strcasecmp( psz, "Transfer-Encoding" ) ) else if( !strcasecmp( psz, "Transfer-Encoding" ) )
{ {
msg_Dbg( p_input, "Transfer-Encoding: %s", p ); msg_Dbg( p_access, "Transfer-Encoding: %s", p );
if( !strncasecmp( p, "chunked", 7 ) ) if( !strncasecmp( p, "chunked", 7 ) )
{ {
p_sys->b_chunked = VLC_TRUE; p_sys->b_chunked = VLC_TRUE;
......
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