Note that there are some explanatory texts on larger screens.

plurals
  1. POWinInet - can't remove Content-Length from headers to manually chunk an upload
    text
    copied!<p>MSDN <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh227298%28v=vs.85%29.aspx" rel="nofollow">states</a> that WinInet does not support chunked upload ("Client code must perform the chunking."). To me that meant I could manually chunk the transfer. My intention was to add "Transfer-Encoding: chunked" via <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384227%28v=vs.85%29.aspx" rel="nofollow">HttpAddRequestHeaders</a>, remove Content-Length via HttpAddRequestHeaders HTTP_ADDREQ_FLAG_REPLACE and then In my InternetWriteFile loop, write the data in chunked encoded blocks. The problem is, I cannot seem to convince WinInet to not send the Content-Length. Even after removal, it ends up sending "Content-Length: 0" to the server (in addition to "Transfer-Encoding: chunked") which is confusing the server.</p> <p>I have also tried setting the HSR_CHUNKED flag in <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384318%28v=vs.85%29.aspx" rel="nofollow">HttpSendRequestEx</a>.</p> <p>Does anyone have an example of getting WinInet to skip sending the Content-Length?</p> <p>I know WinHTTP claims to support chunked upload, but we have other dependencies on WinInet which is why I am looking to solve the problem there if possible.</p> <p>Here is a code sample of what I have tried:</p> <pre><code>#include &lt;windows.h&gt; #include &lt;wininet.h&gt; #include &lt;tchar.h&gt; #include &lt;stdio.h&gt; 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), &amp;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; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload