X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fhttp.c;h=15b2be30d81f302b67ffb689001f9bddba30f283;hb=11097ec199b7c5bd83fda41d6381a639ce2e6bef;hp=cfb207de76f58963f2bdb5d3f2010d073474c06e;hpb=1de3029270b6aeb6a7301aead3b6587ae0a006bb;p=vlc diff --git a/modules/access/http.c b/modules/access/http.c index cfb207de76..15b2be30d8 100644 --- a/modules/access/http.c +++ b/modules/access/http.c @@ -52,6 +52,9 @@ #include +#ifdef HAVE_PROXY_H +# include "proxy.h" +#endif /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -185,12 +188,13 @@ struct access_sys_t char *psz_icy_genre; char *psz_icy_title; - int i_remaining; + int64_t i_remaining; bool b_seekable; bool b_reconnect; bool b_continuous; bool b_pace_control; + bool b_persist; vlc_array_t * cookies; }; @@ -276,6 +280,10 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies ) p_sys->psz_icy_genre = NULL; p_sys->psz_icy_title = NULL; p_sys->i_remaining = 0; + p_sys->b_persist = false; + p_access->info.i_size = -1; + p_access->info.i_pos = 0; + p_access->info.b_eof = false; p_sys->cookies = saved_cookies; @@ -315,7 +323,40 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies ) vlc_UrlParse( &p_sys->proxy, psz, 0 ); free( psz ); } -#ifdef HAVE_GETENV +#ifdef HAVE_PROXY_H + else + { + pxProxyFactory *pf = px_proxy_factory_new(); + if (pf) + { + char *buf; + int i; + i=asprintf(&buf, "%s://%s", p_access->psz_access, p_access->psz_path); + if (i >= 0) + { + msg_Dbg(p_access, "asking libproxy about url '%s'", buf); + char **proxies = px_proxy_factory_get_proxies(pf, buf); + if (proxies[0]) + { + msg_Dbg(p_access, "libproxy suggest to use '%s'", proxies[0]); + if(strcmp(proxies[0],"direct://") != 0) + { + p_sys->b_proxy = true; + vlc_UrlParse( &p_sys->proxy, proxies[0], 0); + } + } + for(i=0;proxies[i];i++) free(proxies[i]); + free(proxies); + free(buf); + } + px_proxy_factory_free(pf); + } + else + { + msg_Err(p_access, "Allocating memory for libproxy failed"); + } + } +#elif HAVE_GETENV else { psz = getenv( "http_proxy" ); @@ -374,7 +415,7 @@ connect: p_sys->i_version = 0; p_sys->b_seekable = false; - if( p_access->b_die || Connect( p_access, 0 ) ) + if( !vlc_object_alive (p_access) || Connect( p_access, 0 ) ) goto error; #ifndef NDEBUG @@ -602,7 +643,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) return 0; } - if( p_access->info.i_size > 0 && + if( p_access->info.i_size >= 0 && i_len + p_access->info.i_pos > p_access->info.i_size ) { if( ( i_len = p_access->info.i_size - p_access->info.i_pos ) == 0 ) @@ -646,20 +687,16 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) i_len = p_sys->i_chunk; } } - - if( p_sys->b_continuous && (ssize_t)i_len > p_sys->i_remaining ) - { + else if( p_access->info.i_size != -1 && (int64_t)i_len > p_sys->i_remaining) { /* Only ask for the remaining length */ - int i_new_len = p_sys->i_remaining; - if( i_new_len == 0 ) - { - Request( p_access, 0 ); - i_read = Read( p_access, p_buffer, i_len ); - return i_read; + i_len = (size_t)p_sys->i_remaining; + if(i_len == 0) { + p_access->info.b_eof = true; + return 0; } - i_len = i_new_len; } + if( p_sys->i_icy_meta > 0 && p_access->info.i_pos > 0 ) { int64_t i_next = p_sys->i_icy_meta - @@ -728,7 +765,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) if( i_read == 0 ) p_access->info.b_eof = true; } - if( p_sys->b_continuous ) + if( p_access->info.i_size != -1 ) { p_sys->i_remaining -= i_read; } @@ -845,6 +882,17 @@ static int Seek( access_t *p_access, int64_t i_pos ) Disconnect( p_access ); + if( p_access->info.i_size + && (uint64_t)i_pos >= (uint64_t)p_access->info.i_size ) { + msg_Err( p_access, "seek to far" ); + int retval = Seek( p_access, p_access->info.i_size - 1 ); + if( retval == VLC_SUCCESS ) { + uint8_t p_buffer[2]; + Read( p_access, p_buffer, 1); + p_access->info.b_eof = false; + } + return retval; + } if( Connect( p_access, i_pos ) ) { msg_Err( p_access, "seek failed" ); @@ -960,8 +1008,10 @@ static int Connect( access_t *p_access, int64_t i_tell ) p_sys->psz_icy_name = NULL; p_sys->psz_icy_genre = NULL; p_sys->psz_icy_title = NULL; + p_sys->i_remaining = 0; + p_sys->b_persist = false; - p_access->info.i_size = 0; + p_access->info.i_size = -1; p_access->info.i_pos = i_tell; p_access->info.b_eof = false; @@ -1029,7 +1079,7 @@ static int Connect( access_t *p_access, int64_t i_tell ) free( psz ); - if( p_access->b_die || p_access->b_error ) + if( !vlc_object_alive (p_access) || p_access->b_error ) { Disconnect( p_access ); return -1; @@ -1059,7 +1109,9 @@ static int Request( access_t *p_access, int64_t i_tell ) access_sys_t *p_sys = p_access->p_sys; char *psz ; v_socket_t *pvs = p_sys->p_vs; + p_sys->b_persist = false; + p_sys->i_remaining = 0; if( p_sys->b_proxy ) { if( p_sys->url.psz_path ) @@ -1102,10 +1154,11 @@ static int Request( access_t *p_access, int64_t i_tell ) net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "User-Agent: %s\r\n", p_sys->psz_user_agent ); /* Offset */ - if( p_sys->i_version == 1 ) + if( p_sys->i_version == 1 && ! p_sys->b_continuous ) { + p_sys->b_persist = true; net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, - "Range: bytes=%"PRId64"-\r\n", i_tell ); + "Range: bytes=%"PRIu64"-\r\n", i_tell ); } /* Cookies */ @@ -1146,17 +1199,6 @@ static int Request( access_t *p_access, int64_t i_tell ) net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "Icy-MetaData: 1\r\n" ); - if( p_sys->b_continuous ) - { - net_Printf( VLC_OBJECT( p_access ), p_sys->fd, pvs, - "Connection: Keep-Alive\r\n" ); - } - else if( p_sys->i_version == 1 ) - { - net_Printf( VLC_OBJECT( p_access ), p_sys->fd, pvs, - "Connection: Close\r\n"); - } - if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "\r\n" ) < 0 ) { msg_Err( p_access, "failed to send request" ); @@ -1222,7 +1264,7 @@ static int Request( access_t *p_access, int64_t i_tell ) goto error; } - if( p_access->b_die || p_access->b_error ) + if( !vlc_object_alive (p_access) || p_access->b_error ) { free( psz ); goto error; @@ -1246,16 +1288,33 @@ static int Request( access_t *p_access, int64_t i_tell ) if( !strcasecmp( psz, "Content-Length" ) ) { - if( p_sys->b_continuous ) - { - p_access->info.i_size = -1; - msg_Dbg( p_access, "this frame size=%lld", atoll(p ) ); - p_sys->i_remaining = atoll( p ); + int64_t i_size = i_tell + (p_sys->i_remaining = atoll( p )); + if(i_size > p_access->info.i_size) { + p_access->info.i_size = i_size; } - else - { - p_access->info.i_size = i_tell + atoll( p ); - msg_Dbg( p_access, "stream size=%"PRId64, p_access->info.i_size ); + msg_Dbg( p_access, "this frame size=%"PRId64, p_sys->i_remaining ); + } + else if( !strcasecmp( psz, "Content-Range" ) ) { + int64_t i_ntell = i_tell; + int64_t i_nend = (p_access->info.i_size > 0)?(p_access->info.i_size - 1):i_tell; + int64_t i_nsize = p_access->info.i_size; + sscanf(p,"bytes %"PRId64"-%"PRId64"/%"PRId64,&i_ntell,&i_nend,&i_nsize); + if(i_nend > i_ntell ) { + p_access->info.i_pos = i_ntell; + p_sys->i_remaining = i_nend+1-i_ntell; + int64_t i_size = (i_nsize > i_nend) ? i_nsize : (i_nend + 1); + if(i_size > p_access->info.i_size) { + p_access->info.i_size = i_size; + } + msg_Dbg( p_access, "stream size=%"PRId64",pos=%"PRId64",remaining=%"PRId64,i_nsize,i_ntell,p_sys->i_remaining); + } + } + else if( !strcasecmp( psz, "Connection" ) ) { + msg_Dbg( p_access, "Connection: %s",p ); + int i = -1; + sscanf(p, "close%n",&i); + if( i >= 0 ) { + p_sys->b_persist = false; } } else if( !strcasecmp( psz, "Location" ) ) @@ -1409,6 +1468,12 @@ static int Request( access_t *p_access, int64_t i_tell ) free( psz ); } + /* We close the stream for zero length data, unless of course the + * server has already promised to do this for us. + */ + if( p_access->info.i_size != -1 && p_sys->i_remaining == 0 && p_sys->b_persist ) { + Disconnect( p_access ); + } return VLC_SUCCESS; error: