📄 http.c
字号:
{ msg_Dbg( p_access, " user='%s'", p_sys->url.psz_username ); } p_sys->b_reconnect = var_CreateGetBool( p_access, "http-reconnect" ); p_sys->b_continuous = var_CreateGetBool( p_access, "http-continuous" );connect: /* Connect */ switch( Connect( p_access, 0 ) ) { case -1: goto error; case -2: /* Retry with http 1.0 */ msg_Dbg( p_access, "switching to HTTP version 1.0" ); p_sys->i_version = 0; p_sys->b_seekable = false; if( !vlc_object_alive (p_access) || Connect( p_access, 0 ) ) goto error;#ifndef NDEBUG case 0: break; default: msg_Err( p_access, "You should not be here" ); abort();#endif } if( p_sys->i_code == 401 ) { char *psz_login = NULL, *psz_password = NULL; char psz_msg[250]; int i_ret; /* FIXME ? */ if( p_sys->url.psz_username && p_sys->url.psz_password && p_sys->auth.psz_nonce && p_sys->auth.i_nonce == 0 ) { goto connect; } snprintf( psz_msg, 250, _("Please enter a valid login name and a password for realm %s."), p_sys->auth.psz_realm ); msg_Dbg( p_access, "authentication failed for realm %s", p_sys->auth.psz_realm ); i_ret = intf_UserLoginPassword( p_access, _("HTTP authentication"), psz_msg, &psz_login, &psz_password ); if( i_ret == DIALOG_OK_YES ) { msg_Dbg( p_access, "retrying with user=%s, pwd=%s", psz_login, psz_password ); if( psz_login ) p_sys->url.psz_username = strdup( psz_login ); if( psz_password ) p_sys->url.psz_password = strdup( psz_password ); free( psz_login ); free( psz_password ); goto connect; } else { free( psz_login ); free( psz_password ); goto error; } } if( ( p_sys->i_code == 301 || p_sys->i_code == 302 || p_sys->i_code == 303 || p_sys->i_code == 307 ) && p_sys->psz_location && *p_sys->psz_location ) { msg_Dbg( p_access, "redirection to %s", p_sys->psz_location ); /* Do not accept redirection outside of HTTP works */ if( strncmp( p_sys->psz_location, "http", 4 ) || ( ( p_sys->psz_location[4] != ':' ) /* HTTP */ && strncmp( p_sys->psz_location + 4, "s:", 2 ) /* HTTP/SSL */ ) ) { msg_Err( p_access, "insecure redirection ignored" ); goto error; } free( p_access->psz_path ); p_access->psz_path = strdup( p_sys->psz_location ); /* Clean up current Open() run */ vlc_UrlClean( &p_sys->url ); AuthReset( &p_sys->auth ); vlc_UrlClean( &p_sys->proxy ); free( p_sys->psz_proxy_passbuf ); AuthReset( &p_sys->proxy_auth ); free( p_sys->psz_mime ); free( p_sys->psz_pragma ); free( p_sys->psz_location ); free( p_sys->psz_user_agent ); Disconnect( p_access ); cookies = p_sys->cookies; free( p_sys ); /* Do new Open() run with new data */ return OpenWithCookies( p_this, cookies ); } if( p_sys->b_mms ) { msg_Dbg( p_access, "this is actually a live mms server, BAIL" ); goto error; } if( !strcmp( p_sys->psz_protocol, "ICY" ) || p_sys->b_icecast ) { if( p_sys->psz_mime && strcasecmp( p_sys->psz_mime, "application/ogg" ) ) { if( !strcasecmp( p_sys->psz_mime, "video/nsv" ) || !strcasecmp( p_sys->psz_mime, "video/nsa" ) ) { free( p_access->psz_demux ); p_access->psz_demux = strdup( "nsv" ); } else if( !strcasecmp( p_sys->psz_mime, "audio/aac" ) || !strcasecmp( p_sys->psz_mime, "audio/aacp" ) ) { free( p_access->psz_demux ); p_access->psz_demux = strdup( "m4a" ); } else if( !strcasecmp( p_sys->psz_mime, "audio/mpeg" ) ) { free( p_access->psz_demux ); p_access->psz_demux = strdup( "mp3" ); } msg_Info( p_access, "Raw-audio server found, %s demuxer selected", p_access->psz_demux );#if 0 /* Doesn't work really well because of the pre-buffering in * shoutcast servers (the buffer content will be sent as fast as * possible). */ p_sys->b_pace_control = false;#endif } else if( !p_sys->psz_mime ) { free( p_access->psz_demux ); /* Shoutcast */ p_access->psz_demux = strdup( "mp3" ); } /* else probably Ogg Vorbis */ } else if( !strcasecmp( p_access->psz_access, "unsv" ) && p_sys->psz_mime && !strcasecmp( p_sys->psz_mime, "misc/ultravox" ) ) { free( p_access->psz_demux ); /* Grrrr! detect ultravox server and force NSV demuxer */ p_access->psz_demux = strdup( "nsv" ); } else if( !strcmp( p_access->psz_access, "itpc" ) ) { free( p_access->psz_demux ); p_access->psz_demux = strdup( "podcast" ); } else if( p_sys->psz_mime && !strncasecmp( p_sys->psz_mime, "application/xspf+xml", 20 ) && ( memchr( " ;\t", p_sys->psz_mime[20], 4 ) != NULL ) ) { free( p_access->psz_demux ); p_access->psz_demux = strdup( "xspf-open" ); } if( p_sys->b_reconnect ) msg_Dbg( p_access, "auto re-connect enabled" ); /* PTS delay */ var_Create( p_access, "http-caching", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT ); return VLC_SUCCESS;error: vlc_UrlClean( &p_sys->url ); vlc_UrlClean( &p_sys->proxy ); free( p_sys->psz_proxy_passbuf ); free( p_sys->psz_mime ); free( p_sys->psz_pragma ); free( p_sys->psz_location ); free( p_sys->psz_user_agent ); Disconnect( p_access ); free( p_sys ); return VLC_EGENERIC;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){ access_t *p_access = (access_t*)p_this; access_sys_t *p_sys = p_access->p_sys; vlc_UrlClean( &p_sys->url ); AuthReset( &p_sys->auth ); vlc_UrlClean( &p_sys->proxy ); AuthReset( &p_sys->proxy_auth ); free( p_sys->psz_mime ); free( p_sys->psz_pragma ); free( p_sys->psz_location ); free( p_sys->psz_icy_name ); free( p_sys->psz_icy_genre ); free( p_sys->psz_icy_title ); free( p_sys->psz_user_agent ); Disconnect( p_access ); if( p_sys->cookies ) { int i; for( i = 0; i < vlc_array_count( p_sys->cookies ); i++ ) free(vlc_array_item_at_index( p_sys->cookies, i )); 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 );}/***************************************************************************** * 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 < 0 ) { p_access->info.b_eof = true; return 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 ) { p_access->info.b_eof = true; return 0; } } if( p_sys->b_chunked ) { if( p_sys->i_chunk < 0 ) { p_access->info.b_eof = true; return 0; } if( p_sys->i_chunk <= 0 ) { char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, p_sys->p_vs ); /* read the chunk header */ if( psz == NULL ) { /* fatal error - end of file */ msg_Dbg( p_access, "failed reading chunk-header line" ); return 0; } p_sys->i_chunk = strtoll( psz, NULL, 16 ); free( psz ); if( p_sys->i_chunk <= 0 ) /* eof */ { p_sys->i_chunk = -1; p_access->info.b_eof = true; return 0; } } if( i_len > p_sys->i_chunk ) { i_len = p_sys->i_chunk; } } else if( p_access->info.i_size != -1 && (int64_t)i_len > p_sys->i_remaining) { /* Only ask for the remaining length */ i_len = (size_t)p_sys->i_remaining; if(i_len == 0) { p_access->info.b_eof = true; return 0; } } if( p_sys->i_icy_meta > 0 && p_access->info.i_pos-p_sys->i_icy_offset > 0 ) { int64_t i_next = p_sys->i_icy_meta - (p_access->info.i_pos - p_sys->i_icy_offset ) % p_sys->i_icy_meta; if( i_next == p_sys->i_icy_meta ) { if( ReadICYMeta( p_access ) ) { p_access->info.b_eof = true; return -1; } } if( 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( i_read > 0 ) { p_access->info.i_pos += i_read; 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( VLC_OBJECT(p_access), p_sys->fd, p_sys->p_vs ); free( psz ); } } } else if( i_read == 0 ) { /* * I very much doubt that this will work. * If i_read == 0, the connection *IS* dead, so the only * sensible thing to do is Disconnect() and then retry. * Otherwise, I got recv() completely wrong. -- Courmisch */ if( p_sys->b_continuous ) { Request( p_access, 0 ); p_sys->b_continuous = false; i_read = Read( p_access, p_buffer, i_len ); p_sys->b_continuous = true; } Disconnect( p_access ); if( p_sys->b_reconnect ) { msg_Dbg( p_access, "got disconnected, trying to reconnect" ); if( Connect( p_access, p_access->info.i_pos ) ) { msg_Dbg( p_access, "reconnection failed" ); } else { p_sys->b_reconnect = false; i_read = Read( p_access, p_buffer, i_len ); p_sys->b_reconnect = true; } } if( i_read == 0 ) p_access->info.b_eof = true; } if( p_access->info.i_size != -1 ) { p_sys->i_remaining -= i_read; } return i_read;}static int ReadICYMeta( access_t *p_access ){ access_sys_t *p_sys = p_access->p_sys; uint8_t buffer; char *p, *psz_meta; 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 ) return VLC_EGENERIC; if( buffer == 0 ) return VLC_SUCCESS; i_read = buffer << 4; /* msg_Dbg( p_access, "ICY meta size=%u", i_read); */ 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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -