Commit de6a0a86 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

wininet: Handle proxy entries of the form <proto>=<proxy>, and allow multiple proxies.

parent da409d6a
......@@ -1343,9 +1343,12 @@ static WCHAR *HTTP_BuildProxyRequestUrl(http_request_t *req)
static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *lpwhs, http_request_t *lpwhr)
{
WCHAR buf[MAXHOSTNAME];
WCHAR protoProxy[MAXHOSTNAME + 15];
DWORD protoProxyLen = sizeof(protoProxy) / sizeof(protoProxy[0]);
WCHAR proxy[MAXHOSTNAME + 15]; /* 15 == "http://" + sizeof(port#) + ":/\0" */
static WCHAR szNul[] = { 0 };
URL_COMPONENTSW UrlComponents;
static const WCHAR protoHttp[] = { 'h','t','t','p',0 };
static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 };
static const WCHAR szFormat[] = { 'h','t','t','p',':','/','/','%','s',0 };
......@@ -1354,11 +1357,13 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *lpwhs, http_reque
UrlComponents.lpszHostName = buf;
UrlComponents.dwHostNameLength = MAXHOSTNAME;
if (!INTERNET_FindProxyForProtocol(hIC->lpszProxy, protoHttp, protoProxy, &protoProxyLen))
return FALSE;
if( CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
hIC->lpszProxy,strlenW(szHttp),szHttp,strlenW(szHttp)) )
sprintfW(proxy, szFormat, hIC->lpszProxy);
protoProxy,strlenW(szHttp),szHttp,strlenW(szHttp)) )
sprintfW(proxy, szFormat, protoProxy);
else
strcpyW(proxy, hIC->lpszProxy);
strcpyW(proxy, protoProxy);
if( !InternetCrackUrlW(proxy, 0, 0, &UrlComponents) )
return FALSE;
if( UrlComponents.dwHostNameLength == 0 )
......@@ -4251,8 +4256,6 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
}
if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
if(strchrW(hIC->lpszProxy, ' '))
FIXME("Several proxies not implemented.\n");
if(hIC->lpszProxyBypass)
FIXME("Proxy bypass is ignored.\n");
}
......
......@@ -363,6 +363,98 @@ static LONG INTERNET_SaveProxySettings( proxyinfo_t *lpwpi )
}
/***********************************************************************
* INTERNET_FindProxyForProtocol
*
* Searches the proxy string for a proxy of the given protocol.
* Returns the found proxy, or the default proxy if none of the given
* protocol is found.
*
* PARAMETERS
* szProxy [In] proxy string to search
* proto [In] protocol to search for, e.g. "http"
* foundProxy [Out] found proxy
* foundProxyLen [In/Out] length of foundProxy buffer, in WCHARs
*
* RETURNS
* TRUE if a proxy is found, FALSE if not. If foundProxy is too short,
* *foundProxyLen is set to the required size in WCHARs, including the
* NULL terminator, and the last error is set to ERROR_INSUFFICIENT_BUFFER.
*/
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen)
{
LPCWSTR ptr;
BOOL ret = FALSE;
TRACE("(%s, %s)\n", debugstr_w(szProxy), debugstr_w(proto));
/* First, look for the specified protocol (proto=scheme://host:port) */
for (ptr = szProxy; !ret && ptr && *ptr; )
{
LPCWSTR end, equal;
if (!(end = strchrW(ptr, ' ')))
end = ptr + strlenW(ptr);
if ((equal = strchrW(ptr, '=')) && equal < end &&
equal - ptr == strlenW(proto) &&
!strncmpiW(proto, ptr, strlenW(proto)))
{
if (end - equal > *foundProxyLen)
{
WARN("buffer too short for %s\n",
debugstr_wn(equal + 1, end - equal - 1));
*foundProxyLen = end - equal;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
else
{
memcpy(foundProxy, equal + 1, (end - equal) * sizeof(WCHAR));
foundProxy[end - equal] = 0;
ret = TRUE;
}
}
if (*end == ' ')
ptr = end + 1;
else
ptr = end;
}
if (!ret)
{
/* It wasn't found: look for no protocol */
for (ptr = szProxy; !ret && ptr && *ptr; )
{
LPCWSTR end, equal;
if (!(end = strchrW(ptr, ' ')))
end = ptr + strlenW(ptr);
if (!(equal = strchrW(ptr, '=')))
{
if (end - ptr + 1 > *foundProxyLen)
{
WARN("buffer too short for %s\n",
debugstr_wn(ptr, end - ptr));
*foundProxyLen = end - ptr + 1;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
else
{
memcpy(foundProxy, ptr, (end - ptr) * sizeof(WCHAR));
foundProxy[end - ptr] = 0;
ret = TRUE;
}
}
if (*end == ' ')
ptr = end + 1;
else
ptr = end;
}
}
if (ret)
TRACE("found proxy for %s: %s\n", debugstr_w(proto),
debugstr_w(foundProxy));
return ret;
}
/***********************************************************************
* InternetInitializeAutoProxyDll (WININET.@)
*
* Setup the internal proxy
......
......@@ -418,6 +418,7 @@ VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength);
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen);
BOOL NETCON_connected(WININET_NETCONNECTION *connection);
DWORD NETCON_init(WININET_NETCONNECTION *connnection, BOOL useSSL);
......
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