Description
Summary
If cpprestsdk is used in an environment where a web proxy requires authentication, and if invalid username/password is provided, the request will continuously be retried. (Only tested in WinHTTP.)
Details
Configure http_client with proxy credentials:
http_client_config clientConfig;
web::web_proxy proxy;
web::credentials proxyCreds(U"username", U"invalidpassword");
proxy.set_credentials(proxyCreds);
clientConfig.set_proxy(proxy);
The initial request will result in a 407 ("Proxy Authentication Required") response error and call winhttp_client::handle_authentication_failure
which will replay the request but with the proxy creds. That subsequent request will also fail because the credentials are invalid, but winhttp_client::handle_authentication_failure
will continue replying the request over and over.
Why?
bool is_redirect = false;
try
{
web::uri current_uri(get_request_url(hRequestHandle));
is_redirect = p_request_context->m_request.absolute_uri().to_string() != current_uri.to_string();
}
catch (const std::exception&) {}
if (is_redirect || !p_request_context->m_proxy_authentication_tried)
{
cred = p_request_context->m_http_client->client_config().proxy().credentials();
p_request_context->m_proxy_authentication_tried = true;
}
is_redirect
is always true
because of a minor bug in winhttp_client::get_request_url
:
DWORD urlSize{ 0 };
if(FALSE == WinHttpQueryOption(hRequestHandle, WINHTTP_OPTION_URL, nullptr, &urlSize) || urlSize == 0)
{
return U("");
}
The WinHttpQueryOption
function will always return FALSE
when lpBuffer
is nullptr
. Before bailing out, we must first check the result GetLastError()
. For example:
DWORD urlSize{ 0 };
if(FALSE == WinHttpQueryOption(hRequestHandle, WINHTTP_OPTION_URL, nullptr, &urlSize) || urlSize == 0)
{
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
{
return U("");
}
}