| @@ -343,6 +343,35 @@ private: | |||||
| InternetSetOption (sessionHandle, option, &timeOutMs, sizeof (timeOutMs)); | InternetSetOption (sessionHandle, option, &timeOutMs, sizeof (timeOutMs)); | ||||
| } | } | ||||
| void sendHTTPRequest (INTERNET_BUFFERS& buffers, WebInputStream::Listener* listener) | |||||
| { | |||||
| if (! HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0)) | |||||
| return; | |||||
| int totalBytesSent = 0; | |||||
| while (totalBytesSent < postData.getSize()) | |||||
| { | |||||
| auto bytesToSend = jmin (1024, (int) postData.getSize() - totalBytesSent); | |||||
| DWORD bytesSent = 0; | |||||
| if (bytesToSend == 0 | |||||
| || ! InternetWriteFile (request, static_cast<const char*> (postData.getData()) + totalBytesSent, | |||||
| (DWORD) bytesToSend, &bytesSent)) | |||||
| { | |||||
| return; | |||||
| } | |||||
| totalBytesSent += bytesSent; | |||||
| if (listener != nullptr | |||||
| && ! listener->postDataSendProgress (owner, totalBytesSent, (int) postData.getSize())) | |||||
| { | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| void openHTTPConnection (URL_COMPONENTS& uc, const String& address, WebInputStream::Listener* listener) | void openHTTPConnection (URL_COMPONENTS& uc, const String& address, WebInputStream::Listener* listener) | ||||
| { | { | ||||
| const TCHAR* mimeTypes[] = { _T("*/*"), nullptr }; | const TCHAR* mimeTypes[] = { _T("*/*"), nullptr }; | ||||
| @@ -365,43 +394,29 @@ private: | |||||
| if (request != 0) | if (request != 0) | ||||
| { | { | ||||
| INTERNET_BUFFERS buffers = { 0 }; | INTERNET_BUFFERS buffers = { 0 }; | ||||
| buffers.dwStructSize = sizeof (INTERNET_BUFFERS); | |||||
| buffers.lpcszHeader = headers.toWideCharPointer(); | |||||
| buffers.dwStructSize = sizeof (INTERNET_BUFFERS); | |||||
| buffers.lpcszHeader = headers.toWideCharPointer(); | |||||
| buffers.dwHeadersLength = (DWORD) headers.length(); | buffers.dwHeadersLength = (DWORD) headers.length(); | ||||
| buffers.dwBufferTotal = (DWORD) postData.getSize(); | |||||
| buffers.dwBufferTotal = (DWORD) postData.getSize(); | |||||
| if (HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0)) | |||||
| auto sendRequestAndTryEnd = [this, &buffers, &listener]() -> bool | |||||
| { | { | ||||
| int bytesSent = 0; | |||||
| sendHTTPRequest (buffers, listener); | |||||
| for (;;) | |||||
| { | |||||
| const int bytesToDo = jmin (1024, (int) postData.getSize() - bytesSent); | |||||
| DWORD bytesDone = 0; | |||||
| if (HttpEndRequest (request, 0, 0, 0)) | |||||
| return true; | |||||
| if (bytesToDo > 0 | |||||
| && ! InternetWriteFile (request, | |||||
| static_cast<const char*> (postData.getData()) + bytesSent, | |||||
| (DWORD) bytesToDo, &bytesDone)) | |||||
| { | |||||
| break; | |||||
| } | |||||
| if (bytesToDo == 0 || (int) bytesDone < bytesToDo) | |||||
| { | |||||
| if (HttpEndRequest (request, 0, 0, 0)) | |||||
| return; | |||||
| return false; | |||||
| }; | |||||
| break; | |||||
| } | |||||
| auto closed = sendRequestAndTryEnd(); | |||||
| bytesSent += bytesDone; | |||||
| // N.B. this is needed for some authenticated HTTP connections | |||||
| if (! closed && GetLastError() == ERROR_INTERNET_FORCE_RETRY) | |||||
| closed = sendRequestAndTryEnd(); | |||||
| if (listener != nullptr | |||||
| && ! listener->postDataSendProgress (owner, bytesSent, (int) postData.getSize())) | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (closed) | |||||
| return; | |||||
| } | } | ||||
| closeConnection(); | closeConnection(); | ||||