📄 http.c
字号:
return VLC_EGENERIC; psz_meta[i_read] = '\0'; /* Just in case */ /* msg_Dbg( p_access, "icy-meta=%s", psz_meta ); */ /* Now parse the meta */ /* Look for StreamTitle= */ p = strcasestr( (char *)psz_meta, "StreamTitle=" ); if( p ) { p += strlen( "StreamTitle=" ); if( *p == '\'' || *p == '"' ) { char closing[] = { p[0], ';', '\0' }; char *psz = strstr( &p[1], closing ); if( !psz ) psz = strchr( &p[1], ';' ); if( psz ) *psz = '\0'; } else { char *psz = strchr( &p[1], ';' ); if( psz ) *psz = '\0'; } if( !p_sys->psz_icy_title || strcmp( p_sys->psz_icy_title, &p[1] ) ) { free( p_sys->psz_icy_title ); p_sys->psz_icy_title = EnsureUTF8( strdup( &p[1] )); p_access->info.i_update |= INPUT_UPDATE_META; msg_Dbg( p_access, "New Title=%s", p_sys->psz_icy_title ); } } free( psz_meta ); return VLC_SUCCESS;}#ifdef HAVE_ZLIB_Hstatic ssize_t ReadCompressed( access_t *p_access, uint8_t *p_buffer, size_t i_len ){ access_sys_t *p_sys = p_access->p_sys; if( p_sys->b_compressed ) { int i_ret; if( !p_sys->inflate.p_buffer ) p_sys->inflate.p_buffer = malloc( 256 * 1024 ); if( p_sys->inflate.stream.avail_in == 0 ) { ssize_t i_read = Read( p_access, p_sys->inflate.p_buffer + p_sys->inflate.stream.avail_in, 256 * 1024 ); if( i_read <= 0 ) return i_read; p_sys->inflate.stream.next_in = p_sys->inflate.p_buffer; p_sys->inflate.stream.avail_in = i_read; } p_sys->inflate.stream.avail_out = i_len; p_sys->inflate.stream.next_out = p_buffer; i_ret = inflate( &p_sys->inflate.stream, Z_SYNC_FLUSH ); msg_Warn( p_access, "inflate return value: %d, %s", i_ret, p_sys->inflate.stream.msg ); return i_len - p_sys->inflate.stream.avail_out; } else { return Read( p_access, p_buffer, i_len ); }}#endif/***************************************************************************** * Seek: close and re-open a connection at the right place *****************************************************************************/static int Seek( access_t *p_access, int64_t i_pos ){ msg_Dbg( p_access, "trying to seek to %"PRId64, 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" ); p_access->info.b_eof = 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; bool *pb_bool; int *pi_int; int64_t *pi_64; vlc_meta_t *p_meta; switch( i_query ) { /* */ case ACCESS_CAN_SEEK: pb_bool = (bool*)va_arg( args, bool* ); *pb_bool = p_sys->b_seekable; break; case ACCESS_CAN_FASTSEEK: pb_bool = (bool*)va_arg( args, bool* ); *pb_bool = false; break; case ACCESS_CAN_PAUSE: case ACCESS_CAN_CONTROL_PACE: pb_bool = (bool*)va_arg( args, bool* );#if 0 /* Disable for now until we have a clock synchro algo * which works with something else than MPEG over UDP */ *pb_bool = p_sys->b_pace_control;#endif *pb_bool = true; break; /* */ case ACCESS_GET_MTU: pi_int = (int*)va_arg( args, int * ); *pi_int = 0; break; case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); *pi_64 = (int64_t)var_GetInteger( p_access, "http-caching" ) * 1000; break; /* */ case ACCESS_SET_PAUSE_STATE: break; case ACCESS_GET_META: p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* ); if( p_sys->psz_icy_name ) vlc_meta_Set( p_meta, vlc_meta_Title, p_sys->psz_icy_name ); if( p_sys->psz_icy_genre ) vlc_meta_Set( p_meta, vlc_meta_Genre, p_sys->psz_icy_genre ); if( p_sys->psz_icy_title ) vlc_meta_Set( p_meta, vlc_meta_NowPlaying, p_sys->psz_icy_title ); break; case ACCESS_GET_CONTENT_TYPE: *va_arg( args, char ** ) = p_sys->psz_mime ? strdup( p_sys->psz_mime ) : NULL; break; case ACCESS_GET_TITLE_INFO: case ACCESS_SET_TITLE: case ACCESS_SET_SEEKPOINT: case ACCESS_SET_PRIVATE_ID_STATE: return VLC_EGENERIC; default: msg_Warn( p_access, "unimplemented query in control" ); return VLC_EGENERIC; } return VLC_SUCCESS;}/***************************************************************************** * Connect: *****************************************************************************/static int Connect( access_t *p_access, int64_t i_tell ){ access_sys_t *p_sys = p_access->p_sys; vlc_url_t srv = p_sys->b_proxy ? p_sys->proxy : p_sys->url; /* Clean info */ free( p_sys->psz_location ); free( p_sys->psz_mime ); free( p_sys->psz_pragma ); free( p_sys->psz_icy_genre ); free( p_sys->psz_icy_name ); free( p_sys->psz_icy_title ); p_sys->psz_location = NULL; p_sys->psz_mime = NULL; p_sys->psz_pragma = NULL; p_sys->b_mms = false; p_sys->b_chunked = false; p_sys->i_chunk = 0; p_sys->i_icy_meta = 0; p_sys->i_icy_offset = 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 = -1; p_access->info.i_pos = i_tell; p_access->info.b_eof = false; /* Open connection */ p_sys->fd = net_ConnectTCP( p_access, srv.psz_host, srv.i_port ); if( p_sys->fd == -1 ) { msg_Err( p_access, "cannot connect to %s:%d", srv.psz_host, srv.i_port ); return -1; } /* Initialize TLS/SSL session */ if( p_sys->b_ssl == true ) { /* CONNECT to establish TLS tunnel through HTTP proxy */ if( p_sys->b_proxy ) { char *psz; unsigned i_status = 0; if( p_sys->i_version == 0 ) { /* CONNECT is not in HTTP/1.0 */ Disconnect( p_access ); return -1; } net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "CONNECT %s:%d HTTP/1.%d\r\nHost: %s:%d\r\n\r\n", p_sys->url.psz_host, p_sys->url.i_port, p_sys->i_version, p_sys->url.psz_host, p_sys->url.i_port); psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ); if( psz == NULL ) { msg_Err( p_access, "cannot establish HTTP/TLS tunnel" ); Disconnect( p_access ); return -1; } sscanf( psz, "HTTP/%*u.%*u %3u", &i_status ); free( psz ); if( ( i_status / 100 ) != 2 ) { msg_Err( p_access, "HTTP/TLS tunnel through proxy denied" ); Disconnect( p_access ); return -1; } do { psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, NULL ); if( psz == NULL ) { msg_Err( p_access, "HTTP proxy connection failed" ); Disconnect( p_access ); return -1; } if( *psz == '\0' ) i_status = 0; free( psz ); if( !vlc_object_alive (p_access) || p_access->b_error ) { Disconnect( p_access ); return -1; } } while( i_status ); } /* TLS/SSL handshake */ p_sys->p_tls = tls_ClientCreate( VLC_OBJECT(p_access), p_sys->fd, srv.psz_host ); if( p_sys->p_tls == NULL ) { msg_Err( p_access, "cannot establish HTTP/TLS session" ); Disconnect( p_access ); return -1; } p_sys->p_vs = &p_sys->p_tls->sock; } return Request( p_access, i_tell ) ? -2 : 0;}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 ) { net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "GET http://%s:%d%s HTTP/1.%d\r\n", p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path, p_sys->i_version ); } else { net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "GET http://%s:%d/ HTTP/1.%d\r\n", p_sys->url.psz_host, p_sys->url.i_port, p_sys->i_version ); } } else { const char *psz_path = p_sys->url.psz_path; if( !psz_path || !*psz_path ) { psz_path = "/"; } if( p_sys->url.i_port != (pvs ? 443 : 80) ) { net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "GET %s HTTP/1.%d\r\nHost: %s:%d\r\n", psz_path, p_sys->i_version, p_sys->url.psz_host, p_sys->url.i_port ); } else { net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "GET %s HTTP/1.%d\r\nHost: %s\r\n", psz_path, p_sys->i_version, p_sys->url.psz_host ); } } /* User Agent */ 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 && ! p_sys->b_continuous ) { p_sys->b_persist = true; net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "Range: bytes=%"PRIu64"-\r\n", i_tell ); } /* Cookies */ if( p_sys->cookies ) { int i; for( i = 0; i < vlc_array_count( p_sys->cookies ); i++ ) { const char * cookie = vlc_array_item_at_index( p_sys->cookies, i ); char * psz_cookie_content = cookie_get_content( cookie ); char * psz_cookie_domain = cookie_get_domain( cookie ); assert( psz_cookie_content ); /* FIXME: This is clearly not conforming to the rfc */ bool is_in_right_domain = (!psz_cookie_domain || strstr( p_sys->url.psz_host, psz_cookie_domain )); if( is_in_right_domain ) { msg_Dbg( p_access, "Sending Cookie %s", psz_cookie_content ); if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "Cookie: %s\r\n", psz_cookie_content ) < 0 ) msg_Err( p_access, "failed to send Cookie" ); } free( psz_cookie_content ); free( psz_cookie_domain ); } } /* Authentication */ if( p_sys->url.psz_username || p_sys->url.psz_password ) AuthReply( p_access, "", &p_sys->url, &p_sys->auth ); /* Proxy Authentication */ if( p_sys->proxy.psz_username || p_sys->proxy.psz_password ) AuthReply( p_access, "Proxy-", &p_sys->proxy, &p_sys->proxy_auth );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -