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
29 #include "wine/test.h"
36 winhttp_receive_response
,
45 enum api function
; /* api responsible for notification */
46 unsigned int status
; /* status received */
47 DWORD flags
; /* a combination of NF_* flags */
50 #define NF_ALLOW 0x0001 /* notification may or may not happen */
51 #define NF_WINE_ALLOW 0x0002 /* wine sends notification when it should not */
52 #define NF_SIGNAL 0x0004 /* signal wait handle when notified */
57 const struct notification
*test
;
71 static void CALLBACK
check_notification( HINTERNET handle
, DWORD_PTR context
, DWORD status
, LPVOID buffer
, DWORD buflen
)
73 BOOL status_ok
, function_ok
;
74 struct info
*info
= (struct info
*)context
;
76 if (status
== WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
)
78 DWORD size
= sizeof(struct info
*);
79 WinHttpQueryOption( handle
, WINHTTP_OPTION_CONTEXT_VALUE
, &info
, &size
);
81 while (info
->index
< info
->count
&& info
->test
[info
->index
].status
!= status
&& (info
->test
[info
->index
].flags
& NF_ALLOW
))
83 while (info
->index
< info
->count
&& (info
->test
[info
->index
].flags
& NF_WINE_ALLOW
))
85 todo_wine
ok(info
->test
[info
->index
].status
!= status
, "unexpected %x notification\n", status
);
86 if (info
->test
[info
->index
].status
== status
) break;
89 ok(info
->index
< info
->count
, "%u: unexpected notification 0x%08x\n", info
->line
, status
);
90 if (info
->index
>= info
->count
) return;
92 status_ok
= (info
->test
[info
->index
].status
== status
);
93 function_ok
= (info
->test
[info
->index
].function
== info
->function
);
94 ok(status_ok
, "%u: expected status 0x%08x got 0x%08x\n", info
->line
, info
->test
[info
->index
].status
, status
);
95 ok(function_ok
, "%u: expected function %u got %u\n", info
->line
, info
->test
[info
->index
].function
, info
->function
);
97 if (status_ok
&& function_ok
&& info
->test
[info
->index
++].flags
& NF_SIGNAL
)
99 SetEvent( info
->wait
);
103 static const struct notification cache_test
[] =
105 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
106 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
107 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
},
108 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
},
109 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
},
110 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
},
111 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
112 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
113 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
114 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
115 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_WINE_ALLOW
},
116 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_WINE_ALLOW
},
117 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
},
118 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
119 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_WINE_ALLOW
},
120 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, NF_WINE_ALLOW
},
121 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
122 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
123 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
124 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
125 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_WINE_ALLOW
},
126 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_WINE_ALLOW
},
127 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
128 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
},
129 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
},
130 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
131 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
132 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, NF_WINE_ALLOW
},
133 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, NF_WINE_ALLOW
},
134 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_WINE_ALLOW
},
135 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, NF_WINE_ALLOW
},
136 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
137 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
138 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
139 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
140 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_WINE_ALLOW
},
141 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_WINE_ALLOW
},
142 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
},
143 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
144 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_WINE_ALLOW
},
145 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, NF_WINE_ALLOW
},
146 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
147 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
148 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
149 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
150 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_WINE_ALLOW
},
151 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_WINE_ALLOW
},
152 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
153 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
},
154 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
}
157 static void setup_test( struct info
*info
, enum api function
, unsigned int line
)
159 if (info
->wait
) ResetEvent( info
->wait
);
160 info
->function
= function
;
162 while (info
->index
< info
->count
&& info
->test
[info
->index
].function
!= function
163 && (info
->test
[info
->index
].flags
& (NF_ALLOW
| NF_WINE_ALLOW
)))
165 ok_(__FILE__
,line
)(info
->test
[info
->index
].function
== function
,
166 "unexpected function %u, expected %u. probably some notifications were missing\n",
167 info
->test
[info
->index
].function
, function
);
170 static void end_test( struct info
*info
, unsigned int line
)
172 ok_(__FILE__
,line
)(info
->index
== info
->count
, "some notifications were missing: %x\n",
173 info
->test
[info
->index
].status
);
176 static void test_connection_cache( void )
178 HANDLE ses
, con
, req
, event
;
179 DWORD size
, status
, err
;
180 BOOL ret
, unload
= TRUE
;
181 struct info info
, *context
= &info
;
183 info
.test
= cache_test
;
184 info
.count
= ARRAY_SIZE( cache_test
);
186 info
.wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
188 ses
= WinHttpOpen( L
"winetest", 0, NULL
, NULL
, 0 );
189 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
191 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
192 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
, &event
, sizeof(event
) );
195 win_skip("Unload event not supported\n");
199 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
201 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
202 ok(ret
, "failed to set context value %u\n", GetLastError());
204 setup_test( &info
, winhttp_connect
, __LINE__
);
205 con
= WinHttpConnect( ses
, L
"test.winehq.org", 0, 0 );
206 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
208 setup_test( &info
, winhttp_open_request
, __LINE__
);
209 req
= WinHttpOpenRequest( con
, NULL
, L
"/tests/hello.html", NULL
, NULL
, NULL
, 0 );
210 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
212 setup_test( &info
, winhttp_send_request
, __LINE__
);
213 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
214 err
= GetLastError();
215 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
217 skip("connection failed, skipping\n");
220 ok(ret
, "failed to send request %u\n", GetLastError());
222 setup_test( &info
, winhttp_receive_response
, __LINE__
);
223 ret
= WinHttpReceiveResponse( req
, NULL
);
224 ok(ret
, "failed to receive response %u\n", GetLastError());
226 size
= sizeof(status
);
227 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
228 ok(ret
, "failed unexpectedly %u\n", GetLastError());
229 ok(status
== 200, "request failed unexpectedly %u\n", status
);
231 ResetEvent( info
.wait
);
232 setup_test( &info
, winhttp_close_handle
, __LINE__
);
233 WinHttpCloseHandle( req
);
234 WaitForSingleObject( info
.wait
, INFINITE
);
236 setup_test( &info
, winhttp_open_request
, __LINE__
);
237 req
= WinHttpOpenRequest( con
, NULL
, L
"/tests/hello.html", NULL
, NULL
, NULL
, 0 );
238 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
240 ret
= WinHttpSetOption( req
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
241 ok(ret
, "failed to set context value %u\n", GetLastError());
243 setup_test( &info
, winhttp_send_request
, __LINE__
);
244 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
245 err
= GetLastError();
246 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
248 skip("connection failed, skipping\n");
251 ok(ret
, "failed to send request %u\n", GetLastError());
253 setup_test( &info
, winhttp_receive_response
, __LINE__
);
254 ret
= WinHttpReceiveResponse( req
, NULL
);
255 ok(ret
, "failed to receive response %u\n", GetLastError());
257 size
= sizeof(status
);
258 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
259 ok(ret
, "failed unexpectedly %u\n", GetLastError());
260 ok(status
== 200, "request failed unexpectedly %u\n", status
);
262 ResetEvent( info
.wait
);
263 setup_test( &info
, winhttp_close_handle
, __LINE__
);
264 WinHttpCloseHandle( req
);
265 WinHttpCloseHandle( req
);
266 WinHttpCloseHandle( con
);
267 WaitForSingleObject( info
.wait
, INFINITE
);
271 status
= WaitForSingleObject( event
, 0 );
272 ok(status
== WAIT_TIMEOUT
, "got %08x\n", status
);
275 setup_test( &info
, winhttp_close_handle
, __LINE__
);
276 WinHttpCloseHandle( ses
);
277 WaitForSingleObject( info
.wait
, INFINITE
);
281 status
= WaitForSingleObject( event
, 100 );
282 ok(status
== WAIT_OBJECT_0
, "got %08x\n", status
);
286 ses
= WinHttpOpen( L
"winetest", 0, NULL
, NULL
, 0 );
287 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
291 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
, &event
, sizeof(event
) );
292 ok(ret
, "failed to set unload option\n");
295 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
297 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
298 ok(ret
, "failed to set context value %u\n", GetLastError());
300 setup_test( &info
, winhttp_connect
, __LINE__
);
301 con
= WinHttpConnect( ses
, L
"test.winehq.org", 0, 0 );
302 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
304 setup_test( &info
, winhttp_open_request
, __LINE__
);
305 req
= WinHttpOpenRequest( con
, NULL
, L
"/tests/hello.html", NULL
, NULL
, NULL
, 0 );
306 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
308 ret
= WinHttpSetOption( req
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
309 ok(ret
, "failed to set context value %u\n", GetLastError());
311 setup_test( &info
, winhttp_send_request
, __LINE__
);
312 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
313 err
= GetLastError();
314 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
316 skip("connection failed, skipping\n");
319 ok(ret
, "failed to send request %u\n", GetLastError());
321 setup_test( &info
, winhttp_receive_response
, __LINE__
);
322 ret
= WinHttpReceiveResponse( req
, NULL
);
323 ok(ret
, "failed to receive response %u\n", GetLastError());
325 size
= sizeof(status
);
326 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
327 ok(ret
, "failed unexpectedly %u\n", GetLastError());
328 ok(status
== 200, "request failed unexpectedly %u\n", status
);
330 ResetEvent( info
.wait
);
331 setup_test( &info
, winhttp_close_handle
, __LINE__
);
332 WinHttpCloseHandle( req
);
333 WaitForSingleObject( info
.wait
, INFINITE
);
335 setup_test( &info
, winhttp_open_request
, __LINE__
);
336 req
= WinHttpOpenRequest( con
, NULL
, L
"/tests/hello.html", NULL
, NULL
, NULL
, 0 );
337 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
339 ret
= WinHttpSetOption( req
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
340 ok(ret
, "failed to set context value %u\n", GetLastError());
342 setup_test( &info
, winhttp_send_request
, __LINE__
);
343 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
344 err
= GetLastError();
345 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
347 skip("connection failed, skipping\n");
350 ok(ret
, "failed to send request %u\n", GetLastError());
352 setup_test( &info
, winhttp_receive_response
, __LINE__
);
353 ret
= WinHttpReceiveResponse( req
, NULL
);
354 ok(ret
, "failed to receive response %u\n", GetLastError());
356 size
= sizeof(status
);
357 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
358 ok(ret
, "failed unexpectedly %u\n", GetLastError());
359 ok(status
== 200, "request failed unexpectedly %u\n", status
);
361 setup_test( &info
, winhttp_close_handle
, __LINE__
);
363 WinHttpCloseHandle( req
);
364 WinHttpCloseHandle( con
);
365 WaitForSingleObject( info
.wait
, INFINITE
);
369 status
= WaitForSingleObject( event
, 0 );
370 ok(status
== WAIT_TIMEOUT
, "got %08x\n", status
);
373 setup_test( &info
, winhttp_close_handle
, __LINE__
);
374 WinHttpCloseHandle( ses
);
375 WaitForSingleObject( info
.wait
, INFINITE
);
376 CloseHandle( info
.wait
);
377 end_test( &info
, __LINE__
);
381 status
= WaitForSingleObject( event
, 100 );
382 ok(status
== WAIT_OBJECT_0
, "got %08x\n", status
);
385 CloseHandle( event
);
388 static const struct notification redirect_test
[] =
390 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
391 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
392 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, NF_WINE_ALLOW
},
393 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, NF_WINE_ALLOW
},
394 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_WINE_ALLOW
},
395 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, NF_WINE_ALLOW
},
396 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
397 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
398 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
399 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
400 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_REDIRECT
},
401 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, NF_ALLOW
},
402 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, NF_ALLOW
},
403 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_ALLOW
},
404 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, NF_ALLOW
},
405 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
406 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
407 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
408 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
409 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_WINE_ALLOW
},
410 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_WINE_ALLOW
},
411 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
412 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
413 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
}
416 static void test_redirect( void )
418 HANDLE ses
, con
, req
;
419 DWORD size
, status
, err
;
421 struct info info
, *context
= &info
;
423 info
.test
= redirect_test
;
424 info
.count
= ARRAY_SIZE( redirect_test
);
426 info
.wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
428 ses
= WinHttpOpen( L
"winetest", 0, NULL
, NULL
, 0 );
429 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
431 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
433 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
434 ok(ret
, "failed to set context value %u\n", GetLastError());
436 setup_test( &info
, winhttp_connect
, __LINE__
);
437 con
= WinHttpConnect( ses
, L
"test.winehq.org", 0, 0 );
438 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
440 setup_test( &info
, winhttp_open_request
, __LINE__
);
441 req
= WinHttpOpenRequest( con
, NULL
, L
"/tests/redirect", NULL
, NULL
, NULL
, 0 );
442 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
444 setup_test( &info
, winhttp_send_request
, __LINE__
);
445 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
446 err
= GetLastError();
447 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
449 skip("connection failed, skipping\n");
452 ok(ret
, "failed to send request %u\n", GetLastError());
454 setup_test( &info
, winhttp_receive_response
, __LINE__
);
455 ret
= WinHttpReceiveResponse( req
, NULL
);
456 ok(ret
, "failed to receive response %u\n", GetLastError());
458 size
= sizeof(status
);
459 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
460 ok(ret
, "failed unexpectedly %u\n", GetLastError());
461 ok(status
== 200, "request failed unexpectedly %u\n", status
);
463 setup_test( &info
, winhttp_close_handle
, __LINE__
);
465 WinHttpCloseHandle( req
);
466 WinHttpCloseHandle( con
);
467 WinHttpCloseHandle( ses
);
468 WaitForSingleObject( info
.wait
, INFINITE
);
469 CloseHandle( info
.wait
);
470 end_test( &info
, __LINE__
);
473 static const struct notification async_test
[] =
475 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
476 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
477 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
, NF_WINE_ALLOW
},
478 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
, NF_WINE_ALLOW
},
479 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_WINE_ALLOW
},
480 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
, NF_WINE_ALLOW
},
481 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
482 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
483 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
, NF_SIGNAL
},
484 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
},
485 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
},
486 { winhttp_receive_response
, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
, NF_SIGNAL
},
487 { winhttp_query_data
, WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
, NF_SIGNAL
},
488 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
, NF_ALLOW
},
489 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
, NF_ALLOW
},
490 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_READ_COMPLETE
, NF_SIGNAL
},
491 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
492 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
493 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
}
496 static void test_async( void )
498 HANDLE ses
, con
, req
, event
;
499 DWORD size
, status
, err
;
500 BOOL ret
, unload
= TRUE
;
501 struct info info
, *context
= &info
;
504 info
.test
= async_test
;
505 info
.count
= ARRAY_SIZE( async_test
);
507 info
.wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
509 ses
= WinHttpOpen( L
"winetest", 0, NULL
, NULL
, WINHTTP_FLAG_ASYNC
);
510 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
512 event
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
513 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
, &event
, sizeof(event
) );
516 win_skip("Unload event not supported\n");
520 SetLastError( 0xdeadbeef );
521 WinHttpSetStatusCallback( ses
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
522 err
= GetLastError();
523 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
525 SetLastError( 0xdeadbeef );
526 ret
= WinHttpSetOption( ses
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(struct info
*) );
527 err
= GetLastError();
528 ok(ret
, "failed to set context value %u\n", err
);
529 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
531 setup_test( &info
, winhttp_connect
, __LINE__
);
532 SetLastError( 0xdeadbeef );
533 con
= WinHttpConnect( ses
, L
"test.winehq.org", 0, 0 );
534 err
= GetLastError();
535 ok(con
!= NULL
, "failed to open a connection %u\n", err
);
536 ok(err
== ERROR_SUCCESS
|| broken(err
== WSAEINVAL
) /* < win7 */, "got %u\n", err
);
538 setup_test( &info
, winhttp_open_request
, __LINE__
);
539 SetLastError( 0xdeadbeef );
540 req
= WinHttpOpenRequest( con
, NULL
, L
"/tests/hello.html", NULL
, NULL
, NULL
, 0 );
541 err
= GetLastError();
542 ok(req
!= NULL
, "failed to open a request %u\n", err
);
543 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
545 setup_test( &info
, winhttp_send_request
, __LINE__
);
546 SetLastError( 0xdeadbeef );
547 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
548 err
= GetLastError();
549 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
551 skip("connection failed, skipping\n");
552 WinHttpCloseHandle( req
);
553 WinHttpCloseHandle( con
);
554 WinHttpCloseHandle( ses
);
555 CloseHandle( info
.wait
);
558 ok(ret
, "failed to send request %u\n", err
);
559 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
561 WaitForSingleObject( info
.wait
, INFINITE
);
563 setup_test( &info
, winhttp_receive_response
, __LINE__
);
564 SetLastError( 0xdeadbeef );
565 ret
= WinHttpReceiveResponse( req
, NULL
);
566 err
= GetLastError();
567 ok(ret
, "failed to receive response %u\n", err
);
568 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
570 WaitForSingleObject( info
.wait
, INFINITE
);
572 size
= sizeof(status
);
573 SetLastError( 0xdeadbeef );
574 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
575 err
= GetLastError();
576 ok(ret
, "failed unexpectedly %u\n", err
);
577 ok(status
== 200, "request failed unexpectedly %u\n", status
);
578 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
580 setup_test( &info
, winhttp_query_data
, __LINE__
);
581 SetLastError( 0xdeadbeef );
582 ret
= WinHttpQueryDataAvailable( req
, NULL
);
583 err
= GetLastError();
584 ok(ret
, "failed to query data available %u\n", err
);
585 ok(err
== ERROR_SUCCESS
|| err
== ERROR_IO_PENDING
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
587 WaitForSingleObject( info
.wait
, INFINITE
);
589 setup_test( &info
, winhttp_read_data
, __LINE__
);
590 ret
= WinHttpReadData( req
, buffer
, sizeof(buffer
), NULL
);
591 ok(ret
, "failed to read data %u\n", err
);
593 WaitForSingleObject( info
.wait
, INFINITE
);
595 setup_test( &info
, winhttp_close_handle
, __LINE__
);
596 WinHttpCloseHandle( req
);
597 WinHttpCloseHandle( con
);
601 status
= WaitForSingleObject( event
, 0 );
602 ok(status
== WAIT_TIMEOUT
, "got %08x\n", status
);
604 WinHttpCloseHandle( ses
);
605 WaitForSingleObject( info
.wait
, INFINITE
);
606 end_test( &info
, __LINE__
);
610 status
= WaitForSingleObject( event
, 2000 );
611 ok(status
== WAIT_OBJECT_0
, "got %08x\n", status
);
613 CloseHandle( event
);
614 CloseHandle( info
.wait
);
615 end_test( &info
, __LINE__
);
618 static const char okmsg
[] =
619 "HTTP/1.1 200 OK\r\n"
620 "Server: winetest\r\n"
623 static const char page1
[] =
625 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
626 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
635 static int server_socket
;
636 static HANDLE server_socket_available
, server_socket_done
;
638 static DWORD CALLBACK
server_thread(LPVOID param
)
640 struct server_info
*si
= param
;
641 int r
, c
= -1, i
, on
;
643 struct sockaddr_in sa
;
646 int last_request
= 0;
648 WSAStartup(MAKEWORD(1,1), &wsaData
);
650 s
= socket(AF_INET
, SOCK_STREAM
, 0);
651 if (s
== INVALID_SOCKET
)
655 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
657 memset(&sa
, 0, sizeof sa
);
658 sa
.sin_family
= AF_INET
;
659 sa
.sin_port
= htons(si
->port
);
660 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
662 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
670 if (c
== -1) c
= accept(s
, NULL
, NULL
);
672 memset(buffer
, 0, sizeof buffer
);
673 for(i
= 0; i
< sizeof buffer
- 1; i
++)
675 r
= recv(c
, &buffer
[i
], 1, 0);
679 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
680 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
683 if (strstr(buffer
, "GET /quit"))
685 send(c
, okmsg
, sizeof okmsg
- 1, 0);
686 send(c
, page1
, sizeof page1
- 1, 0);
689 else if(strstr(buffer
, "GET /socket"))
692 SetEvent(server_socket_available
);
693 WaitForSingleObject(server_socket_done
, INFINITE
);
694 ResetEvent(server_socket_available
);
699 } while (!last_request
);
705 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
707 HINTERNET ses
, con
, req
;
709 DWORD count
, status
, size
;
712 ses
= WinHttpOpen(NULL
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
713 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
715 con
= WinHttpConnect(ses
, L
"localhost", port
, 0);
716 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
718 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
719 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
721 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
722 ok(ret
, "failed to send request %u\n", GetLastError());
724 ret
= WinHttpReceiveResponse(req
, NULL
);
725 ok(ret
, "failed to receive response %u\n", GetLastError());
728 size
= sizeof(status
);
729 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
730 ok(ret
, "failed to query status code %u\n", GetLastError());
731 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
734 memset(buffer
, 0, sizeof(buffer
));
735 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
736 ok(ret
, "failed to read data %u\n", GetLastError());
737 ok(count
== sizeof page1
- 1, "count was wrong\n");
738 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
740 WinHttpCloseHandle(req
);
741 WinHttpCloseHandle(con
);
742 WinHttpCloseHandle(ses
);
745 static const struct notification open_socket_request_test
[] =
747 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
748 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
749 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
},
750 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
},
751 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
},
752 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
, NF_ALLOW
}, /* some versions call it twice. why? */
753 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
},
754 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
755 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
756 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
, NF_SIGNAL
}
759 static const struct notification reuse_socket_request_test
[] =
761 { winhttp_connect
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
762 { winhttp_open_request
, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
},
763 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
},
764 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_REQUEST_SENT
},
765 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
, NF_SIGNAL
},
768 static void open_async_request(int port
, struct test_request
*req
, struct info
*info
, const WCHAR
*path
, BOOL reuse_connection
)
773 if (reuse_connection
)
775 info
->test
= reuse_socket_request_test
;
776 info
->count
= ARRAY_SIZE( reuse_socket_request_test
);
780 info
->test
= open_socket_request_test
;
781 info
->count
= ARRAY_SIZE( open_socket_request_test
);
784 req
->session
= WinHttpOpen( L
"winetest", 0, NULL
, NULL
, WINHTTP_FLAG_ASYNC
);
785 ok(req
->session
!= NULL
, "failed to open session %u\n", GetLastError());
787 WinHttpSetOption( req
->session
, WINHTTP_OPTION_CONTEXT_VALUE
, &info
, sizeof(struct info
*) );
788 WinHttpSetStatusCallback( req
->session
, check_notification
, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
, 0 );
790 setup_test( info
, winhttp_connect
, __LINE__
);
791 req
->connection
= WinHttpConnect( req
->session
, L
"localhost", port
, 0 );
792 ok(req
->connection
!= NULL
, "failed to open a connection %u\n", GetLastError());
794 setup_test( info
, winhttp_open_request
, __LINE__
);
795 req
->request
= WinHttpOpenRequest( req
->connection
, NULL
, path
, NULL
, NULL
, NULL
, 0 );
796 ok(req
->request
!= NULL
, "failed to open a request %u\n", GetLastError());
798 setup_test( info
, winhttp_send_request
, __LINE__
);
799 ret
= WinHttpSendRequest( req
->request
, NULL
, 0, NULL
, 0, 0, 0 );
800 ok(ret
, "failed to send request %u\n", GetLastError());
803 static void open_socket_request(int port
, struct test_request
*req
, struct info
*info
)
805 ResetEvent( server_socket_done
);
806 open_async_request( port
, req
, info
, L
"/socket", FALSE
);
807 WaitForSingleObject( server_socket_available
, INFINITE
);
810 static const struct notification server_reply_test
[] =
812 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
, NF_ALLOW
},
813 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
, NF_ALLOW
},
814 { winhttp_send_request
, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
, NF_SIGNAL
}
817 static void server_send_reply(struct test_request
*req
, struct info
*info
, const char *msg
)
821 send( server_socket
, msg
, strlen( msg
), 0 );
822 WaitForSingleObject( info
->wait
, INFINITE
);
824 info
->test
= server_reply_test
;
825 info
->count
= ARRAY_SIZE( server_reply_test
);
827 setup_test( info
, winhttp_send_request
, __LINE__
);
828 ret
= WinHttpReceiveResponse( req
->request
, NULL
);
829 ok(ret
, "failed to receive response %u\n", GetLastError());
831 WaitForSingleObject( info
->wait
, INFINITE
);
832 end_test( info
, __LINE__
);
835 #define server_read_data(a) _server_read_data(a,__LINE__)
836 static void _server_read_data(const char *expect_prefix
, unsigned int line
)
841 size
= recv( server_socket
, buf
, sizeof(buf
), 0 );
842 len
= strlen( expect_prefix
);
843 ok_(__FILE__
,line
)(size
> len
, "data too short\n");
847 ok_(__FILE__
,line
)(!strcmp( buf
, expect_prefix
), "unexpected data \"%s\"\n", buf
);
851 static const struct notification close_request_test
[] =
853 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
854 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
855 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
}
858 static const struct notification close_allow_connection_close_request_test
[] =
860 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_ALLOW
},
861 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_ALLOW
},
862 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
863 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
},
864 { winhttp_close_handle
, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
, NF_SIGNAL
}
867 static void close_request(struct test_request
*req
, struct info
*info
, BOOL allow_closing_connection
)
871 if (allow_closing_connection
)
873 info
->test
= close_allow_connection_close_request_test
;
874 info
->count
= ARRAY_SIZE( close_allow_connection_close_request_test
);
878 info
->test
= close_request_test
;
879 info
->count
= ARRAY_SIZE( close_request_test
);
882 setup_test( info
, winhttp_close_handle
, __LINE__
);
884 ret
= WinHttpCloseHandle( req
->request
);
885 ok(ret
, "WinHttpCloseHandle failed: %u\n", GetLastError());
886 ret
= WinHttpCloseHandle( req
->connection
);
887 ok(ret
, "WinHttpCloseHandle failed: %u\n", GetLastError());
888 ret
= WinHttpCloseHandle( req
->session
);
889 ok(ret
, "WinHttpCloseHandle failed: %u\n", GetLastError());
891 WaitForSingleObject( info
->wait
, INFINITE
);
892 end_test( info
, __LINE__
);
895 static const struct notification read_test
[] =
897 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
, NF_ALLOW
},
898 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
, NF_ALLOW
},
899 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_READ_COMPLETE
, NF_SIGNAL
}
902 static const struct notification read_allow_close_test
[] =
904 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
, NF_ALLOW
},
905 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
, NF_ALLOW
},
906 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
, NF_ALLOW
},
907 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
, NF_ALLOW
},
908 { winhttp_read_data
, WINHTTP_CALLBACK_STATUS_READ_COMPLETE
, NF_SIGNAL
}
911 #define read_request_data(a,b,c,d) _read_request_data(a,b,c,d,__LINE__)
912 static void _read_request_data(struct test_request
*req
, struct info
*info
, const char *expected_data
, BOOL closing_connection
, unsigned line
)
918 if (closing_connection
)
920 info
->test
= read_allow_close_test
;
921 info
->count
= ARRAY_SIZE( read_allow_close_test
);
925 info
->test
= read_test
;
926 info
->count
= ARRAY_SIZE( read_test
);
930 setup_test( info
, winhttp_read_data
, line
);
931 memset(buffer
, '?', sizeof(buffer
));
932 ret
= WinHttpReadData( req
->request
, buffer
, sizeof(buffer
), NULL
);
933 ok(ret
, "failed to read data %u\n", GetLastError());
935 WaitForSingleObject( info
->wait
, INFINITE
);
937 len
= strlen(expected_data
);
938 ok(!memcmp(buffer
, expected_data
, len
), "unexpected data\n");
941 static void test_persistent_connection(int port
)
943 struct test_request req
;
946 trace("Testing persistent connection...\n");
948 info
.wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
);
950 open_socket_request( port
, &req
, &info
);
951 server_send_reply( &req
, &info
,
952 "HTTP/1.1 200 OK\r\n"
953 "Server: winetest\r\n"
954 "Connection: keep-alive\r\n"
955 "Content-Length: 1\r\n"
958 read_request_data( &req
, &info
, "X", FALSE
);
959 close_request( &req
, &info
, FALSE
);
961 /* chunked connection test */
962 open_async_request( port
, &req
, &info
, L
"/test", TRUE
);
963 server_read_data( "GET /test HTTP/1.1\r\n" );
964 server_send_reply( &req
, &info
,
965 "HTTP/1.1 200 OK\r\n"
966 "Server: winetest\r\n"
967 "Transfer-Encoding: chunked\r\n"
968 "Connection: keep-alive\r\n"
972 read_request_data( &req
, &info
, "123456789", FALSE
);
973 close_request( &req
, &info
, FALSE
);
975 /* HTTP/1.1 connections are persistent by default, no additional header is needed */
976 open_async_request( port
, &req
, &info
, L
"/test", TRUE
);
977 server_read_data( "GET /test HTTP/1.1\r\n" );
978 server_send_reply( &req
, &info
,
979 "HTTP/1.1 200 OK\r\n"
980 "Server: winetest\r\n"
981 "Content-Length: 2\r\n"
984 read_request_data( &req
, &info
, "xx", FALSE
);
985 close_request( &req
, &info
, FALSE
);
987 open_async_request( port
, &req
, &info
, L
"/test", TRUE
);
988 server_read_data( "GET /test HTTP/1.1\r\n" );
989 server_send_reply( &req
, &info
,
990 "HTTP/1.1 200 OK\r\n"
991 "Server: winetest\r\n"
992 "Content-Length: 2\r\n"
993 "Connection: close\r\n"
996 close_request( &req
, &info
, TRUE
);
998 SetEvent( server_socket_done
);
999 CloseHandle( info
.wait
);
1002 START_TEST (notification
)
1004 struct server_info si
;
1008 test_connection_cache();
1012 si
.event
= CreateEventW( NULL
, 0, 0, NULL
);
1015 thread
= CreateThread( NULL
, 0, server_thread
, &si
, 0, NULL
);
1016 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
1018 server_socket_available
= CreateEventW( NULL
, 0, 0, NULL
);
1019 server_socket_done
= CreateEventW( NULL
, 0, 0, NULL
);
1021 ret
= WaitForSingleObject( si
.event
, 10000 );
1022 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
1023 if (ret
!= WAIT_OBJECT_0
)
1025 CloseHandle(thread
);
1029 test_persistent_connection( si
.port
);
1031 /* send the basic request again to shutdown the server thread */
1032 test_basic_request( si
.port
, NULL
, L
"/quit" );
1034 WaitForSingleObject( thread
, 3000 );
1035 CloseHandle( thread
);
1036 CloseHandle( server_socket_available
);
1037 CloseHandle( server_socket_done
);