2 * test status notifications
4 * Copyright 2008 Hans Leidekker for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
29 static const WCHAR user_agent
[] = {'w','i','n','e','t','e','s','t',0};
30 static const WCHAR test_winehq
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
37 winhttp_receive_response
,
46 enum api function
; /* api responsible for notification */
47 unsigned int status
; /* status received */
50 BOOL skipped_for_proxy
;
56 const struct notification
*test
;
63 static BOOL
proxy_active(void)
65 WINHTTP_PROXY_INFO proxy_info
;
68 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
70 active
= (proxy_info
.lpszProxy
!= NULL
);
72 GlobalFree(proxy_info
.lpszProxy
);
73 if (proxy_info
.lpszProxyBypass
!= NULL
)
74 GlobalFree(proxy_info
.lpszProxyBypass
);
82 static void CALLBACK
check_notification( HINTERNET handle
, DWORD_PTR context
, DWORD status
, LPVOID buffer
, DWORD buflen
)
84 BOOL status_ok
, function_ok
;
85 struct info
*info
= (struct info
*)context
;
86 unsigned int i
= info
->index
;
88 if (status
== WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
)
90 DWORD size
= sizeof(struct info
*);
91 WinHttpQueryOption( handle
, WINHTTP_OPTION_CONTEXT_VALUE
, &info
, &size
);
93 ok(i
< info
->count
, "%u: unexpected notification 0x%08x\n", info
->line
, status
);
94 if (i
>= info
->count
) return;
96 status_ok
= (info
->test
[i
].status
== status
);
97 function_ok
= (info
->test
[i
].function
== info
->function
);
98 if (!info
->test
[i
].ignore
&& !info
->test
[i
].todo
)
100 ok(status_ok
, "%u: expected status 0x%08x got 0x%08x\n", info
->line
, info
->test
[i
].status
, status
);
101 ok(function_ok
, "%u: expected function %u got %u\n", info
->line
, info
->test
[i
].function
, info
->function
);
103 else if (!info
->test
[i
].ignore
)
105 todo_wine
ok(status_ok
, "%u: expected status 0x%08x got 0x%08x\n", info
->line
, info
->test
[i
].status
, status
);
108 todo_wine
ok(function_ok
, "%u: expected function %u got %u\n", info
->line
, info
->test
[i
].function
, info
->function
);
111 if (status_ok
&& function_ok
) info
->index
++;
114 while (info
->test
[info
->index
].skipped_for_proxy
)
118 if (status
& (WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS
| WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
))
120 SetEvent( info
->wait
);
124 static const struct notification cache_test
[] =
126 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
127 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
128 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
},
129 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
},
130 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
},
131 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
},
132 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
133 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
134 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
135 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
136 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, FALSE
, TRUE
},
137 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, FALSE
, TRUE
},
138 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, FALSE
, TRUE
},
139 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
140 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
},
141 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
},
142 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
143 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
144 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
145 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
146 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, FALSE
, TRUE
},
147 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, FALSE
, TRUE
},
148 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, FALSE
, TRUE
},
149 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, TRUE
, TRUE
},
150 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, TRUE
, TRUE
}
153 static void setup_test( struct info
*info
, enum api function
, unsigned int line
)
155 info
->function
= function
;
159 static void test_connection_cache( void )
161 HANDLE ses
, con
, req
, event
;
162 DWORD size
, status
, err
;
163 BOOL ret
, unload
= TRUE
;
164 struct info info
, *context
= &info
;
166 info
.test
= cache_test
;
167 info
.count
= sizeof(cache_test
) / sizeof(cache_test
[0]);
171 ses
= WinHttpOpen( user_agent
, 0, NULL
, NULL
, 0 );
172 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
174 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
175 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
, &event
, sizeof(event
) );
178 win_skip("Unload event not supported\n");
182 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
184 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
185 ok(ret
, "failed to set context value %u\n", GetLastError());
187 setup_test( &info
, winhttp_connect
, __LINE__
);
188 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
189 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
191 setup_test( &info
, winhttp_open_request
, __LINE__
);
192 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
193 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
195 setup_test( &info
, winhttp_send_request
, __LINE__
);
196 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
197 err
= GetLastError();
198 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
200 skip("connection failed, skipping\n");
203 ok(ret
, "failed to send request %u\n", GetLastError());
205 setup_test( &info
, winhttp_receive_response
, __LINE__
);
206 ret
= WinHttpReceiveResponse( req
, NULL
);
207 ok(ret
, "failed to receive response %u\n", GetLastError());
209 size
= sizeof(status
);
210 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
211 ok(ret
, "failed unexpectedly %u\n", GetLastError());
212 ok(status
== 200, "request failed unexpectedly %u\n", status
);
214 setup_test( &info
, winhttp_close_handle
, __LINE__
);
215 WinHttpCloseHandle( req
);
217 setup_test( &info
, winhttp_open_request
, __LINE__
);
218 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
219 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
221 ret
= WinHttpSetOption( req
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
222 ok(ret
, "failed to set context value %u\n", GetLastError());
224 setup_test( &info
, winhttp_send_request
, __LINE__
);
225 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
226 err
= GetLastError();
227 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
229 skip("connection failed, skipping\n");
232 ok(ret
, "failed to send request %u\n", GetLastError());
234 setup_test( &info
, winhttp_receive_response
, __LINE__
);
235 ret
= WinHttpReceiveResponse( req
, NULL
);
236 ok(ret
, "failed to receive response %u\n", GetLastError());
238 size
= sizeof(status
);
239 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
240 ok(ret
, "failed unexpectedly %u\n", GetLastError());
241 ok(status
== 200, "request failed unexpectedly %u\n", status
);
243 setup_test( &info
, winhttp_close_handle
, __LINE__
);
244 WinHttpCloseHandle( req
);
246 setup_test( &info
, winhttp_close_handle
, __LINE__
);
247 WinHttpCloseHandle( req
);
248 WinHttpCloseHandle( con
);
252 status
= WaitForSingleObject( event
, 0 );
253 ok(status
== WAIT_TIMEOUT
, "got %08x\n", status
);
256 WinHttpCloseHandle( ses
);
258 Sleep(2000); /* make sure connection is evicted from cache */
261 status
= WaitForSingleObject( event
, 0 );
262 ok(status
== WAIT_OBJECT_0
, "got %08x\n", status
);
267 ses
= WinHttpOpen( user_agent
, 0, NULL
, NULL
, 0 );
268 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
272 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
, &event
, sizeof(event
) );
273 ok(ret
, "failed to set unload option\n");
276 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
278 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
279 ok(ret
, "failed to set context value %u\n", GetLastError());
281 setup_test( &info
, winhttp_connect
, __LINE__
);
282 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
283 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
285 setup_test( &info
, winhttp_open_request
, __LINE__
);
286 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
287 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
289 ret
= WinHttpSetOption( req
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
290 ok(ret
, "failed to set context value %u\n", GetLastError());
292 setup_test( &info
, winhttp_send_request
, __LINE__
);
293 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
294 err
= GetLastError();
295 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
297 skip("connection failed, skipping\n");
300 ok(ret
, "failed to send request %u\n", GetLastError());
302 setup_test( &info
, winhttp_receive_response
, __LINE__
);
303 ret
= WinHttpReceiveResponse( req
, NULL
);
304 ok(ret
, "failed to receive response %u\n", GetLastError());
306 size
= sizeof(status
);
307 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
308 ok(ret
, "failed unexpectedly %u\n", GetLastError());
309 ok(status
== 200, "request failed unexpectedly %u\n", status
);
311 setup_test( &info
, winhttp_close_handle
, __LINE__
);
312 WinHttpCloseHandle( req
);
314 setup_test( &info
, winhttp_open_request
, __LINE__
);
315 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
316 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
318 ret
= WinHttpSetOption( req
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
319 ok(ret
, "failed to set context value %u\n", GetLastError());
321 setup_test( &info
, winhttp_send_request
, __LINE__
);
322 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
323 err
= GetLastError();
324 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
326 skip("connection failed, skipping\n");
329 ok(ret
, "failed to send request %u\n", GetLastError());
331 setup_test( &info
, winhttp_receive_response
, __LINE__
);
332 ret
= WinHttpReceiveResponse( req
, NULL
);
333 ok(ret
, "failed to receive response %u\n", GetLastError());
335 size
= sizeof(status
);
336 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
337 ok(ret
, "failed unexpectedly %u\n", GetLastError());
338 ok(status
== 200, "request failed unexpectedly %u\n", status
);
340 setup_test( &info
, winhttp_close_handle
, __LINE__
);
342 WinHttpCloseHandle( req
);
343 WinHttpCloseHandle( con
);
347 status
= WaitForSingleObject( event
, 0 );
348 ok(status
== WAIT_TIMEOUT
, "got %08x\n", status
);
351 WinHttpCloseHandle( ses
);
353 Sleep(2000); /* make sure connection is evicted from cache */
356 status
= WaitForSingleObject( event
, 0 );
357 ok(status
== WAIT_OBJECT_0
, "got %08x\n", status
);
360 CloseHandle( event
);
363 static const struct notification redirect_test
[] =
365 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
366 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
367 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, FALSE
, TRUE
},
368 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, FALSE
, TRUE
},
369 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
},
370 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
},
371 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
372 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
373 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
374 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
375 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_REDIRECT
},
376 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, FALSE
, TRUE
, TRUE
},
377 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, FALSE
, TRUE
, TRUE
},
378 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, FALSE
, FALSE
, TRUE
},
379 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, FALSE
, FALSE
, TRUE
},
380 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
381 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
382 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
383 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
384 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, FALSE
, TRUE
},
385 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, FALSE
, TRUE
},
386 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, FALSE
, TRUE
},
387 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, TRUE
, TRUE
},
388 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, TRUE
, TRUE
}
391 static void test_redirect( void )
393 HANDLE ses
, con
, req
;
394 DWORD size
, status
, err
;
396 struct info info
, *context
= &info
;
398 info
.test
= redirect_test
;
399 info
.count
= sizeof(redirect_test
) / sizeof(redirect_test
[0]);
403 ses
= WinHttpOpen( user_agent
, 0, NULL
, NULL
, 0 );
404 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
406 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
408 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
409 ok(ret
, "failed to set context value %u\n", GetLastError());
411 setup_test( &info
, winhttp_connect
, __LINE__
);
412 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
413 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
415 setup_test( &info
, winhttp_open_request
, __LINE__
);
416 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
417 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
419 setup_test( &info
, winhttp_send_request
, __LINE__
);
420 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
421 err
= GetLastError();
422 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
424 skip("connection failed, skipping\n");
427 ok(ret
, "failed to send request %u\n", GetLastError());
429 setup_test( &info
, winhttp_receive_response
, __LINE__
);
430 ret
= WinHttpReceiveResponse( req
, NULL
);
431 ok(ret
, "failed to receive response %u\n", GetLastError());
433 size
= sizeof(status
);
434 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
435 ok(ret
, "failed unexpectedly %u\n", GetLastError());
436 ok(status
== 200, "request failed unexpectedly %u\n", status
);
438 setup_test( &info
, winhttp_close_handle
, __LINE__
);
440 WinHttpCloseHandle( req
);
441 WinHttpCloseHandle( con
);
442 WinHttpCloseHandle( ses
);
445 static const struct notification async_test
[] =
447 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
448 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
449 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, FALSE
, TRUE
},
450 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, FALSE
, TRUE
},
451 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
},
452 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
},
453 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
454 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
455 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
},
456 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
457 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
458 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_REDIRECT
},
459 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, FALSE
, TRUE
, TRUE
},
460 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, FALSE
, TRUE
, TRUE
},
461 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, FALSE
, FALSE
, TRUE
},
462 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, FALSE
, FALSE
, TRUE
},
463 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
464 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
465 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
466 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
467 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
},
468 { winhttp_query_data
, WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
},
469 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
, FALSE
, TRUE
},
470 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
, FALSE
, TRUE
},
471 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_READ_COMPLETE
, FALSE
, TRUE
},
472 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, FALSE
, TRUE
},
473 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, FALSE
, TRUE
},
474 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, FALSE
, TRUE
},
475 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, TRUE
, TRUE
},
476 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, TRUE
, TRUE
}
479 static void test_async( void )
481 HANDLE ses
, con
, req
, event
;
482 DWORD size
, status
, err
;
483 BOOL ret
, unload
= TRUE
;
484 struct info info
, *context
= &info
;
487 info
.test
= async_test
;
488 info
.count
= sizeof(async_test
) / sizeof(async_test
[0]);
490 info
.wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
492 ses
= WinHttpOpen( user_agent
, 0, NULL
, NULL
, WINHTTP_FLAG_ASYNC
);
493 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
495 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
496 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
, &event
, sizeof(event
) );
499 win_skip("Unload event not supported\n");
503 SetLastError( 0xdeadbeef );
504 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
505 err
= GetLastError();
506 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
508 SetLastError( 0xdeadbeef );
509 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
510 err
= GetLastError();
511 ok(ret
, "failed to set context value %u\n", err
);
512 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
514 setup_test( &info
, winhttp_connect
, __LINE__
);
515 SetLastError( 0xdeadbeef );
516 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
517 err
= GetLastError();
518 ok(con
!= NULL
, "failed to open a connection %u\n", err
);
519 ok(err
== ERROR_SUCCESS
|| broken(err
== WSAEINVAL
) /* < win7 */, "got %u\n", err
);
521 setup_test( &info
, winhttp_open_request
, __LINE__
);
522 SetLastError( 0xdeadbeef );
523 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
524 err
= GetLastError();
525 ok(req
!= NULL
, "failed to open a request %u\n", err
);
526 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
528 setup_test( &info
, winhttp_send_request
, __LINE__
);
529 SetLastError( 0xdeadbeef );
530 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
531 err
= GetLastError();
532 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
534 skip("connection failed, skipping\n");
535 WinHttpCloseHandle( req
);
536 WinHttpCloseHandle( con
);
537 WinHttpCloseHandle( ses
);
538 CloseHandle( info
.wait
);
541 ok(ret
, "failed to send request %u\n", err
);
542 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
544 WaitForSingleObject( info
.wait
, INFINITE
);
546 setup_test( &info
, winhttp_receive_response
, __LINE__
);
547 SetLastError( 0xdeadbeef );
548 ret
= WinHttpReceiveResponse( req
, NULL
);
549 err
= GetLastError();
550 ok(ret
, "failed to receive response %u\n", err
);
551 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
553 WaitForSingleObject( info
.wait
, INFINITE
);
555 size
= sizeof(status
);
556 SetLastError( 0xdeadbeef );
557 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
558 err
= GetLastError();
559 ok(ret
, "failed unexpectedly %u\n", err
);
560 ok(status
== 200, "request failed unexpectedly %u\n", status
);
561 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
563 setup_test( &info
, winhttp_query_data
, __LINE__
);
564 SetLastError( 0xdeadbeef );
565 ret
= WinHttpQueryDataAvailable( req
, NULL
);
566 err
= GetLastError();
567 ok(ret
, "failed to query data available %u\n", err
);
568 ok(err
== ERROR_SUCCESS
|| err
== ERROR_IO_PENDING
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
570 WaitForSingleObject( info
.wait
, INFINITE
);
572 setup_test( &info
, winhttp_read_data
, __LINE__
);
573 SetLastError( 0xdeadbeef );
574 ret
= WinHttpReadData( req
, buffer
, sizeof(buffer
), NULL
);
575 err
= GetLastError();
576 ok(ret
, "failed to read data %u\n", err
);
577 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
579 WaitForSingleObject( info
.wait
, INFINITE
);
581 setup_test( &info
, winhttp_close_handle
, __LINE__
);
582 WinHttpCloseHandle( req
);
583 WinHttpCloseHandle( con
);
587 status
= WaitForSingleObject( event
, 0 );
588 ok(status
== WAIT_TIMEOUT
, "got %08x\n", status
);
590 WinHttpCloseHandle( ses
);
592 WaitForSingleObject( info
.wait
, INFINITE
);
596 status
= WaitForSingleObject( event
, 2000 );
597 ok(status
== WAIT_OBJECT_0
, "got %08x\n", status
);
599 CloseHandle( event
);
600 CloseHandle( info
.wait
);
603 START_TEST (notification
)
605 test_connection_cache();
607 Sleep(2000); /* make sure previous connection is evicted from cache */