Signed-off-by: Daniel Lehman <dlehman25(a)gmail.com>
---
not sure how to add a permanent standalone test for this
because of how long it runs, but i tested it locally:
1) create a file > 4GB:
sudo dd if=/dev/zero of=/var/lib/tomcat8/webapps/ROOT/6GBFILE bs=1G count=6
2) add wininet test (run on Ubuntu 18.04.3 and Win10 1903):
- wine/dlls/wininet/tests/http.c
static void test_large_file(void)
{
BOOL res;
DWORD nread;
DWORD64 sum;
HINTERNET session;
HINTERNET request;
HINTERNET connection;
const char *types[2] = { "*", NULL };
char buffer[65536] = {0};
session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
ok(!!session, "failed gle %d\n", GetLastError());
connection = InternetConnectA(session,
"192.168.2.242", 8080,
NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
ok(!!connection, "failed gle %d\n", GetLastError());
request = HttpOpenRequestA(connection, "GET", "/6GBFILE", NULL, NULL, types,
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
0xdeadbead);
ok(!!request, "failed gle %d\n", GetLastError());
res = HttpSendRequestA(request, "", -1, NULL, 0);
ok(res, "failed gle %d\n", GetLastError());
sum = 0;
nread = 0;
do
{
res = InternetReadFile(request, buffer, sizeof(buffer), &nread);
ok(res, "failed gle %d\n", GetLastError());
sum += nread;
} while (nread > 0);
ok(sum == (DWORD64)0x180000000, "failed to read all bytes: %x%08x\n",
(DWORD)(sum >> 32), (DWORD)sum);
InternetCloseHandle(request);
InternetCloseHandle(connection);
InternetCloseHandle(session);
}
Signed-off-by: Daniel Lehman <dlehman25(a)gmail.com>
---
dlls/wininet/http.c | 28 ++++++++++++++++++----------
dlls/wininet/internet.h | 6 +++---
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 538fc2bf6b..871418e2e3 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -2440,7 +2440,7 @@ static void create_cache_entry(http_request_t *req)
return;
}
- b = CreateUrlCacheEntryW(url, req->contentLength == ~0u ? 0 : req->contentLength, NULL, file_name, 0);
+ b = CreateUrlCacheEntryW(url, req->contentLength == ~0 ? 0 : req->contentLength, NULL, file_name, 0);
if(!b) {
WARN("Could not create cache entry: %08x\n", GetLastError());
return;
@@ -2644,7 +2644,7 @@ static DWORD netconn_drain_content(data_stream_t *stream, http_request_t *req, B
int len, res;
size_t size;
- if(netconn_stream->content_length == ~0u)
+ if(netconn_stream->content_length == ~0)
return WSAEISCONN;
while(netconn_stream->content_read < netconn_stream->content_length) {
@@ -2750,7 +2750,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
TRACE("reading %u byte chunk\n", chunked_stream->chunk_size);
chunked_stream->buf_size++;
chunked_stream->buf_pos--;
- if(req->contentLength == ~0u) req->contentLength = chunked_stream->chunk_size;
+ if(req->contentLength == ~0) req->contentLength = chunked_stream->chunk_size;
else req->contentLength += chunked_stream->chunk_size;
chunked_stream->state = CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE;
}
@@ -2883,7 +2883,7 @@ static DWORD set_content_length(http_request_t *request)
size = sizeof(request->contentLength);
if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
&request->contentLength, &size, NULL) != ERROR_SUCCESS)
- request->contentLength = ~0u;
+ request->contentLength = ~0;
request->netconn_stream.content_length = request->contentLength;
request->netconn_stream.content_read = request->read_size;
@@ -2909,7 +2909,7 @@ static DWORD set_content_length(http_request_t *request)
}
request->data_stream = &chunked_stream->data_stream;
- request->contentLength = ~0u;
+ request->contentLength = ~0;
}
if(request->hdr.decoding) {
@@ -3299,7 +3299,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
request->hdr.dwFlags = dwFlags;
request->hdr.dwContext = dwContext;
request->hdr.decoding = session->hdr.decoding;
- request->contentLength = ~0u;
+ request->contentLength = ~0;
request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl;
request->data_stream = &request->netconn_stream.data_stream;
@@ -3724,9 +3724,17 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
/* coalesce value to requested type */
if (dwInfoLevel & HTTP_QUERY_FLAG_NUMBER && lpBuffer)
{
- *(int *)lpBuffer = atoiW(lphttpHdr->lpszValue);
- TRACE(" returning number: %d\n", *(int *)lpBuffer);
- }
+ if (*lpdwBufferLength == sizeof(ULONGLONG))
+ {
+ *(ULONGLONG *)lpBuffer = strtoulW(lphttpHdr->lpszValue, NULL, 10);
+ TRACE(" returning number: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)lpBuffer));
+ }
+ else
+ {
+ *(int *)lpBuffer = atoiW(lphttpHdr->lpszValue);
+ TRACE(" returning number: %d\n", *(int *)lpBuffer);
+ }
+ }
else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer)
{
time_t tmpTime;
@@ -4907,7 +4915,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
loop_next = FALSE;
if(redirected) {
- request->contentLength = ~0u;
+ request->contentLength = ~0;
request->bytesToWrite = 0;
}
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index f712fb6b64..40e51bec32 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -335,8 +335,8 @@ typedef struct {
typedef struct {
data_stream_t data_stream;
- DWORD content_length;
- DWORD content_read;
+ ULONGLONG content_length;
+ ULONGLONG content_read;
} netconn_stream_t;
#define READ_BUFFER_SIZE 8192
@@ -372,7 +372,7 @@ typedef struct
struct HttpAuthInfo *proxyAuthInfo;
CRITICAL_SECTION read_section; /* section to protect the following fields */
- DWORD contentLength; /* total number of bytes to be read */
+ ULONGLONG contentLength; /* total number of bytes to be read */
BOOL read_gzip; /* are we reading in gzip mode? */
DWORD read_pos; /* current read position in read_buf */
DWORD read_size; /* valid data size in read_buf */
--
2.17.1