英文:
C++::HttpQueryInfo returns status code 403 only the first time
问题
I have the following code that it works for any site that I have tried except this one where I get status code 403 after running ::HttpQueryInfo
. But, if I call ::HttpSendRequest
twice before calling ::HttpQueryInfo
it returns status code 200, it works as expected without problems and I don't understand why I would need to call twice the ::HttpSendRequest
for this particular situation.
HINTERNET hInternet;
::InternetConnect(hInternet, L"dev.mysql.com", 443, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
const TCHAR * lplpszAcceptTypes[] = { _T("*/*"), nullptr };
::HttpOpenRequest(hInternet, L"GET",
L"/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.31-winx64.msi",
L"HTTP/1.0", L"", lplpszAcceptTypes,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_SECURE,
0);
::HttpSendRequest(hInternet, NULL, 0, 0, 0);
DWORD statusCode = 0, size = sizeof(DWORD);
::HttpQueryInfo(hInternet, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&statusCode,
&size, nullptr);
Also, I don't know if it's useful but this is the response header
HTTP/1.1 403 Forbidden
Server: AkamaiNetStorage
Content-Length: 4545
Content-Type: text/html
Set-Cookie: AK_NETWORKTYPE=ESSL; expires=Wed, 17-May-2023 09:21:16 GMT
ETag: "46491460e504640b96a3f5e60da0945f:1434117667"
Expires: Wed, 17 May 2023 09:19:16 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Wed, 17 May 2023 09:19:16 GMT
Connection: keep-alive
英文:
I have the following code that it works for any site that I have tried except this one where I get status code 403 after running ::HttpQueryInfo
. But, if I call ::HttpSendRequest
twice before calling ::HttpQueryInfo
it returns status code 200, it works as expected without problems and I don't understand why I would need to call twice the ::HttpSendRequest
for this particular situation.
HINTERNET hInternet;
::InternetConnect(hInternet, L"dev.mysql.com", 443, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
const TCHAR * lplpszAcceptTypes[] = { _T("*/*"), nullptr };
::HttpOpenRequest(hInternet, L"GET",
L"/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.31-winx64.msi",
L"HTTP/1.0", L"", lplpszAcceptTypes,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_SECURE,
0);
::HttpSendRequest(hInternet, NULL, 0, 0, 0);
DWORD statusCode = 0, size = sizeof(DWORD);
::HttpQueryInfo(hInternet, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&statusCode,
&size, nullptr);
Also, I don't know if it's useful but this is the response header
HTTP/1.1 403 Forbidden
Server: AkamaiNetStorage
Content-Length: 4545
Content-Type: text/html
Set-Cookie: AK_NETWORKTYPE=ESSL; expires=Wed, 17-May-2023 09:21:16 GMT
ETag: "46491460e504640b96a3f5e60da0945f:1434117667"
Expires: Wed, 17 May 2023 09:19:16 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Wed, 17 May 2023 09:19:16 GMT
Connection: keep-alive
答案1
得分: 1
服务器正在进行某种请求验证。在 Fiddler 中测试该 URL 会产生相同的 403 结果。
通过添加以下头信息使请求看起来更像是一个真实的浏览器请求:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: */*
Accept-Encoding: gzip, deflate, br
这样请求就会成功(尽管响应是一个将自动被 WinHTTP 尊重的 302 重定向到另一个 CDN URL)。
英文:
The server is performing some sort of request validation. Testing that URL in Fiddler produces the same 403 result.
Making the request look more like a real browser request by adding the headers:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: */*
Accept-Encoding: gzip, deflate, br
Makes the request work (although the response is a 302 redirect to a different CDN URL, which WinHTTP should honor automatically).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论