winhttp: Don't try to read data when the server response is HTTP_STATUS_NO_CONTENT or HTTP_STATUS_NOT_MODIFIED.
Tests based on a patch by Bruno Jesus.
This commit is contained in:
parent
97cd0291b0
commit
2087a9fbe9
|
@ -1802,14 +1802,15 @@ static BOOL handle_authorization( request_t *request, DWORD status )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the request content length based on the headers */
|
/* set the request content length based on the headers */
|
||||||
static DWORD set_content_length( request_t *request )
|
static DWORD set_content_length( request_t *request, DWORD status )
|
||||||
{
|
{
|
||||||
WCHAR encoding[20];
|
WCHAR encoding[20];
|
||||||
DWORD buflen;
|
DWORD buflen = sizeof(request->content_length);
|
||||||
|
|
||||||
buflen = sizeof(request->content_length);
|
if (status == HTTP_STATUS_NO_CONTENT || status == HTTP_STATUS_NOT_MODIFIED)
|
||||||
if (!query_headers( request, WINHTTP_QUERY_CONTENT_LENGTH|WINHTTP_QUERY_FLAG_NUMBER,
|
request->content_length = 0;
|
||||||
NULL, &request->content_length, &buflen, NULL ))
|
else if (!query_headers( request, WINHTTP_QUERY_CONTENT_LENGTH|WINHTTP_QUERY_FLAG_NUMBER,
|
||||||
|
NULL, &request->content_length, &buflen, NULL ))
|
||||||
request->content_length = ~0u;
|
request->content_length = ~0u;
|
||||||
|
|
||||||
buflen = sizeof(encoding);
|
buflen = sizeof(encoding);
|
||||||
|
@ -2302,7 +2303,7 @@ static BOOL receive_response( request_t *request, BOOL async )
|
||||||
query = WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER;
|
query = WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER;
|
||||||
if (!(ret = query_headers( request, query, NULL, &status, &size, NULL ))) break;
|
if (!(ret = query_headers( request, query, NULL, &status, &size, NULL ))) break;
|
||||||
|
|
||||||
set_content_length( request );
|
set_content_length( request, status );
|
||||||
|
|
||||||
if (!(request->hdr.disable_flags & WINHTTP_DISABLE_COOKIES)) record_cookies( request );
|
if (!(request->hdr.disable_flags & WINHTTP_DISABLE_COOKIES)) record_cookies( request );
|
||||||
|
|
||||||
|
@ -2329,7 +2330,7 @@ static BOOL receive_response( request_t *request, BOOL async )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) refill_buffer( request, FALSE );
|
if (request->content_length) refill_buffer( request, FALSE );
|
||||||
|
|
||||||
if (async)
|
if (async)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1801,6 +1801,10 @@ static const char nocontentmsg[] =
|
||||||
"Server: winetest\r\n"
|
"Server: winetest\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
static const char notmodified[] =
|
||||||
|
"HTTP/1.1 304 Not Modified\r\n"
|
||||||
|
"\r\n";
|
||||||
|
|
||||||
static const char noauthmsg[] =
|
static const char noauthmsg[] =
|
||||||
"HTTP/1.1 401 Unauthorized\r\n"
|
"HTTP/1.1 401 Unauthorized\r\n"
|
||||||
"Server: winetest\r\n"
|
"Server: winetest\r\n"
|
||||||
|
@ -1888,6 +1892,11 @@ static DWORD CALLBACK server_thread(LPVOID param)
|
||||||
{
|
{
|
||||||
send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
|
send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
|
||||||
}
|
}
|
||||||
|
if (strstr(buffer, "GET /not_modified"))
|
||||||
|
{
|
||||||
|
send(c, notmodified, sizeof notmodified - 1, 0);
|
||||||
|
Sleep(6000);
|
||||||
|
}
|
||||||
if (strstr(buffer, "GET /quit"))
|
if (strstr(buffer, "GET /quit"))
|
||||||
{
|
{
|
||||||
send(c, okmsg, sizeof okmsg - 1, 0);
|
send(c, okmsg, sizeof okmsg - 1, 0);
|
||||||
|
@ -2129,7 +2138,7 @@ static void test_no_content(int port)
|
||||||
{
|
{
|
||||||
static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
|
static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
|
||||||
HINTERNET ses, con, req;
|
HINTERNET ses, con, req;
|
||||||
WCHAR buf[128];
|
char buf[128];
|
||||||
DWORD size, len = sizeof(buf), bytes_read, status;
|
DWORD size, len = sizeof(buf), bytes_read, status;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
|
@ -2181,6 +2190,7 @@ static void test_no_content(int port)
|
||||||
ok(size == 0, "expected 0, got %d\n", size);
|
ok(size == 0, "expected 0, got %d\n", size);
|
||||||
|
|
||||||
ret = WinHttpReadData(req, buf, len, &bytes_read);
|
ret = WinHttpReadData(req, buf, len, &bytes_read);
|
||||||
|
ok(ret, "expected success\n");
|
||||||
ok( bytes_read == 0, "expected 0, got %u available\n", bytes_read );
|
ok( bytes_read == 0, "expected 0, got %u available\n", bytes_read );
|
||||||
|
|
||||||
size = 12345;
|
size = 12345;
|
||||||
|
@ -2202,6 +2212,55 @@ static void test_no_content(int port)
|
||||||
WinHttpCloseHandle(ses);
|
WinHttpCloseHandle(ses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_not_modified(int port)
|
||||||
|
{
|
||||||
|
static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
|
||||||
|
static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
|
||||||
|
BOOL ret;
|
||||||
|
HINTERNET session, request, connection;
|
||||||
|
DWORD status, size, start = GetTickCount();
|
||||||
|
SYSTEMTIME st;
|
||||||
|
WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3];
|
||||||
|
|
||||||
|
memcpy(today, ifmodifiedW, sizeof(ifmodifiedW));
|
||||||
|
GetSystemTime(&st);
|
||||||
|
WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]);
|
||||||
|
|
||||||
|
session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||||
|
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
||||||
|
ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
connection = WinHttpConnect(session, localhostW, port, 0);
|
||||||
|
ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER,
|
||||||
|
WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
|
||||||
|
ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = WinHttpSendRequest(request, today, ~0u, NULL, 0, 0, 0);
|
||||||
|
ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = WinHttpReceiveResponse(request, NULL);
|
||||||
|
ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
size = sizeof(status);
|
||||||
|
ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
|
||||||
|
NULL, &status, &size, NULL);
|
||||||
|
ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
|
||||||
|
ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status);
|
||||||
|
|
||||||
|
size = 0xdeadbeef;
|
||||||
|
ret = WinHttpQueryDataAvailable(request, &size);
|
||||||
|
ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
|
||||||
|
ok(!size, "got %u\n", size);
|
||||||
|
|
||||||
|
WinHttpCloseHandle(request);
|
||||||
|
WinHttpCloseHandle(connection);
|
||||||
|
WinHttpCloseHandle(session);
|
||||||
|
start = GetTickCount() - start;
|
||||||
|
ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_bad_header( int port )
|
static void test_bad_header( int port )
|
||||||
{
|
{
|
||||||
static const WCHAR bad_headerW[] =
|
static const WCHAR bad_headerW[] =
|
||||||
|
@ -3211,6 +3270,7 @@ START_TEST (winhttp)
|
||||||
test_basic_request(si.port, NULL, basicW);
|
test_basic_request(si.port, NULL, basicW);
|
||||||
test_no_headers(si.port);
|
test_no_headers(si.port);
|
||||||
test_no_content(si.port);
|
test_no_content(si.port);
|
||||||
|
test_not_modified(si.port);
|
||||||
test_basic_authentication(si.port);
|
test_basic_authentication(si.port);
|
||||||
test_bad_header(si.port);
|
test_bad_header(si.port);
|
||||||
test_multiple_reads(si.port);
|
test_multiple_reads(si.port);
|
||||||
|
|
Loading…
Reference in New Issue