标签: winhttp

使用WinINET为虚拟用户创建强大的HTTP连接

我正在制作一个程序,使用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启用其所有代理设置来创建连接?

proxy winapi wininet winhttp

5
推荐指数
1
解决办法
2956
查看次数

WinHttp POST机构未收到

我正在向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)

php iis-7 winhttp

5
推荐指数
1
解决办法
2002
查看次数

多线程WinHttp下载

我正在创建一个Delphi应用程序来从Internet下载文件,如果服务器支持范围请求它将是多线程的.进度也被转发回GUI.

当前的软件模型使用TThread组件.GUI调用a TDownloadThread然后生成TDownloadPartThreads- 这些是实际通过'WinHttp'进行下载的线程.

我的问题:CPU已用完,即使只下载4个线程的下载.

我的假设原因:

  1. 我每8192字节写一次目标文件,想知道在写入一个块之前是否应该缓冲它?
  2. 线程通信是通过Synchronize(MainForm.UpdateProgress(Downloaded, TotalSize))我听到的AWFUL来完成的,也许我应该在线程之间共享一个对象,这样我可以使用主窗体上的计时器来访问它,以更新进度?

我的解决方案

  1. 交错文件写入只写每个x字节.

  2. 更新TThread要使用的组件,OmniThreadLibrary并以某种方式将数据发送回主表单.TDownloadPart然后,每个线程将成为一个IOmniWorker并通过与主表单共享对象来发回其进度.然后,主窗体将使用计时器来更新其进度,如:ProgressBar1.Position := sharedDataObject.Progress;

希望有人可以指出我正确的方向!

delphi multithreading winhttp omnithreadlibrary

5
推荐指数
1
解决办法
1235
查看次数

如何使用wininet强制执行1.x.x

我在我的应用程序中使用wininet库,事实证明sslv3 loooves poodle,一些网站关闭它,我的应用程序不能在某些PC上工作,除非用户在Windows中的Internet设置中设置使用TLS 1.X. 有没有人知道强制wininet使用tls 1.x连接的方法?

c++ ssl wininet winhttp

5
推荐指数
1
解决办法
3079
查看次数

WinHttp不会从WinXP上的Amazon S3下载

最近,亚马逊已禁用对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)

ssl winhttp amazon-s3 visual-c++

5
推荐指数
1
解决办法
996
查看次数

什么导致来自WinHttpSendRequest的间歇性SEC_E_BUFFER_TOO_SMALL错误?

我有一个工具,它针对具有相同标题,相同帖子正文等的相同URL 执行HTTP S POST命令,进行多次迭代.

我遇到的是,对于一些测试人员来说,WinHttpSendRequest()函数经常失败,随后对GetLastError()的调用返回此处记录的SEC_E_BUFFER_TOO_SMALL(0x80090321):COM错误代码(安全性和设置).

这不是WinHttpSendRequest()的文档错误代码,相当广泛的谷歌搜索没有发现任何东西.

我有四倍检查我提供的输入WinHttpSendRequest()是正确和有效的,并且这些输入连续工作了数万次......直到它没有.

我无法提供MVCE,但根据此处提供的假设,我正在寻找错误代码返回的任何可能原因.

c++ ssl https winhttp

5
推荐指数
1
解决办法
1831
查看次数

如何向可能重定向到登录页面的页面发出POST请求

我在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)

post vba winhttp outlook-vba

4
推荐指数
2
解决办法
2万
查看次数

使用WinHttp发布表单

在发布到服务器之前,我是否需要添加任何标头?

例如,目前我正在尝试以这种方式发送请求以及发布数据,

  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)

这有用吗?

c++ winhttp

4
推荐指数
2
解决办法
8543
查看次数

VBA WinHTTP从密码保护的https网站下载文件

我正在尝试使用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)

=======================编辑:========================

所以我今天玩了一点,我想我正在向前迈进.这就是我得到的.我像这样修改了代码: …

excel internet-explorer vba download winhttp

4
推荐指数
1
解决办法
3万
查看次数

WinHttpRequest 超时

我正在使用 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)

autohotkey winhttp winhttprequest

4
推荐指数
1
解决办法
7266
查看次数