我正在制作一个程序,使用Wininet系列API在Windows上从Internet下载一个简单的文件,因为我想利用它与IE兼容的代理行为.众所周知,目前的IE有几个代理设置:自动检测(WPAD),自动配置(PAC),手动单URL,每个协议的代理服务器,袜子,直接,...对于大多数用户,"直接下载" 工作良好; 但对于某些用户(特别是那些在防火墙/ NAT后面的用户),他们在建立连接时总是需要特殊的代理设置.
编写代码来处理所有这些情况是很痛苦的,所以我希望WinINET InternetOpen (INTERNET_OPEN_TYPE_PRECONFIG)可以帮助我.它适用于大多数用户,但我仍然发现一些用户抱怨连接失败.这些用户可能具有非常特殊的网络环境(例如,需要用户名/密码auth代理)并且直接连接不适用于他们.
有时虚拟用户配置错误,我想让wininet为我尝试"全部"可能的代理设置; 遗憾的是,INTERNET_OPEN_TYPE_PRECONFIG只会尝试用户配置的那个,而不是"每个可能的代理设置".
所以我的问题是,如何使一个程序具有最强大的能力来解决虚拟用户的所有http连接(特别是代理配置)(即,他们不了解如何配置他们的系统)?是否有任何建议的方式来建立HTTP连接而无需处理代理内容?(即,"超级"连接解算器将尝试所有可能的代理设置),或者是否有任何方法告诉WinINET启用其所有代理设置来创建连接?
我正在向IIS7服务器上的php脚本发送带有POST数据的WinHttp请求,并且服务器未接收到POST主体.如果我使用GET发送WinHttp,或者使用NULL主体发送POST,或者使用带有正文的POST通过HTML表单发送,则一切都按预期工作.
下面是一些简单的代码,显示了使用和不使用正文的WinHttp POST调用之间的区别:
没有身体:
HINTERNET hSession = WinHttpOpen(L"WinHTTP/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);//WINHTTP_FLAG_ASYNC);
HINTERNET mConnection = WinHttpConnect(hSession, L"127.0.0.1", 80, 0);
HINTERNET hRequest = WinHttpOpenRequest(mConnection, L"POST", L"/test.php", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
void* bodyData = NULL;
DWORD bodyLength = 0;
bResult = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, bodyData, bodyLength, bodyLength, 0);
Run Code Online (Sandbox Code Playgroud)
身体:
HINTERNET hSession = WinHttpOpen(L"WinHTTP/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);//WINHTTP_FLAG_ASYNC);
HINTERNET mConnection = WinHttpConnect(hSession, L"127.0.0.1", 80, 0);
HINTERNET hRequest = WinHttpOpenRequest(mConnection, L"POST", L"/test.php", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
char* pBodyStr = "a=1&b=2";
void* bodyData = (void*) …Run Code Online (Sandbox Code Playgroud) 我正在创建一个Delphi应用程序来从Internet下载文件,如果服务器支持范围请求它将是多线程的.进度也被转发回GUI.
当前的软件模型使用TThread组件.GUI调用a TDownloadThread然后生成TDownloadPartThreads- 这些是实际通过'WinHttp'进行下载的线程.
我的问题:CPU已用完,即使只下载4个线程的下载.
我的假设原因:
Synchronize(MainForm.UpdateProgress(Downloaded, TotalSize))我听到的AWFUL来完成的,也许我应该在线程之间共享一个对象,这样我可以使用主窗体上的计时器来访问它,以更新进度?我的解决方案
交错文件写入只写每个x字节.
更新TThread要使用的组件,OmniThreadLibrary并以某种方式将数据发送回主表单.TDownloadPart然后,每个线程将成为一个IOmniWorker并通过与主表单共享对象来发回其进度.然后,主窗体将使用计时器来更新其进度,如:ProgressBar1.Position := sharedDataObject.Progress;
希望有人可以指出我正确的方向!
我在我的应用程序中使用wininet库,事实证明sslv3 loooves poodle,一些网站关闭它,我的应用程序不能在某些PC上工作,除非用户在Windows中的Internet设置中设置使用TLS 1.X. 有没有人知道强制wininet使用tls 1.x连接的方法?
最近,亚马逊已禁用对S3存储桶的SSL支持,这似乎会导致Win XP SP3出现问题.我用这个代码
hSession = WinHttpOpen(L"MySession",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (bHTTPS)
{
DWORD flags = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &flags, sizeof(flags));
}
port = bHTTPS ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
hConnect = WinHttpConnect(hSession, srv_w, port, 0);
hRequest = WinHttpOpenRequest(hConnect, vrb_w, adr_w, NULL, WINHTTP_NO_REFERER, NULL, WINHTTP_FLAG_REFRESH | (bHTTPS ? WINHTTP_FLAG_SECURE : 0));
if (bHTTPS)
{
DWORD dwSecFlag = SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
SECURITY_FLAG_IGNORE_UNKNOWN_CA |
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwSecFlag, sizeof(dwSecFlag));
}
WinHttpSendRequest(hRequest, hdr_w, (headers != NULL) ? -1 : 0, data, size, size, …Run Code Online (Sandbox Code Playgroud) 我有一个工具,它针对具有相同标题,相同帖子正文等的相同URL 执行HTTP S POST命令,进行多次迭代.
我遇到的是,对于一些测试人员来说,WinHttpSendRequest()函数经常失败,随后对GetLastError()的调用返回此处记录的SEC_E_BUFFER_TOO_SMALL(0x80090321):COM错误代码(安全性和设置).
这不是WinHttpSendRequest()的文档错误代码,相当广泛的谷歌搜索没有发现任何东西.
我有四倍检查我提供的输入WinHttpSendRequest()是正确和有效的,并且这些输入连续工作了数万次......直到它没有.
我无法提供MVCE,但根据此处提供的假设,我正在寻找错误代码返回的任何可能原因.
我在Outlook VBA中使用宏来通过POST将文件提交到URL:
Set http = New WinHttp.WinHttpRequest
http.Open "POST", UrlToPostTo, False 'True '
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send data
Run Code Online (Sandbox Code Playgroud)
我的问题是接受请求的页面(在这种情况下,文件上载页面)受到身份验证的保护 - 上面的初始请求将返回登录页面而不是页面本身.
我试图检测登录页面是否出现,如果是,则将用户名和密码作为表单变量发布(我希望这相当于人类在网页浏览器中输入用户名和密码进入页面).
所以步骤是:
*请求URL(包含文件和帖子).
*检查响应是否是登录页面.
*如果是,则在同一个http会话中,将用户名和密码提交给URL.
*如果服务器现在处理原始帖子,那么好,否则我可以再次发布.
代码如下:
' if the login page comes back, send credentials '
If (InStr(http.ResponseText, "j_password") > 0) Then
Dim loginData As String
loginData = "j_username=theusername&j_password=thepassword"
http.Open "POST", UrlToPostTo, False
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send loginData …Run Code Online (Sandbox Code Playgroud) 在发布到服务器之前,我是否需要添加任何标头?
例如,目前我正在尝试以这种方式发送请求以及发布数据,
LPCWSTR post = L"name=User&subject=Hi&message=Hi";
if (!(WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, (LPVOID)post, wcslen(post),
wcslen(post), 0)))
{
//error
}
Run Code Online (Sandbox Code Playgroud)
这有用吗?
我正在尝试使用WinHTTP从https密码保护的站点保存文件.这是代码:
Sub SaveFileFromURL()
Dim FileNum As Long
Dim FileData() As Byte
Dim WHTTP As Object
fileUrl = "https://www.website.com/dir1/dir2/file.xls"
filePath = "C:\myfile.xls"
myuser = "username"
mypass = "password"
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
WHTTP.Open "GET", fileUrl, False
WHTTP.SetCredentials myuser, mypass, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
WHTTP.Send
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
FileNum = FreeFile
Open filePath For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
MsgBox "File has been saved!", vbInformation, "Success"
End Sub
Run Code Online (Sandbox Code Playgroud)
问题在于身份验证.该文件正在保存,但是当我在Excel中打开它时,它只是html登录页面而不是实际文件.如果我复制直接文件URL并将其粘贴到浏览器地址栏中并且我没有登录到网页,效果是一样的.我看到了登录页面.然后,如果我输入我的登录名和密码,下载窗口将显示允许我保存文件.
所以我认为SetCredentials部分代码不能正常工作,如果我调试.打印WHTTP.ResponseBody它是html代码而不是实际文件数据.
有没有办法将用户标识和密码传递给WinHTTP,以便我能够正确保存文件?
这是页面地址:
https://sst.msde.state.md.us/
Run Code Online (Sandbox Code Playgroud)
=======================编辑:========================
所以我今天玩了一点,我想我正在向前迈进.这就是我得到的.我像这样修改了代码: …
我正在使用 AHK 脚本发送一些 POST 请求。我正在尝试获得超时响应,以便向用户弹出一些消息。我不知道如何使用“SetTimeouts”方法和“WaitForResponse”见下面的代码
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.SetTimeouts(3000,3000,3000,3000)
openConnection(WebRequest,ip){
WebRequest.Open("POST", "http://" ip "/cgi/drsLogin",true)
WebRequest.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
WebRequest.Send("action=login&username=admin&password=admin")
time := WebRequest.WaitForResponse(2)
if (time = -1) {
addTextToGui("Connection Timeout")
}
else{
return
}
return
}
Run Code Online (Sandbox Code Playgroud)