#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include "windef.h"
#include "winbase.h"
static int strcmp_wa(LPCWSTR strw, const char *stra)
{
WCHAR buf[512];
- MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
return lstrcmpW(strw, buf);
}
DWORD dwStatusInformationLength
)
{
+ ros_skip_flaky
CHECK_EXPECT(dwInternetStatus);
switch (dwInternetStatus)
{
length = sizeof(buffer)-2;
memset(buffer, 0x77, sizeof(buffer));
+ SetLastError(0xdeadbeef);
res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length,0x0);
ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
+ ok(GetLastError() == 0 ||
+ broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
/* show that the function writes data past the length returned */
ok(buffer[length-2], "Expected any header character, got 0x00\n");
ok(!buffer[length-1], "Expected 0x00, got %02X\n", buffer[length-1]);
{
char *buffer = HeapAlloc(GetProcessHeap(),0,length+1);
+ SetLastError(0xdeadbeef);
res = InternetReadFile(hor,buffer,length,&got);
+ ok(GetLastError() == 0 ||
+ broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
buffer[got]=0;
trace("ReadFile -> %i %i\n",res,got);
if (length == 0)
{
got = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
res = InternetReadFile( hor, buffer, 1, &got );
ok( res, "InternetReadFile failed: %u\n", GetLastError() );
+ ok(GetLastError() == 0 ||
+ broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
ok( !got, "got %u\n", got );
break;
}
"Server: winetest\r\n"
"\r\n";
+static const char okmsg201[] =
+"HTTP/1.1 201 OK\r\n"
+"Server: winetest\r\n"
+"\r\n";
+
static const char okmsg2[] =
"HTTP/1.1 200 OK\r\n"
"Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
"Set-Cookie: two\r\n"
"\r\n";
+static DWORD64 content_length;
+static const char largemsg[] =
+"HTTP/1.1 200 OK\r\n"
+"Content-Length: %I64u\r\n"
+"\r\n";
+
static const char okmsg_cookie_path[] =
"HTTP/1.1 200 OK\r\n"
"Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
else
send(c, notokmsg, sizeof notokmsg-1, 0);
}
+ if (strstr(buffer, "HEAD /upload3.txt"))
+ {
+ if (strstr(buffer, "Authorization: Basic dXNlcjE6cHdkMQ=="))
+ send(c, okmsg, sizeof okmsg-1, 0);
+ else
+ send(c, noauthmsg, sizeof noauthmsg-1, 0);
+ }
+ if (strstr(buffer, "HEAD /upload4.txt"))
+ {
+ if (strstr(buffer, "Authorization: Bearer dXNlcjE6cHdkMQ=="))
+ send(c, okmsg, sizeof okmsg-1, 0);
+ else if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
+ send(c, okmsg201, sizeof okmsg-1, 0);
+ else
+ send(c, noauthmsg, sizeof noauthmsg-1, 0);
+ }
if (strstr(buffer, "/test_cookie_path1"))
{
if (strstr(buffer, "subcookie=data"))
{
send(c, okmsg, sizeof(okmsg)-1, 0);
}
+
+ if (strstr(buffer, "HEAD /test_large_content"))
+ {
+ char msg[sizeof(largemsg) + 16];
+ sprintf(msg, largemsg, content_length);
+ send(c, msg, strlen(msg), 0);
+ }
if (strstr(buffer, "HEAD /test_auth_host1"))
{
if (strstr(buffer, "Authorization: Basic dGVzdDE6cGFzcw=="))
len = sizeof(content_length);
content_length = -1;
ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &content_length, &len, 0);
- ok(ret, "HttpQueryInfo dailed: %u\n", GetLastError());
+ ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
ok(len == sizeof(DWORD), "len = %u\n", len);
ok(content_length == 100, "content_length = %u\n", content_length);
DWORD i, size;
BOOL res;
- for(i=0; i < sizeof(http_status_tests)/sizeof(*http_status_tests); i++) {
+ for(i = 0; i < ARRAY_SIZE(http_status_tests); i++) {
send_buffer = http_status_tests[i].response_text;
open_simple_request(&req, "localhost", port, NULL, "/send_from_buffer");
HINTERNET ses, con, req;
DWORD status, size;
BOOL ret;
+ char buffer[0x40];
ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
ok( ses != NULL, "InternetOpenA failed\n" );
ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "user"), "got %s\n", buffer);
+ ok(size == 4, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
+ ok(size == 3, "got %u\n", size);
+
status = 0xdeadbeef;
size = sizeof(status);
ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "user"), "got %s\n", buffer);
+ ok(size == 4, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
+ ok(size == 3, "got %u\n", size);
+
status = 0xdeadbeef;
size = sizeof(status);
ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
InternetCloseHandle( ses );
}
+static void test_basic_auth_credentials_end_session(int port)
+{
+ HINTERNET ses, con, req;
+ DWORD status, size;
+ BOOL ret;
+ char buffer[0x40];
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, "user", "pwd",
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "user"), "got %s\n", buffer);
+ ok(size == 4, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
+ ok(size == 3, "got %u\n", size);
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == HTTP_STATUS_OK, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ /* Clear the cached credentials */
+ ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL,
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "PUT", "/upload2.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, ""), "got %s\n", buffer);
+ ok(size == 0, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, ""), "got %s\n", buffer);
+ ok(size == 0, "got %u\n", size);
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+}
+
+static void test_basic_auth_credentials_different(int port)
+{
+ HINTERNET ses, con, req;
+ DWORD status, size;
+ BOOL ret;
+ char buffer[0x40];
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, "user", "pwd",
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "user"), "got %s\n", buffer);
+ ok(size == 4, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
+ ok(size == 3, "got %u\n", size);
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 200, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, "user1", "pwd1",
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload3.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "user1"), "got %s\n", buffer);
+ ok(size == 5, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "pwd1"), "got %s\n", buffer);
+ ok(size == 4, "got %u\n", size);
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 200, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+}
+
+/*
+ * Manually set the Authorization for both calls.
+ */
+static void test_basic_auth_credentials_manual(int port)
+{
+ HINTERNET ses, con, req;
+ DWORD status, size;
+ BOOL ret;
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ /* Clear the cached credentials */
+ ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ /* Set Authorization Header */
+ ret = HttpAddRequestHeadersA(req, "Authorization: Basic dXNlcjpwd2Q=\r\n", ~0u,
+ HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
+ ok(ret, "HttpAddRequestHeaders Failed\n");
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 200, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+
+ /* Show manual headers are cached. */
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 401, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload4.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ /* Set Authorization Header */
+ ret = HttpAddRequestHeadersA(req, "Authorization: Bearer dXNlcjE6cHdkMQ==\r\n", ~0u,
+ HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
+ ok(ret, "HttpAddRequestHeaders Failed\n");
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 200, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+}
+
+/*
+ * Manually set the Authorization for the bearer call, which shows the cached is used.
+ */
+static void test_basic_auth_credentials_cached_manual(int port)
+{
+ HINTERNET ses, con, req;
+ DWORD status, size;
+ BOOL ret;
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ /* Clear the cached credentials */
+ ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+
+ con = InternetConnectA( ses, "localhost", port, "user", "pwd",
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 200, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload4.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ /* Setting an Authorization Header doesn't override the cached one. */
+ ret = HttpAddRequestHeadersA(req, "Authorization: Bearer dXNlcjE6cHdkMQ==\r\n", ~0u,
+ HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
+ ok(ret, "HttpAddRequestHeaders Failed\n");
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == 201, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+}
+
static void test_async_read(int port)
{
HINTERNET ses, con, req;
ret = InternetReadFileExA( req, &ib, 0, 0xdeadbeef );
if (!count) /* the first part should arrive immediately */
ok( ret, "InternetReadFileExA failed %u\n", GetLastError() );
+ ros_skip_flaky
if (!ret)
{
ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+ ros_skip_flaky
CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
if (!pending_reads++)
{
ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
ok( bytes == 0, "expected 0, got %u\n", bytes );
+ ros_skip_flaky
CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
if (!pending_reads++)
res = WaitForSingleObject( complete_event, INFINITE );
ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res );
ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
+ ros_skip_flaky {
todo_wine_if( pending_reads > 1 )
ok( bytes != 0, "expected bytes != 0\n" );
+ }
+ ros_skip_flaky
CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+ ros_skip_flaky
CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
}
if (!bytes) break;
}
+ ros_skip_flaky
ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads );
ok( !strcmp(buffer, page1), "unexpected buffer content\n" );
close_async_handle( ses, 2 );
close_request(&req);
}
+struct large_test
+{
+ DWORD64 content_length;
+ BOOL ret;
+};
+
+static void test_large_content(int port)
+{
+ struct large_test tests[] = {
+ { 0, TRUE },
+ { UINT_MAX-1, TRUE },
+ { UINT_MAX, TRUE },
+ { (DWORD64)UINT_MAX+1, FALSE },
+ { ~0, FALSE },
+ };
+ test_request_t req;
+ DWORD sizelen, len;
+ DWORD read_size;
+ DWORD64 len64;
+ char buf[16];
+ BOOL ret;
+ size_t i;
+
+ open_simple_request(&req, "localhost", port, "HEAD", "/test_large_content");
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ content_length = tests[i].content_length;
+ ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
+ ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
+
+ len = ~0;
+ sizelen = sizeof(len);
+ SetLastError(0xdeadbeef);
+ ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
+ &len, &sizelen, 0);
+ if (tests[i].ret)
+ {
+ ok(ret, "HttpQueryInfo should have succeeded\n");
+ ok(GetLastError() == ERROR_SUCCESS ||
+ broken(GetLastError() == 0xdeadbeef), /* xp, 2k8, vista */
+ "expected ERROR_SUCCESS, got %x\n", GetLastError());
+ ok(len == (DWORD)tests[i].content_length, "expected %u, got %u\n",
+ (DWORD)tests[i].content_length, len);
+ }
+ else
+ {
+ ok(!ret, "HttpQueryInfo should have failed\n");
+ ok(GetLastError() == ERROR_HTTP_INVALID_HEADER,
+ "expected ERROR_HTTP_INVALID_HEADER, got %x\n", GetLastError());
+ ok(len == ~0, "expected ~0, got %u\n", len);
+ }
+ ok(sizelen == sizeof(DWORD), "sizelen %u\n", sizelen);
+ }
+
+ /* test argument size */
+ len64 = ~0;
+ sizelen = sizeof(len64);
+ SetLastError(0xdeadbeef);
+ ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
+ &len64, &len, 0);
+ ok(!ret, "HttpQueryInfo should have failed\n");
+ ok(GetLastError() == ERROR_HTTP_INVALID_HEADER,
+ "expected ERROR_HTTP_INVALID_HEADER, got %x\n", GetLastError());
+ ok(sizelen == sizeof(DWORD64), "sizelen %u\n", sizelen);
+ ok(len64 == ~0, "len64 %x%08x\n", (DWORD)(len64 >> 32), (DWORD)len64);
+
+ close_request(&req);
+
+ /* test internal use of HttpQueryInfo on large size */
+ open_read_test_request(port, &req,
+ "HTTP/1.1 200 OK\r\n"
+ "Server: winetest\r\n"
+ "Content-Length: 4294967296\r\n"
+ "\r\n"
+ "xx");
+ read_expect_async(req.request, buf, 4, &read_size, "xx");
+ send_response_and_wait("yy1234567890", FALSE, buf, &read_size, "xxyy", 4, 0, 2);
+ read_expect_sync_data(req.request, buf, 10, "1234567890");
+
+ SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
+ SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
+ close_async_handle(req.session, 2);
+ CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
+ CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
+ close_connection();
+}
+
static void test_http_connection(void)
{
struct server_info si;
si.hEvent = CreateEventW(NULL, 0, 0, NULL);
si.port = 7531;
- hThread = CreateThread(NULL, 0, server_thread, (LPVOID) &si, 0, &id);
+ hThread = CreateThread(NULL, 0, server_thread, &si, 0, &id);
ok( hThread != NULL, "create thread failed\n");
r = WaitForSingleObject(si.hEvent, 10000);
test_request_content_length(si.port);
test_accept_encoding(si.port);
test_basic_auth_credentials_reuse(si.port);
+ test_basic_auth_credentials_end_session(si.port);
+ test_basic_auth_credentials_different(si.port);
+ test_basic_auth_credentials_manual(si.port);
+ test_basic_auth_credentials_cached_manual(si.port);
test_async_read(si.port);
test_http_read(si.port);
test_connection_break(si.port);
}
#endif
test_remove_dot_segments(si.port);
+ test_large_content(si.port);
/* send the basic request again to shutdown the server thread */
test_basic_request(si.port, "GET", "/quit");
} cert_struct_test_t;
static const cert_struct_test_t test_winehq_org_cert = {
+ "US\r\n"
+ "55114\r\n"
+ "MN\r\n"
+ "Saint Paul\r\n"
+ "Ste 120\r\n"
+ "700 Raymond Ave\r\n"
+ "CodeWeavers\r\n"
+ "IT\r\n"
+ "Secure Link SSL Wildcard\r\n"
"*.winehq.org",
"US\r\n"
- "GeoTrust Inc.\r\n"
- "RapidSSL SHA256 CA"
+ "VA\r\n"
+ "Herndon\r\n"
+ "Network Solutions L.L.C.\r\n"
+ "Network Solutions OV Server CA 2"
};
static const cert_struct_test_t test_winehq_com_cert = {
"Minnesota\r\n"
"Saint Paul\r\n"
"WineHQ\r\n"
+ "IT\r\n"
"test.winehq.com\r\n"
"webmaster@winehq.org",
"US\r\n"
"Minnesota\r\n"
+ "Saint Paul\r\n"
"WineHQ\r\n"
+ "IT\r\n"
"test.winehq.com\r\n"
"webmaster@winehq.org"
};
size = sizeof(info);
res = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size);
+ if (!res)
+ {
+ win_skip("Querying INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT failed, skipping tests\n");
+ return;
+ }
+
ok(res, "InternetQueryOption failed: %u\n", GetLastError());
ok(size == sizeof(info), "size = %u\n", size);
ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
WaitForSingleObject(complete_event, INFINITE);
- ok(req_error == ERROR_INTERNET_SEC_CERT_REV_FAILED || broken(req_error == ERROR_INTERNET_SEC_CERT_ERRORS),
+ ok(req_error == ERROR_INTERNET_SEC_CERT_ERRORS,
"req_error = %d\n", req_error);
size = 0;
ok(!cert->lpszEncryptionAlgName, "unexpected encryption algorithm name\n");
ok(!cert->lpszProtocolName, "unexpected protocol name\n");
ok(cert->dwKeySize != 0xdeadbeef, "unexpected key size\n");
+
+ LocalFree(cert->lpszSubjectInfo);
+ LocalFree(cert->lpszIssuerInfo);
}
HeapFree(GetProcessHeap(), 0, cert);
+ ros_skip_flaky
CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
- if(req_error != ERROR_INTERNET_SEC_CERT_REV_FAILED) {
+ if(req_error != ERROR_INTERNET_SEC_CERT_ERRORS) {
win_skip("Unexpected cert errors %u, skipping security flags tests\n", req_error);
close_async_handle(ses, 3);
test_request_flags(req, 8);
/* IE11 finds both rev failure and invalid CA. Previous versions required rev failure
to be ignored before invalid CA was reported. */
- test_secflags_option(req, _SECURITY_FLAG_CERT_REV_FAILED, _SECURITY_FLAG_CERT_INVALID_CA);
+ test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA, _SECURITY_FLAG_CERT_REV_FAILED);
set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_REVOCATION);
- test_secflags_option(req, _SECURITY_FLAG_CERT_REV_FAILED|SECURITY_FLAG_IGNORE_REVOCATION, _SECURITY_FLAG_CERT_INVALID_CA);
+ test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA|SECURITY_FLAG_IGNORE_REVOCATION, _SECURITY_FLAG_CERT_REV_FAILED);
SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
WaitForSingleObject(complete_event, INFINITE);
- ok(req_error == ERROR_INTERNET_SEC_CERT_ERRORS, "req_error = %d\n", req_error);
+ ok(req_error == ERROR_INTERNET_INVALID_CA || req_error == ERROR_INTERNET_SEC_CERT_ERRORS, "req_error = %d\n", req_error);
CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
test_request_flags(req, INTERNET_REQFLAG_NO_HEADERS);
- test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_REV_FAILED|_SECURITY_FLAG_CERT_INVALID_CA, 0);
+ test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
test_security_info("https://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_UNKNOWN_CA);
- test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA|_SECURITY_FLAG_CERT_REV_FAILED
+ test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA
|SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_UNKNOWN_CA, 0);
test_http_version(req);
test_request_flags(req, 0);
test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION
- |SECURITY_FLAG_STRENGTH_STRONG|_SECURITY_FLAG_CERT_REV_FAILED|_SECURITY_FLAG_CERT_INVALID_CA, 0);
+ |SECURITY_FLAG_STRENGTH_STRONG|_SECURITY_FLAG_CERT_INVALID_CA, 0);
test_cert_struct(req, &test_winehq_com_cert);
test_security_info("https://test.winehq.com/data/some_file.html?q", 0,
- _SECURITY_FLAG_CERT_INVALID_CA|_SECURITY_FLAG_CERT_REV_FAILED);
+ _SECURITY_FLAG_CERT_INVALID_CA);
res = InternetReadFile(req, buf, sizeof(buf), &size);
ok(res, "InternetReadFile failed: %u\n", GetLastError());
CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_STRENGTH_STRONG
- |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_REV_FAILED|_SECURITY_FLAG_CERT_INVALID_CA, 0);
+ |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
test_http_version(req);
SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
test_request_flags(req, 0);
test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_STRENGTH_STRONG
- |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_REV_FAILED|_SECURITY_FLAG_CERT_INVALID_CA, 0);
+ |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
res = InternetReadFile(req, buf, sizeof(buf), &size);
ok(res, "InternetReadFile failed: %u\n", GetLastError());
static const struct notification_data notification_data[] = {
{
async_send_request_ex_chunked_test,
- sizeof(async_send_request_ex_chunked_test)/sizeof(async_send_request_ex_chunked_test[0]),
+ ARRAY_SIZE(async_send_request_ex_chunked_test),
"GET",
"test.winehq.org",
"tests/data.php"
},
{
async_send_request_ex_test,
- sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
+ ARRAY_SIZE(async_send_request_ex_test),
"POST",
"test.winehq.org",
"tests/post.php",
},
{
async_send_request_ex_test2,
- sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
+ ARRAY_SIZE(async_send_request_ex_test2),
"POST",
"test.winehq.org",
"tests/post.php"
},
{
async_send_request_ex_resolve_failure_test,
- sizeof(async_send_request_ex_resolve_failure_test)/sizeof(async_send_request_ex_resolve_failure_test[0]),
+ ARRAY_SIZE(async_send_request_ex_resolve_failure_test),
"GET",
"brokenhost",
"index.html",