[vlc-devel] [PATCH] win32/netconf: detect proxy URL from system configuration
Rémi Denis-Courmont
remi at remlab.net
Fri Feb 9 18:51:35 CET 2018
Le torstaina 8. helmikuuta 2018, 19.58.29 EET Pierre Lamot a écrit :
> ---
> configure.ac | 6 ++
> src/win32/netconf.c | 267
> ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 215
> insertions(+), 58 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 10fd5f91eb..ca6193ed77 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -668,6 +668,12 @@ AC_SEARCH_LIBS([inet_pton], [nsl], [
> ])
> ],, [${SOCKET_LIBS}])
>
> +
> +AS_IF([test "${SYS}" = "mingw32" -a "${enable_winstore_app}" != "yes"], [
> + VLC_ADD_LIBS([libvlccore], [-lwinhttp])
> +])
What´s the point in doing that here?
> +
> +
> LIBS="${LIBS} ${SOCKET_LIBS}"
> AC_LINK_IFELSE([
> AC_LANG_PROGRAM([#ifdef _WIN32
> diff --git a/src/win32/netconf.c b/src/win32/netconf.c
> index 3a6dcda1ea..ec7b9a8b9e 100644
> --- a/src/win32/netconf.c
> +++ b/src/win32/netconf.c
> @@ -24,86 +24,237 @@
>
> #include <string.h>
> #include <windows.h>
> +#if !VLC_WINSTORE_APP
> +# include <winhttp.h>
> +#endif
>
> #include <vlc_common.h>
> +#include <vlc_charset.h>
> #include <vlc_network.h>
> #include <vlc_url.h>
>
> -char *vlc_getProxyUrl(const char *psz_url)
> +#define PROXY_TYPE_UNKNOWNED 0
> +#define PROXY_TYPE_SOCKS 1
> +#define PROXY_TYPE_HTTP 2
> +#define PROXY_TYPE_HTTPS 3
> +
> +/**
> + * this function parses the proxy list returned by WinHttpGetProxyForUrl.
> + * it returns the first proxy found using the prefered protocol (https >
> http > socks) + *
> + * The proxy server list contains one or more of the following strings
> + * separated by semicolons or whitespace.
> + * ([<scheme>=][<scheme>"://"]<server>[":"<port>])
> + */
I guess that this is _not_ looking good in Doxygen.
> +static char* parse_proxy( char* psz_proxy )
> {
> - VLC_UNUSED(psz_url);
> + int i_ret_proxy_type = PROXY_TYPE_UNKNOWNED;
> + char* psz_ret_proxy = NULL;
> + char* psz_next_proxy = NULL;
> + char* psz_equal;
>
> - char *proxy = config_GetPsz( (vlc_object_t *)(NULL), "http-proxy" );
> - if (proxy == NULL)
> - return NULL;
> + const char* psz_end = strchr( psz_proxy, '\0' );
>
> - char *proxy_pwd = config_GetPsz( (vlc_object_t *)(NULL),
> "http-proxy-pwd" );
> - if (proxy_pwd == NULL)
> - return proxy;
> + while( psz_proxy < psz_end )
> + {
> + int i_proxy_type = PROXY_TYPE_HTTP;
>
> - vlc_url_t url;
> - if (vlc_UrlParse(&url, proxy) < 0) {
> - free (proxy);
> - free (proxy_pwd);
> - return NULL;
> + //strip leading space / empty proxies
> + psz_proxy += strspn( psz_proxy, " \t;" );
> + if( psz_proxy == psz_end )
> + return psz_ret_proxy;
> +
> + //detect [<scheme>=]
> + if( ( psz_equal = strchr( psz_proxy, '=' ) ) )
> + {
> + *psz_equal = '\0';
> + if( strcasecmp( psz_proxy, "https" ) == 0 )
> + i_proxy_type = PROXY_TYPE_HTTPS;
> + else if( strcasecmp( psz_proxy, "http" ) == 0 )
> + i_proxy_type = PROXY_TYPE_HTTP;
> + else if( strcasecmp( psz_proxy, "socks" ) == 0 )
> + i_proxy_type = PROXY_TYPE_SOCKS;
> + else
> + i_proxy_type = PROXY_TYPE_UNKNOWNED;
> + psz_proxy = psz_equal + 1;
> + }
> +
> + int i_proxylen = strcspn( psz_proxy, " \t;" );
> + psz_proxy[i_proxylen] = '\0';
> + psz_next_proxy = psz_proxy + i_proxylen + 1;
> +
> + if( strncasecmp( psz_proxy, "http://", 7 ) == 0
> + && PROXY_TYPE_HTTP > i_ret_proxy_type )
> + {
> + if(psz_ret_proxy)
> + free( psz_ret_proxy );
> + psz_ret_proxy = strdup( psz_proxy );
> + i_ret_proxy_type = PROXY_TYPE_HTTP;
> + }
> + else if( strncasecmp( psz_proxy, "https://", 8 ) == 0
> + && PROXY_TYPE_HTTPS > i_ret_proxy_type )
> + {
> + if( psz_ret_proxy )
> + free( psz_ret_proxy );
> + psz_ret_proxy = strdup( psz_proxy );
> + i_ret_proxy_type = PROXY_TYPE_HTTPS;
> + }
> + else if( strncasecmp( psz_proxy, "socks://", 8 ) == 0
> + && PROXY_TYPE_SOCKS > i_ret_proxy_type )
> + {
> + if( psz_ret_proxy )
> + free( psz_ret_proxy );
> + psz_ret_proxy = strdup( psz_proxy );
> + i_ret_proxy_type = PROXY_TYPE_SOCKS;
> + }
> + else if( i_proxy_type > i_ret_proxy_type
> + && !strstr( psz_proxy, "://" ) )
> + {
> + switch ( i_proxy_type ) {
> + case PROXY_TYPE_HTTPS:
> + if( psz_ret_proxy )
> + free( psz_ret_proxy );
> + if( asprintf( &psz_ret_proxy, "https://%s", psz_proxy ) ==
> -1 ) + return NULL;
> + break;
> + case PROXY_TYPE_SOCKS:
> + if( psz_ret_proxy )
> + free( psz_ret_proxy );
> + if( asprintf( &psz_ret_proxy, "socks://%s", psz_proxy ) ==
> -1 ) + return NULL;
> + break;
> + case PROXY_TYPE_UNKNOWNED:
> + break;
> + default:
> + if( psz_ret_proxy )
> + free( psz_ret_proxy );
> + if( asprintf( &psz_ret_proxy, "http://%s", psz_proxy ) ==
> -1 ) + return NULL;
> + break;
> + }
> +
> + i_ret_proxy_type = i_proxy_type;
> + }
> +
> + psz_proxy = psz_next_proxy;
> }
> + return psz_ret_proxy;
> +}
Too repetitive. Also redundant checks.
> +
> +char *vlc_getProxyUrl(const char *psz_url)
> +{
> + char *proxy = config_GetPsz( (vlc_object_t *)(NULL), "http-proxy" );
> + if (proxy != NULL)
> + {
Hmm no. On 4.0 upgrade, users who set a single proxy for lack of better
option, will still end up using the single proxy instead of the more flexible
Windows setting.
> - if (url.psz_password == NULL )
> - url.psz_password = vlc_uri_encode(proxy_pwd);
> + char *proxy_pwd = config_GetPsz( (vlc_object_t *)(NULL),
> "http-proxy-pwd" ); + if (proxy_pwd == NULL)
> + return proxy;
> +
> + vlc_url_t url;
> + if (vlc_UrlParse(&url, proxy) < 0)
> + {
> + free (proxy);
> + free (proxy_pwd);
> + return NULL;
> + }
>
> - char *proxy_url = vlc_uri_compose (&url);
> - vlc_UrlClean (&url);
> + if (url.psz_password == NULL )
> + url.psz_password = vlc_uri_encode(proxy_pwd);
>
> - free (proxy_pwd);
> - free (proxy);
> + char *proxy_url = vlc_uri_compose (&url);
> + vlc_UrlClean (&url);
>
> -#if 0
> - /* Try to get the proxy server address from Windows internet settings.
> */ - HKEY h_key;
> + free (proxy_pwd);
> + free (proxy);
> + return proxy_url;
> + }
>
> - /* Open the key */
> - if( RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Microsoft"
> - "\\Windows\\CurrentVersion\\Internet Settings",
> - 0, KEY_READ, &h_key ) == ERROR_SUCCESS )
> +#if VLC_WINSTORE_APP
> + return NULL;
> +#else
> + if ( psz_url == NULL )
> return NULL;
>
> - DWORD len = sizeof( DWORD );
> - BYTE proxyEnable;
> -
> - /* Get the proxy enable value */
> - if( RegQueryValueEx( h_key, "ProxyEnable", NULL, NULL,
> - &proxyEnable, &len ) != ERROR_SUCCESS
> - || !proxyEnable )
> - goto out;
> -
> - /* Proxy is enabled */
> - /* Get the proxy URL :
> - Proxy server value in the registry can be something like
> "address:port" - or "ftp=address1:port1;http=address2:port2 ..."
> - depending of the configuration. */
> - unsigned char key[256];
> -
> - len = sizeof( key );
> - if( RegQueryValueEx( h_key, "ProxyServer", NULL, NULL,
> - key, &len ) == ERROR_SUCCESS )
> + char *psz_proxy = NULL;
> + wchar_t *pwsz_url = ToWide( psz_url );
> + bool b_autoproxy = false;
> +
> + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieConfig;
> + WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
> + WINHTTP_PROXY_INFO autoProxyInfo;
> +
> + memset( &ieConfig, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG) );
> + memset( &autoProxyOptions, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS) );
> + memset( &autoProxyInfo, 0, sizeof(WINHTTP_PROXY_INFO) );
> +
> + if( WinHttpGetIEProxyConfigForCurrentUser(&ieConfig) )
> {
> - /* FIXME: This is lame. The string should be tokenized. */
> -#warning FIXME.
> - char *psz_proxy = strstr( (char *)key, "http=" );
> - if( psz_proxy != NULL )
> + if( ieConfig.fAutoDetect )
> + b_autoproxy = true;
> + if( ieConfig.lpszAutoConfigUrl != NULL )
> {
> - psz_proxy += 5;
> - char *end = strchr( psz_proxy, ';' );
> - if( end != NULL )
> - *end = '\0';
> + b_autoproxy = true;
> + autoProxyOptions.lpszAutoConfigUrl =
> ieConfig.lpszAutoConfigUrl; }
> + }
> + else
> + b_autoproxy = true;
> +
> + if( b_autoproxy )
> + {
> + if( autoProxyOptions.lpszAutoConfigUrl != NULL )
> + autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
> else
> - psz_proxy = (char *)key;
> - proxy_url = strdup( psz_proxy );
> + {
> + autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
> + autoProxyOptions.dwAutoDetectFlags =
> WINHTTP_AUTO_DETECT_TYPE_DHCP +
> | WINHTTP_AUTO_DETECT_TYPE_DNS_A; + }
> + autoProxyOptions.fAutoLogonIfChallenged = TRUE;
> +
> + HINTERNET handle = WinHttpOpen( L"VLC Proxy Lookup/1.0",
> + WINHTTP_ACCESS_TYPE_NO_PROXY,
> WINHTTP_NO_PROXY_NAME, +
> WINHTTP_NO_PROXY_BYPASS, 0 ); +
> + if( !handle )
> + goto end;
> +
> + b_autoproxy = WinHttpGetProxyForUrl( handle, pwsz_url,
> &autoProxyOptions, &autoProxyInfo ); +
> + WinHttpCloseHandle(handle);
> + }
> +
> + if( b_autoproxy )
> + {
> + if( autoProxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY )
> + psz_proxy = FromWide( autoProxyInfo.lpszProxy );
> + }
> + else if( ieConfig.lpszProxy )
> + psz_proxy = FromWide( ieConfig.lpszProxy );;
> +
> + if( psz_proxy )
> + {
> + char* tmp = parse_proxy( psz_proxy );
> + free( psz_proxy );
> + psz_proxy = tmp;
> }
>
> -out:
> - RegCloseKey( h_key );
> +end:
> + if( autoProxyInfo.lpszProxy != NULL )
> + GlobalFree( autoProxyInfo.lpszProxy );
> + if( autoProxyInfo.lpszProxyBypass != NULL )
> + GlobalFree( autoProxyInfo.lpszProxyBypass );
> +
> + if( ieConfig.lpszAutoConfigUrl != NULL )
> + GlobalFree( ieConfig.lpszAutoConfigUrl );
> + if( ieConfig.lpszProxy != NULL )
> + GlobalFree( ieConfig.lpszProxy );
> + if( ieConfig.lpszProxyBypass != NULL )
> + GlobalFree( ieConfig.lpszProxyBypass );
> +
> + free( pwsz_url );
> +
> + return psz_proxy;
> #endif
> - return proxy_url;
> }
--
雷米‧德尼-库尔蒙
https://www.remlab.net/
More information about the vlc-devel
mailing list