wininet-HTTPREQ_ReadFile_Async: Update patchset and add initial tests.

This commit is contained in:
Sebastian Lackner 2016-04-27 08:39:35 +02:00
parent 8ae9a00d2e
commit 0d846617c9
7 changed files with 347 additions and 36 deletions

View File

@ -1971,6 +1971,13 @@ if test "$enable_wpcap_Dynamic_Linking" -eq 1; then
enable_wpcap_Several_Fixes=1
fi
if test "$enable_wininet_Cleanup" -eq 1; then
if test "$enable_wininet_HTTPREQ_ReadFile_Async" -gt 1; then
abort "Patchset wininet-HTTPREQ_ReadFile_Async disabled, but wininet-Cleanup depends on that."
fi
enable_wininet_HTTPREQ_ReadFile_Async=1
fi
if test "$enable_wined3d_CSMT_Helper" -eq 1; then
if test "$enable_makedep_PARENTSPEC" -gt 1; then
abort "Patchset makedep-PARENTSPEC disabled, but wined3d-CSMT_Helper depends on that."
@ -7424,8 +7431,29 @@ if test "$enable_winhttp_System_Proxy_Autoconfig" -eq 1; then
) >> "$patchlist"
fi
# Patchset wininet-HTTPREQ_ReadFile_Async
# |
# | Modified files:
# | * dlls/wininet/http.c, dlls/wininet/tests/http.c
# |
if test "$enable_wininet_HTTPREQ_ReadFile_Async" -eq 1; then
patch_apply wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.-resen.patch
patch_apply wininet-HTTPREQ_ReadFile_Async/0002-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch
patch_apply wininet-HTTPREQ_ReadFile_Async/0003-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.-resen.patch
patch_apply wininet-HTTPREQ_ReadFile_Async/0004-wininet-tests-Add-tests-for-asynchronous-InternetRea.patch
(
echo '+ { "Michael Müller", "wininet: Fix async check in HTTPREQ_ReadFileEx.", 1 },';
echo '+ { "Sebastian Lackner", "wininet/tests: Add tests for asynchronous InternetReadFileEx.", 3 },';
echo '+ { "Michael Müller", "wininet: Handle async mode in HTTPREQ_ReadFile.", 1 },';
echo '+ { "Sebastian Lackner", "wininet/tests: Add tests for asynchronous InternetReadFile.", 3 },';
) >> "$patchlist"
fi
# Patchset wininet-Cleanup
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * wininet-HTTPREQ_ReadFile_Async
# |
# | Modified files:
# | * dlls/wininet/http.c, dlls/wininet/tests/http.c
# |
@ -7444,20 +7472,6 @@ if test "$enable_wininet_Cleanup" -eq 1; then
) >> "$patchlist"
fi
# Patchset wininet-HTTPREQ_ReadFile_Async
# |
# | Modified files:
# | * dlls/wininet/http.c
# |
if test "$enable_wininet_HTTPREQ_ReadFile_Async" -eq 1; then
patch_apply wininet-HTTPREQ_ReadFile_Async/0001-wininet-Fix-async-check-in-HTTPREQ_ReadFileEx.patch
patch_apply wininet-HTTPREQ_ReadFile_Async/0002-wininet-Handle-async-mode-in-HTTPREQ_ReadFile.patch
(
echo '+ { "Michael Müller", "wininet: Fix async check in HTTPREQ_ReadFileEx.", 1 },';
echo '+ { "Michael Müller", "wininet: Handle async mode in HTTPREQ_ReadFile.", 1 },';
) >> "$patchlist"
fi
# Patchset wininet-HttpOpenRequestW
# |
# | This patchset fixes the following Wine bugs:

View File

