gpt4 book ai didi

winapi - WinInet - 无法从 header 中删除内容长度以手动对上传进行分块

转载 作者:行者123 更新时间:2023-12-02 02:29:12 25 4
gpt4 key购买 nike

MSDN states WinInet 不支持分块上传(“客户端代码必须执行分块。”)。对我来说,这意味着我可以手动分块传输。我的意图是通过 HttpAddRequestHeaders 添加“Transfer-Encoding: chunked” ,通过 HttpAddRequestHeaders HTTP_ADDREQ_FLAG_REPLACE 删除 Content-Length,然后在我的 InternetWriteFile 循环中,将数据写入分块编码 block 中。问题是,我似乎无法说服 WinInet 不发送内容长度。即使在删除之后,它最终也会向服务器发送“Content-Length:0”(除了“Transfer-Encoding:chunked”之外),这会让服务器感到困惑。

我还尝试在 HttpSendRequestEx 中设置 HSR_CHUNKED 标志.

有人有让 WinInet 跳过发送内容长度的示例吗?

我知道 WinHTTP 声称支持分块上传,但我们对 WinInet 有其他依赖关系,这就是为什么我希望尽可能解决那里的问题。

这是我尝试过的代码示例:

#include <windows.h>
#include <wininet.h>
#include <tchar.h>
#include <stdio.h>

bool http_putfile(HINTERNET hConnection, TCHAR* resource);

#define HOST _T("www.website.com")
#define RESOURCE _T("/path/for/resource")

int _tmain(int argc, TCHAR* argv[])
{
LPCTSTR lpszHostName = HOST;
INTERNET_PORT nServerPort = INTERNET_DEFAULT_HTTP_PORT;
DWORD dwService = INTERNET_SERVICE_HTTP;
DWORD dwFlags = NULL;
DWORD dwContext = 0;

HINTERNET hSession = InternetOpen(
argv[0],
INTERNET_OPEN_TYPE_DIRECT,
NULL,
NULL,
NULL);

if(hSession != NULL)
{
HINTERNET hConnection = InternetConnect(
hSession,
lpszHostName,
nServerPort,
NULL,
NULL,
dwService,
dwFlags,
dwContext);

if(hConnection != NULL)
{
http_putfile(hConnection, RESOURCE);

InternetCloseHandle(hConnection);
}
else
{
printf("InternetConnect failed: %d\n", GetLastError());
}

InternetCloseHandle(hSession);
}
else
{
printf("InternetOpen failed: %d\n", GetLastError());
}

return 0;
}

bool http_putfile(HINTERNET hConnection, TCHAR* resource)
{
bool result = false;

HINTERNET hRequest = HttpOpenRequest(
hConnection,
_T("PUT"),
resource,
NULL,
NULL,
NULL,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_CACHE_WRITE,
0);

if(hRequest != NULL)
{
HttpAddRequestHeaders(
hRequest,
_T("Transfer-Encoding: chunked\r\n"),
-1L,
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);

// have tried:
// Content-Length
// Content-Length:
// Content-Length\r\n
// Content-Length:\r\n
// all with/without HTTP_ADDREQ_FLAG_ADD. Have even tried adding in a Content-Length
// and then removing it. All results show "Content-Length: 0" in the header on the wire.
if(HttpAddRequestHeaders(
hRequest,
_T("Content-Length"),
-1L,
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE) == FALSE)
{
DWORD err = GetLastError();
}

// have tried both 0 here for flags as documented on msdn
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384318%28v=vs.85%29.aspx
// as well as other combinations of INITIATE/CHUNKED
if(HttpSendRequestEx(hRequest, NULL, NULL, HSR_INITIATE | HSR_CHUNKED /* 0 */, NULL))
{
DWORD wrote = 0;
char* chunks = "5\r\nCHUNK0\r\n";

if(InternetWriteFile(
hRequest,
chunks,
strlen(chunks),
&wrote) == FALSE)
{
printf("InternetWriteFile failed: %d\n", GetLastError());
}

HttpEndRequest(hRequest, NULL, 0, NULL);
}
else
{
printf("HttpSendRequestEx failed: %d\n", GetLastError);
}

InternetCloseHandle(hRequest);
}
else
{
printf("HttpOpenRequest failed: %d\n", GetLastError());
}

return result;
}

最佳答案

嗯,看来你是对的。事实上,我没有看到任何表明 WinINet 支持分块上传的信息; only WinHTTP does 。看着Wine source code (这往往非常准确),“Content-Length” header 始终附加到除“GET”之外的任何方法的请求中。

根据HTTP specs ,如果存在非同一性“Transfer-Encoding” header ,则该消息被认为是分块的。如果还存在“Content-Length” header ,则必须忽略它。如果虚假的“Content-Length:0” header 给您带来了问题,那么可以认为这是服务器的问题。我会尝试一下 WinHTTP,看看它是否可以解决问题。

关于winapi - WinInet - 无法从 header 中删除内容长度以手动对上传进行分块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10050153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com