ReactOS 0.4.15-dev-7788-g1ad9096
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 const WCHAR user_agent[] = {'w','i','n','e','t','e','s','t',0};
32static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
33static const WCHAR tests_hello_html[] = {'/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
34static const WCHAR tests_redirect[] = {'/','t','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
35static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
36
37enum api
38{
47};
48
50{
51 enum api function; /* api responsible for notification */
52 unsigned int status; /* status received */
53 DWORD flags; /* a combination of NF_* flags */
54};
55
56#define NF_ALLOW 0x0001 /* notification may or may not happen */
57#define NF_WINE_ALLOW 0x0002 /* wine sends notification when it should not */
58#define NF_SIGNAL 0x0004 /* signal wait handle when notified */
59
60struct info
61{
63 const struct notification *test;
64 unsigned int count;
65 unsigned int index;
67 unsigned int line;
68};
69
71{
75};
76
78{
79 BOOL status_ok, function_ok;
80 struct info *info = (struct info *)context;
81
83 {
84 DWORD size = sizeof(struct info *);
86 }
87 while (info->index < info->count && info->test[info->index].status != status && (info->test[info->index].flags & NF_ALLOW))
88 info->index++;
89 while (info->index < info->count && (info->test[info->index].flags & NF_WINE_ALLOW))
90 {
91 todo_wine ok(info->test[info->index].status != status, "unexpected %x notification\n", status);
92 if (info->test[info->index].status == status) break;
93 info->index++;
94 }
95 ok(info->index < info->count, "%u: unexpected notification 0x%08x\n", info->line, status);
96 if (info->index >= info->count) return;
97
98 status_ok = (info->test[info->index].status == status);
99 function_ok = (info->test[info->index].function == info->function);
100 ok(status_ok, "%u: expected status 0x%08x got 0x%08x\n", info->line, info->test[info->index].status, status);
101 ok(function_ok, "%u: expected function %u got %u\n", info->line, info->test[info->index].function, info->function);
102
103 if (status_ok && function_ok && info->test[info->index++].flags & NF_SIGNAL)
104 {
105 SetEvent( info->wait );
106 }
107}
108
109static const struct notification cache_test[] =
110{
161};
162
163static void setup_test( struct info *info, enum api function, unsigned int line )
164{
165 if (info->wait) ResetEvent( info->wait );
167 info->line = line;
168 while (info->index < info->count && info->test[info->index].function != function
169 && (info->test[info->index].flags & (NF_ALLOW | NF_WINE_ALLOW)))
170 info->index++;
171 ok_(__FILE__,line)(info->test[info->index].function == function,
172 "unexpected function %u, expected %u. probably some notifications were missing\n",
173 info->test[info->index].function, function);
174}
175
176static void end_test( struct info *info, unsigned int line )
177{
178 ok_(__FILE__,line)(info->index == info->count, "some notifications were missing: %x\n",
179 info->test[info->index].status);
180}
181
182static void test_connection_cache( void )
183{
184 HANDLE ses, con, req, event;
186 BOOL ret, unload = TRUE;
187 struct info info, *context = &info;
188
191 info.index = 0;
193
194 ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 );
195 ok(ses != NULL, "failed to open session %u\n", GetLastError());
196
197 event = CreateEventW( NULL, FALSE, FALSE, NULL );
199 if (!ret)
200 {
201 win_skip("Unload event not supported\n");
202 unload = FALSE;
203 }
204
206
207 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
208 ok(ret, "failed to set context value %u\n", GetLastError());
209
210 setup_test( &info, winhttp_connect, __LINE__ );
211 con = WinHttpConnect( ses, test_winehq, 0, 0 );
212 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
213
214 setup_test( &info, winhttp_open_request, __LINE__ );
216 ok(req != NULL, "failed to open a request %u\n", GetLastError());
217
218 setup_test( &info, winhttp_send_request, __LINE__ );
219 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
220 err = GetLastError();
222 {
223 skip("connection failed, skipping\n");
224 goto done;
225 }
226 ok(ret, "failed to send request %u\n", GetLastError());
227
230 ok(ret, "failed to receive response %u\n", GetLastError());
231
232 size = sizeof(status);
234 ok(ret, "failed unexpectedly %u\n", GetLastError());
235 ok(status == 200, "request failed unexpectedly %u\n", status);
236
238 setup_test( &info, winhttp_close_handle, __LINE__ );
239 WinHttpCloseHandle( req );
241
242 setup_test( &info, winhttp_open_request, __LINE__ );
244 ok(req != NULL, "failed to open a request %u\n", GetLastError());
245
246 ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
247 ok(ret, "failed to set context value %u\n", GetLastError());
248
249 setup_test( &info, winhttp_send_request, __LINE__ );
250 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
251 err = GetLastError();
253 {
254 skip("connection failed, skipping\n");
255 goto done;
256 }
257 ok(ret, "failed to send request %u\n", GetLastError());
258
261 ok(ret, "failed to receive response %u\n", GetLastError());
262
263 size = sizeof(status);
265 ok(ret, "failed unexpectedly %u\n", GetLastError());
266 ok(status == 200, "request failed unexpectedly %u\n", status);
267
269 setup_test( &info, winhttp_close_handle, __LINE__ );
270 WinHttpCloseHandle( req );
271 WinHttpCloseHandle( req );
272 WinHttpCloseHandle( con );
274
275 if (unload)
276 {
278 ok(status == WAIT_TIMEOUT, "got %08x\n", status);
279 }
280
281 setup_test( &info, winhttp_close_handle, __LINE__ );
282 WinHttpCloseHandle( ses );
284
285 if (unload)
286 {
288 ok(status == WAIT_OBJECT_0, "got %08x\n", status);
289 }
290
291
292 ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 );
293 ok(ses != NULL, "failed to open session %u\n", GetLastError());
294
295 if (unload)
296 {
298 ok(ret, "failed to set unload option\n");
299 }
300
302
303 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
304 ok(ret, "failed to set context value %u\n", GetLastError());
305
306 setup_test( &info, winhttp_connect, __LINE__ );
307 con = WinHttpConnect( ses, test_winehq, 0, 0 );
308 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
309
310 setup_test( &info, winhttp_open_request, __LINE__ );
312 ok(req != NULL, "failed to open a request %u\n", GetLastError());
313
314 ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
315 ok(ret, "failed to set context value %u\n", GetLastError());
316
317 setup_test( &info, winhttp_send_request, __LINE__ );
318 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
319 err = GetLastError();
321 {
322 skip("connection failed, skipping\n");
323 goto done;
324 }
325 ok(ret, "failed to send request %u\n", GetLastError());
326
329 ok(ret, "failed to receive response %u\n", GetLastError());
330
331 size = sizeof(status);
333 ok(ret, "failed unexpectedly %u\n", GetLastError());
334 ok(status == 200, "request failed unexpectedly %u\n", status);
335
337 setup_test( &info, winhttp_close_handle, __LINE__ );
338 WinHttpCloseHandle( req );
340
341 setup_test( &info, winhttp_open_request, __LINE__ );
343 ok(req != NULL, "failed to open a request %u\n", GetLastError());
344
345 ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
346 ok(ret, "failed to set context value %u\n", GetLastError());
347
348 setup_test( &info, winhttp_send_request, __LINE__ );
349 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
350 err = GetLastError();
352 {
353 skip("connection failed, skipping\n");
354 goto done;
355 }
356 ok(ret, "failed to send request %u\n", GetLastError());
357
360 ok(ret, "failed to receive response %u\n", GetLastError());
361
362 size = sizeof(status);
364 ok(ret, "failed unexpectedly %u\n", GetLastError());
365 ok(status == 200, "request failed unexpectedly %u\n", status);
366
367 setup_test( &info, winhttp_close_handle, __LINE__ );
368done:
369 WinHttpCloseHandle( req );
370 WinHttpCloseHandle( con );
372
373 if (unload)
374 {
376 ok(status == WAIT_TIMEOUT, "got %08x\n", status);
377 }
378
379 setup_test( &info, winhttp_close_handle, __LINE__ );
380 WinHttpCloseHandle( ses );
383 end_test( &info, __LINE__ );
384
385 if (unload)
386 {
388 ok(status == WAIT_OBJECT_0, "got %08x\n", status);
389 }
390
392}
393
394static const struct notification redirect_test[] =
395{
420};
421
422static void test_redirect( void )
423{
424 HANDLE ses, con, req;
426 BOOL ret;
427 struct info info, *context = &info;
428
431 info.index = 0;
433
434 ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 );
435 ok(ses != NULL, "failed to open session %u\n", GetLastError());
436
438
439 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
440 ok(ret, "failed to set context value %u\n", GetLastError());
441
442 setup_test( &info, winhttp_connect, __LINE__ );
443 con = WinHttpConnect( ses, test_winehq, 0, 0 );
444 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
445
446 setup_test( &info, winhttp_open_request, __LINE__ );
447 req = WinHttpOpenRequest( con, NULL, tests_redirect, NULL, NULL, NULL, 0 );
448 ok(req != NULL, "failed to open a request %u\n", GetLastError());
449
450 setup_test( &info, winhttp_send_request, __LINE__ );
451 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
452 err = GetLastError();
454 {
455 skip("connection failed, skipping\n");
456 goto done;
457 }
458 ok(ret, "failed to send request %u\n", GetLastError());
459
462 ok(ret, "failed to receive response %u\n", GetLastError());
463
464 size = sizeof(status);
466 ok(ret, "failed unexpectedly %u\n", GetLastError());
467 ok(status == 200, "request failed unexpectedly %u\n", status);
468
469 setup_test( &info, winhttp_close_handle, __LINE__ );
470done:
471 WinHttpCloseHandle( req );
472 WinHttpCloseHandle( con );
473 WinHttpCloseHandle( ses );
476 end_test( &info, __LINE__ );
477}
478
479static const struct notification async_test[] =
480{
500};
501
502static void test_async( void )
503{
504 HANDLE ses, con, req, event;
506 BOOL ret, unload = TRUE;
507 struct info info, *context = &info;
508 char buffer[1024];
509
512 info.index = 0;
514
516 ok(ses != NULL, "failed to open session %u\n", GetLastError());
517
518 event = CreateEventW( NULL, FALSE, FALSE, NULL );
520 if (!ret)
521 {
522 win_skip("Unload event not supported\n");
523 unload = FALSE;
524 }
525
526 SetLastError( 0xdeadbeef );
528 err = GetLastError();
529 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
530
531 SetLastError( 0xdeadbeef );
532 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
533 err = GetLastError();
534 ok(ret, "failed to set context value %u\n", err);
535 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
536
537 setup_test( &info, winhttp_connect, __LINE__ );
538 SetLastError( 0xdeadbeef );
539 con = WinHttpConnect( ses, test_winehq, 0, 0 );
540 err = GetLastError();
541 ok(con != NULL, "failed to open a connection %u\n", err);
542 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err);
543
544 setup_test( &info, winhttp_open_request, __LINE__ );
545 SetLastError( 0xdeadbeef );
547 err = GetLastError();
548 ok(req != NULL, "failed to open a request %u\n", err);
549 ok(err == ERROR_SUCCESS, "got %u\n", err);
550
551 setup_test( &info, winhttp_send_request, __LINE__ );
552 SetLastError( 0xdeadbeef );
553 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
554 err = GetLastError();
556 {
557 skip("connection failed, skipping\n");
558 WinHttpCloseHandle( req );
559 WinHttpCloseHandle( con );
560 WinHttpCloseHandle( ses );
562 return;
563 }
564 ok(ret, "failed to send request %u\n", err);
565 ok(err == ERROR_SUCCESS, "got %u\n", err);
566
568
570 SetLastError( 0xdeadbeef );
572 err = GetLastError();
573 ok(ret, "failed to receive response %u\n", err);
574 ok(err == ERROR_SUCCESS, "got %u\n", err);
575
577
578 size = sizeof(status);
579 SetLastError( 0xdeadbeef );
581 err = GetLastError();
582 ok(ret, "failed unexpectedly %u\n", err);
583 ok(status == 200, "request failed unexpectedly %u\n", status);
584 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
585
586 setup_test( &info, winhttp_query_data, __LINE__ );
587 SetLastError( 0xdeadbeef );
589 err = GetLastError();
590 ok(ret, "failed to query data available %u\n", err);
591 ok(err == ERROR_SUCCESS || err == ERROR_IO_PENDING || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
592
594
595 setup_test( &info, winhttp_read_data, __LINE__ );
596 ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL );
597 ok(ret, "failed to read data %u\n", err);
598
600
601 setup_test( &info, winhttp_close_handle, __LINE__ );
602 WinHttpCloseHandle( req );
603 WinHttpCloseHandle( con );
604
605 if (unload)
606 {
608 ok(status == WAIT_TIMEOUT, "got %08x\n", status);
609 }
610 WinHttpCloseHandle( ses );
612 end_test( &info, __LINE__ );
613
614 if (unload)
615 {
617 ok(status == WAIT_OBJECT_0, "got %08x\n", status);
618 }
621 end_test( &info, __LINE__ );
622}
623
624static const char okmsg[] =
625"HTTP/1.1 200 OK\r\n"
626"Server: winetest\r\n"
627"\r\n";
628
629static const char page1[] =
630"<HTML>\r\n"
631"<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
632"<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
633"</HTML>\r\n\r\n";
634
635struct server_info
636{
638 int port;
639};
640
641static int server_socket;
643
645{
646 struct server_info *si = param;
647 int r, c = -1, i, on;
648 SOCKET s;
649 struct sockaddr_in sa;
650 char buffer[0x100];
651 WSADATA wsaData;
652 int last_request = 0;
653
654 WSAStartup(MAKEWORD(1,1), &wsaData);
655
657 if (s == INVALID_SOCKET)
658 return 1;
659
660 on = 1;
661 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
662
663 memset(&sa, 0, sizeof sa);
664 sa.sin_family = AF_INET;
665 sa.sin_port = htons(si->port);
666 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
667
668 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
669 if (r < 0)
670 return 1;
671
672 listen(s, 0);
673 SetEvent(si->event);
674 do
675 {
676 if (c == -1) c = accept(s, NULL, NULL);
677
678 memset(buffer, 0, sizeof buffer);
679 for(i = 0; i < sizeof buffer - 1; i++)
680 {
681 r = recv(c, &buffer[i], 1, 0);
682 if (r != 1)
683 break;
684 if (i < 4) continue;
685 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
686 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
687 break;
688 }
689 if (strstr(buffer, "GET /quit"))
690 {
691 send(c, okmsg, sizeof okmsg - 1, 0);
692 send(c, page1, sizeof page1 - 1, 0);
693 last_request = 1;
694 }
695 else if(strstr(buffer, "GET /socket"))
696 {
701 }
702 shutdown(c, 2);
703 closesocket(c);
704 c = -1;
705 } while (!last_request);
706
707 closesocket(s);
708 return 0;
709}
710
711static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
712{
713 HINTERNET ses, con, req;
714 char buffer[0x100];
716 BOOL ret;
717
719 ok(ses != NULL, "failed to open session %u\n", GetLastError());
720
721 con = WinHttpConnect(ses, localhostW, port, 0);
722 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
723
724 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
725 ok(req != NULL, "failed to open a request %u\n", GetLastError());
726
727 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
728 ok(ret, "failed to send request %u\n", GetLastError());
729
731 ok(ret, "failed to receive response %u\n", GetLastError());
732
733 status = 0xdeadbeef;
734 size = sizeof(status);
736 ok(ret, "failed to query status code %u\n", GetLastError());
737 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
738
739 count = 0;
740 memset(buffer, 0, sizeof(buffer));
741 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
742 ok(ret, "failed to read data %u\n", GetLastError());
743 ok(count == sizeof page1 - 1, "count was wrong\n");
744 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
745
749}
750
752{
758 { winhttp_send_request, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER, NF_ALLOW }, /* some versions call it twice. why? */
763};
764
766{
772};
773
774static void open_async_request(int port, struct test_request *req, struct info *info, const WCHAR *path, BOOL reuse_connection)
775{
776 BOOL ret;
777
778 info->index = 0;
779 if (reuse_connection)
780 {
783 }
784 else
785 {
788 }
789
791 ok(req->session != NULL, "failed to open session %u\n", GetLastError());
792
795
796 setup_test( info, winhttp_connect, __LINE__ );
797 req->connection = WinHttpConnect( req->session, localhostW, port, 0 );
798 ok(req->connection != NULL, "failed to open a connection %u\n", GetLastError());
799
802 ok(req->request != NULL, "failed to open a request %u\n", GetLastError());
803
805 ret = WinHttpSendRequest( req->request, NULL, 0, NULL, 0, 0, 0 );
806 ok(ret, "failed to send request %u\n", GetLastError());
807}
808
809static void open_socket_request(int port, struct test_request *req, struct info *info)
810{
811 static const WCHAR socketW[] = {'/','s','o','c','k','e','t',0};
812
814 open_async_request( port, req, info, socketW, FALSE );
816}
817
818static const struct notification server_reply_test[] =
819{
823};
824
825static void server_send_reply(struct test_request *req, struct info *info, const char *msg)
826{
827 BOOL ret;
828
829 send( server_socket, msg, strlen( msg ), 0 );
831
834 info->index = 0;
837 ok(ret, "failed to receive response %u\n", GetLastError());
838
840 end_test( info, __LINE__ );
841}
842
843#define server_read_data(a) _server_read_data(a,__LINE__)
844static void _server_read_data(const char *expect_prefix, unsigned int line)
845{
846 char buf[1024];
847 DWORD size, len;
848
849 size = recv( server_socket, buf, sizeof(buf), 0 );
850 len = strlen( expect_prefix );
851 ok_(__FILE__,line)(size > len, "data too short\n");
852 if (size >= len)
853 {
854 buf[len] = 0;
855 ok_(__FILE__,line)(!strcmp( buf, expect_prefix ), "unexpected data \"%s\"\n", buf);
856 }
857}
858
859static const struct notification close_request_test[] =
860{
864};
865
867{
873};
874
875static void close_request(struct test_request *req, struct info *info, BOOL allow_closing_connection)
876{
877 BOOL ret;
878
879 if (allow_closing_connection)
880 {
883 }
884 else
885 {
888 }
889 info->index = 0;
891
893 ok(ret, "WinHttpCloseHandle failed: %u\n", GetLastError());
895 ok(ret, "WinHttpCloseHandle failed: %u\n", GetLastError());
897 ok(ret, "WinHttpCloseHandle failed: %u\n", GetLastError());
898
900 end_test( info, __LINE__ );
901}
902
903static const struct notification read_test[] =
904{
908};
909
910static const struct notification read_allow_close_test[] =
911{
917};
918
919#define read_request_data(a,b,c,d) _read_request_data(a,b,c,d,__LINE__)
920static void _read_request_data(struct test_request *req, struct info *info, const char *expected_data, BOOL closing_connection, unsigned line)
921{
922 char buffer[1024];
923 DWORD len;
924 BOOL ret;
925
926 if (closing_connection)
927 {
930 }
931 else
932 {
935 }
936 info->index = 0;
937
939 memset(buffer, '?', sizeof(buffer));
940 ret = WinHttpReadData( req->request, buffer, sizeof(buffer), NULL );
941 ok(ret, "failed to read data %u\n", GetLastError());
942
944
945 len = strlen(expected_data);
946 ok(!memcmp(buffer, expected_data, len), "unexpected data\n");
947}
948
950{
951 struct test_request req;
952 struct info info;
953
954 static const WCHAR testW[] = {'/','t','e','s','t',0};
955
956 trace("Testing persistent connection...\n");
957
959
960 open_socket_request( port, &req, &info );
961 server_send_reply( &req, &info,
962 "HTTP/1.1 200 OK\r\n"
963 "Server: winetest\r\n"
964 "Connection: keep-alive\r\n"
965 "Content-Length: 1\r\n"
966 "\r\n"
967 "X" );
968 read_request_data( &req, &info, "X", FALSE );
969 close_request( &req, &info, FALSE );
970
971 /* chunked connection test */
973 server_read_data( "GET /test HTTP/1.1\r\n" );
974 server_send_reply( &req, &info,
975 "HTTP/1.1 200 OK\r\n"
976 "Server: winetest\r\n"
977 "Transfer-Encoding: chunked\r\n"
978 "Connection: keep-alive\r\n"
979 "\r\n"
980 "9\r\n123456789\r\n"
981 "0\r\n\r\n" );
982 read_request_data( &req, &info, "123456789", FALSE );
983 close_request( &req, &info, FALSE );
984
985 /* HTTP/1.1 connections are persistent by default, no additional header is needed */
987 server_read_data( "GET /test HTTP/1.1\r\n" );
988 server_send_reply( &req, &info,
989 "HTTP/1.1 200 OK\r\n"
990 "Server: winetest\r\n"
991 "Content-Length: 2\r\n"
992 "\r\n"
993 "xx" );
994 read_request_data( &req, &info, "xx", FALSE );
995 close_request( &req, &info, FALSE );
996
998 server_read_data( "GET /test HTTP/1.1\r\n" );
999 server_send_reply( &req, &info,
1000 "HTTP/1.1 200 OK\r\n"
1001 "Server: winetest\r\n"
1002 "Content-Length: 2\r\n"
1003 "Connection: close\r\n"
1004 "\r\n"
1005 "yy" );
1006 close_request( &req, &info, TRUE );
1007
1010}
1011
1013{
1014 static const WCHAR quitW[] = {'/','q','u','i','t',0};
1015 struct server_info si;
1016 HANDLE thread;
1017 DWORD ret;
1018
1020 test_redirect();
1021 test_async();
1022
1023 si.event = CreateEventW( NULL, 0, 0, NULL );
1024 si.port = 7533;
1025
1026 thread = CreateThread( NULL, 0, server_thread, &si, 0, NULL );
1027 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
1028
1031
1032 ret = WaitForSingleObject( si.event, 10000 );
1033 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
1034 if (ret != WAIT_OBJECT_0)
1035 {
1037 return;
1038 }
1039
1041
1042 /* send the basic request again to shutdown the server thread */
1043 test_basic_request( si.port, NULL, quitW );
1044
1045 WaitForSingleObject( thread, 3000 );
1049}
@ end_test
Definition: FsRtlMcb.c:1246
#define broken(x)
Definition: _sntprintf.h:21
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#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:33
static HANDLE thread
Definition: service.c:33
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_IO_PENDING
Definition: dderror.h:15
#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 SetLastError(x)
Definition: compat.h:752
#define CALLBACK
Definition: compat.h:35
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
USHORT port
Definition: uri.c:228
BOOL WINAPI WinHttpQueryOption(HINTERNET handle, DWORD option, LPVOID buffer, LPDWORD buflen)
Definition: session.c:1253
HINTERNET WINAPI WinHttpOpen(LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags)
Definition: session.c:250
HINTERNET WINAPI WinHttpConnect(HINTERNET hsession, LPCWSTR server, INTERNET_PORT port, DWORD reserved)
Definition: session.c:541
BOOL WINAPI WinHttpCloseHandle(HINTERNET handle)
Definition: session.c:1195
HINTERNET WINAPI WinHttpOpenRequest(HINTERNET hconnect, LPCWSTR verb, LPCWSTR object, LPCWSTR version, LPCWSTR referrer, LPCWSTR *types, DWORD flags)
Definition: session.c:1117
BOOL WINAPI WinHttpSetOption(HINTERNET handle, DWORD option, LPVOID buffer, DWORD buflen)
Definition: session.c:1312
WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET handle, WINHTTP_STATUS_CALLBACK callback, DWORD flags, DWORD_PTR reserved)
Definition: session.c:2056
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
#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
GLdouble s
Definition: gl.h:2039
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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
#define inet_addr(cp)
Definition: inet.h:98
static const WCHAR testW[]
Definition: jsregexp.c:44
#define c
Definition: ke_i.h:80
#define htons(x)
Definition: module.h:215
#define todo_wine
Definition: custom.c:79
api
Definition: http.c:7355
#define close_request(a)
Definition: http.c:547
#define closesocket
Definition: ncftp.h:477
static const struct notification close_request_test[]
Definition: notification.c:859
static void open_async_request(int port, struct test_request *req, struct info *info, const WCHAR *path, BOOL reuse_connection)
Definition: notification.c:774
static const struct notification server_reply_test[]
Definition: notification.c:818
static DWORD CALLBACK server_thread(LPVOID param)
Definition: notification.c:644
static const struct notification reuse_socket_request_test[]
Definition: notification.c:765
static const struct notification async_test[]
Definition: notification.c:479
static const char okmsg[]
Definition: notification.c:624
static const struct notification cache_test[]
Definition: notification.c:109
static const WCHAR test_winehq[]
Definition: notification.c:32
static void test_connection_cache(void)
Definition: notification.c:182
static const struct notification redirect_test[]
Definition: notification.c:394
#define NF_ALLOW
Definition: notification.c:56
static const char page1[]
Definition: notification.c:629
api
Definition: notification.c:38
@ winhttp_connect
Definition: notification.c:39
@ winhttp_read_data
Definition: notification.c:44
@ winhttp_write_data
Definition: notification.c:45
@ winhttp_query_data
Definition: notification.c:43
@ winhttp_open_request
Definition: notification.c:40
@ winhttp_send_request
Definition: notification.c:41
@ winhttp_receive_response
Definition: notification.c:42
@ winhttp_close_handle
Definition: notification.c:46
static const struct notification close_allow_connection_close_request_test[]
Definition: notification.c:866
static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
Definition: notification.c:711
static HANDLE server_socket_available
Definition: notification.c:642
static const WCHAR tests_hello_html[]
Definition: notification.c:33
#define NF_WINE_ALLOW
Definition: notification.c:57
static HANDLE server_socket_done
Definition: notification.c:642
static void test_redirect(void)
Definition: notification.c:422
static void setup_test(struct info *info, enum api function, unsigned int line)
Definition: notification.c:163
static int server_socket
Definition: notification.c:641
static void _read_request_data(struct test_request *req, struct info *info, const char *expected_data, BOOL closing_connection, unsigned line)
Definition: notification.c:920
#define server_read_data(a)
Definition: notification.c:843
static void test_async(void)
Definition: notification.c:502
static const struct notification read_test[]
Definition: notification.c:903
static void _server_read_data(const char *expect_prefix, unsigned int line)
Definition: notification.c:844
#define read_request_data(a, b, c, d)
Definition: notification.c:919
static void CALLBACK check_notification(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD buflen)
Definition: notification.c:77
static void test_persistent_connection(int port)
Definition: notification.c:949
static const WCHAR localhostW[]
Definition: notification.c:35
static const WCHAR user_agent[]
Definition: notification.c:31
static const WCHAR tests_redirect[]
Definition: notification.c:34
static void open_socket_request(int port, struct test_request *req, struct info *info)
Definition: notification.c:809
static void server_send_reply(struct test_request *req, struct info *info, const char *msg)
Definition: notification.c:825
#define NF_SIGNAL
Definition: notification.c:58
static const struct notification open_socket_request_test[]
Definition: notification.c:751
static const struct notification read_allow_close_test[]
Definition: notification.c:910
#define err(...)
BOOL WINAPI WinHttpQueryHeaders(HINTERNET hrequest, DWORD level, LPCWSTR name, LPVOID buffer, LPDWORD buflen, LPDWORD index)
Definition: request.c:856
BOOL WINAPI WinHttpReadData(HINTERNET hrequest, LPVOID buffer, DWORD to_read, LPDWORD read)
Definition: request.c:3053
BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET hrequest, LPDWORD available)
Definition: request.c:3005
BOOL WINAPI WinHttpSendRequest(HINTERNET hrequest, LPCWSTR headers, DWORD headers_len, LPVOID optional, DWORD optional_len, DWORD total_len, DWORD_PTR context)
Definition: request.c:2350
BOOL WINAPI WinHttpReceiveResponse(HINTERNET hrequest, LPVOID reserved)
Definition: request.c:2924
#define win_skip
Definition: test.h:160
#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
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: http.c:7252
unsigned int line
Definition: notification.c:67
enum api function
Definition: notification.c:62
unsigned int index
Definition: notification.c:65
const struct notification * test
Definition: notification.c:63
HANDLE wait
Definition: notification.c:66
unsigned int count
Definition: notification.c:64
Definition: parser.c:49
enum api function
Definition: notification.c:51
unsigned int status
Definition: notification.c:52
HANDLE event
Definition: notification.c:637
Definition: ps.c:97
HINTERNET session
Definition: notification.c:72
HINTERNET connection
Definition: notification.c:73
HINTERNET request
Definition: notification.c:74
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:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define WSAEINVAL
Definition: winerror.h:1946
#define HTTP_STATUS_OK
Definition: winhttp.h:240
#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
Definition: winhttp.h:387
#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
Definition: winhttp.h:397
#define WINHTTP_OPTION_CONTEXT_VALUE
Definition: winhttp.h:112
#define WINHTTP_CALLBACK_STATUS_REDIRECT
Definition: winhttp.h:393
#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
Definition: winhttp.h:384
#define WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT
Definition: winhttp.h:141
#define ERROR_WINHTTP_CANNOT_CONNECT
Definition: winhttp.h:201
#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT
Definition: winhttp.h:385
#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
Definition: winhttp.h:396
#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
Definition: winhttp.h:386
#define WINHTTP_QUERY_STATUS_CODE
Definition: winhttp.h:317
#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
Definition: winhttp.h:388
#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Definition: winhttp.h:398
#define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
Definition: winhttp.h:391
#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS
Definition: winhttp.h:421
#define WINHTTP_QUERY_FLAG_NUMBER
Definition: winhttp.h:377
#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
Definition: winhttp.h:389
#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
Definition: winhttp.h:382
#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
Definition: winhttp.h:383
#define WINHTTP_ACCESS_TYPE_NO_PROXY
Definition: winhttp.h:63
#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
Definition: winhttp.h:401
#define WINHTTP_FLAG_ASYNC
Definition: winhttp.h:51
#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
Definition: winhttp.h:380
#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
Definition: winhttp.h:381
#define ERROR_WINHTTP_TIMEOUT
Definition: winhttp.h:189
#define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
Definition: winhttp.h:390
#define INVALID_SOCKET
Definition: winsock.h:332
UINT_PTR SOCKET
Definition: winsock.h:47
#define SO_REUSEADDR
Definition: winsock.h:180
#define SOL_SOCKET
Definition: winsock.h:398
__wchar_t WCHAR
Definition: xmlstorage.h:180