@ -1,4 +1,4 @@
From 5049ef6fb20ab57cfe18209df3deee1bf1c5d069 Mon Sep 17 00:00:00 2001
From 284cf431a6dc5ba77356c0103098f4009cb498eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 15 May 2015 21:18:37 +0200
Subject: wininet/tests: Test auth credential reusage with host override.
@ -8,12 +8,12 @@ Subject: wininet/tests: Test auth credential reusage with host override.
1 file changed, 92 insertions(+)
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 559ab3e..29abb2f 100644
index 16773e6..a6e860b 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -2394,6 +2394,20 @@ static DWORD CALLBACK server_thread(LPVOID param)
else
send(c, notokmsg, sizeof notokmsg-1, 0);
@@ -2401,6 +2401,20 @@ static DWORD CALLBACK server_thread(LPVOID param)
WaitForSingleObject(conn_wait_event, INFINITE);
send(c, page1_mid, page1_end - page1_mid, 0);
}
+ if (strstr(buffer, "HEAD /test_auth_host1"))
+ {
@ -32,7 +32,7 @@ index 559ab3e..29abb2f 100644
shutdown(c, 2);
closesocket(c);
c = -1;
@@ -3086,6 +3100,84 @@ static void test_header_override(int port)
@@ -3112,6 +3126,84 @@ static void test_header_override(int port)
InternetCloseHandle(req);
InternetCloseHandle(con);
InternetCloseHandle(ses);
@ -118,5 +118,5 @@ index 559ab3e..29abb2f 100644
static void test_http1_1(int port)
--
2.4.3
2.8.0

View File

@ -1 +1,2 @@
# Fixes: [28911] Add HTTP Host header in HttpSendRequest instead of HttpOpenRequest
Depends: wininet-HTTPREQ_ReadFile_Async

View File

@ -1,8 +1,13 @@
From c0897fede8556c5970ff7a5db97795a0ccd88b43 Mon Sep 17 00:00:00 2001
From 6545fc4c2c3fcc407b849185f9042118826e2ed7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 5 Apr 2016 17:55:47 +0200
Subject: wininet: Fix async check in HTTPREQ_ReadFileEx.
Date: Tue, 26 Apr 2016 23:37:13 +0200
Subject: wininet: Fix async check in HTTPREQ_ReadFileEx. (resend)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michael Müller <michael@fds-team.de>
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
---
dlls/wininet/http.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@ -21,5 +26,5 @@ index bdc659d..2774ab0 100644
read_file_ex_task_t *task;
--
2.7.1
2.8.0

View File

@ -0,0 +1,162 @@
From f9828f2ad26faa73c8820f98610a393c46339289 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 26 Apr 2016 23:37:54 +0200
Subject: wininet/tests: Add tests for asynchronous InternetReadFileEx. (v3)
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
---
dlls/wininet/tests/http.c | 117 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 1 deletion(-)
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 82fd10b..fcaba10 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -109,7 +109,7 @@ static int expect[MAX_INTERNET_STATUS], optional[MAX_INTERNET_STATUS],
wine_allow[MAX_INTERNET_STATUS], notified[MAX_INTERNET_STATUS];
static const char *status_string[MAX_INTERNET_STATUS];
-static HANDLE hCompleteEvent, conn_close_event;
+static HANDLE hCompleteEvent, conn_close_event, conn_wait_event;
static DWORD req_error;
#define TESTF_REDIRECT 0x01
@@ -2358,6 +2358,15 @@ static DWORD CALLBACK server_thread(LPVOID param)
else
send(c, notokmsg, sizeof notokmsg-1, 0);
}
+ if (strstr(buffer, "/async_read"))
+ {
+ const char *page1_mid = page1 + (sizeof page1 - 1)/2;
+ const char *page1_end = page1 + sizeof page1 - 1;
+ send(c, okmsg, sizeof okmsg-1, 0);
+ send(c, page1, page1_mid - page1, 0);
+ WaitForSingleObject(conn_wait_event, INFINITE);
+ send(c, page1_mid, page1_end - page1_mid, 0);
+ }
shutdown(c, 2);
closesocket(c);
c = -1;
@@ -4420,6 +4429,111 @@ static void test_basic_auth_credentials_reuse(int port)
InternetCloseHandle( ses );
}
+static void test_async_read(int port)
+{
+ HINTERNET ses, con, req;
+ INTERNET_BUFFERSA ib;
+ char buffer[0x100];
+ DWORD pending_reads;
+ DWORD res, count;
+ BOOL ret;
+
+ hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+ /* test asynchronous InternetReadFileEx */
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+ pInternetSetStatusCallbackA( ses, &callback );
+
+ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
+
+ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
+ req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
+
+ SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
+ SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
+ SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
+ SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
+ SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
+ SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
+ SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
+ SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
+ SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
+ SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
+ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
+
+ SetLastError( 0xdeadbeef );
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
+ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+ WaitForSingleObject( hCompleteEvent, INFINITE );
+ ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
+
+ CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
+ CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
+ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
+ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
+ CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
+ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
+ CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
+ CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+ CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
+ CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
+ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
+
+ pending_reads = 0;
+ memset( &ib, 0, sizeof(ib) );
+ memset( buffer, 0, sizeof(buffer) );
+ ib.dwStructSize = sizeof(ib);
+ for (count = 0; count < sizeof(buffer); count += ib.dwBufferLength)
+ {
+ ib.lpvBuffer = buffer + count;
+ ib.dwBufferLength = min(16, sizeof(buffer) - count);
+
+ SET_OPTIONAL( INTERNET_STATUS_RECEIVING_RESPONSE );
+ SET_OPTIONAL( INTERNET_STATUS_RESPONSE_RECEIVED );
+
+ ret = InternetReadFileExA( req, &ib, 0, 0xdeadbeef );
+ if (!count) /* the first part should arrive immediately */
+ ok( ret, "InternetReadFileExA failed %u\n", GetLastError() );
+ if (!ret)
+ {
+ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
+ if (!pending_reads++)
+ {
+ res = WaitForSingleObject( hCompleteEvent, 0 );
+ ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
+ SetEvent( conn_wait_event );
+ }
+ res = WaitForSingleObject( hCompleteEvent, 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 );
+ todo_wine_if( pending_reads > 1 )
+ ok( ib.dwBufferLength != 0, "expected ib.dwBufferLength != 0\n" );
+ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
+ }
+
+ CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
+ CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+ if (!ib.dwBufferLength) break;
+ }
+
+ todo_wine
+ 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, hCompleteEvent, 2 );
+
+ CloseHandle( hCompleteEvent );
+ CloseHandle( conn_wait_event );
+}
+
static void test_http_connection(void)
{
struct server_info si;
@@ -4469,6 +4583,7 @@ static void test_http_connection(void)
test_request_content_length(si.port);
test_accept_encoding(si.port);
test_basic_auth_credentials_reuse(si.port);
+ test_async_read(si.port);
/* send the basic request again to shutdown the server thread */
test_basic_request(si.port, "GET", "/quit");
--
2.8.0

View File

@ -1,14 +1,19 @@
From e2da56d0cda302fbc815da6f35ef5cc0cf5f7c95 Mon Sep 17 00:00:00 2001
From ace80a3673e0f48a26e27b821c03e96140c1557b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 5 Apr 2016 17:58:29 +0200
Subject: wininet: Handle async mode in HTTPREQ_ReadFile.
Date: Tue, 26 Apr 2016 23:38:16 +0200
Subject: wininet: Handle async mode in HTTPREQ_ReadFile. (resend)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michael Müller <michael@fds-team.de>
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
---
dlls/wininet/http.c | 57 +++++++++++++++++++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 17 deletions(-)
dlls/wininet/http.c | 61 ++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 17 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 2774ab0..fac3d4d 100644
index 2774ab0..6c2c567 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -3105,23 +3105,6 @@ static BOOL drain_content(http_request_t *req, BOOL blocking)
@ -35,7 +40,7 @@ index 2774ab0..fac3d4d 100644
typedef struct {
task_header_t hdr;
void *buf;
@@ -3238,6 +3221,46 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
@@ -3238,6 +3221,50 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
return res;
}
@ -51,8 +56,11 @@ index 2774ab0..fac3d4d 100644
+ if (TryEnterCriticalSection( &req->read_section ))
+ {
+ if (get_avail_data(req))
+ goto read_data;
+
+ {
+ res = HTTPREQ_Read(req, buffer, size, read);
+ LeaveCriticalSection( &req->read_section );
+ goto done;
+ }
+ LeaveCriticalSection( &req->read_section );
+ }
+
@ -61,6 +69,7 @@ index 2774ab0..fac3d4d 100644
+ task->size = size;
+ task->ret_read = read;
+
+ *read = 0;
+ INTERNET_AsyncCall(&task->hdr);
+
+ return ERROR_IO_PENDING;
@ -70,12 +79,12 @@ index 2774ab0..fac3d4d 100644
+ if(hdr->dwError == INTERNET_HANDLE_IN_USE)
+ hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
+
+read_data:
+ res = HTTPREQ_Read(req, buffer, size, read);
+ if(res == ERROR_SUCCESS)
+ res = hdr->dwError;
+ LeaveCriticalSection( &req->read_section );
+
+done:
+ return res;
+}
+
@ -83,5 +92,5 @@ index 2774ab0..fac3d4d 100644
task_header_t hdr;
DWORD *ret_size;
--
2.7.1
2.8.0

