ReactOS 0.4.16-dev-2491-g3dc6630
notification.c
Go to the documentation of this file.
1/*
2 * test status notifications
3 *
4 * Copyright 2008 Hans Leidekker for CodeWeavers
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <stdarg.h>
22#include <stdlib.h>
23#include <windef.h>
24#include <winbase.h>
25#include <winsock2.h>
26#include <ws2tcpip.h>
27#include <winhttp.h>
28
29#include "wine/test.h"
30
31static DWORD (WINAPI *pWinHttpWebSocketClose)(HINTERNET,USHORT,void*,DWORD);
32static HINTERNET (WINAPI *pWinHttpWebSocketCompleteUpgrade)(HINTERNET,DWORD_PTR);
33static DWORD (WINAPI *pWinHttpWebSocketQueryCloseStatus)(HINTERNET,USHORT*,void*,DWORD,DWORD*);
34static DWORD (WINAPI *pWinHttpWebSocketReceive)(HINTERNET,void*,DWORD,DWORD*,WINHTTP_WEB_SOCKET_BUFFER_TYPE*);
35static DWORD (WINAPI *pWinHttpWebSocketSend)(HINTERNET,WINHTTP_WEB_SOCKET_BUFFER_TYPE,void*,DWORD);
36static DWORD (WINAPI *pWinHttpWebSocketShutdown)(HINTERNET,USHORT,void*,DWORD);
37
38enum api
39{
53};
54
56{
57 enum api function; /* api responsible for notification */
58 unsigned int status; /* status received */
59 DWORD flags; /* a combination of NF_* flags */
60};
61
62#define NF_ALLOW 0x0001 /* notification may or may not happen */
63#define NF_WINE_ALLOW 0x0002 /* wine sends notification when it should not */
64#define NF_SIGNAL 0x0004 /* signal wait handle when notified */
65#define NF_MAIN_THREAD 0x0008 /* the operation completes synchronously and callback is called from the main thread */
66#define NF_SAVE_BUFFER 0x0010 /* save buffer data when notified */
67#define NF_OTHER_THREAD 0x0020 /* the operation completes asynchronously and callback is called from the other thread */
68
69struct info
70{
72 const struct notification *test;
73 unsigned int count;
74 unsigned int index;
76 unsigned int line;
80 char buffer[256];
81 unsigned int buflen;
82};
83
85{
89};
90
92{
93 BOOL status_ok, function_ok;
94 struct info *info = (struct info *)context;
95
98
100 {
101 DWORD size = sizeof(struct info *);
103 }
104 while (info->index < info->count && info->test[info->index].status != status && (info->test[info->index].flags & NF_ALLOW))
105 info->index++;
106 while (info->index < info->count && (info->test[info->index].flags & NF_WINE_ALLOW))
107 {
108 todo_wine ok( info->test[info->index].status != status, "unexpected %#lx notification\n", status );
109 if (info->test[info->index].status == status) break;
110 info->index++;
111 }
112 ok( info->index < info->count, "%u: unexpected notification %#lx\n", info->line, status );
113 if (info->index >= info->count) return;
114
115 status_ok = (info->test[info->index].status == status);
116 function_ok = (info->test[info->index].function == info->function);
117
118 ok( status_ok, "%u: expected status %#x got %#lx\n", info->line, info->test[info->index].status, status );
119 ok(function_ok, "%u: expected function %u got %u\n", info->line, info->test[info->index].function, info->function);
120
121 if (info->test[info->index].flags & NF_MAIN_THREAD)
122 {
123 ok(GetCurrentThreadId() == info->main_thread_id, "%u: expected callback %#lx to be called from the same thread\n",
124 info->line, status);
125 }
126 else if (info->test[info->index].flags & NF_OTHER_THREAD)
127 {
128 ok(GetCurrentThreadId() != info->main_thread_id, "%u: expected callback %#lx to be called from the other thread\n",
129 info->line, status);
130 }
131 if (info->test[info->index].flags & NF_SAVE_BUFFER)
132 {
133 info->buflen = buflen;
134 memcpy( info->buffer, buffer, min( buflen, sizeof(info->buffer) ));
135 }
136
137 if (status_ok && function_ok && info->test[info->index++].flags & NF_SIGNAL)
138 {
139 SetEvent( info->wait );
140 }
141}
142
143static const struct notification cache_test_async[] =
144{
191};
192
193static const struct notification cache_test[] =
194{
237};
238
239static void setup_test( struct info *info, enum api function, unsigned int line )
240{
241 if (info->wait) ResetEvent( info->wait );
243 info->line = line;
244 while (info->index < info->count && info->test[info->index].function != function
245 && (info->test[info->index].flags & (NF_ALLOW | NF_WINE_ALLOW)))
246 info->index++;
247 ok_(__FILE__,line)(info->test[info->index].function == function,
248 "unexpected function %u, expected %u. probably some notifications were missing\n",
249 info->test[info->index].function, function);
250 info->last_thread_id = 0xdeadbeef;
251 info->last_status = 0xdeadbeef;
253}
254
255static void end_test( struct info *info, unsigned int line )
256{
257 ok_(__FILE__,line)(info->index == info->count, "some notifications were missing: %x\n",
258 info->test[info->index].status);
259}
260
262{
263 HANDLE ses, con, req, event;
265 BOOL ret, unload = TRUE;
266 struct info info, *context = &info;
267
270 info.index = 0;
272
273 ses = WinHttpOpen( L"winetest", 0, NULL, NULL, async ? WINHTTP_FLAG_ASYNC : 0 );
274 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
275
276 event = CreateEventW( NULL, FALSE, FALSE, NULL );
278 if (!ret)
279 {
280 win_skip("Unload event not supported\n");
281 unload = FALSE;
282 }
283
285
286 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
287 ok( ret, "failed to set context value %lu\n", GetLastError() );
288
289 setup_test( &info, winhttp_connect, __LINE__ );
290 con = WinHttpConnect( ses, L"test.winehq.org", 0, 0 );
291 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
292
293 setup_test( &info, winhttp_open_request, __LINE__ );
294 req = WinHttpOpenRequest( con, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
295 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
296
297 setup_test( &info, winhttp_send_request, __LINE__ );
298 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
299 err = GetLastError();
301 {
302 skip("connection failed, skipping\n");
303 goto done;
304 }
305 ok( ret, "failed to send request %lu\n", GetLastError() );
307
310 ok( ret, "failed to receive response %lu\n", GetLastError() );
311
313
314 size = sizeof(status);
316 ok( ret, "failed unexpectedly %lu\n", GetLastError() );
317 ok( status == 200, "request failed unexpectedly %lu\n", status );
318
320 setup_test( &info, winhttp_close_handle, __LINE__ );
321 WinHttpCloseHandle( req );
322
324
325 setup_test( &info, winhttp_open_request, __LINE__ );
326 req = WinHttpOpenRequest( con, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
327 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
328
329 ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
330 ok( ret, "failed to set context value %lu\n", GetLastError() );
331
332 setup_test( &info, winhttp_send_request, __LINE__ );
333 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
334 err = GetLastError();
336 {
337 skip("connection failed, skipping\n");
338 goto done;
339 }
340 ok( ret, "failed to send request %lu\n", GetLastError() );
341
343
346 ok( ret, "failed to receive response %lu\n", GetLastError() );
347
349
350 size = sizeof(status);
352 ok( ret, "failed unexpectedly %lu\n", GetLastError() );
353 ok( status == 200, "request failed unexpectedly %lu\n", status );
354
356 setup_test( &info, winhttp_close_handle, __LINE__ );
357 WinHttpCloseHandle( req );
358 WinHttpCloseHandle( req );
359 WinHttpCloseHandle( con );
361
362 if (unload)
363 {
365 ok( status == WAIT_TIMEOUT, "got %#lx\n", status );
366 }
367
368 setup_test( &info, winhttp_close_handle, __LINE__ );
369 WinHttpCloseHandle( ses );
371
372 if (unload)
373 {
375 ok( status == WAIT_OBJECT_0, "got %#lx\n", status );
376 }
377
378 ses = WinHttpOpen( L"winetest", 0, NULL, NULL, 0 );
379 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
380
381 if (unload)
382 {
384 ok(ret, "failed to set unload option\n");
385 }
386
388
389 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
390 ok( ret, "failed to set context value %lu\n", GetLastError() );
391
392 setup_test( &info, winhttp_connect, __LINE__ );
393 con = WinHttpConnect( ses, L"test.winehq.org", 0, 0 );
394 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
395
396 setup_test( &info, winhttp_open_request, __LINE__ );
397 req = WinHttpOpenRequest( con, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
398 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
399
400 ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
401 ok( ret, "failed to set context value %lu\n", GetLastError() );
402
403 setup_test( &info, winhttp_send_request, __LINE__ );
404 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
405 err = GetLastError();
407 {
408 skip("connection failed, skipping\n");
409 goto done;
410 }
411 ok( ret, "failed to send request %lu\n", GetLastError() );
412
415 ok( ret, "failed to receive response %lu\n", GetLastError() );
416
417 size = sizeof(status);
419 ok( ret, "failed unexpectedly %lu\n", GetLastError() );
420 ok( status == 200, "request failed unexpectedly %lu\n", status );
421
423 setup_test( &info, winhttp_close_handle, __LINE__ );
424 WinHttpCloseHandle( req );
426
427 setup_test( &info, winhttp_open_request, __LINE__ );
428 req = WinHttpOpenRequest( con, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
429 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
430
431 ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
432 ok( ret, "failed to set context value %lu\n", GetLastError() );
433
434 setup_test( &info, winhttp_send_request, __LINE__ );
435 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
436 err = GetLastError();
438 {
439 skip("connection failed, skipping\n");
440 goto done;
441 }
442 ok( ret, "failed to send request %lu\n", GetLastError() );
443
446 ok( ret, "failed to receive response %lu\n", GetLastError() );
447
448 size = sizeof(status);
450 ok( ret, "failed unexpectedly %lu\n", GetLastError() );
451 ok( status == 200, "request failed unexpectedly %lu\n", status );
452
453 setup_test( &info, winhttp_close_handle, __LINE__ );
454done:
455 WinHttpCloseHandle( req );
456 WinHttpCloseHandle( con );
458
459 if (unload)
460 {
462 ok( status == WAIT_TIMEOUT, "got %#lx\n", status );
463 }
464
465 setup_test( &info, winhttp_close_handle, __LINE__ );
466 WinHttpCloseHandle( ses );
469 end_test( &info, __LINE__ );
470
471 if (unload)
472 {
474 ok( status == WAIT_OBJECT_0, "got %#lx\n", status );
475 }
476
478}
479
480static const struct notification redirect_test[] =
481{
504};
505
506static const struct notification redirect_test_async[] =
507{
532};
533
535{
536 HANDLE ses, con, req;
538 BOOL ret;
539 struct info info, *context = &info;
540
543 info.index = 0;
545
546 ses = WinHttpOpen( L"winetest", 0, NULL, NULL, async ? WINHTTP_FLAG_ASYNC : 0 );
547 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
548
550
551 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
552 ok( ret, "failed to set context value %lu\n", GetLastError() );
553
554 setup_test( &info, winhttp_connect, __LINE__ );
555 con = WinHttpConnect( ses, L"test.winehq.org", 0, 0 );
556 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
557
558 setup_test( &info, winhttp_open_request, __LINE__ );
559 req = WinHttpOpenRequest( con, NULL, L"/tests/redirect", NULL, NULL, NULL, 0 );
560 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
561
562 setup_test( &info, winhttp_send_request, __LINE__ );
563 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
564 err = GetLastError();
566 {
567 skip("connection failed, skipping\n");
568 goto done;
569 }
570 ok( ret, "failed to send request %lu\n", GetLastError() );
572
575 ok( ret, "failed to receive response %lu\n", GetLastError() );
577
578 size = sizeof(status);
579 status = 0xdeadbeef;
581 ok( ret, "failed unexpectedly %lu\n", GetLastError() );
582 ok( status == 200, "request failed unexpectedly %lu\n", status );
583
584 setup_test( &info, winhttp_close_handle, __LINE__ );
585done:
586 WinHttpCloseHandle( req );
587 WinHttpCloseHandle( con );
588 WinHttpCloseHandle( ses );
591 end_test( &info, __LINE__ );
592}
593
594static const struct notification async_test[] =
595{
618};
619
620static void test_async( void )
621{
622 HANDLE ses, con, req, event;
624 BOOL ret, unload = TRUE;
625 struct info info, *context = &info;
626 char buffer[1024];
627
630 info.index = 0;
632
633 ses = WinHttpOpen( L"winetest", 0, NULL, NULL, WINHTTP_FLAG_ASYNC );
634 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
635
636 event = CreateEventW( NULL, FALSE, FALSE, NULL );
638 if (!ret)
639 {
640 win_skip("Unload event not supported\n");
641 unload = FALSE;
642 }
643
644 SetLastError( 0xdeadbeef );
646 err = GetLastError();
647 ok( err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
648
649 SetLastError( 0xdeadbeef );
650 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
651 err = GetLastError();
652 ok( ret, "failed to set context value %lu\n", err );
653 ok( err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
654
655 setup_test( &info, winhttp_connect, __LINE__ );
656 SetLastError( 0xdeadbeef );
657 con = WinHttpConnect( ses, L"test.winehq.org", 0, 0 );
658 err = GetLastError();
659 ok( con != NULL, "failed to open a connection %lu\n", err );
660 ok( err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %lu\n", err );
661
662 setup_test( &info, winhttp_open_request, __LINE__ );
663 SetLastError( 0xdeadbeef );
664 req = WinHttpOpenRequest( con, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
665 err = GetLastError();
666 ok( req != NULL, "failed to open a request %lu\n", err );
667 ok( err == ERROR_SUCCESS, "got %lu\n", err );
668
670 err = GetLastError();
671 ok(ret, "WinHttpAddRequestHeaders failed to add new header, got %d with error %lu\n", ret, err);
672
673 setup_test( &info, winhttp_send_request, __LINE__ );
674 SetLastError( 0xdeadbeef );
675 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
676 err = GetLastError();
678 {
679 skip("connection failed, skipping\n");
680 WinHttpCloseHandle( req );
681 WinHttpCloseHandle( con );
682 WinHttpCloseHandle( ses );
684 return;
685 }
686 ok( ret, "failed to send request %lu\n", err );
687 ok( err == ERROR_SUCCESS, "got %lu\n", err );
688
690
692 SetLastError( 0xdeadbeef );
694 err = GetLastError();
695 ok( ret, "failed to receive response %lu\n", err );
696 ok( err == ERROR_SUCCESS, "got %lu\n", err );
697
698 SetLastError( 0xdeadbeef );
700 err = GetLastError();
701 ok( ret, "failed to receive response %lu\n", err );
702 ok( err == ERROR_SUCCESS, "got %lu\n", err );
703
705
706 size = sizeof(status);
707 SetLastError( 0xdeadbeef );
709 err = GetLastError();
710 ok( ret, "failed unexpectedly %lu\n", err );
711 ok( status == 200, "request failed unexpectedly %lu\n", status );
712 ok( err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
713
714 setup_test( &info, winhttp_query_data, __LINE__ );
715 SetLastError( 0xdeadbeef );
717 err = GetLastError();
718 ok( ret, "failed to query data available %lu\n", err );
719 ok( err == ERROR_SUCCESS || err == ERROR_IO_PENDING || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
720
725 "got unexpected thread %#lx, err %#lx\n", info.last_thread_id, err );
726
727 setup_test( &info, winhttp_read_data, __LINE__ );
728 ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL );
729 ok( ret, "failed to read data %lu\n", err );
730
732
736 "got unexpected thread %#lx, err %#lx\n", info.last_thread_id, err );
737
738 setup_test( &info, winhttp_close_handle, __LINE__ );
739 WinHttpCloseHandle( req );
740 WinHttpCloseHandle( con );
741
742 if (unload)
743 {
745 ok( status == WAIT_TIMEOUT, "got %#lx\n", status );
746 }
747 WinHttpCloseHandle( ses );
749 end_test( &info, __LINE__ );
750
751 if (unload)
752 {
754 ok( status == WAIT_OBJECT_0, "got %#lx\n", status );
755 }
758 end_test( &info, __LINE__ );
759}
760
761static const struct notification websocket_test[] =
762{
787};
788
789static const struct notification websocket_test2[] =
790{
808};
809
810static const struct notification websocket_test3[] =
811{
825
829
831};
832
834{
848
851
853};
854
855static const struct notification websocket_test5[] =
856{
870
879};
880
881#define BIG_BUFFER_SIZE (16 * 1024)
882
884{
885 HANDLE session, connection, request, socket, event;
887 WINHTTP_WEB_SOCKET_STATUS *ws_status;
890 BOOL ret, unload = TRUE;
891 struct info info, *context = &info;
892 unsigned char *big_buffer;
893 char buffer[1024];
894 USHORT close_status;
896 unsigned int i, test_index, offset;
897
898 if (!pWinHttpWebSocketCompleteUpgrade)
899 {
900 win_skip( "WinHttpWebSocketCompleteUpgrade not supported\n" );
901 return;
902 }
903
906 info.index = 0;
908
909 session = WinHttpOpen( L"winetest", 0, NULL, NULL, WINHTTP_FLAG_ASYNC );
910 ok( session != NULL, "got %lu\n", GetLastError() );
911
912 event = CreateEventW( NULL, FALSE, FALSE, NULL );
914 if (!ret)
915 {
916 win_skip( "Unload event not supported\n" );
917 unload = FALSE;
918 }
919
920 if (secure)
921 {
924 ok( ret, "failed to set protocols %lu\n", GetLastError() );
925 }
926
927 SetLastError( 0xdeadbeef );
929 err = GetLastError();
930 ok( err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
931
932 SetLastError( 0xdeadbeef );
934 err = GetLastError();
935 ok( ret, "got %lu\n", err );
936 ok( err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
937
938 setup_test( &info, winhttp_connect, __LINE__ );
939 SetLastError( 0xdeadbeef );
940 connection = WinHttpConnect( session, L"ws.ifelse.io", 0, 0 );
941 err = GetLastError();
942 ok( connection != NULL, "got %lu\n", err );
943 ok( err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %lu\n", err );
944
945 setup_test( &info, winhttp_open_request, __LINE__ );
946 SetLastError( 0xdeadbeef );
948 err = GetLastError();
949 ok( request != NULL, "got %lu\n", err );
950 ok( err == ERROR_SUCCESS, "got %lu\n", err );
951
952 if (secure)
953 {
957 ok( ret, "failed to set security flags %lu\n", GetLastError() );
958 }
959
961 ok( ret, "got %lu\n", GetLastError() );
962
963 setup_test( &info, winhttp_send_request, __LINE__ );
964
965 value = 15;
967 ok(ret, "got %lu\n", GetLastError());
968 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, 0, 0 );
969 err = GetLastError();
970 ok( ret, "got err %lu.\n", err );
971
973
974 value = 32768;
976 ok(ret, "got %lu\n", GetLastError());
977
978 SetLastError( 0xdeadbeef );
979 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, 0, 0 );
980 err = GetLastError();
982 {
983 skip( "connection failed, skipping\n" );
985 WinHttpCloseHandle( connection );
988 return;
989 }
990 ok( ret, "got %lu\n", err );
991 ok( err == ERROR_SUCCESS, "got %lu\n", err );
993
995 SetLastError( 0xdeadbeef );
997 err = GetLastError();
998 ok( ret, "got %lu\n", err );
999 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1001
1002 size = sizeof(status);
1003 SetLastError( 0xdeadbeef );
1005 err = GetLastError();
1006 ok( ret, "failed unexpectedly %lu\n", err );
1007 ok( status == 101, "got %lu\n", status );
1008 ok( err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err );
1009
1011 SetLastError( 0xdeadbeef );
1012 socket = pWinHttpWebSocketCompleteUpgrade( request, (DWORD_PTR)context );
1013 err = GetLastError();
1014 ok( socket != NULL, "got %lu\n", err );
1015 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1016
1018
1020
1021 /* The send is executed synchronously (even if sending a reasonably big buffer exceeding SSL buffer size).
1022 * It is possible to trigger queueing the send into another thread but that involves sending a considerable
1023 * amount of big enough buffers. */
1024 big_buffer = malloc( BIG_BUFFER_SIZE );
1025 for (i = 0; i < BIG_BUFFER_SIZE; ++i) big_buffer[i] = (i & 0xff) ^ 0xcc;
1026
1027 setup_test( &info, winhttp_websocket_send, __LINE__ );
1028 err = pWinHttpWebSocketSend( socket, WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE, big_buffer, BIG_BUFFER_SIZE / 2 );
1029 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1031
1033 big_buffer + BIG_BUFFER_SIZE / 2, BIG_BUFFER_SIZE / 2 );
1034 ok( err == ERROR_INVALID_PARAMETER, "got %lu\n", err );
1035 err = pWinHttpWebSocketSend( socket, WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE,
1036 big_buffer + BIG_BUFFER_SIZE / 2, BIG_BUFFER_SIZE / 2 );
1037 ok( err == ERROR_INVALID_PARAMETER, "got %lu\n", err );
1038
1039 setup_test( &info, winhttp_websocket_send, __LINE__ );
1041 big_buffer + BIG_BUFFER_SIZE / 2, BIG_BUFFER_SIZE / 2 );
1042 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1044
1045 setup_test( &info, winhttp_websocket_send, __LINE__ );
1046 err = pWinHttpWebSocketSend( socket, WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, NULL, 0 );
1047 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1049
1050 setup_test( &info, winhttp_websocket_send, __LINE__ );
1051 err = pWinHttpWebSocketSend( socket, WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, (void *)"hello", sizeof("hello") );
1052 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1054
1056 err = pWinHttpWebSocketShutdown( socket, 1000, (void *)"success", sizeof("success") );
1057 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1058
1059 err = pWinHttpWebSocketSend( socket, WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, (void *)"hello", sizeof("hello") );
1060 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1061
1063
1064 err = pWinHttpWebSocketShutdown( socket, 1000, (void *)"success", sizeof("success") );
1065 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1066 err = pWinHttpWebSocketSend( socket, WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, (void *)"hello", sizeof("hello") );
1067 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1068
1070 buffer[0] = 0;
1071 size = 0xdeadbeef;
1072 type = 0xdeadbeef;
1073 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1074 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1076 ok( info.buflen == sizeof(*ws_status), "got %u\n", info.buflen );
1077 ws_status = (WINHTTP_WEB_SOCKET_STATUS *)info.buffer;
1079 "got unexpected eBufferType %u\n", ws_status->eBufferType );
1080 ok( size == 0xdeadbeef, "got %lu\n", size );
1081 ok( type == 0xdeadbeef, "got %u\n", type );
1082 ok( buffer[0] == 'R', "unexpected data\n" );
1083
1084 memset( big_buffer, 0, BIG_BUFFER_SIZE );
1085 offset = 0;
1086 test_index = info.index;
1087 do
1088 {
1089 info.index = test_index;
1091 size = 0xdeadbeef;
1092 type = 0xdeadbeef;
1093 ws_status = (WINHTTP_WEB_SOCKET_STATUS *)info.buffer;
1094 ws_status->eBufferType = ~0u;
1095 err = pWinHttpWebSocketReceive( socket, big_buffer + offset, BIG_BUFFER_SIZE - offset, &size, &type );
1096 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1098 ok( info.buflen == sizeof(*ws_status), "got %u\n", info.buflen );
1100 || ws_status->eBufferType == WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE, "got %u\n", ws_status->eBufferType );
1101 offset += ws_status->dwBytesTransferred;
1102 ok( offset <= BIG_BUFFER_SIZE, "got %lu\n", ws_status->dwBytesTransferred );
1103 ok( size == 0xdeadbeef, "got %lu\n", size );
1104 ok( type == 0xdeadbeef, "got %u\n", type );
1105 }
1107
1108 ok( offset == BIG_BUFFER_SIZE, "got %u\n", offset );
1109
1110 for (i = 0; i < BIG_BUFFER_SIZE; ++i)
1111 if (big_buffer[i] != ((i & 0xff) ^ 0xcc)) break;
1112 ok( i == BIG_BUFFER_SIZE, "unexpected data %#x at %u\n", (unsigned char)big_buffer[i], i );
1113
1114 free( big_buffer );
1115
1116 close_status = 0xdead;
1117 size = sizeof(buffer) + 1;
1118 err = pWinHttpWebSocketQueryCloseStatus( socket, &close_status, buffer, sizeof(buffer), &size );
1119 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1120 ok( close_status == 0xdead, "got %u\n", close_status );
1121 ok( size == sizeof(buffer) + 1, "got %lu\n", size );
1122
1124 err = pWinHttpWebSocketClose( socket, 1000, (void *)"success", sizeof("success") );
1125 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1127
1128 close_status = 0xdead;
1129 size = sizeof(buffer) + 1;
1130 err = pWinHttpWebSocketQueryCloseStatus( socket, &close_status, buffer, sizeof(buffer), &size );
1131 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1132 ok( close_status == 1000, "got %u\n", close_status );
1133 ok( size <= sizeof(buffer), "got %lu\n", size );
1134
1135 setup_test( &info, winhttp_close_handle, __LINE__ );
1137
1139 end_test( &info, __LINE__ );
1140
1141 /* Test socket close while receive is pending. */
1144 info.index = 0;
1145
1146 setup_test( &info, winhttp_open_request, __LINE__ );
1147 request = WinHttpOpenRequest( connection, NULL, L"/", NULL, NULL, NULL, secure ? WINHTTP_FLAG_SECURE : 0);
1148 ok( request != NULL, "got %lu\n", err );
1149
1150 if (secure)
1151 {
1155 ok( ret, "failed to set security flags %lu\n", GetLastError() );
1156 }
1157
1159 ok( ret, "got %lu\n", GetLastError() );
1160
1161 setup_test( &info, winhttp_send_request, __LINE__ );
1162 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, 0, 0 );
1163 ok( ret, "got %lu\n", GetLastError() );
1165
1168 ok( ret, "got %lu\n", err );
1170
1171 size = sizeof(status);
1173 ok( ret, "failed unexpectedly %lu\n", err );
1174 ok( status == 101, "got %lu\n", status );
1175
1177 socket = pWinHttpWebSocketCompleteUpgrade( request, (DWORD_PTR)context );
1178 ok( socket != NULL, "got %lu\n", err );
1180
1182 buffer[0] = 0;
1183 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1184 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1186 ok( buffer[0] == 'R', "unexpected data\n" );
1187
1188 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1189 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1190
1192 err = pWinHttpWebSocketClose( socket, 1000, (void *)"success", sizeof("success") );
1193 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1194 ok( info.buflen == sizeof(*result), "got %u\n", info.buflen );
1196 ok( result->Operation == WINHTTP_WEB_SOCKET_RECEIVE_OPERATION, "got %u\n", result->Operation );
1197 ok( !result->AsyncResult.dwResult, "got %Iu\n", result->AsyncResult.dwResult );
1198 ok( result->AsyncResult.dwError == ERROR_WINHTTP_OPERATION_CANCELLED, "got %lu\n", result->AsyncResult.dwError );
1199
1200 close_status = 0xdead;
1201 size = sizeof(buffer) + 1;
1202 err = pWinHttpWebSocketQueryCloseStatus( socket, &close_status, buffer, sizeof(buffer), &size );
1203 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1204 ok( close_status == 0xdead, "got %u\n", close_status );
1205 ok( size == sizeof(buffer) + 1, "got %lu\n", size );
1206
1208
1209 close_status = 0xdead;
1210 size = sizeof(buffer) + 1;
1211 err = pWinHttpWebSocketQueryCloseStatus( socket, &close_status, buffer, sizeof(buffer), &size );
1212 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1213 ok( close_status == 1000, "got %u\n", close_status );
1214 ok( size <= sizeof(buffer), "got %lu\n", size );
1215
1216 setup_test( &info, winhttp_close_handle, __LINE__ );
1219
1221 end_test( &info, __LINE__ );
1222
1223
1224 /* Test socket handle close while web socket close is pending. */
1227 info.index = 0;
1228
1229 setup_test( &info, winhttp_open_request, __LINE__ );
1230 request = WinHttpOpenRequest( connection, NULL, L"/", NULL, NULL, NULL, secure ? WINHTTP_FLAG_SECURE : 0);
1231 ok( request != NULL, "got %lu\n", err );
1232
1233 if (secure)
1234 {
1238 ok( ret, "failed to set security flags %lu\n", GetLastError() );
1239 }
1240
1242 ok( ret, "got %lu\n", GetLastError() );
1243
1244 setup_test( &info, winhttp_send_request, __LINE__ );
1245 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, 0, 0 );
1246 ok( ret, "got %lu\n", GetLastError() );
1248
1251 ok( ret, "got %lu\n", err );
1253
1254 size = sizeof(status);
1256 ok( ret, "failed unexpectedly %lu\n", err );
1257 ok( status == 101, "got %lu\n", status );
1258
1260 socket = pWinHttpWebSocketCompleteUpgrade( request, (DWORD_PTR)context );
1261 ok( socket != NULL, "got %lu\n", err );
1263
1265 buffer[0] = 0;
1266 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1267 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1269 ok( buffer[0] == 'R', "unexpected data\n" );
1270
1272
1273 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1274 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1275
1276 err = pWinHttpWebSocketClose( socket, 1000, (void *)"success", sizeof("success") );
1277 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1278
1279 info.buflen = 0xdeadbeef;
1282
1283 ok( info.buflen == sizeof(*result), "got %u\n", info.buflen );
1285 ok( result->Operation == WINHTTP_WEB_SOCKET_CLOSE_OPERATION, "got %u\n", result->Operation );
1286 todo_wine ok( !result->AsyncResult.dwResult, "got %Iu\n", result->AsyncResult.dwResult );
1287 ok( result->AsyncResult.dwError == ERROR_WINHTTP_OPERATION_CANCELLED, "got %lu\n", result->AsyncResult.dwError );
1288
1289 setup_test( &info, winhttp_close_handle, __LINE__ );
1292 end_test( &info, __LINE__ );
1293
1294 /* Test socket handle close while receive is pending. */
1297 info.index = 0;
1298
1299 setup_test( &info, winhttp_open_request, __LINE__ );
1300 request = WinHttpOpenRequest( connection, NULL, L"/", NULL, NULL, NULL, secure ? WINHTTP_FLAG_SECURE : 0);
1301 ok( request != NULL, "got %lu\n", err );
1302
1303 if (secure)
1304 {
1308 ok( ret, "failed to set security flags %lu\n", GetLastError() );
1309 }
1310
1312 ok( ret, "got %lu\n", GetLastError() );
1313
1314 setup_test( &info, winhttp_send_request, __LINE__ );
1315 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, 0, 0 );
1316 ok( ret, "got %lu\n", GetLastError() );
1318
1321 ok( ret, "got %lu\n", err );
1323
1324 size = sizeof(status);
1326 ok( ret, "failed unexpectedly %lu\n", err );
1327 ok( status == 101, "got %lu\n", status );
1328
1330 socket = pWinHttpWebSocketCompleteUpgrade( request, (DWORD_PTR)context );
1331 ok( socket != NULL, "got %lu\n", err );
1333
1335 buffer[0] = 0;
1336 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1337 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1339 ok( buffer[0] == 'R', "unexpected data\n" );
1340
1342
1343 info.buflen = 0xdeadbeef;
1344
1345 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1346 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1347
1350
1351 ok( info.buflen == sizeof(*result), "got %u\n", info.buflen );
1353 ok( result->Operation == WINHTTP_WEB_SOCKET_RECEIVE_OPERATION, "got %u\n", result->Operation );
1354 ok( !result->AsyncResult.dwResult, "got %Iu\n", result->AsyncResult.dwResult );
1355 ok( result->AsyncResult.dwError == ERROR_WINHTTP_OPERATION_CANCELLED, "got %lu\n", result->AsyncResult.dwError );
1356
1357 setup_test( &info, winhttp_close_handle, __LINE__ );
1360 end_test( &info, __LINE__ );
1361
1362 /* Test socket shutdown while receive is pending. */
1365 info.index = 0;
1366
1367 setup_test( &info, winhttp_open_request, __LINE__ );
1368 request = WinHttpOpenRequest( connection, NULL, L"/", NULL, NULL, NULL, secure ? WINHTTP_FLAG_SECURE : 0);
1369 ok( request != NULL, "got %lu\n", err );
1370
1371 if (secure)
1372 {
1376 ok( ret, "failed to set security flags %lu\n", GetLastError() );
1377 }
1378
1380 ok( ret, "got %lu\n", GetLastError() );
1381
1382 setup_test( &info, winhttp_send_request, __LINE__ );
1383 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, 0, 0 );
1384 ok( ret, "got %lu\n", GetLastError() );
1386
1389 ok( ret, "got %lu\n", err );
1391
1392 size = sizeof(status);
1394 ok( ret, "failed unexpectedly %lu\n", err );
1395 ok( status == 101, "got %lu\n", status );
1396
1398 socket = pWinHttpWebSocketCompleteUpgrade( request, (DWORD_PTR)context );
1399 ok( socket != NULL, "got %lu\n", err );
1401
1403 buffer[0] = 0;
1404 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1405 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1407 ok( buffer[0] == 'R', "unexpected data\n" );
1408
1409 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1410 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1411 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1412 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1413
1415 ws_status = (WINHTTP_WEB_SOCKET_STATUS *)info.buffer;
1416 ws_status->eBufferType = ~0u;
1417 err = pWinHttpWebSocketShutdown( socket, 1000, (void *)"success", sizeof("success") );
1418 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1419
1420 close_status = 0xdead;
1421 size = sizeof(buffer) + 1;
1422 err = pWinHttpWebSocketQueryCloseStatus( socket, &close_status, buffer, sizeof(buffer), &size );
1423 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1424 ok( close_status == 0xdead, "got %u\n", close_status );
1425 ok( size == sizeof(buffer) + 1, "got %lu\n", size );
1426
1428
1429 ok( info.buflen == sizeof(*ws_status), "got %u\n", info.buflen );
1430 ok( ws_status->eBufferType == WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE, "got %u\n", ws_status->eBufferType );
1431 ok( !ws_status->dwBytesTransferred, "got %lu\n", ws_status->dwBytesTransferred );
1432
1433 close_status = 0xdead;
1434 size = sizeof(buffer) + 1;
1435 err = pWinHttpWebSocketQueryCloseStatus( socket, &close_status, buffer, sizeof(buffer), &size );
1436 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1437 ok( close_status == 1000, "got %u\n", close_status );
1438 ok( size <= sizeof(buffer), "got %lu\n", size );
1439
1440 err = pWinHttpWebSocketReceive( socket, buffer, sizeof(buffer), &size, &type );
1441 ok( err == ERROR_INVALID_OPERATION, "got %lu\n", err );
1442
1443 info.buflen = 0xdeadbeef;
1445 err = pWinHttpWebSocketClose( socket, 1000, (void *)"success", sizeof("success") );
1446 ok( err == ERROR_SUCCESS, "got %lu\n", err );
1447
1449 ok( !info.buflen, "got %u\n", info.buflen );
1450
1451 setup_test( &info, winhttp_close_handle, __LINE__ );
1452
1455 WinHttpCloseHandle( connection );
1456
1457 if (unload)
1458 {
1460 ok( status == WAIT_TIMEOUT, "got %#lx\n", status );
1461 }
1464 end_test( &info, __LINE__ );
1465
1466 if (unload)
1467 {
1468 status = WaitForSingleObject( event, 2000 );
1469 ok( status == WAIT_OBJECT_0, "got %#lx\n", status );
1470 }
1471 CloseHandle( event );
1473 end_test( &info, __LINE__ );
1474}
1475
1476static const char okmsg[] =
1477"HTTP/1.1 200 OK\r\n"
1478"Server: winetest\r\n"
1479"\r\n";
1480
1481static const char page1[] =
1482"<HTML>\r\n"
1483"<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1484"<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1485"</HTML>\r\n\r\n";
1486
1487struct server_info
1488{
1490 int port;
1491};
1492
1493static int server_socket;
1495
1497{
1498 struct server_info *si = param;
1499 int r, c = -1, i, on;
1500 SOCKET s;
1501 struct sockaddr_in sa;
1502 char buffer[0x100];
1503 WSADATA wsaData;
1504 int last_request = 0;
1505
1506 WSAStartup(MAKEWORD(1,1), &wsaData);
1507
1508 s = socket(AF_INET, SOCK_STREAM, 0);
1509 if (s == INVALID_SOCKET)
1510 return 1;
1511
1512 on = 1;
1513 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1514
1515 memset(&sa, 0, sizeof sa);
1516 sa.sin_family = AF_INET;
1517 sa.sin_port = htons(si->port);
1518 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1519
1520 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1521 if (r < 0)
1522 return 1;
1523
1524 listen(s, 0);
1525 SetEvent(si->event);
1526 do
1527 {
1528 if (c == -1) c = accept(s, NULL, NULL);
1530 memset(buffer, 0, sizeof buffer);
1531 for(i = 0; i < sizeof buffer - 1; i++)
1532 {
1533 r = recv(c, &buffer[i], 1, 0);
1534 if (r != 1)
1535 break;
1536 if (i < 4) continue;
1537 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1538 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1539 break;
1540 }
1541 if (strstr(buffer, "GET /quit"))
1542 {
1543 send(c, okmsg, sizeof okmsg - 1, 0);
1544 send(c, page1, sizeof page1 - 1, 0);
1545 last_request = 1;
1546 }
1547 else if(strstr(buffer, "GET /socket"))
1548 {
1549 server_socket = c;
1553 }
1554 shutdown(c, 2);
1555 closesocket(c);
1557 c = -1;
1558 } while (!last_request);
1559
1560 closesocket(s);
1561 return 0;
1562}
1563
1564static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1565{
1566 HINTERNET ses, con, req;
1567 char buffer[0x100];
1569 BOOL ret;
1570
1572 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
1573
1574 con = WinHttpConnect(ses, L"localhost", port, 0);
1575 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
1576
1577 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1578 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
1579
1580 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1581 ok( ret, "failed to send request %lu\n", GetLastError() );
1582
1584 ok( ret, "failed to receive response %lu\n", GetLastError() );
1585
1586 status = 0xdeadbeef;
1587 size = sizeof(status);
1589 ok( ret, "failed to query status code %lu\n", GetLastError());
1590 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status );
1591
1592 count = 0;
1593 memset(buffer, 0, sizeof(buffer));
1594 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1595 ok( ret, "failed to read data %lu\n", GetLastError() );
1596 ok(count == sizeof page1 - 1, "count was wrong\n");
1597 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1598
1599 WinHttpCloseHandle(req);
1600 WinHttpCloseHandle(con);
1601 WinHttpCloseHandle(ses);
1602}
1603
1605{
1611 { winhttp_send_request, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER, NF_ALLOW }, /* some versions call it twice. why? */
1616};
1617
1619{
1625};
1626
1627static void open_async_request(int port, struct test_request *req, struct info *info, const WCHAR *path, BOOL reuse_connection)
1628{
1629 BOOL ret;
1630
1631 info->index = 0;
1632 if (reuse_connection)
1633 {
1636 }
1637 else
1638 {
1641 }
1642
1643 req->session = WinHttpOpen( L"winetest", 0, NULL, NULL, WINHTTP_FLAG_ASYNC );
1644 ok( req->session != NULL, "failed to open session %lu\n", GetLastError() );
1645
1646 WinHttpSetOption( req->session, WINHTTP_OPTION_CONTEXT_VALUE, &info, sizeof(struct info *) );
1648
1649 setup_test( info, winhttp_connect, __LINE__ );
1650 req->connection = WinHttpConnect( req->session, L"localhost", port, 0 );
1651 ok( req->connection != NULL, "failed to open a connection %lu\n", GetLastError() );
1652
1653 setup_test( info, winhttp_open_request, __LINE__ );
1654 req->request = WinHttpOpenRequest( req->connection, NULL, path, NULL, NULL, NULL, 0 );
1655 ok( req->request != NULL, "failed to open a request %lu\n", GetLastError() );
1656
1657 setup_test( info, winhttp_send_request, __LINE__ );
1658 ret = WinHttpSendRequest( req->request, NULL, 0, NULL, 0, 0, 0 );
1659 ok( ret, "failed to send request %lu\n", GetLastError() );
1660}
1661
1662static void open_socket_request(int port, struct test_request *req, struct info *info)
1663{
1665 open_async_request( port, req, info, L"/socket", FALSE );
1667}
1668
1669static const struct notification server_reply_test[] =
1670{
1674};
1675
1676static void server_send_reply(struct test_request *req, struct info *info, const char *msg)
1677{
1678 BOOL ret;
1679
1680 send( server_socket, msg, strlen( msg ), 0 );
1682
1685 info->index = 0;
1686 setup_test( info, winhttp_send_request, __LINE__ );
1688 ok( ret, "failed to receive response %lu\n", GetLastError() );
1689
1691 end_test( info, __LINE__ );
1692}
1693
1694#define server_read_data(a) _server_read_data(a,__LINE__)
1695static void _server_read_data(const char *expect_prefix, unsigned int line)
1696{
1697 char buf[1024];
1698 DWORD size, len;
1699
1700 size = recv( server_socket, buf, sizeof(buf), 0 );
1701 len = strlen( expect_prefix );
1702 ok_(__FILE__,line)(size > len, "data too short\n");
1703 if (size >= len)
1704 {
1705 buf[len] = 0;
1706 ok_(__FILE__,line)(!strcmp( buf, expect_prefix ), "unexpected data \"%s\"\n", buf);
1707 }
1708}
1709
1710static const struct notification close_request_test[] =
1711{
1715};
1716
1718{
1722};
1723
1724static void close_request(struct test_request *req, struct info *info, BOOL allow_closing_connection)
1725{
1726 BOOL ret;
1727
1728 if (allow_closing_connection)
1729 {
1732 }
1733 else
1734 {
1737 }
1738 info->index = 0;
1739 setup_test( info, winhttp_close_handle, __LINE__ );
1740
1741 ret = WinHttpCloseHandle( req->request );
1742 ok( ret, "WinHttpCloseHandle failed: %lu\n", GetLastError() );
1744 ok( ret, "WinHttpCloseHandle failed: %lu\n", GetLastError() );
1745 ret = WinHttpCloseHandle( req->session );
1746 ok( ret, "WinHttpCloseHandle failed: %lu\n", GetLastError() );
1747
1749 end_test( info, __LINE__ );
1750}
1751
1752static const struct notification read_test[] =
1753{
1757};
1758
1759#define read_request_data(a,b,c) _read_request_data(a,b,c,__LINE__)
1760static void _read_request_data(struct test_request *req, struct info *info, const char *expected_data, unsigned line)
1761{
1762 char buffer[1024];
1763 DWORD len;
1764 BOOL ret;
1765
1766 info->test = read_test;
1768 info->index = 0;
1769
1771 memset(buffer, '?', sizeof(buffer));
1772 ret = WinHttpReadData( req->request, buffer, sizeof(buffer), NULL );
1773 ok( ret, "failed to read data %lu\n", GetLastError() );
1774
1776
1777 len = strlen(expected_data);
1778 ok(!memcmp(buffer, expected_data, len), "unexpected data\n");
1779}
1780
1782{
1783 struct test_request req;
1784 struct info info;
1785
1786 trace("Testing persistent connection...\n");
1787
1789
1790 open_socket_request( port, &req, &info );
1791 server_send_reply( &req, &info,
1792 "HTTP/1.1 200 OK\r\n"
1793 "Server: winetest\r\n"
1794 "Connection: keep-alive\r\n"
1795 "Content-Length: 1\r\n"
1796 "\r\n"
1797 "X" );
1798 read_request_data( &req, &info, "X" );
1799 close_request( &req, &info, FALSE );
1800
1801 /* chunked connection test */
1802 open_async_request( port, &req, &info, L"/test", TRUE );
1803 server_read_data( "GET /test HTTP/1.1\r\n" );
1804 server_send_reply( &req, &info,
1805 "HTTP/1.1 200 OK\r\n"
1806 "Server: winetest\r\n"
1807 "Transfer-Encoding: chunked\r\n"
1808 "Connection: keep-alive\r\n"
1809 "\r\n"
1810 "9\r\n123456789\r\n"
1811 "0\r\n\r\n" );
1812 read_request_data( &req, &info, "123456789" );
1813 close_request( &req, &info, FALSE );
1814
1815 /* HTTP/1.1 connections are persistent by default, no additional header is needed */
1816 open_async_request( port, &req, &info, L"/test", TRUE );
1817 server_read_data( "GET /test HTTP/1.1\r\n" );
1818 server_send_reply( &req, &info,
1819 "HTTP/1.1 200 OK\r\n"
1820 "Server: winetest\r\n"
1821 "Content-Length: 2\r\n"
1822 "\r\n"
1823 "xx" );
1824 read_request_data( &req, &info, "xx" );
1825 close_request( &req, &info, FALSE );
1826
1827 open_async_request( port, &req, &info, L"/test", TRUE );
1828 server_read_data( "GET /test HTTP/1.1\r\n" );
1829 server_send_reply( &req, &info,
1830 "HTTP/1.1 200 OK\r\n"
1831 "Server: winetest\r\n"
1832 "Content-Length: 2\r\n"
1833 "Connection: close\r\n"
1834 "\r\n"
1835 "yy" );
1836 read_request_data( &req, &info, "yy" );
1837 close_request( &req, &info, TRUE );
1838
1842}
1843
1845{
1857};
1858
1859/* The limit is 128 before Win7 and 3 on newer Windows. */
1860#define TEST_RECURSION_LIMIT 128
1861
1863 DWORD status, void *buffer, DWORD buflen )
1864{
1866 DWORD err;
1867 BOOL ret;
1868 BYTE b;
1869
1870 switch (status)
1871 {
1875 if (status == context->call_receive_response_status)
1876 {
1877 if (context->total_len)
1878 {
1879 ret = WinHttpWriteData( context->request, context->send_buffer, context->total_len, NULL );
1880 ok(ret, "failed.\n");
1881 }
1882 else
1883 {
1884 context->receive_response_thread_id = GetCurrentThreadId();
1885 ret = WinHttpReceiveResponse( context->request, NULL );
1886 ok( ret, "failed to receive response, GetLastError() %lu\n", GetLastError() );
1887 }
1888 }
1889 break;
1890
1892 trace("WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE thread %04lx.\n", GetCurrentThreadId());
1893 context->receive_response_thread_id = GetCurrentThreadId();
1894 ret = WinHttpReceiveResponse( context->request, NULL );
1895 ok( ret, "failed to receive response, GetLastError() %lu\n", GetLastError() );
1896 break;
1897
1899 if (context->call_receive_response_status != WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE)
1900 ok( GetCurrentThreadId() != context->main_thread_id,
1901 "expected callback to be called from the other thread, got main.\n" );
1902 context->headers_available = TRUE;
1903 SetEvent( context->wait );
1904 break;
1905
1907 {
1908 DWORD len;
1909
1910 if (!context->read_from_callback)
1911 {
1912 SetEvent( context->wait );
1913 break;
1914 }
1915
1916 if (!*(DWORD *)buffer)
1917 {
1918 SetEvent( context->wait );
1919 break;
1920 }
1921
1922 ok( context->recursion_count < TEST_RECURSION_LIMIT,
1923 "got %lu, thread %#lx\n", context->recursion_count, GetCurrentThreadId() );
1924 context->max_recursion_query = max( context->max_recursion_query, context->recursion_count );
1925 InterlockedIncrement( &context->recursion_count );
1926 b = 0xff;
1927 len = 0xdeadbeef;
1928 ret = WinHttpReadData( context->request, &b, 1, &len );
1929 err = GetLastError();
1930 ok( ret, "failed to read data, GetLastError() %lu\n", err );
1931 ok( err == ERROR_SUCCESS || err == ERROR_IO_PENDING, "got %lu\n", err );
1932 ok( b != 0xff, "got %#x.\n", b );
1933 ok( len == 1, "got %lu.\n", len );
1934 if (err == ERROR_SUCCESS) context->have_sync_callback = TRUE;
1935 InterlockedDecrement( &context->recursion_count );
1936 break;
1937 }
1938
1940 {
1941 static DWORD len;
1942
1943 if (!buflen)
1944 {
1945 SetEvent( context->wait );
1946 break;
1947 }
1948 ok( context->recursion_count < TEST_RECURSION_LIMIT,
1949 "got %lu, thread %#lx\n", context->recursion_count, GetCurrentThreadId() );
1950 context->max_recursion_read = max( context->max_recursion_read, context->recursion_count );
1951 context->read_from_callback = TRUE;
1952 InterlockedIncrement( &context->recursion_count );
1953 len = 0xdeadbeef;
1954 /* Use static variable len here so write to it doesn't destroy the stack on old Windows which
1955 * doesn't set the value at once. */
1956 ret = WinHttpQueryDataAvailable( context->request, &len );
1957 err = GetLastError();
1958 ok( ret, "failed to query data available, GetLastError() %lu\n", err );
1959 ok( err == ERROR_SUCCESS || err == ERROR_IO_PENDING, "got %lu\n", err );
1960 ok( len != 0xdeadbeef || broken( len == 0xdeadbeef ) /* Win7 */, "got %lu.\n", len );
1961 if (err == ERROR_SUCCESS) context->have_sync_callback = TRUE;
1962 InterlockedDecrement( &context->recursion_count );
1963 break;
1964 }
1965
1967 if (!context->headers_available
1968 && context->call_receive_response_status == WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE)
1969 ok( GetCurrentThreadId() == context->receive_response_thread_id,
1970 "expected callback to be called from the same thread, got %lx.\n", GetCurrentThreadId() );
1971 break;
1972 }
1973}
1974
1975static void test_recursion(void)
1976{
1977 static DWORD request_callback_status_tests[] =
1978 {
1981 };
1983 HANDLE session, connection, request;
1984 DWORD size, status, err;
1985 char buffer[1024];
1986 unsigned int i;
1987 BOOL ret;
1988 BYTE b;
1989
1990 memset( &context, 0, sizeof(context) );
1991
1992 context.wait = CreateEventW( NULL, FALSE, FALSE, NULL );
1993 context.main_thread_id = GetCurrentThreadId();
1994
1995 session = WinHttpOpen( L"winetest", 0, NULL, NULL, WINHTTP_FLAG_ASYNC );
1996 ok( !!session, "failed to open session, GetLastError() %lu\n", GetLastError() );
1997
1999
2000 connection = WinHttpConnect( session, L"test.winehq.org", 0, 0 );
2001 ok( !!connection, "failed to open a connection, GetLastError() %lu\n", GetLastError() );
2002
2003 request = WinHttpOpenRequest( connection, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
2004 ok( !!request, "failed to open a request, GetLastError() %lu\n", GetLastError() );
2005
2006 context.request = request;
2007
2009 ok( ret, "failed to receive response, GetLastError() %lu\n", GetLastError() );
2010
2011 context.call_receive_response_status = WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE;
2012 context.total_len = 1;
2013 context.send_buffer = &b;
2014 b = 0;
2015 ret = WinHttpSendRequest( request, NULL, 0, NULL, 0, context.total_len, (DWORD_PTR)&context );
2016 err = GetLastError();
2018 {
2019 skip("Connection failed, skipping\n");
2022 WinHttpCloseHandle( connection );
2024 CloseHandle( context.wait );
2025 return;
2026 }
2027 ok( ret, "failed to send request, GetLastError() %lu\n", GetLastError() );
2028
2030 context.total_len = 0;
2031 context.send_buffer = NULL;
2032
2033 size = sizeof(status);
2035 &status, &size, NULL );
2036 ok( ret, "request failed, GetLastError() %lu\n", GetLastError() );
2037 ok( status == 200, "request failed unexpectedly, status %lu\n", status );
2038
2040 ok( ret, "failed to query data available, GetLastError() %lu\n", GetLastError() );
2041
2043
2044 ret = WinHttpReadData( request, &b, 1, NULL );
2045 ok( ret, "failed to read data, GetLastError() %lu\n", GetLastError() );
2046
2048 if (context.have_sync_callback)
2049 {
2050 ok( context.max_recursion_query >= 2, "got %lu\n", context.max_recursion_query );
2051 ok( context.max_recursion_read >= 2, "got %lu\n", context.max_recursion_read );
2052 }
2053 else skip( "no sync callbacks\n");
2054
2056
2057 for (i = 0; i < ARRAY_SIZE(request_callback_status_tests); ++i)
2058 {
2059 winetest_push_context( "i %u", i );
2060
2061 request = WinHttpOpenRequest( connection, NULL, L"/tests/hello.html", NULL, NULL, NULL, 0 );
2062 ok( !!request, "failed to open a request, GetLastError() %lu\n", GetLastError() );
2063
2064 context.request = request;
2065 context.call_receive_response_status = request_callback_status_tests[i];
2066 context.headers_available = FALSE;
2067
2069 err = GetLastError();
2071 {
2072 skip("Connection failed, skipping\n");
2075 WinHttpCloseHandle( connection );
2077 CloseHandle( context.wait );
2079 return;
2080 }
2081
2083
2084 ret = WinHttpReadData( request, buffer, sizeof(buffer), NULL );
2085 ok( ret, "failed to read data, GetLastError() %lu\n", GetLastError() );
2086
2088
2091 }
2092
2094 WinHttpCloseHandle( connection );
2096 CloseHandle( context.wait );
2097}
2098
2100{
2101 HMODULE mod = GetModuleHandleA( "winhttp.dll" );
2102 struct server_info si;
2103 HANDLE thread;
2104 DWORD ret;
2105
2106 pWinHttpWebSocketClose = (void *)GetProcAddress( mod, "WinHttpWebSocketClose" );
2107 pWinHttpWebSocketCompleteUpgrade = (void *)GetProcAddress( mod, "WinHttpWebSocketCompleteUpgrade" );
2108 pWinHttpWebSocketQueryCloseStatus = (void *)GetProcAddress( mod, "WinHttpWebSocketQueryCloseStatus" );
2109 pWinHttpWebSocketReceive = (void *)GetProcAddress( mod, "WinHttpWebSocketReceive" );
2110 pWinHttpWebSocketSend = (void *)GetProcAddress( mod, "WinHttpWebSocketSend" );
2111 pWinHttpWebSocketShutdown = (void *)GetProcAddress( mod, "WinHttpWebSocketShutdown" );
2112
2115 winetest_push_context( "async" );
2119 test_async();
2121 winetest_push_context( "secure" );
2125
2126 si.event = CreateEventW( NULL, 0, 0, NULL );
2127 si.port = 7533;
2128
2130 ok( thread != NULL, "failed to create thread %lu\n", GetLastError() );
2131
2135
2136 ret = WaitForSingleObject( si.event, 10000 );
2137 ok( ret == WAIT_OBJECT_0, "failed to start winhttp test server %lu\n", GetLastError() );
2138 if (ret != WAIT_OBJECT_0)
2139 {
2141 return;
2142 }
2143
2145
2146 /* send the basic request again to shutdown the server thread */
2147 test_basic_request( si.port, NULL, L"/quit" );
2148
2149 WaitForSingleObject( thread, 3000 );
2154}
@ end_test
Definition: FsRtlMcb.c:1246
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
ULONG WSAAPI inet_addr(IN CONST CHAR FAR *cp)
Definition: addrconv.c:71
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:20
struct protocol * protocols
Definition: dispatch.c:56
static HANDLE thread
Definition: service.c:33
static void * context_ptr(context_t *context)
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define CALLBACK
Definition: compat.h:35
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
USHORT port
Definition: uri.c:228
HINTERNET WINAPI WinHttpOpenRequest(HINTERNET hconnect, const WCHAR *verb, const WCHAR *object, const WCHAR *version, const WCHAR *referrer, const WCHAR **types, DWORD flags)
Definition: session.c:1277
BOOL WINAPI WinHttpQueryOption(HINTERNET handle, DWORD option, void *buffer, DWORD *buflen)
Definition: session.c:1420
HINTERNET WINAPI WinHttpOpen(LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags)
Definition: session.c:304
HINTERNET WINAPI WinHttpConnect(HINTERNET hsession, const WCHAR *server, INTERNET_PORT port, DWORD reserved)
Definition: session.c:594
BOOL WINAPI WinHttpSetOption(HINTERNET handle, DWORD option, void *buffer, DWORD buflen)
Definition: session.c:1479
BOOL WINAPI WinHttpCloseHandle(HINTERNET handle)
Definition: session.c:1358
WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET handle, WINHTTP_STATUS_CALLBACK callback, DWORD flags, DWORD_PTR reserved)
Definition: session.c:2435
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
struct _cl_event * event
Definition: glext.h:7739
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
#define win_skip
Definition: minitest.h:67
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
static SYSTEM_INFO si
Definition: virtual.c:39
static int secure
Definition: server.c:157
static BOOL test_redirect
Definition: protocol.c:149
api
Definition: http.c:7355
#define close_request(a)
Definition: http.c:547
#define min(a, b)
Definition: monoChain.cc:55
#define closesocket
Definition: ncftp.h:477
static const struct notification close_request_test[]
#define read_request_data(a, b, c)
static const struct notification websocket_test[]
Definition: notification.c:761
static void open_async_request(int port, struct test_request *req, struct info *info, const WCHAR *path, BOOL reuse_connection)
static USHORT
Definition: notification.c:31
static const struct notification server_reply_test[]
static DWORD CALLBACK server_thread(LPVOID param)
static const struct notification websocket_test2[]
Definition: notification.c:789
static const struct notification reuse_socket_request_test[]
static const struct notification async_test[]
Definition: notification.c:594
static const char okmsg[]
static const struct notification cache_test[]
Definition: notification.c:193
#define NF_SAVE_BUFFER
Definition: notification.c:66
static HANDLE server_socket_closed
static const struct notification websocket_test5[]
Definition: notification.c:855
static const struct notification websocket_test3[]
Definition: notification.c:810
static const struct notification redirect_test[]
Definition: notification.c:480
static void test_connection_cache(BOOL async)
Definition: notification.c:261
static struct notification websocket_test4[]
Definition: notification.c:833
#define NF_ALLOW
Definition: notification.c:62
#define NF_MAIN_THREAD
Definition: notification.c:65
static DWORD_PTR
Definition: notification.c:32
static const char page1[]
api
Definition: notification.c:39
@ winhttp_connect
Definition: notification.c:40
@ winhttp_read_data
Definition: notification.c:50
@ winhttp_websocket_shutdown
Definition: notification.c:47
@ winhttp_write_data
Definition: notification.c:51
@ winhttp_query_data
Definition: notification.c:49
@ winhttp_open_request
Definition: notification.c:41
@ winhttp_websocket_close
Definition: notification.c:48
@ winhttp_send_request
Definition: notification.c:42
@ winhttp_websocket_complete_upgrade
Definition: notification.c:44
@ winhttp_receive_response
Definition: notification.c:43
@ winhttp_websocket_send
Definition: notification.c:45
@ winhttp_websocket_receive
Definition: notification.c:46
@ winhttp_close_handle
Definition: notification.c:52
static const struct notification close_allow_connection_close_request_test[]
static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
static void _read_request_data(struct test_request *req, struct info *info, const char *expected_data, unsigned line)
static HANDLE server_socket_available
#define TEST_RECURSION_LIMIT
#define NF_WINE_ALLOW
Definition: notification.c:63
static HANDLE server_socket_done
static USHORT void DWORD *static void DWORD WINHTTP_WEB_SOCKET_BUFFER_TYPE *static WINHTTP_WEB_SOCKET_BUFFER_TYPE
Definition: notification.c:35
static void setup_test(struct info *info, enum api function, unsigned int line)
Definition: notification.c:239
static const struct notification redirect_test_async[]
Definition: notification.c:506
static void CALLBACK test_recursion_callback(HINTERNET handle, DWORD_PTR context_ptr, DWORD status, void *buffer, DWORD buflen)
static int server_socket
static const struct notification cache_test_async[]
Definition: notification.c:143
#define server_read_data(a)
static void test_async(void)
Definition: notification.c:620
static const struct notification read_test[]
static void _server_read_data(const char *expect_prefix, unsigned int line)
static void test_websocket(BOOL secure)
Definition: notification.c:883
static void CALLBACK check_notification(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD buflen)
Definition: notification.c:91
static void test_persistent_connection(int port)
#define NF_OTHER_THREAD
Definition: notification.c:67
static void DWORD
Definition: notification.c:31
static void open_socket_request(int port, struct test_request *req, struct info *info)
static void server_send_reply(struct test_request *req, struct info *info, const char *msg)
#define NF_SIGNAL
Definition: notification.c:64
#define BIG_BUFFER_SIZE
Definition: notification.c:881
static const struct notification open_socket_request_test[]
static void test_recursion(void)
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define err(...)
BOOL WINAPI WinHttpQueryHeaders(HINTERNET hrequest, DWORD level, const WCHAR *name, void *buffer, DWORD *buflen, DWORD *index)
Definition: request.c:814
BOOL WINAPI WinHttpAddRequestHeaders(HINTERNET hrequest, const WCHAR *headers, DWORD len, DWORD flags)
Definition: request.c:521
BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET hrequest, LPDWORD available)
Definition: request.c:3156
BOOL WINAPI WinHttpWriteData(HINTERNET hrequest, const void *buffer, DWORD to_write, DWORD *written)
Definition: request.c:3371
BOOL WINAPI WinHttpReadData(HINTERNET hrequest, void *buffer, DWORD to_read, DWORD *read)
Definition: request.c:3252
BOOL WINAPI WinHttpSendRequest(HINTERNET hrequest, const WCHAR *headers, DWORD headers_len, void *optional, DWORD optional_len, DWORD total_len, DWORD_PTR context)
Definition: request.c:2397
BOOL WINAPI WinHttpReceiveResponse(HINTERNET hrequest, LPVOID reserved)
Definition: request.c:3068
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType
Definition: winhttp.h:820
Definition: http.c:7252
unsigned int line
Definition: notification.c:76
enum api function
Definition: notification.c:71
unsigned int index
Definition: notification.c:74
DWORD main_thread_id
Definition: notification.c:77
DWORD last_status
Definition: notification.c:79
DWORD last_thread_id
Definition: notification.c:78
char buffer[256]
Definition: notification.c:80
const struct notification * test
Definition: notification.c:72
HANDLE wait
Definition: notification.c:75
unsigned int buflen
Definition: notification.c:81
unsigned int count
Definition: notification.c:73
Definition: parser.c:49
enum api function
Definition: notification.c:57
unsigned int status
Definition: notification.c:58
BOOL async
Definition: http.c:7368
Definition: tftpd.h:86
Definition: ps.c:97
HINTERNET session
Definition: notification.c:86
HINTERNET connection
Definition: notification.c:87
HINTERNET request
Definition: notification.c:88
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define MAKEWORD(a, b)
Definition: typedefs.h:248
Definition: pdh_main.c:96
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_OPERATION
Definition: winerror.h:1689
#define WSAEINVAL
Definition: winerror.h:2845
#define HTTP_STATUS_OK
Definition: winhttp.h:301
#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
Definition: winhttp.h:450
#define WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE
Definition: winhttp.h:466
#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
Definition: winhttp.h:460
#define WINHTTP_OPTION_CONTEXT_VALUE
Definition: winhttp.h:121
#define WINHTTP_CALLBACK_STATUS_REDIRECT
Definition: winhttp.h:456
#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
Definition: winhttp.h:447
#define WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
Definition: winhttp.h:150
#define ERROR_WINHTTP_OPERATION_CANCELLED
Definition: winhttp.h:244
#define WINHTTP_OPTION_SECURITY_FLAGS
Definition: winhttp.h:114
#define WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE
Definition: winhttp.h:467
#define ERROR_WINHTTP_CANNOT_CONNECT
Definition: winhttp.h:247
LPVOID HINTERNET
Definition: winhttp.h:37
#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT
Definition: winhttp.h:448
#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
Definition: winhttp.h:459
#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
Definition: winhttp.h:449
#define WINHTTP_QUERY_STATUS_CODE
Definition: winhttp.h:379
#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
Definition: winhttp.h:451
#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Definition: winhttp.h:461
#define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
Definition: winhttp.h:454
#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
Definition: winhttp.h:491
#define WINHTTP_ADDREQ_FLAG_ADD
Definition: winhttp.h:92
#define WINHTTP_QUERY_FLAG_NUMBER
Definition: winhttp.h:439
#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
Definition: winhttp.h:452
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:344
@ WINHTTP_WEB_SOCKET_CLOSE_OPERATION
Definition: winhttp.h:782
@ WINHTTP_WEB_SOCKET_RECEIVE_OPERATION
Definition: winhttp.h:781
#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
Definition: winhttp.h:445
@ WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE
Definition: winhttp.h:792
@ WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE
Definition: winhttp.h:791
@ WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE
Definition: winhttp.h:790
@ WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE
Definition: winhttp.h:789
@ WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE
Definition: winhttp.h:788
#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
Definition: winhttp.h:446
#define WINHTTP_ACCESS_TYPE_NO_PROXY
Definition: winhttp.h:70
#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
Definition: winhttp.h:464
enum _WINHTTP_WEB_SOCKET_BUFFER_TYPE WINHTTP_WEB_SOCKET_BUFFER_TYPE
#define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
Definition: winhttp.h:463
#define WINHTTP_FLAG_ASYNC
Definition: winhttp.h:58
#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
Definition: winhttp.h:443
#define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
Definition: winhttp.h:462
#define WINHTTP_ADDREQ_FLAG_REPLACE
Definition: winhttp.h:96
#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
Definition: winhttp.h:444
#define ERROR_WINHTTP_TIMEOUT
Definition: winhttp.h:235
#define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
Definition: winhttp.h:453
#define WINHTTP_FLAG_SECURE
Definition: winhttp.h:67
#define WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE
Definition: winhttp.h:165
#define WINHTTP_OPTION_SECURE_PROTOCOLS
Definition: winhttp.h:136
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
Definition: winhttp.h:518
#define WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET
Definition: winhttp.h:160
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:343
#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID
Definition: winhttp.h:345
#define INVALID_SOCKET
Definition: winsock.h:326
UINT_PTR SOCKET
Definition: winsock.h:41
#define SO_REUSEADDR
Definition: winsock.h:174
#define SOL_SOCKET
Definition: winsock.h:392
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193