View File

@ -0,0 +1,120 @@
From 748c8bfe4b67785a4c2933365d73a87e3ed31f80 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 26 Apr 2016 23:38:41 +0200
Subject: wininet/tests: Add tests for asynchronous InternetReadFile. (v3)
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
---
dlls/wininet/tests/http.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 88 insertions(+), 1 deletion(-)
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index fcaba10..67392cd 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -4435,7 +4435,7 @@ static void test_async_read(int port)
INTERNET_BUFFERSA ib;
char buffer[0x100];
DWORD pending_reads;
- DWORD res, count;
+ DWORD res, count, bytes;
BOOL ret;
hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
@@ -4529,6 +4529,93 @@ static void test_async_read(int port)
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, hCompleteEvent, 2 );
+ ResetEvent( conn_wait_event );
+
+ /* test asynchronous InternetReadFile */
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+ pInternetSetStatusCallbackA( ses, &callback );
+
+ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
+
+ SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
+ req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+ CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
+
+ SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
+ SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
+ SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
+ SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
+ SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
+ SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
+ SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
+ SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
+ SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
+ SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
+ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
+
+ SetLastError( 0xdeadbeef );
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
+ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+ WaitForSingleObject( hCompleteEvent, INFINITE );
+ ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
+
+ CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
+ CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
+ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
+ CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
+ CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
+ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
+ CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
+ CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+ CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
+ CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
+ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
+
+ pending_reads = 0;
+ memset( buffer, 0, sizeof(buffer) );
+ for (count = 0; count < sizeof(buffer); count += bytes)
+ {
+ SET_OPTIONAL( INTERNET_STATUS_RECEIVING_RESPONSE );
+ SET_OPTIONAL( INTERNET_STATUS_RESPONSE_RECEIVED );
+
+ bytes = 0xdeadbeef;
+ ret = InternetReadFile( req, buffer + count, min(16, sizeof(buffer) - count), &bytes );
+ if (!count) /* the first part should arrive immediately */
+ ok( ret, "InternetReadFile failed %u\n", GetLastError() );
+ if (!ret)
+ {
+ ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+ ok( bytes == 0, "expected 0, got %u\n", bytes );
+ SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
+ if (!pending_reads++)
+ {
+ res = WaitForSingleObject( hCompleteEvent, 0 );
+ ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
+ SetEvent( conn_wait_event );
+ }
+ res = WaitForSingleObject( hCompleteEvent, 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 );
+ todo_wine_if( pending_reads > 1 )
+ ok( bytes != 0, "expected bytes != 0\n" );
+ CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
+ }
+
+ CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
+ CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+ if (!bytes) break;
+ }
+
+ todo_wine
+ 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, hCompleteEvent, 2 );
CloseHandle( hCompleteEvent );
CloseHandle( conn_wait_event );
--
2.8.0