wined3d: Use wined3d_uint32_compare() in compare_sig().
[wine.git] / dlls / wininet / tests / http.c
blobcf3f62f868a112610c0f45475e5d6f5e24bb1f25
1 /*
2 * Wininet - HTTP tests
4 * Copyright 2002 Aric Stewart
5 * Copyright 2004 Mike McCormack
6 * Copyright 2005 Hans Leidekker
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <limits.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wininet.h"
31 #include "winineti.h"
32 #include "winsock2.h"
34 #include "wine/test.h"
36 /* Undocumented security flags */
37 #define _SECURITY_FLAG_CERT_REV_FAILED 0x00800000
38 #define _SECURITY_FLAG_CERT_INVALID_CA 0x01000000
39 #define _SECURITY_FLAG_CERT_INVALID_CN 0x02000000
40 #define _SECURITY_FLAG_CERT_INVALID_DATE 0x04000000
42 #define TEST_URL "http://test.winehq.org/tests/hello.html"
44 static BOOL first_connection_to_test_url = TRUE;
45 static BOOL https_support = TRUE;
47 /* Adapted from dlls/urlmon/tests/protocol.c */
49 #define SET_EXPECT2(status, num) \
50 expect[status] = num
52 #define SET_EXPECT(status) \
53 SET_EXPECT2(status, 1)
55 #define SET_OPTIONAL2(status, num) \
56 optional[status] = num
58 #define SET_OPTIONAL(status) \
59 SET_OPTIONAL2(status, 1)
61 /* SET_WINE_ALLOW's should be used with an appropriate
62 * todo_wine CHECK_NOTIFIED at a later point in the code */
63 #define SET_WINE_ALLOW2(status, num) \
64 wine_allow[status] = num
66 #define SET_WINE_ALLOW(status) \
67 SET_WINE_ALLOW2(status, 1)
69 #define CHECK_EXPECT(status) \
70 do { \
71 if (!expect[status] && !optional[status] && wine_allow[status]) \
72 { \
73 todo_wine ok(expect[status], "unexpected status %d (%s)\n", status, \
74 status < MAX_INTERNET_STATUS && status_string[status] ? \
75 status_string[status] : "unknown"); \
76 wine_allow[status]--; \
77 } \
78 else \
79 { \
80 ok(expect[status] || optional[status], "unexpected status %d (%s)\n", status, \
81 status < MAX_INTERNET_STATUS && status_string[status] ? \
82 status_string[status] : "unknown"); \
83 if (expect[status]) expect[status]--; \
84 else if(optional[status]) optional[status]--; \
85 } \
86 notified[status]++; \
87 }while(0)
89 /* CLEAR_NOTIFIED used in cases when notification behavior
90 * differs between Windows versions */
91 #define CLEAR_NOTIFIED(status) \
92 expect[status] = optional[status] = wine_allow[status] = notified[status] = 0;
94 #define CHECK_NOTIFIED2(status, num) \
95 do { \
96 ok(notified[status] + optional[status] == (num), \
97 "expected status %d (%s) %d times, received %d times\n", \
98 status, status < MAX_INTERNET_STATUS && status_string[status] ? \
99 status_string[status] : "unknown", (num), notified[status]); \
100 CLEAR_NOTIFIED(status); \
101 }while(0)
103 #define CHECK_NOTIFIED(status) \
104 CHECK_NOTIFIED2(status, 1)
106 #define CHECK_NOT_NOTIFIED(status) \
107 CHECK_NOTIFIED2(status, 0)
109 #define MAX_INTERNET_STATUS (INTERNET_STATUS_COOKIE_HISTORY+1)
110 static int expect[MAX_INTERNET_STATUS], optional[MAX_INTERNET_STATUS],
111 wine_allow[MAX_INTERNET_STATUS], notified[MAX_INTERNET_STATUS];
112 static const char *status_string[MAX_INTERNET_STATUS];
114 static HANDLE complete_event, conn_close_event, conn_wait_event, server_req_rec_event, request_sent_event;
115 static DWORD req_error;
116 static BOOL is_ie7plus = TRUE;
118 #define TESTF_REDIRECT 0x01
119 #define TESTF_COMPRESSED 0x02
120 #define TESTF_CHUNKED 0x04
122 typedef struct {
123 const char *url;
124 const char *redirected_url;
125 const char *host;
126 const char *path;
127 const char *headers;
128 DWORD flags;
129 const char *post_data;
130 const char *content;
131 } test_data_t;
133 static const test_data_t test_data[] = {
135 "http://test.winehq.org/tests/data.php",
136 "http://test.winehq.org/tests/data.php",
137 "test.winehq.org",
138 "/tests/data.php",
140 TESTF_CHUNKED
143 "http://test.winehq.org/tests/redirect",
144 "http://test.winehq.org/tests/hello.html",
145 "test.winehq.org",
146 "/tests/redirect",
148 TESTF_REDIRECT
151 "http://test.winehq.org/tests/gzip.php",
152 "http://test.winehq.org/tests/gzip.php",
153 "test.winehq.org",
154 "/tests/gzip.php",
155 "Accept-Encoding: gzip, deflate",
156 TESTF_COMPRESSED
159 "http://test.winehq.org/tests/post.php",
160 "http://test.winehq.org/tests/post.php",
161 "test.winehq.org",
162 "/tests/post.php",
163 "Content-Type: application/x-www-form-urlencoded",
165 "mode=Test",
166 "mode => Test\n"
170 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET ,INTERNET_STATUS_CALLBACK);
171 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackW)(HINTERNET ,INTERNET_STATUS_CALLBACK);
172 static BOOL (WINAPI *pInternetGetSecurityInfoByURLA)(LPSTR,PCCERT_CHAIN_CONTEXT*,DWORD*);
174 static BOOL is_lang_english(void)
176 static HMODULE hkernel32 = NULL;
177 static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
178 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
180 if (!hkernel32)
182 hkernel32 = GetModuleHandleA("kernel32.dll");
183 pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
184 pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
186 if (pGetThreadUILanguage)
187 return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
188 if (pGetUserDefaultUILanguage)
189 return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
191 return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
194 static int strcmp_wa(LPCWSTR strw, const char *stra)
196 WCHAR buf[512];
197 MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
198 return lstrcmpW(strw, buf);
201 static BOOL proxy_active(void)
203 HKEY internet_settings;
204 DWORD proxy_enable;
205 DWORD size;
207 if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
208 0, KEY_QUERY_VALUE, &internet_settings) != ERROR_SUCCESS)
209 return FALSE;
211 size = sizeof(DWORD);
212 if (RegQueryValueExA(internet_settings, "ProxyEnable", NULL, NULL, (LPBYTE) &proxy_enable, &size) != ERROR_SUCCESS)
213 proxy_enable = 0;
215 RegCloseKey(internet_settings);
217 return proxy_enable != 0;
220 static void init_events(void)
222 complete_event = CreateEventW(NULL, FALSE, FALSE, NULL);
223 conn_close_event = CreateEventW(NULL, FALSE, FALSE, NULL);
224 conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
225 server_req_rec_event = CreateEventW(NULL, FALSE, FALSE, NULL);
226 request_sent_event = CreateEventW(NULL, FALSE, FALSE, NULL);
229 static void free_events(void)
231 CloseHandle(complete_event);
232 CloseHandle(conn_close_event);
233 CloseHandle(conn_wait_event);
234 CloseHandle(server_req_rec_event);
235 CloseHandle(request_sent_event);
238 static void reset_events(void)
240 ResetEvent(complete_event);
241 ResetEvent(conn_close_event);
242 ResetEvent(conn_wait_event);
243 ResetEvent(server_req_rec_event);
244 ResetEvent(request_sent_event);
247 #define test_status_code(a,b) _test_status_code(__LINE__,a,b, FALSE)
248 #define test_status_code_todo(a,b) _test_status_code(__LINE__,a,b, TRUE)
249 static void _test_status_code(unsigned line, HINTERNET req, DWORD excode, BOOL is_todo)
251 DWORD code, size, index;
252 char exbuf[12], bufa[10];
253 WCHAR bufw[10];
254 BOOL res;
256 code = 0xdeadbeef;
257 size = sizeof(code);
258 res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, NULL);
259 ok_(__FILE__,line)(res, "[1] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE|number) failed: %u\n", GetLastError());
260 todo_wine_if (is_todo)
261 ok_(__FILE__,line)(code == excode, "code = %d, expected %d\n", code, excode);
262 ok_(__FILE__,line)(size == sizeof(code), "size = %u\n", size);
264 code = 0xdeadbeef;
265 index = 0;
266 size = sizeof(code);
267 res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, &index);
268 ok_(__FILE__,line)(res, "[2] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE|number index) failed: %u\n", GetLastError());
269 ok_(__FILE__,line)(!index, "index = %d, expected 0\n", index);
270 ok_(__FILE__,line)(size == sizeof(code), "size = %u\n", size);
272 sprintf(exbuf, "%u", excode);
274 size = sizeof(bufa);
275 res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE, bufa, &size, NULL);
276 ok_(__FILE__,line)(res, "[3] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
277 todo_wine_if (is_todo)
278 ok_(__FILE__,line)(!strcmp(bufa, exbuf), "unexpected status code %s, expected %s\n", bufa, exbuf);
279 ok_(__FILE__,line)(size == strlen(exbuf), "unexpected size %d for \"%s\"\n", size, exbuf);
281 size = 0;
282 res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE, NULL, &size, NULL);
283 ok_(__FILE__,line)(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
284 "[4] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
285 ok_(__FILE__,line)(size == strlen(exbuf)+1, "unexpected size %d for \"%s\"\n", size, exbuf);
287 size = sizeof(bufw);
288 res = HttpQueryInfoW(req, HTTP_QUERY_STATUS_CODE, bufw, &size, NULL);
289 ok_(__FILE__,line)(res, "[5] HttpQueryInfoW(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
290 todo_wine_if (is_todo)
291 ok_(__FILE__,line)(!strcmp_wa(bufw, exbuf), "unexpected status code %s, expected %s\n", bufa, exbuf);
292 ok_(__FILE__,line)(size == strlen(exbuf)*sizeof(WCHAR), "unexpected size %d for \"%s\"\n", size, exbuf);
294 size = 0;
295 res = HttpQueryInfoW(req, HTTP_QUERY_STATUS_CODE, bufw, &size, NULL);
296 ok_(__FILE__,line)(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
297 "[6] HttpQueryInfoW(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
298 ok_(__FILE__,line)(size == (strlen(exbuf)+1)*sizeof(WCHAR), "unexpected size %d for \"%s\"\n", size, exbuf);
300 if(0) {
301 size = sizeof(bufw);
302 res = HttpQueryInfoW(req, HTTP_QUERY_STATUS_CODE, NULL, &size, NULL);
303 ok(!res && GetLastError() == ERROR_INVALID_PARAMETER, "HttpQueryInfo(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
304 ok(size == sizeof(bufw), "unexpected size %d\n", size);
307 code = 0xdeadbeef;
308 index = 1;
309 size = sizeof(code);
310 res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, &index);
311 ok_(__FILE__,line)(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
312 "[7] HttpQueryInfoA failed: %x(%d)\n", res, GetLastError());
314 code = 0xdeadbeef;
315 size = sizeof(code);
316 res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_REQUEST_HEADERS, &code, &size, NULL);
317 ok_(__FILE__,line)(!res && GetLastError() == ERROR_HTTP_INVALID_QUERY_REQUEST,
318 "[8] HttpQueryInfoA failed: %x(%d)\n", res, GetLastError());
321 #define test_request_flags(a,b) _test_request_flags(__LINE__,a,b,FALSE)
322 #define test_request_flags_todo(a,b) _test_request_flags(__LINE__,a,b,TRUE)
323 static void _test_request_flags(unsigned line, HINTERNET req, DWORD exflags, BOOL is_todo)
325 DWORD flags, size;
326 BOOL res;
328 flags = 0xdeadbeef;
329 size = sizeof(flags);
330 res = InternetQueryOptionW(req, INTERNET_OPTION_REQUEST_FLAGS, &flags, &size);
331 ok_(__FILE__,line)(res, "InternetQueryOptionW(INTERNET_OPTION_REQUEST_FLAGS) failed: %u\n", GetLastError());
333 /* FIXME: Remove once we have INTERNET_REQFLAG_CACHE_WRITE_DISABLED implementation */
334 flags &= ~INTERNET_REQFLAG_CACHE_WRITE_DISABLED;
335 todo_wine_if (is_todo)
336 ok_(__FILE__,line)(flags == exflags, "flags = %x, expected %x\n", flags, exflags);
339 #define test_request_url(a,b) _test_request_url(__LINE__,a,b)
340 static void _test_request_url(unsigned line, HINTERNET req, const char *expected_url)
342 char buf[INTERNET_MAX_URL_LENGTH];
343 DWORD size = sizeof(buf);
344 BOOL res;
346 res = InternetQueryOptionA(req, INTERNET_OPTION_URL, buf, &size);
347 ok_(__FILE__,line)(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
348 ok_(__FILE__,line)(size == strlen(expected_url), "size = %u\n", size);
349 ok_(__FILE__,line)(!strcmp(buf, expected_url), "unexpected URL %s, expected %s\n", buf, expected_url);
352 #define test_http_version(a) _test_http_version(__LINE__,a)
353 static void _test_http_version(unsigned line, HINTERNET req)
355 HTTP_VERSION_INFO v = {0xdeadbeef, 0xdeadbeef};
356 DWORD size;
357 BOOL res;
359 size = sizeof(v);
360 res = InternetQueryOptionW(req, INTERNET_OPTION_HTTP_VERSION, &v, &size);
361 ok_(__FILE__,line)(res, "InternetQueryOptionW(INTERNET_OPTION_HTTP_VERSION) failed: %u\n", GetLastError());
362 ok_(__FILE__,line)(v.dwMajorVersion == 1, "dwMajorVersion = %d\n", v.dwMajorVersion);
363 ok_(__FILE__,line)(v.dwMinorVersion == 1, "dwMinorVersion = %d\n", v.dwMinorVersion);
366 static int close_handle_cnt;
368 static VOID WINAPI callback(
369 HINTERNET hInternet,
370 DWORD_PTR dwContext,
371 DWORD dwInternetStatus,
372 LPVOID lpvStatusInformation,
373 DWORD dwStatusInformationLength
376 CHECK_EXPECT(dwInternetStatus);
377 switch (dwInternetStatus)
379 case INTERNET_STATUS_RESOLVING_NAME:
380 if(winetest_debug > 1)
381 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RESOLVING_NAME \"%s\" %d\n",
382 GetCurrentThreadId(), hInternet, dwContext,
383 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
384 *(LPSTR)lpvStatusInformation = '\0';
385 break;
386 case INTERNET_STATUS_NAME_RESOLVED:
387 if(winetest_debug > 1)
388 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_NAME_RESOLVED \"%s\" %d\n",
389 GetCurrentThreadId(), hInternet, dwContext,
390 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
391 *(LPSTR)lpvStatusInformation = '\0';
392 break;
393 case INTERNET_STATUS_CONNECTING_TO_SERVER:
394 if(winetest_debug > 1)
395 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTING_TO_SERVER \"%s\" %d\n",
396 GetCurrentThreadId(), hInternet, dwContext,
397 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
398 ok(dwStatusInformationLength == strlen(lpvStatusInformation)+1, "unexpected size %u\n",
399 dwStatusInformationLength);
400 *(LPSTR)lpvStatusInformation = '\0';
401 break;
402 case INTERNET_STATUS_CONNECTED_TO_SERVER:
403 if(winetest_debug > 1)
404 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTED_TO_SERVER \"%s\" %d\n",
405 GetCurrentThreadId(), hInternet, dwContext,
406 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
407 ok(dwStatusInformationLength == strlen(lpvStatusInformation)+1, "unexpected size %u\n",
408 dwStatusInformationLength);
409 *(LPSTR)lpvStatusInformation = '\0';
410 break;
411 case INTERNET_STATUS_SENDING_REQUEST:
412 if(winetest_debug > 1)
413 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_SENDING_REQUEST %p %d\n",
414 GetCurrentThreadId(), hInternet, dwContext,
415 lpvStatusInformation,dwStatusInformationLength);
416 break;
417 case INTERNET_STATUS_REQUEST_SENT:
418 ok(dwStatusInformationLength == sizeof(DWORD),
419 "info length should be sizeof(DWORD) instead of %d\n",
420 dwStatusInformationLength);
421 if(winetest_debug > 1)
422 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REQUEST_SENT 0x%x %d\n",
423 GetCurrentThreadId(), hInternet, dwContext,
424 *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
425 break;
426 case INTERNET_STATUS_RECEIVING_RESPONSE:
427 if(winetest_debug > 1)
428 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RECEIVING_RESPONSE %p %d\n",
429 GetCurrentThreadId(), hInternet, dwContext,
430 lpvStatusInformation,dwStatusInformationLength);
431 break;
432 case INTERNET_STATUS_RESPONSE_RECEIVED:
433 ok(dwStatusInformationLength == sizeof(DWORD),
434 "info length should be sizeof(DWORD) instead of %d\n",
435 dwStatusInformationLength);
436 if(winetest_debug > 1)
437 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RESPONSE_RECEIVED 0x%x %d\n",
438 GetCurrentThreadId(), hInternet, dwContext,
439 *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
440 break;
441 case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
442 if(winetest_debug > 1)
443 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CTL_RESPONSE_RECEIVED %p %d\n",
444 GetCurrentThreadId(), hInternet,dwContext,
445 lpvStatusInformation,dwStatusInformationLength);
446 break;
447 case INTERNET_STATUS_PREFETCH:
448 if(winetest_debug > 1)
449 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_PREFETCH %p %d\n",
450 GetCurrentThreadId(), hInternet, dwContext,
451 lpvStatusInformation,dwStatusInformationLength);
452 break;
453 case INTERNET_STATUS_CLOSING_CONNECTION:
454 if(winetest_debug > 1)
455 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CLOSING_CONNECTION %p %d\n",
456 GetCurrentThreadId(), hInternet, dwContext,
457 lpvStatusInformation,dwStatusInformationLength);
458 break;
459 case INTERNET_STATUS_CONNECTION_CLOSED:
460 if(winetest_debug > 1)
461 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTION_CLOSED %p %d\n",
462 GetCurrentThreadId(), hInternet, dwContext,
463 lpvStatusInformation,dwStatusInformationLength);
464 break;
465 case INTERNET_STATUS_HANDLE_CREATED:
466 ok(dwStatusInformationLength == sizeof(HINTERNET),
467 "info length should be sizeof(HINTERNET) instead of %d\n",
468 dwStatusInformationLength);
469 if(winetest_debug > 1)
470 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CREATED %p %d\n",
471 GetCurrentThreadId(), hInternet, dwContext,
472 *(HINTERNET *)lpvStatusInformation,dwStatusInformationLength);
473 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
474 SET_EXPECT(INTERNET_STATUS_DETECTING_PROXY);
475 break;
476 case INTERNET_STATUS_HANDLE_CLOSING:
477 ok(dwStatusInformationLength == sizeof(HINTERNET),
478 "info length should be sizeof(HINTERNET) instead of %d\n",
479 dwStatusInformationLength);
480 if(winetest_debug > 1)
481 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CLOSING %p %d\n",
482 GetCurrentThreadId(), hInternet, dwContext,
483 *(HINTERNET *)lpvStatusInformation, dwStatusInformationLength);
484 if(!InterlockedDecrement(&close_handle_cnt))
485 SetEvent(complete_event);
486 break;
487 case INTERNET_STATUS_REQUEST_COMPLETE:
489 INTERNET_ASYNC_RESULT *iar = (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
490 ok(dwStatusInformationLength == sizeof(INTERNET_ASYNC_RESULT),
491 "info length should be sizeof(INTERNET_ASYNC_RESULT) instead of %d\n",
492 dwStatusInformationLength);
493 ok(iar->dwResult == 1 || iar->dwResult == 0, "iar->dwResult = %ld\n", iar->dwResult);
494 if(winetest_debug > 1)
495 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REQUEST_COMPLETE {%ld,%d} %d\n",
496 GetCurrentThreadId(), hInternet, dwContext,
497 iar->dwResult,iar->dwError,dwStatusInformationLength);
498 req_error = iar->dwError;
499 if(!close_handle_cnt)
500 SetEvent(complete_event);
501 break;
503 case INTERNET_STATUS_REDIRECT:
504 if(winetest_debug > 1)
505 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REDIRECT \"%s\" %d\n",
506 GetCurrentThreadId(), hInternet, dwContext,
507 (LPCSTR)lpvStatusInformation, dwStatusInformationLength);
508 *(LPSTR)lpvStatusInformation = '\0';
509 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
510 SET_EXPECT(INTERNET_STATUS_DETECTING_PROXY);
511 break;
512 case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
513 if(winetest_debug > 1)
514 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_INTERMEDIATE_RESPONSE %p %d\n",
515 GetCurrentThreadId(), hInternet, dwContext,
516 lpvStatusInformation, dwStatusInformationLength);
517 break;
518 default:
519 if(winetest_debug > 1)
520 trace("%04x:Callback %p 0x%lx %d %p %d\n",
521 GetCurrentThreadId(), hInternet, dwContext, dwInternetStatus,
522 lpvStatusInformation, dwStatusInformationLength);
526 typedef struct {
527 HINTERNET session;
528 HINTERNET connection;
529 HINTERNET request;
530 } test_request_t;
532 #define open_simple_request(a,b,c,d,e) _open_simple_request(__LINE__,a,b,c,d,e)
533 static void _open_simple_request(unsigned line, test_request_t *req, const char *host,
534 int port, const char *verb, const char *url)
536 req->session = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
537 ok_(__FILE__,line)(req->session != NULL, "InternetOpenA failed: %u\n", GetLastError());
539 req->connection = InternetConnectA(req->session, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
540 ok_(__FILE__,line)(req->connection != NULL, "InternetConnectA failed: %u\n", GetLastError());
542 req->request = HttpOpenRequestA(req->connection, verb, url, NULL, NULL, NULL, 0, 0);
543 ok_(__FILE__,line)(req->request != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
546 #define close_request(a) _close_request(__LINE__,a)
547 static void _close_request(unsigned line, test_request_t *req)
549 BOOL ret;
551 ret = InternetCloseHandle(req->request);
552 ok_(__FILE__,line)(ret, "InternetCloseHandle(request) failed: %u\n", GetLastError());
553 ret = InternetCloseHandle(req->connection);
554 ok_(__FILE__,line)(ret, "InternetCloseHandle(connection) failed: %u\n", GetLastError());
555 ret = InternetCloseHandle(req->session);
556 ok_(__FILE__,line)(ret, "InternetCloseHandle(session) failed: %u\n", GetLastError());
559 #define receive_simple_request(a,b,c) _receive_simple_request(__LINE__,a,b,c)
560 static DWORD _receive_simple_request(unsigned line, HINTERNET req, char *buf, size_t buf_size)
562 DWORD read = 0;
563 BOOL ret;
565 ret = InternetReadFile(req, buf, buf_size, &read);
566 ok_(__FILE__,line)(ret, "InternetReadFile failed: %u\n", GetLastError());
568 return read;
571 static void close_async_handle(HINTERNET handle, int handle_cnt)
573 BOOL res;
575 close_handle_cnt = handle_cnt;
577 SET_EXPECT2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
578 res = InternetCloseHandle(handle);
579 ok(res, "InternetCloseHandle failed: %u\n", GetLastError());
580 WaitForSingleObject(complete_event, INFINITE);
581 CHECK_NOTIFIED2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
584 static void InternetReadFile_test(int flags, const test_data_t *test)
586 char *post_data = NULL;
587 BOOL res, on_async = TRUE;
588 CHAR buffer[4000];
589 WCHAR wbuffer[4000];
590 DWORD length, length2, index, exlen = 0, post_len = 0;
591 const char *types[2] = { "*", NULL };
592 HINTERNET hi, hic = 0, hor = 0;
593 DWORD contents_length, accepts_ranges;
594 BOOL not_supported;
596 trace("Starting InternetReadFile test with flags 0x%x on url %s\n",flags,test->url);
597 reset_events();
599 hi = InternetOpenA((test->flags & TESTF_COMPRESSED) ? "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" : "",
600 INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
601 ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
603 if (hi == 0x0) goto abort;
605 pInternetSetStatusCallbackA(hi,&callback);
607 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
609 hic=InternetConnectA(hi, test->host, INTERNET_INVALID_PORT_NUMBER,
610 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
611 ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
613 if (hic == 0x0) goto abort;
615 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
616 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
618 hor = HttpOpenRequestA(hic, test->post_data ? "POST" : "GET", test->path, NULL, NULL, types,
619 INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
620 0xdeadbead);
621 if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
623 * If the internet name can't be resolved we are probably behind
624 * a firewall or in some other way not directly connected to the
625 * Internet. Not enough reason to fail the test. Just ignore and
626 * abort.
628 } else {
629 ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
632 if (hor == 0x0) goto abort;
634 test_request_flags(hor, INTERNET_REQFLAG_NO_HEADERS);
635 test_request_url(hor, test->url);
637 length = sizeof(buffer);
638 res = HttpQueryInfoA(hor, HTTP_QUERY_RAW_HEADERS, buffer, &length, 0x0);
639 ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
640 ok(length == 0 || (length == 1 && !*buffer) /* win10 */, "HTTP_QUERY_RAW_HEADERS: expected length 0, but got %d\n", length);
641 ok(!strcmp(buffer, ""), "HTTP_QUERY_RAW_HEADERS: expected string \"\", but got \"%s\"\n", buffer);
643 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
644 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
645 CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
646 SET_OPTIONAL2(INTERNET_STATUS_COOKIE_SENT,2);
647 SET_OPTIONAL2(INTERNET_STATUS_COOKIE_RECEIVED,2);
648 if (first_connection_to_test_url)
650 SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
651 SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
653 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
654 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
655 SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1);
656 SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1);
657 SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1);
658 SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1);
659 if(test->flags & TESTF_REDIRECT) {
660 SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
661 SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
663 SET_EXPECT(INTERNET_STATUS_REDIRECT);
664 SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER);
665 SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER);
666 if (flags & INTERNET_FLAG_ASYNC)
667 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
669 if(test->flags & TESTF_COMPRESSED) {
670 BOOL b = TRUE;
672 res = InternetSetOptionA(hor, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
673 ok(res || broken(!res && GetLastError() == ERROR_INTERNET_INVALID_OPTION),
674 "InternetSetOption failed: %u\n", GetLastError());
675 if(!res)
676 goto abort;
679 test_status_code(hor, 0);
681 if(test->post_data) {
682 post_len = strlen(test->post_data);
683 post_data = HeapAlloc(GetProcessHeap(), 0, post_len);
684 memcpy(post_data, test->post_data, post_len);
686 SetLastError(0xdeadbeef);
687 res = HttpSendRequestA(hor, test->headers, -1, post_data, post_len);
688 if (flags & INTERNET_FLAG_ASYNC)
689 ok(!res && (GetLastError() == ERROR_IO_PENDING),
690 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
691 else
692 ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED),
693 "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
695 if (flags & INTERNET_FLAG_ASYNC) {
696 WaitForSingleObject(complete_event, INFINITE);
697 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
699 HeapFree(GetProcessHeap(), 0, post_data);
701 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
702 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_RECEIVED);
703 if (first_connection_to_test_url)
705 if (! proxy_active())
707 CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
708 CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
710 else
712 CLEAR_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
713 CLEAR_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
716 else
718 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
719 CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
721 CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1);
722 CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1);
723 CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1);
724 CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1);
725 if(test->flags & TESTF_REDIRECT)
726 CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
727 if (flags & INTERNET_FLAG_ASYNC)
728 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
729 /* Sent on WinXP only if first_connection_to_test_url is TRUE, on Win98 always sent */
730 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
731 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
733 test_request_flags(hor, 0);
735 length = 100;
736 res = InternetQueryOptionA(hor,INTERNET_OPTION_URL,buffer,&length);
737 ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed with error %d\n", GetLastError());
739 length = sizeof(buffer)-2;
740 memset(buffer, 0x77, sizeof(buffer));
741 SetLastError(0xdeadbeef);
742 res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length,0x0);
743 ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
744 ok(GetLastError() == 0 ||
745 broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
746 /* show that the function writes data past the length returned */
747 ok(buffer[length-2], "Expected any header character, got 0x00\n");
748 ok(!buffer[length-1], "Expected 0x00, got %02X\n", buffer[length-1]);
749 ok(!buffer[length], "Expected 0x00, got %02X\n", buffer[length]);
750 ok(buffer[length+1] == 0x77, "Expected 0x77, got %02X\n", buffer[length+1]);
752 length2 = length;
753 res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length2,0x0);
754 ok(!res, "Expected 0x00, got %d\n", res);
755 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
756 ok(length2 == length+1, "Expected %d, got %d\n", length+1, length2);
757 /* the in length of the buffer must be +1 but the length returned does not count this */
758 length2 = length+1;
759 memset(buffer, 0x77, sizeof(buffer));
760 res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length2,0x0);
761 ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
762 ok(buffer[length2] == 0x00, "Expected 0x00, got %02X\n", buffer[length2]);
763 ok(buffer[length2+1] == 0x77, "Expected 0x77, got %02X\n", buffer[length2+1]);
764 ok(length2 == length, "Value should not have changed: %d != %d\n", length2, length);
766 length = sizeof(wbuffer)-2*sizeof(WCHAR);
767 memset(wbuffer, 0x77, sizeof(wbuffer));
768 res = HttpQueryInfoW(hor, HTTP_QUERY_RAW_HEADERS, wbuffer, &length, 0x0);
769 ok(res, "HttpQueryInfoW(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
770 ok(length % sizeof(WCHAR) == 0, "Expected that length is a multiple of sizeof(WCHAR), got %d.\n", length);
771 length /= sizeof(WCHAR);
772 /* show that the function writes data past the length returned */
773 ok(wbuffer[length-2], "Expected any header character, got 0x0000\n");
774 ok(!wbuffer[length-1], "Expected 0x0000, got %04X\n", wbuffer[length-1]);
775 ok(!wbuffer[length], "Expected 0x0000, got %04X\n", wbuffer[length]);
776 ok(wbuffer[length+1] == 0x7777 || broken(wbuffer[length+1] != 0x7777),
777 "Expected 0x7777, got %04X\n", wbuffer[length+1]);
779 length2 = length*sizeof(WCHAR);
780 res = HttpQueryInfoW(hor,HTTP_QUERY_RAW_HEADERS,wbuffer,&length2,0x0);
781 ok(!res, "Expected 0x00, got %d\n", res);
782 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
783 ok(length2 % sizeof(WCHAR) == 0, "Expected that length is a multiple of sizeof(WCHAR), got %d.\n", length2);
784 length2 /= sizeof(WCHAR);
785 ok(length2 == length+1, "Expected %d, got %d\n", length+1, length2);
786 /* the in length of the buffer must be +1 but the length returned does not count this */
787 length2 = (length+1)*sizeof(WCHAR);
788 memset(wbuffer, 0x77, sizeof(wbuffer));
789 res = HttpQueryInfoW(hor,HTTP_QUERY_RAW_HEADERS,wbuffer,&length2,0x0);
790 ok(res, "HttpQueryInfoW(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
791 ok(length2 % sizeof(WCHAR) == 0, "Expected that length is a multiple of sizeof(WCHAR), got %d.\n", length2);
792 length2 /= sizeof(WCHAR);
793 ok(!wbuffer[length2], "Expected 0x0000, got %04X\n", wbuffer[length2]);
794 ok(wbuffer[length2+1] == 0x7777, "Expected 0x7777, got %04X\n", wbuffer[length2+1]);
795 ok(length2 == length, "Value should not have changed: %d != %d\n", length2, length);
797 test_request_url(hor, test->redirected_url);
799 index = 0;
800 length = 0;
801 SetLastError(0xdeadbeef);
802 ok(HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,NULL,&length,&index) == FALSE,"Query worked\n");
803 if(test->flags & TESTF_COMPRESSED)
804 ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
805 "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", GetLastError());
806 ok(index == 0, "Index was incremented\n");
808 index = 0;
809 length = 16;
810 res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,&index);
811 trace("Option HTTP_QUERY_CONTENT_LENGTH -> %i %s (%u)\n",res,buffer,GetLastError());
812 if(test->flags & TESTF_COMPRESSED)
814 ok(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
815 "expected ERROR_HTTP_HEADER_NOT_FOUND, got %x (%u)\n", res, GetLastError());
816 contents_length = 0;
818 else
820 contents_length = atoi(buffer);
822 ok(!res || index == 1, "Index was not incremented although result is %x (index = %u)\n", res, index);
824 length = 64;
825 *buffer = 0;
826 res = HttpQueryInfoA(hor,HTTP_QUERY_ACCEPT_RANGES,&buffer,&length,0x0);
827 trace("Option HTTP_QUERY_ACCEPT_RANGES -> %i %s (%u)\n",res,buffer,GetLastError());
828 accepts_ranges = res && !strcmp(buffer, "bytes");
830 length = 100;
831 res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
832 buffer[length]=0;
833 trace("Option HTTP_QUERY_CONTENT_TYPE -> %i %s\n",res,buffer);
835 length = 100;
836 res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_ENCODING,buffer,&length,0x0);
837 buffer[length]=0;
838 trace("Option HTTP_QUERY_CONTENT_ENCODING -> %i %s\n",res,buffer);
840 SetLastError(0xdeadbeef);
841 length = InternetSetFilePointer(hor, 0, NULL, FILE_END, 0);
842 not_supported = length == INVALID_SET_FILE_POINTER
843 && GetLastError() == ERROR_INTERNET_INVALID_OPERATION;
844 if (accepts_ranges)
845 todo_wine ok((length == contents_length && (GetLastError() == ERROR_SUCCESS
846 || broken(GetLastError() == 0xdeadbeef))) || broken(not_supported),
847 "Got unexpected length %#x, GetLastError() %u, contents_length %u, accepts_ranges %#x.\n",
848 length, GetLastError(), contents_length, accepts_ranges);
849 else
850 ok(not_supported, "Got unexpected length %#x, GetLastError() %u.\n", length, GetLastError());
852 if (length != INVALID_SET_FILE_POINTER)
854 SetLastError(0xdeadbeef);
855 length = InternetSetFilePointer(hor, 0, NULL, FILE_BEGIN, 0);
856 ok(!length && (GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef)),
857 "Got unexpected length %#x, GetLastError() %u.\n", length, GetLastError());
860 SetLastError(0xdeadbeef);
861 res = InternetReadFile(NULL, buffer, 100, &length);
862 ok(!res, "InternetReadFile should have failed\n");
863 ok(GetLastError() == ERROR_INVALID_HANDLE,
864 "InternetReadFile should have set last error to ERROR_INVALID_HANDLE instead of %u\n",
865 GetLastError());
867 length = 100;
868 if(winetest_debug > 1)
869 trace("Entering Query loop\n");
871 while (TRUE)
873 if (flags & INTERNET_FLAG_ASYNC)
874 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
876 /* IE11 calls those in InternetQueryDataAvailable call. */
877 SET_OPTIONAL(INTERNET_STATUS_RECEIVING_RESPONSE);
878 SET_OPTIONAL(INTERNET_STATUS_RESPONSE_RECEIVED);
880 length = 0;
881 res = InternetQueryDataAvailable(hor,&length,0x0,0x0);
883 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
885 if (flags & INTERNET_FLAG_ASYNC)
887 if (res)
889 CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
890 if(exlen) {
891 ok(length >= exlen, "length %u < exlen %u\n", length, exlen);
892 exlen = 0;
895 else if (GetLastError() == ERROR_IO_PENDING)
897 if(winetest_debug > 1)
898 trace("pending\n");
899 /* on some tests, InternetQueryDataAvailable returns non-zero length and ERROR_IO_PENDING */
900 if(!(test->flags & TESTF_CHUNKED))
901 ok(!length, "InternetQueryDataAvailable returned ERROR_IO_PENDING and %u length\n", length);
902 WaitForSingleObject(complete_event, INFINITE);
903 exlen = length;
904 ok(exlen, "length = 0\n");
905 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
906 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
907 ok(req_error, "req_error = 0\n");
908 continue;
909 }else {
910 ok(0, "InternetQueryDataAvailable failed: %u\n", GetLastError());
912 }else {
913 ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
915 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
917 if(winetest_debug > 1)
918 trace("length %u\n", length);
919 if(test->flags & TESTF_CHUNKED)
920 ok(length <= 8192, "length = %d, expected <= 8192\n", length);
921 if (length)
923 char *buffer;
924 buffer = HeapAlloc(GetProcessHeap(),0,length+1);
926 res = InternetReadFile(hor,buffer,length,&length);
928 buffer[length]=0;
930 if(winetest_debug > 1)
931 trace("ReadFile -> %s %i\n", res ? "TRUE" : "FALSE", length);
933 if(test->content)
934 ok(!strcmp(buffer, test->content), "buffer = '%s', expected '%s'\n", buffer, test->content);
935 HeapFree(GetProcessHeap(),0,buffer);
936 }else {
937 ok(!on_async, "Returned zero size in response to request complete\n");
938 break;
940 on_async = FALSE;
942 if(test->flags & TESTF_REDIRECT) {
943 CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
944 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
946 abort:
947 if(winetest_debug > 1)
948 trace("aborting\n");
949 close_async_handle(hi, 2);
950 first_connection_to_test_url = FALSE;
953 static void InternetReadFile_chunked_test(void)
955 BOOL res;
956 CHAR buffer[4000];
957 DWORD length, got;
958 const char *types[2] = { "*", NULL };
959 HINTERNET hi, hic = 0, hor = 0;
961 trace("Starting InternetReadFile chunked test\n");
963 hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
964 ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
966 if (hi == 0x0) goto abort;
968 hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER,
969 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
970 ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
972 if (hic == 0x0) goto abort;
974 hor = HttpOpenRequestA(hic, "GET", "/tests/chunked", NULL, NULL, types,
975 INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
976 0xdeadbead);
977 if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
979 * If the internet name can't be resolved we are probably behind
980 * a firewall or in some other way not directly connected to the
981 * Internet. Not enough reason to fail the test. Just ignore and
982 * abort.
984 } else {
985 ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
988 if (hor == 0x0) goto abort;
990 SetLastError(0xdeadbeef);
991 res = HttpSendRequestA(hor, "", -1, NULL, 0);
992 ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED),
993 "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
995 test_request_flags(hor, 0);
997 length = 100;
998 res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
999 buffer[length]=0;
1000 trace("Option CONTENT_TYPE -> %i %s\n",res,buffer);
1002 SetLastError( 0xdeadbeef );
1003 length = 100;
1004 res = HttpQueryInfoA(hor,HTTP_QUERY_TRANSFER_ENCODING,buffer,&length,0x0);
1005 buffer[length]=0;
1006 trace("Option TRANSFER_ENCODING -> %i %s\n",res,buffer);
1007 ok( res || ( proxy_active() && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND ),
1008 "Failed to get TRANSFER_ENCODING option, error %u\n", GetLastError() );
1009 ok( !strcmp( buffer, "chunked" ) || ( ! res && proxy_active() && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND ),
1010 "Wrong transfer encoding '%s'\n", buffer );
1012 SetLastError( 0xdeadbeef );
1013 length = 16;
1014 res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0);
1015 ok( !res, "Found CONTENT_LENGTH option '%s'\n", buffer );
1016 ok( GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "Wrong error %u\n", GetLastError() );
1018 length = 100;
1019 trace("Entering Query loop\n");
1021 while (TRUE)
1023 res = InternetQueryDataAvailable(hor,&length,0x0,0x0);
1024 ok(!(!res && length != 0),"InternetQueryDataAvailable failed with non-zero length\n");
1025 ok(res, "InternetQueryDataAvailable failed, error %d\n", GetLastError());
1026 trace("got %u available\n",length);
1027 if (length)
1029 char *buffer = HeapAlloc(GetProcessHeap(),0,length+1);
1031 SetLastError(0xdeadbeef);
1032 res = InternetReadFile(hor,buffer,length,&got);
1033 ok(GetLastError() == 0 ||
1034 broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
1036 buffer[got]=0;
1037 trace("ReadFile -> %i %i\n",res,got);
1038 ok( length == got, "only got %u of %u available\n", got, length );
1039 ok( buffer[got-1] == '\n', "received partial line '%s'\n", buffer );
1041 HeapFree(GetProcessHeap(),0,buffer);
1042 if (!got) break;
1044 if (length == 0)
1046 got = 0xdeadbeef;
1047 SetLastError(0xdeadbeef);
1048 res = InternetReadFile( hor, buffer, 1, &got );
1049 ok( res, "InternetReadFile failed: %u\n", GetLastError() );
1050 ok(GetLastError() == 0 ||
1051 broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
1052 ok( !got, "got %u\n", got );
1053 break;
1056 abort:
1057 trace("aborting\n");
1058 if (hor != 0x0) {
1059 res = InternetCloseHandle(hor);
1060 ok (res, "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n");
1062 if (hi != 0x0) {
1063 res = InternetCloseHandle(hi);
1064 ok (res, "InternetCloseHandle of handle opened by InternetOpenA failed\n");
1068 static void InternetReadFileExA_test(int flags)
1070 DWORD rc;
1071 DWORD length;
1072 const char *types[2] = { "*", NULL };
1073 HINTERNET hi, hic = 0, hor = 0;
1074 INTERNET_BUFFERSA inetbuffers;
1076 trace("Starting InternetReadFileExA test with flags 0x%x\n",flags);
1077 reset_events();
1079 hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
1080 ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
1082 if (hi == 0x0) goto abort;
1084 pInternetSetStatusCallbackA(hi,&callback);
1086 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1088 hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER,
1089 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
1090 ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
1092 if (hic == 0x0) goto abort;
1094 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1095 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1097 hor = HttpOpenRequestA(hic, "GET", "/tests/redirect", NULL, NULL, types,
1098 INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
1099 0xdeadbead);
1100 if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
1102 * If the internet name can't be resolved we are probably behind
1103 * a firewall or in some other way not directly connected to the
1104 * Internet. Not enough reason to fail the test. Just ignore and
1105 * abort.
1107 } else {
1108 ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
1111 if (hor == 0x0) goto abort;
1113 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1114 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
1115 CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
1116 if (first_connection_to_test_url)
1118 SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
1119 SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
1121 SET_OPTIONAL2(INTERNET_STATUS_COOKIE_SENT, 2);
1122 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
1123 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
1124 SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, 2);
1125 SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, 2);
1126 SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, 2);
1127 SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, 2);
1128 SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
1129 SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
1130 SET_EXPECT(INTERNET_STATUS_REDIRECT);
1131 SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER);
1132 SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER);
1133 if (flags & INTERNET_FLAG_ASYNC)
1134 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
1135 else
1136 SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_COMPLETE);
1138 SetLastError(0xdeadbeef);
1139 rc = HttpSendRequestA(hor, "", -1, NULL, 0);
1140 if (flags & INTERNET_FLAG_ASYNC)
1141 ok(((rc == 0)&&(GetLastError() == ERROR_IO_PENDING)),
1142 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
1143 else
1144 ok((rc != 0) || GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED,
1145 "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
1147 if (!rc && (GetLastError() == ERROR_IO_PENDING)) {
1148 WaitForSingleObject(complete_event, INFINITE);
1149 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
1152 if (first_connection_to_test_url)
1154 CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
1155 CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
1157 else
1159 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
1160 CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
1162 CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, 2);
1163 CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, 2);
1164 CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, 2);
1165 CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, 2);
1166 CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
1167 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
1168 CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
1169 if (flags & INTERNET_FLAG_ASYNC)
1170 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1171 else
1172 todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1173 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
1174 /* Sent on WinXP only if first_connection_to_test_url is TRUE, on Win98 always sent */
1175 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
1176 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
1178 if(is_ie7plus) {
1179 rc = InternetReadFileExW(hor, NULL, 0, 0xdeadcafe);
1180 ok(!rc && (GetLastError() == ERROR_INVALID_PARAMETER),
1181 "InternetReadFileEx should have failed with ERROR_INVALID_PARAMETER instead of %s, %u\n",
1182 rc ? "TRUE" : "FALSE", GetLastError());
1185 /* tests invalid dwStructSize */
1186 inetbuffers.dwStructSize = sizeof(inetbuffers)+1;
1187 inetbuffers.lpcszHeader = NULL;
1188 inetbuffers.dwHeadersLength = 0;
1189 inetbuffers.dwBufferLength = 10;
1190 inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, 10);
1191 inetbuffers.dwOffsetHigh = 1234;
1192 inetbuffers.dwOffsetLow = 5678;
1193 rc = InternetReadFileExA(hor, &inetbuffers, 0, 0xdeadcafe);
1194 ok(!rc && (GetLastError() == ERROR_INVALID_PARAMETER),
1195 "InternetReadFileEx should have failed with ERROR_INVALID_PARAMETER instead of %s, %u\n",
1196 rc ? "TRUE" : "FALSE", GetLastError());
1197 HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
1199 test_request_flags(hor, 0);
1201 /* tests to see whether lpcszHeader is used - it isn't */
1202 inetbuffers.dwStructSize = sizeof(inetbuffers);
1203 inetbuffers.lpcszHeader = (LPCSTR)0xdeadbeef;
1204 inetbuffers.dwHeadersLength = 255;
1205 inetbuffers.dwBufferLength = 0;
1206 inetbuffers.lpvBuffer = NULL;
1207 inetbuffers.dwOffsetHigh = 1234;
1208 inetbuffers.dwOffsetLow = 5678;
1209 rc = InternetReadFileExA(hor, &inetbuffers, 0, 0xdeadcafe);
1210 ok(rc, "InternetReadFileEx failed with error %u\n", GetLastError());
1211 trace("read %i bytes\n", inetbuffers.dwBufferLength);
1213 rc = InternetReadFileExA(NULL, &inetbuffers, 0, 0xdeadcafe);
1214 ok(!rc && (GetLastError() == ERROR_INVALID_HANDLE),
1215 "InternetReadFileEx should have failed with ERROR_INVALID_HANDLE instead of %s, %u\n",
1216 rc ? "TRUE" : "FALSE", GetLastError());
1218 length = 0;
1219 trace("Entering Query loop\n");
1221 while (TRUE)
1223 inetbuffers.dwStructSize = sizeof(inetbuffers);
1224 inetbuffers.dwBufferLength = 1024;
1225 inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, inetbuffers.dwBufferLength+1);
1226 inetbuffers.dwOffsetHigh = 1234;
1227 inetbuffers.dwOffsetLow = 5678;
1229 SET_WINE_ALLOW(INTERNET_STATUS_RECEIVING_RESPONSE);
1230 SET_WINE_ALLOW(INTERNET_STATUS_RESPONSE_RECEIVED);
1231 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
1232 rc = InternetReadFileExA(hor, &inetbuffers, IRF_ASYNC | IRF_USE_CONTEXT, 0xcafebabe);
1233 if (!rc)
1235 if (GetLastError() == ERROR_IO_PENDING)
1237 trace("InternetReadFileEx -> PENDING\n");
1238 ok(flags & INTERNET_FLAG_ASYNC,
1239 "Should not get ERROR_IO_PENDING without INTERNET_FLAG_ASYNC\n");
1240 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1241 WaitForSingleObject(complete_event, INFINITE);
1242 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1243 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1244 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
1246 else
1248 trace("InternetReadFileEx -> FAILED %u\n", GetLastError());
1249 break;
1252 else
1254 trace("InternetReadFileEx -> SUCCEEDED\n");
1255 CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1256 if (inetbuffers.dwBufferLength)
1258 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1259 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1261 else
1263 /* Win98 still sends these when 0 bytes are read, WinXP does not */
1264 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1265 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1269 trace("read %i bytes\n", inetbuffers.dwBufferLength);
1270 ((char *)inetbuffers.lpvBuffer)[inetbuffers.dwBufferLength] = '\0';
1272 ok(inetbuffers.dwOffsetHigh == 1234 && inetbuffers.dwOffsetLow == 5678,
1273 "InternetReadFileEx sets offsets to 0x%x%08x\n",
1274 inetbuffers.dwOffsetHigh, inetbuffers.dwOffsetLow);
1276 HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
1278 if (!inetbuffers.dwBufferLength)
1279 break;
1281 length += inetbuffers.dwBufferLength;
1283 ok(length > 0, "failed to read any of the document\n");
1284 trace("Finished. Read %d bytes\n", length);
1286 abort:
1287 close_async_handle(hi, 2);
1288 first_connection_to_test_url = FALSE;
1291 static void InternetOpenUrlA_test(void)
1293 HINTERNET myhinternet, myhttp;
1294 char buffer[0x400];
1295 DWORD size, readbytes, totalbytes=0;
1296 BOOL ret;
1298 ret = DeleteUrlCacheEntryA(TEST_URL);
1299 ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND,
1300 "DeleteUrlCacheEntry returned %x, GetLastError() = %d\n", ret, GetLastError());
1302 myhinternet = InternetOpenA("Winetest",0,NULL,NULL,INTERNET_FLAG_NO_CACHE_WRITE);
1303 ok((myhinternet != 0), "InternetOpen failed, error %u\n",GetLastError());
1304 size = 0x400;
1305 ret = InternetCanonicalizeUrlA(TEST_URL, buffer, &size,ICU_BROWSER_MODE);
1306 ok( ret, "InternetCanonicalizeUrl failed, error %u\n",GetLastError());
1308 SetLastError(0);
1309 myhttp = InternetOpenUrlA(myhinternet, TEST_URL, 0, 0,
1310 INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_TRANSFER_BINARY,0);
1311 if (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1312 return; /* WinXP returns this when not connected to the net */
1313 ok((myhttp != 0),"InternetOpenUrl failed, error %u\n",GetLastError());
1314 ret = InternetReadFile(myhttp, buffer,0x400,&readbytes);
1315 ok( ret, "InternetReadFile failed, error %u\n",GetLastError());
1316 totalbytes += readbytes;
1317 while (readbytes && InternetReadFile(myhttp, buffer,0x400,&readbytes))
1318 totalbytes += readbytes;
1319 trace("read 0x%08x bytes\n",totalbytes);
1321 InternetCloseHandle(myhttp);
1322 InternetCloseHandle(myhinternet);
1324 ret = DeleteUrlCacheEntryA(TEST_URL);
1325 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "INTERNET_FLAG_NO_CACHE_WRITE flag doesn't work\n");
1328 static void HttpSendRequestEx_test(void)
1330 HINTERNET hSession;
1331 HINTERNET hConnect;
1332 HINTERNET hRequest;
1334 INTERNET_BUFFERSA BufferIn;
1335 DWORD dwBytesWritten, dwBytesRead, error;
1336 CHAR szBuffer[256];
1337 int i;
1338 BOOL ret;
1340 static char szPostData[] = "mode=Test";
1341 static const char szContentType[] = "Content-Type: application/x-www-form-urlencoded";
1343 hSession = InternetOpenA("Wine Regression Test",
1344 INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1345 ok( hSession != NULL ,"Unable to open Internet session\n");
1346 hConnect = InternetConnectA(hSession, "test.winehq.org",
1347 INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1349 ok( hConnect != NULL, "Unable to connect to http://test.winehq.org\n");
1350 hRequest = HttpOpenRequestA(hConnect, "POST", "/tests/post.php",
1351 NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1352 if (!hRequest && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1354 skip( "Network unreachable, skipping test\n" );
1355 goto done;
1357 ok( hRequest != NULL, "Failed to open request handle err %u\n", GetLastError());
1359 test_request_flags(hRequest, INTERNET_REQFLAG_NO_HEADERS);
1361 BufferIn.dwStructSize = sizeof(BufferIn);
1362 BufferIn.Next = (INTERNET_BUFFERSA*)0xdeadcab;
1363 BufferIn.lpcszHeader = szContentType;
1364 BufferIn.dwHeadersLength = sizeof(szContentType)-1;
1365 BufferIn.dwHeadersTotal = sizeof(szContentType)-1;
1366 BufferIn.lpvBuffer = szPostData;
1367 BufferIn.dwBufferLength = 3;
1368 BufferIn.dwBufferTotal = sizeof(szPostData)-1;
1369 BufferIn.dwOffsetLow = 0;
1370 BufferIn.dwOffsetHigh = 0;
1372 SetLastError(0xdeadbeef);
1373 ret = HttpSendRequestExA(hRequest, &BufferIn, NULL, 0 ,0);
1374 error = GetLastError();
1375 ok(ret, "HttpSendRequestEx Failed with error %u\n", error);
1376 ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", error);
1378 test_request_flags(hRequest, INTERNET_REQFLAG_NO_HEADERS);
1380 for (i = 3; szPostData[i]; i++)
1381 ok(InternetWriteFile(hRequest, &szPostData[i], 1, &dwBytesWritten),
1382 "InternetWriteFile failed\n");
1384 test_request_flags(hRequest, INTERNET_REQFLAG_NO_HEADERS);
1386 ok(HttpEndRequestA(hRequest, NULL, 0, 0), "HttpEndRequest Failed\n");
1388 test_request_flags(hRequest, 0);
1390 ok(InternetReadFile(hRequest, szBuffer, 255, &dwBytesRead),
1391 "Unable to read response\n");
1392 szBuffer[dwBytesRead] = 0;
1394 ok(dwBytesRead == 13,"Read %u bytes instead of 13\n",dwBytesRead);
1395 ok(strncmp(szBuffer,"mode => Test\n",dwBytesRead)==0 || broken(proxy_active()),"Got string %s\n",szBuffer);
1397 ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
1398 done:
1399 ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
1400 ok(InternetCloseHandle(hSession), "Close session handle failed\n");
1403 static void InternetOpenRequest_test(void)
1405 HINTERNET session, connect, request;
1406 static const char *types[] = { "*", "", NULL };
1407 static const WCHAR slash[] = {'/', 0}, any[] = {'*', 0}, empty[] = {0};
1408 static const WCHAR *typesW[] = { any, empty, NULL };
1409 BOOL ret;
1411 session = InternetOpenA("Wine Regression Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1412 ok(session != NULL ,"Unable to open Internet session\n");
1414 connect = InternetConnectA(session, NULL, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1415 INTERNET_SERVICE_HTTP, 0, 0);
1416 ok(connect == NULL, "InternetConnectA should have failed\n");
1417 ok(GetLastError() == ERROR_INVALID_PARAMETER, "InternetConnectA with NULL server named should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
1419 connect = InternetConnectA(session, "", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1420 INTERNET_SERVICE_HTTP, 0, 0);
1421 ok(connect == NULL, "InternetConnectA should have failed\n");
1422 ok(GetLastError() == ERROR_INVALID_PARAMETER, "InternetConnectA with blank server named should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
1424 connect = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1425 INTERNET_SERVICE_HTTP, 0, 0);
1426 ok(connect != NULL, "Unable to connect to http://test.winehq.org with error %d\n", GetLastError());
1428 request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1429 if (!request && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1431 skip( "Network unreachable, skipping test\n" );
1432 goto done;
1434 ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1436 ret = HttpSendRequestW(request, NULL, 0, NULL, 0);
1437 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1438 ok(InternetCloseHandle(request), "Close request handle failed\n");
1440 request = HttpOpenRequestW(connect, NULL, slash, NULL, NULL, typesW, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1441 ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1443 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1444 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1445 ok(InternetCloseHandle(request), "Close request handle failed\n");
1447 done:
1448 ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1449 ok(InternetCloseHandle(session), "Close session handle failed\n");
1452 static void test_cache_read(void)
1454 HINTERNET session, connection, req;
1455 FILETIME now, tomorrow, yesterday;
1456 BYTE content[1000], buf[2000];
1457 char file_path[MAX_PATH];
1458 ULARGE_INTEGER li;
1459 HANDLE file;
1460 DWORD size;
1461 unsigned i;
1462 BOOL res;
1464 static const char cache_only_url[] = "http://test.winehq.org/tests/cache-only";
1465 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
1467 trace("Testing cache read...\n");
1468 reset_events();
1470 for(i = 0; i < sizeof(content); i++)
1471 content[i] = '0' + (i%10);
1473 GetSystemTimeAsFileTime(&now);
1474 li.u.HighPart = now.dwHighDateTime;
1475 li.u.LowPart = now.dwLowDateTime;
1476 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
1477 tomorrow.dwHighDateTime = li.u.HighPart;
1478 tomorrow.dwLowDateTime = li.u.LowPart;
1479 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
1480 yesterday.dwHighDateTime = li.u.HighPart;
1481 yesterday.dwLowDateTime = li.u.LowPart;
1483 res = CreateUrlCacheEntryA(cache_only_url, sizeof(content), "", file_path, 0);
1484 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
1486 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1487 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1489 WriteFile(file, content, sizeof(content), &size, NULL);
1490 CloseHandle(file);
1492 res = CommitUrlCacheEntryA(cache_only_url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
1493 cache_headers, sizeof(cache_headers)-1, "", 0);
1494 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
1496 session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
1497 ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
1499 pInternetSetStatusCallbackA(session, callback);
1501 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1502 connection = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT,
1503 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
1504 ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
1505 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1507 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1508 req = HttpOpenRequestA(connection, "GET", "/tests/cache-only", NULL, NULL, NULL, 0, 0xdeadbead);
1509 ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
1510 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1512 SET_WINE_ALLOW(INTERNET_STATUS_CONNECTING_TO_SERVER);
1513 SET_WINE_ALLOW(INTERNET_STATUS_CONNECTED_TO_SERVER);
1514 SET_WINE_ALLOW(INTERNET_STATUS_SENDING_REQUEST);
1515 SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_SENT);
1516 SET_WINE_ALLOW(INTERNET_STATUS_RECEIVING_RESPONSE);
1517 SET_WINE_ALLOW(INTERNET_STATUS_RESPONSE_RECEIVED);
1518 SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_COMPLETE);
1520 res = HttpSendRequestA(req, NULL, -1, NULL, 0);
1521 todo_wine
1522 ok(res, "HttpSendRequest failed: %u\n", GetLastError());
1524 if(res) {
1525 size = 0;
1526 res = InternetQueryDataAvailable(req, &size, 0, 0);
1527 ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
1528 ok(size == sizeof(content), "size = %u\n", size);
1530 size = sizeof(buf);
1531 res = InternetReadFile(req, buf, sizeof(buf), &size);
1532 ok(res, "InternetReadFile failed: %u\n", GetLastError());
1533 ok(size == sizeof(content), "size = %u\n", size);
1534 ok(!memcmp(content, buf, sizeof(content)), "unexpected content\n");
1537 close_async_handle(session, 2);
1539 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
1540 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
1541 CLEAR_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
1542 CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
1543 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1544 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1545 CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1547 res = DeleteUrlCacheEntryA(cache_only_url);
1548 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
1551 static void test_http_cache(void)
1553 HINTERNET session, connect, request;
1554 char file_name[MAX_PATH], url[INTERNET_MAX_URL_LENGTH];
1555 DWORD size, file_size;
1556 BYTE buf[100];
1557 HANDLE file;
1558 BOOL ret;
1559 FILETIME filetime_zero = {0};
1561 static const char cached_content[] = "data read from cache";
1562 static const char *types[] = { "*", "", NULL };
1564 session = InternetOpenA("Wine Regression Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1565 ok(session != NULL ,"Unable to open Internet session\n");
1567 connect = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1568 INTERNET_SERVICE_HTTP, 0, 0);
1569 ok(connect != NULL, "Unable to connect to http://test.winehq.org with error %d\n", GetLastError());
1571 request = HttpOpenRequestA(connect, NULL, "/tests/hello.html", NULL, NULL, types, INTERNET_FLAG_NEED_FILE, 0);
1572 if (!request && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1574 skip( "Network unreachable, skipping test\n" );
1576 ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1577 ok(InternetCloseHandle(session), "Close session handle failed\n");
1579 return;
1581 ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1583 size = sizeof(url);
1584 ret = InternetQueryOptionA(request, INTERNET_OPTION_URL, url, &size);
1585 ok(ret, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
1586 ok(!strcmp(url, "http://test.winehq.org/tests/hello.html"), "Wrong URL %s\n", url);
1588 size = sizeof(file_name);
1589 ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1590 ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1591 ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1592 ok(!size, "size = %d\n", size);
1594 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1595 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1597 size = sizeof(file_name);
1598 ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1599 ok(ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) failed: %u\n", GetLastError());
1601 file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
1602 FILE_ATTRIBUTE_NORMAL, NULL);
1603 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1604 file_size = GetFileSize(file, NULL);
1605 ok(file_size == 106, "file size = %u\n", file_size);
1607 size = sizeof(buf);
1608 ret = InternetReadFile(request, buf, sizeof(buf), &size);
1609 ok(ret, "InternetReadFile failed: %u\n", GetLastError());
1610 ok(size == 100, "size = %u\n", size);
1612 file_size = GetFileSize(file, NULL);
1613 ok(file_size == 106, "file size = %u\n", file_size);
1614 CloseHandle(file);
1616 ret = DeleteFileA(file_name);
1617 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, "Deleting file returned %x(%u)\n", ret, GetLastError());
1619 ok(InternetCloseHandle(request), "Close request handle failed\n");
1621 file = CreateFileA(file_name, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1622 FILE_ATTRIBUTE_NORMAL, NULL);
1623 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1624 ret = WriteFile(file, cached_content, sizeof(cached_content), &size, NULL);
1625 ok(ret && size, "WriteFile failed: %d, %d\n", ret, size);
1626 ret = CommitUrlCacheEntryA(url, file_name, filetime_zero, filetime_zero, NORMAL_CACHE_ENTRY, NULL, 0, NULL, 0);
1627 ok(ret, "CommitUrlCacheEntry failed: %d\n", GetLastError());
1628 CloseHandle(file);
1630 /* Send the same request, requiring it to be retrieved from the cache */
1631 request = HttpOpenRequestA(connect, "GET", "/tests/hello.html", NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
1633 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1634 ok(ret, "HttpSendRequest failed\n");
1636 size = sizeof(buf);
1637 ret = InternetReadFile(request, buf, sizeof(buf), &size);
1638 ok(ret, "InternetReadFile failed: %u\n", GetLastError());
1639 ok(size == 100, "size = %u\n", size);
1640 buf[99] = 0;
1641 todo_wine ok(!strcmp((char*)buf, cached_content), "incorrect page data: %s\n", (char*)buf);
1643 ok(InternetCloseHandle(request), "Close request handle failed\n");
1645 DeleteUrlCacheEntryA(url);
1646 request = HttpOpenRequestA(connect, "GET", "/tests/hello.html", NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
1647 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1648 todo_wine ok(!ret, "HttpSendRequest succeeded\n");
1649 if(!ret)
1650 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() = %d\n", GetLastError());
1651 ok(InternetCloseHandle(request), "Close request handle failed\n");
1653 request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1654 ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1656 size = sizeof(file_name);
1657 ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1658 ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1659 ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1660 ok(!size, "size = %d\n", size);
1662 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1663 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1665 size = sizeof(file_name);
1666 file_name[0] = 0;
1667 ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1668 if (ret)
1670 file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1671 FILE_ATTRIBUTE_NORMAL, NULL);
1672 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1673 CloseHandle(file);
1675 else
1677 /* < IE8 */
1678 ok(file_name[0] == 0, "Didn't expect a file name\n");
1681 ok(InternetCloseHandle(request), "Close request handle failed\n");
1682 ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1683 ok(InternetCloseHandle(session), "Close session handle failed\n");
1685 test_cache_read();
1688 static void InternetLockRequestFile_test(void)
1690 char file_name[MAX_PATH];
1691 test_request_t req;
1692 HANDLE lock, lock2;
1693 DWORD size;
1694 BOOL ret;
1696 open_simple_request(&req, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, "/tests/hello.html");
1698 size = sizeof(file_name);
1699 ret = InternetQueryOptionA(req.request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1700 ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1701 ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1702 ok(!size, "size = %d\n", size);
1704 lock = NULL;
1705 ret = InternetLockRequestFile(req.request, &lock);
1706 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "InternetLockRequestFile returned: %x(%u)\n", ret, GetLastError());
1708 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
1709 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1711 size = sizeof(file_name);
1712 ret = InternetQueryOptionA(req.request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1713 ok(ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) failed: %u\n", GetLastError());
1715 ret = InternetLockRequestFile(req.request, &lock);
1716 ok(ret, "InternetLockRequestFile returned: %x(%u)\n", ret, GetLastError());
1717 ok(lock != NULL, "lock == NULL\n");
1719 ret = InternetLockRequestFile(req.request, &lock2);
1720 ok(ret, "InternetLockRequestFile returned: %x(%u)\n", ret, GetLastError());
1721 ok(lock == lock2, "lock != lock2\n");
1723 ret = InternetUnlockRequestFile(lock2);
1724 ok(ret, "InternetUnlockRequestFile failed: %u\n", GetLastError());
1726 ret = DeleteFileA(file_name);
1727 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, "Deleting file returned %x(%u)\n", ret, GetLastError());
1729 ok(InternetCloseHandle(req.request), "Close request handle failed\n");
1731 ret = DeleteFileA(file_name);
1732 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, "Deleting file returned %x(%u)\n", ret, GetLastError());
1734 ret = InternetUnlockRequestFile(lock);
1735 ok(ret, "InternetUnlockRequestFile failed: %u\n", GetLastError());
1737 ret = DeleteFileA(file_name);
1738 ok(ret, "Deleting file returned %x(%u)\n", ret, GetLastError());
1741 static void HttpHeaders_test(void)
1743 HINTERNET hSession;
1744 HINTERNET hConnect;
1745 HINTERNET hRequest;
1746 CHAR buffer[256];
1747 WCHAR wbuffer[256];
1748 DWORD len = 256;
1749 DWORD oldlen;
1750 DWORD index = 0;
1751 BOOL ret;
1753 hSession = InternetOpenA("Wine Regression Test",
1754 INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1755 ok( hSession != NULL ,"Unable to open Internet session\n");
1756 hConnect = InternetConnectA(hSession, "test.winehq.org",
1757 INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1759 ok( hConnect != NULL, "Unable to connect to http://test.winehq.org\n");
1760 hRequest = HttpOpenRequestA(hConnect, "POST", "/tests/post.php",
1761 NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1762 if (!hRequest && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1764 skip( "Network unreachable, skipping test\n" );
1765 goto done;
1767 ok( hRequest != NULL, "Failed to open request handle\n");
1769 index = 0;
1770 len = sizeof(buffer);
1771 strcpy(buffer,"Warning");
1772 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1773 buffer,&len,&index)==0,"Warning hearder reported as Existing\n");
1775 ok(HttpAddRequestHeadersA(hRequest,"Warning:test1",-1,HTTP_ADDREQ_FLAG_ADD),
1776 "Failed to add new header\n");
1778 index = 0;
1779 len = sizeof(buffer);
1780 strcpy(buffer,"Warning");
1781 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1782 buffer,&len,&index),"Unable to query header\n");
1783 ok(index == 1, "Index was not incremented\n");
1784 ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1785 ok(len == 5, "Invalid length (exp. 5, got %d)\n", len);
1786 ok((len < sizeof(buffer)) && (buffer[len] == 0), "Buffer not NULL-terminated\n"); /* len show only 5 characters but the buffer is NULL-terminated*/
1787 len = sizeof(buffer);
1788 strcpy(buffer,"Warning");
1789 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1790 buffer,&len,&index)==0,"Second Index Should Not Exist\n");
1792 index = 0;
1793 len = 5; /* could store the string but not the NULL terminator */
1794 strcpy(buffer,"Warning");
1795 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1796 buffer,&len,&index) == FALSE,"Query succeeded on a too small buffer\n");
1797 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1798 ok(index == 0, "Index was incremented\n");
1799 ok(strcmp(buffer,"Warning")==0, "incorrect string was returned(%s)\n",buffer); /* string not touched */
1800 ok(len == 6, "Invalid length (exp. 6, got %d)\n", len); /* unlike success, the length includes the NULL-terminator */
1802 /* a call with NULL will fail but will return the length */
1803 index = 0;
1804 len = sizeof(buffer);
1805 SetLastError(0xdeadbeef);
1806 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1807 NULL,&len,&index) == FALSE,"Query worked\n");
1808 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1809 ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1810 ok(index == 0, "Index was incremented\n");
1812 /* even for a len that is too small */
1813 index = 0;
1814 len = 15;
1815 SetLastError(0xdeadbeef);
1816 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1817 NULL,&len,&index) == FALSE,"Query worked\n");
1818 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1819 ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1820 ok(index == 0, "Index was incremented\n");
1822 index = 0;
1823 len = 0;
1824 SetLastError(0xdeadbeef);
1825 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1826 NULL,&len,&index) == FALSE,"Query worked\n");
1827 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1828 ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1829 ok(index == 0, "Index was incremented\n");
1830 oldlen = len; /* bytes; at least long enough to hold buffer & nul */
1833 /* a working query */
1834 index = 0;
1835 len = sizeof(buffer);
1836 memset(buffer, 'x', sizeof(buffer));
1837 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1838 buffer,&len,&index),"Unable to query header\n");
1839 ok(len + sizeof(CHAR) <= oldlen, "Result longer than advertised\n");
1840 ok((len < sizeof(buffer)-sizeof(CHAR)) && (buffer[len/sizeof(CHAR)] == 0),"No NUL at end\n");
1841 ok(len == strlen(buffer) * sizeof(CHAR), "Length wrong\n");
1842 /* what's in the middle differs between Wine and Windows so currently we check only the beginning and the end */
1843 ok(strncmp(buffer, "POST /tests/post.php HTTP/1", 25)==0, "Invalid beginning of headers string\n");
1844 ok(strcmp(buffer + strlen(buffer) - 4, "\r\n\r\n")==0, "Invalid end of headers string\n");
1845 ok(index == 0, "Index was incremented\n");
1847 /* Like above two tests, but for W version */
1849 index = 0;
1850 len = 0;
1851 SetLastError(0xdeadbeef);
1852 ok(HttpQueryInfoW(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1853 NULL,&len,&index) == FALSE,"Query worked\n");
1854 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1855 ok(len > 80, "Invalid length (exp. more than 80, got %d)\n", len);
1856 ok(index == 0, "Index was incremented\n");
1857 oldlen = len; /* bytes; at least long enough to hold buffer & nul */
1859 /* a working query */
1860 index = 0;
1861 len = sizeof(wbuffer);
1862 memset(wbuffer, 'x', sizeof(wbuffer));
1863 ok(HttpQueryInfoW(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1864 wbuffer,&len,&index),"Unable to query header\n");
1865 ok(len + sizeof(WCHAR) <= oldlen, "Result longer than advertised\n");
1866 ok(len == lstrlenW(wbuffer) * sizeof(WCHAR), "Length wrong\n");
1867 ok((len < sizeof(wbuffer)-sizeof(WCHAR)) && (wbuffer[len/sizeof(WCHAR)] == 0),"No NUL at end\n");
1868 ok(index == 0, "Index was incremented\n");
1870 /* end of W version tests */
1872 /* Without HTTP_QUERY_FLAG_REQUEST_HEADERS */
1873 index = 0;
1874 len = sizeof(buffer);
1875 memset(buffer, 'x', sizeof(buffer));
1876 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,
1877 buffer,&len,&index) == TRUE,"Query failed\n");
1878 ok(len == 2 || len == 4 /* win10 */, "Expected 2 or 4, got %d\n", len);
1879 ok(memcmp(buffer, "\r\n\r\n", len) == 0, "Expected CRLF, got '%s'\n", buffer);
1880 ok(index == 0, "Index was incremented\n");
1882 ok(HttpAddRequestHeadersA(hRequest,"Warning:test2",-1,HTTP_ADDREQ_FLAG_ADD),
1883 "Failed to add duplicate header using HTTP_ADDREQ_FLAG_ADD\n");
1885 index = 0;
1886 len = sizeof(buffer);
1887 strcpy(buffer,"Warning");
1888 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1889 buffer,&len,&index),"Unable to query header\n");
1890 ok(index == 1, "Index was not incremented\n");
1891 ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1892 len = sizeof(buffer);
1893 strcpy(buffer,"Warning");
1894 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1895 buffer,&len,&index),"Failed to get second header\n");
1896 ok(index == 2, "Index was not incremented\n");
1897 ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1898 len = sizeof(buffer);
1899 strcpy(buffer,"Warning");
1900 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1901 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1903 ok(HttpAddRequestHeadersA(hRequest,"Warning:test3",-1,HTTP_ADDREQ_FLAG_REPLACE), "Failed to replace header using HTTP_ADDREQ_FLAG_REPLACE\n");
1905 index = 0;
1906 len = sizeof(buffer);
1907 strcpy(buffer,"Warning");
1908 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1909 buffer,&len,&index),"Unable to query header\n");
1910 ok(index == 1, "Index was not incremented\n");
1911 ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1912 len = sizeof(buffer);
1913 strcpy(buffer,"Warning");
1914 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1915 buffer,&len,&index),"Failed to get second header\n");
1916 ok(index == 2, "Index was not incremented\n");
1917 ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1918 len = sizeof(buffer);
1919 strcpy(buffer,"Warning");
1920 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1921 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1923 ok(HttpAddRequestHeadersA(hRequest,"Warning:test4",-1,HTTP_ADDREQ_FLAG_ADD_IF_NEW)==0, "HTTP_ADDREQ_FLAG_ADD_IF_NEW replaced existing header\n");
1925 index = 0;
1926 len = sizeof(buffer);
1927 strcpy(buffer,"Warning");
1928 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1929 buffer,&len,&index),"Unable to query header\n");
1930 ok(index == 1, "Index was not incremented\n");
1931 ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1932 len = sizeof(buffer);
1933 strcpy(buffer,"Warning");
1934 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1935 buffer,&len,&index),"Failed to get second header\n");
1936 ok(index == 2, "Index was not incremented\n");
1937 ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1938 len = sizeof(buffer);
1939 strcpy(buffer,"Warning");
1940 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1941 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1943 ok(HttpAddRequestHeadersA(hRequest,"Warning:test4",-1, HTTP_ADDREQ_FLAG_COALESCE), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1945 index = 0;
1946 len = sizeof(buffer);
1947 strcpy(buffer,"Warning");
1948 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1949 buffer,&len,&index),"Unable to query header\n");
1950 ok(index == 1, "Index was not incremented\n");
1951 ok(strcmp(buffer,"test2, test4")==0, "incorrect string was returned(%s)\n", buffer);
1952 len = sizeof(buffer);
1953 strcpy(buffer,"Warning");
1954 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1955 ok(index == 2, "Index was not incremented\n");
1956 ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1957 len = sizeof(buffer);
1958 strcpy(buffer,"Warning");
1959 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1961 ok(HttpAddRequestHeadersA(hRequest,"Warning:test5",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1963 index = 0;
1964 len = sizeof(buffer);
1965 strcpy(buffer,"Warning");
1966 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1967 ok(index == 1, "Index was not incremented\n");
1968 ok(strcmp(buffer,"test2, test4, test5")==0, "incorrect string was returned(%s)\n",buffer);
1969 len = sizeof(buffer);
1970 strcpy(buffer,"Warning");
1971 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1972 ok(index == 2, "Index was not incremented\n");
1973 ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1974 len = sizeof(buffer);
1975 strcpy(buffer,"Warning");
1976 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1978 ok(HttpAddRequestHeadersA(hRequest,"Warning:test6",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1980 index = 0;
1981 len = sizeof(buffer);
1982 strcpy(buffer,"Warning");
1983 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1984 ok(index == 1, "Index was not incremented\n");
1985 ok(strcmp(buffer,"test2, test4, test5; test6")==0, "incorrect string was returned(%s)\n",buffer);
1986 len = sizeof(buffer);
1987 strcpy(buffer,"Warning");
1988 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1989 ok(index == 2, "Index was not incremented\n");
1990 ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1991 len = sizeof(buffer);
1992 strcpy(buffer,"Warning");
1993 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1995 ok(HttpAddRequestHeadersA(hRequest,"Warning:test7",-1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE), "HTTP_ADDREQ_FLAG_ADD with HTTP_ADDREQ_FLAG_REPALCE Did not work\n");
1997 index = 0;
1998 len = sizeof(buffer);
1999 strcpy(buffer,"Warning");
2000 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2001 ok(index == 1, "Index was not incremented\n");
2002 ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
2003 len = sizeof(buffer);
2004 strcpy(buffer,"Warning");
2005 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
2006 ok(index == 2, "Index was not incremented\n");
2007 ok(strcmp(buffer,"test7")==0, "incorrect string was returned(%s)\n",buffer);
2008 len = sizeof(buffer);
2009 strcpy(buffer,"Warning");
2010 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
2012 /* Ensure that blank headers are ignored and don't cause a failure */
2013 ok(HttpAddRequestHeadersA(hRequest,"\r\nBlankTest:value\r\n\r\n",-1, HTTP_ADDREQ_FLAG_ADD_IF_NEW), "Failed to add header with blank entries in list\n");
2015 index = 0;
2016 len = sizeof(buffer);
2017 strcpy(buffer,"BlankTest");
2018 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2019 ok(index == 1, "Index was not incremented\n");
2020 ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer);
2022 /* Ensure that malformed header separators are ignored and don't cause a failure */
2023 ok(HttpAddRequestHeadersA(hRequest,"\r\rMalformedTest:value\n\nMalformedTestTwo: value2\rMalformedTestThree: value3\n\n\r\r\n",-1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE),
2024 "Failed to add header with malformed entries in list\n");
2026 index = 0;
2027 len = sizeof(buffer);
2028 strcpy(buffer,"MalformedTest");
2029 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2030 ok(index == 1, "Index was not incremented\n");
2031 ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer);
2032 index = 0;
2033 len = sizeof(buffer);
2034 strcpy(buffer,"MalformedTestTwo");
2035 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2036 ok(index == 1, "Index was not incremented\n");
2037 ok(strcmp(buffer,"value2")==0, "incorrect string was returned(%s)\n",buffer);
2038 index = 0;
2039 len = sizeof(buffer);
2040 strcpy(buffer,"MalformedTestThree");
2041 ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2042 ok(index == 1, "Index was not incremented\n");
2043 ok(strcmp(buffer,"value3")==0, "incorrect string was returned(%s)\n",buffer);
2045 ret = HttpAddRequestHeadersA(hRequest, "Authorization: Basic\r\n", -1, HTTP_ADDREQ_FLAG_ADD);
2046 ok(ret, "unable to add header %u\n", GetLastError());
2048 index = 0;
2049 buffer[0] = 0;
2050 len = sizeof(buffer);
2051 ret = HttpQueryInfoA(hRequest, HTTP_QUERY_AUTHORIZATION|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &len, &index);
2052 ok(ret, "unable to query header %u\n", GetLastError());
2053 ok(index == 1, "index was not incremented\n");
2054 ok(!strcmp(buffer, "Basic"), "incorrect string was returned (%s)\n", buffer);
2056 ret = HttpAddRequestHeadersA(hRequest, "Authorization:\r\n", -1, HTTP_ADDREQ_FLAG_REPLACE);
2057 ok(ret, "unable to remove header %u\n", GetLastError());
2059 index = 0;
2060 len = sizeof(buffer);
2061 SetLastError(0xdeadbeef);
2062 ok(!HttpQueryInfoA(hRequest, HTTP_QUERY_AUTHORIZATION|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &len, &index),
2063 "header still present\n");
2064 ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "got %u\n", GetLastError());
2066 ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
2067 done:
2068 ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
2069 ok(InternetCloseHandle(hSession), "Close session handle failed\n");
2072 static const char garbagemsg[] =
2073 "Garbage: Header\r\n";
2075 static const char contmsg[] =
2076 "HTTP/1.1 100 Continue\r\n";
2078 static const char expandcontmsg[] =
2079 "HTTP/1.1 100 Continue\r\n"
2080 "Server: winecontinue\r\n"
2081 "Tag: something witty\r\n";
2083 static const char okmsg[] =
2084 "HTTP/1.1 200 OK\r\n"
2085 "Server: winetest\r\n"
2086 "\r\n";
2088 static const char okmsg201[] =
2089 "HTTP/1.1 201 OK\r\n"
2090 "Server: winetest\r\n"
2091 "\r\n";
2093 static const char okmsg2[] =
2094 "HTTP/1.1 200 OK\r\n"
2095 "Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
2096 "Server: winetest\r\n"
2097 "Content-Length: 0\r\n"
2098 "Set-Cookie: one\r\n"
2099 "Set-Cookie: two\r\n"
2100 "\r\n";
2102 static DWORD64 content_length;
2103 static const char largemsg[] =
2104 "HTTP/1.1 200 OK\r\n"
2105 "Content-Length: %I64u\r\n"
2106 "\r\n";
2108 static const char notokmsg[] =
2109 "HTTP/1.1 400 Bad Request\r\n"
2110 "Server: winetest\r\n"
2111 "\r\n";
2113 static const char noauthmsg[] =
2114 "HTTP/1.1 401 Unauthorized\r\n"
2115 "Server: winetest\r\n"
2116 "Connection: close\r\n"
2117 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2118 "\r\n";
2120 static const char noauthmsg2[] =
2121 "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed\r\n"
2122 "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"
2123 "\0d`0|6\n"
2124 "Server: winetest\r\n";
2126 static const char proxymsg[] =
2127 "HTTP/1.1 407 Proxy Authentication Required\r\n"
2128 "Server: winetest\r\n"
2129 "Proxy-Connection: close\r\n"
2130 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
2131 "\r\n";
2133 static const char page1[] =
2134 "<HTML>\r\n"
2135 "<HEAD><TITLE>wininet test page</TITLE></HEAD>\r\n"
2136 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2137 "</HTML>\r\n\r\n";
2139 static const char ok_with_length[] =
2140 "HTTP/1.1 200 OK\r\n"
2141 "Connection: Keep-Alive\r\n"
2142 "Content-Length: 18\r\n\r\n"
2143 "HTTP/1.1 211 OK\r\n\r\n";
2145 static const char ok_with_length2[] =
2146 "HTTP/1.1 210 OK\r\n"
2147 "Connection: Keep-Alive\r\n"
2148 "Content-Length: 19\r\n\r\n"
2149 "HTTP/1.1 211 OK\r\n\r\n";
2151 struct server_info {
2152 HANDLE hEvent;
2153 int port;
2156 static int test_cache_gzip;
2157 static const char *send_buffer;
2158 static int server_socket;
2160 static DWORD CALLBACK server_thread(LPVOID param)
2162 struct server_info *si = param;
2163 int r, c = -1, i, on, count = 0;
2164 SOCKET s;
2165 struct sockaddr_in sa;
2166 char *buffer;
2167 size_t buffer_size;
2168 WSADATA wsaData;
2169 int last_request = 0;
2170 char host_header[22];
2171 char host_header_override[30];
2172 static int test_no_cache = 0;
2174 WSAStartup(MAKEWORD(1,1), &wsaData);
2176 s = socket(AF_INET, SOCK_STREAM, 0);
2177 if (s == INVALID_SOCKET)
2178 return 1;
2180 on = 1;
2181 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2183 memset(&sa, 0, sizeof sa);
2184 sa.sin_family = AF_INET;
2185 sa.sin_port = htons(si->port);
2186 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2188 r = bind(s, (struct sockaddr*) &sa, sizeof sa);
2189 if (r<0)
2190 return 1;
2192 listen(s, 0);
2194 SetEvent(si->hEvent);
2196 sprintf(host_header, "Host: localhost:%d", si->port);
2197 sprintf(host_header_override, "Host: test.local:%d\r\n", si->port);
2198 buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size = 1000);
2202 if(c == -1)
2203 c = accept(s, NULL, NULL);
2205 memset(buffer, 0, buffer_size);
2206 for(i=0;; i++)
2208 if(i == buffer_size)
2209 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, buffer_size *= 2);
2211 r = recv(c, buffer+i, 1, 0);
2212 if (r != 1)
2213 break;
2214 if (i<4) continue;
2215 if (buffer[i-2] == '\n' && buffer[i] == '\n' &&
2216 buffer[i-3] == '\r' && buffer[i-1] == '\r')
2217 break;
2219 if (strstr(buffer, "GET /test1"))
2221 if (!strstr(buffer, "Content-Length: 0"))
2223 send(c, okmsg, sizeof okmsg-1, 0);
2224 send(c, page1, sizeof page1-1, 0);
2226 else
2227 send(c, notokmsg, sizeof notokmsg-1, 0);
2229 if (strstr(buffer, "CONNECT "))
2231 if (!strstr(buffer, "Content-Length: 0"))
2232 send(c, notokmsg, sizeof notokmsg-1, 0);
2233 else
2234 send(c, proxymsg, sizeof proxymsg-1, 0);
2236 if (strstr(buffer, "/test2"))
2238 if (strstr(buffer, "Proxy-Authorization: Basic bWlrZToxMTAx"))
2240 send(c, okmsg, sizeof okmsg-1, 0);
2241 send(c, page1, sizeof page1-1, 0);
2243 else
2244 send(c, proxymsg, sizeof proxymsg-1, 0);
2246 if (strstr(buffer, "/test3"))
2248 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2249 send(c, okmsg, sizeof okmsg-1, 0);
2250 else
2251 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2253 if (strstr(buffer, "/test4"))
2255 if (strstr(buffer, "Connection: Close"))
2256 send(c, okmsg, sizeof okmsg-1, 0);
2257 else
2258 send(c, notokmsg, sizeof notokmsg-1, 0);
2260 if (strstr(buffer, "POST /test5") ||
2261 strstr(buffer, "RPC_IN_DATA /test5") ||
2262 strstr(buffer, "RPC_OUT_DATA /test5"))
2264 if (strstr(buffer, "Content-Length: 0"))
2266 send(c, okmsg, sizeof okmsg-1, 0);
2267 send(c, page1, sizeof page1-1, 0);
2269 else
2270 send(c, notokmsg, sizeof notokmsg-1, 0);
2272 if (strstr(buffer, "GET /test6"))
2274 send(c, contmsg, sizeof contmsg-1, 0);
2275 send(c, contmsg, sizeof contmsg-1, 0);
2276 send(c, okmsg, sizeof okmsg-1, 0);
2277 send(c, page1, sizeof page1-1, 0);
2279 if (strstr(buffer, "POST /test7"))
2281 if (strstr(buffer, "Content-Length: 100"))
2283 if (strstr(buffer, "POST /test7b"))
2284 recvfrom(c, buffer, buffer_size, 0, NULL, NULL);
2285 send(c, okmsg, sizeof okmsg-1, 0);
2286 send(c, page1, sizeof page1-1, 0);
2288 else
2289 send(c, notokmsg, sizeof notokmsg-1, 0);
2291 if (strstr(buffer, "/test8"))
2293 if (!strstr(buffer, "Connection: Close") &&
2294 strstr(buffer, "Connection: Keep-Alive") &&
2295 !strstr(buffer, "Cache-Control: no-cache") &&
2296 !strstr(buffer, "Pragma: no-cache") &&
2297 strstr(buffer, host_header))
2298 send(c, okmsg, sizeof okmsg-1, 0);
2299 else
2300 send(c, notokmsg, sizeof notokmsg-1, 0);
2302 if (strstr(buffer, "/test9"))
2304 if (!strstr(buffer, "Connection: Close") &&
2305 !strstr(buffer, "Connection: Keep-Alive") &&
2306 !strstr(buffer, "Cache-Control: no-cache") &&
2307 !strstr(buffer, "Pragma: no-cache") &&
2308 strstr(buffer, host_header))
2309 send(c, okmsg, sizeof okmsg-1, 0);
2310 else
2311 send(c, notokmsg, sizeof notokmsg-1, 0);
2313 if (strstr(buffer, "/testA"))
2315 if (!strstr(buffer, "Connection: Close") &&
2316 !strstr(buffer, "Connection: Keep-Alive") &&
2317 (strstr(buffer, "Cache-Control: no-cache") ||
2318 strstr(buffer, "Pragma: no-cache")) &&
2319 strstr(buffer, host_header))
2320 send(c, okmsg, sizeof okmsg-1, 0);
2321 else
2322 send(c, notokmsg, sizeof notokmsg-1, 0);
2324 if (strstr(buffer, "/testC"))
2326 if (strstr(buffer, "Cookie: cookie=biscuit"))
2327 send(c, okmsg, sizeof okmsg-1, 0);
2328 else
2329 send(c, notokmsg, sizeof notokmsg-1, 0);
2331 if (strstr(buffer, "/testD"))
2333 send(c, okmsg2, sizeof okmsg2-1, 0);
2335 if (strstr(buffer, "/testE"))
2337 send(c, noauthmsg2, sizeof noauthmsg2-1, 0);
2339 if (strstr(buffer, "GET /quit"))
2341 send(c, okmsg, sizeof okmsg-1, 0);
2342 send(c, page1, sizeof page1-1, 0);
2343 last_request = 1;
2345 if (strstr(buffer, "GET /testF"))
2347 send(c, expandcontmsg, sizeof expandcontmsg-1, 0);
2348 send(c, garbagemsg, sizeof garbagemsg-1, 0);
2349 send(c, contmsg, sizeof contmsg-1, 0);
2350 send(c, garbagemsg, sizeof garbagemsg-1, 0);
2351 send(c, okmsg, sizeof okmsg-1, 0);
2352 send(c, page1, sizeof page1-1, 0);
2354 if (strstr(buffer, "GET /testG"))
2356 send(c, page1, sizeof page1-1, 0);
2359 if (strstr(buffer, "GET /testJ"))
2361 if (count == 0)
2363 count++;
2364 send(c, ok_with_length, sizeof(ok_with_length)-1, 0);
2366 else
2368 send(c, ok_with_length2, sizeof(ok_with_length2)-1, 0);
2369 count = 0;
2372 if (strstr(buffer, "GET /testH"))
2374 send(c, ok_with_length2, sizeof(ok_with_length2)-1, 0);
2375 recvfrom(c, buffer, buffer_size, 0, NULL, NULL);
2376 send(c, ok_with_length, sizeof(ok_with_length)-1, 0);
2378 if (strstr(buffer, "GET /test_no_content_content_length"))
2380 static const char nocontentmsg[] = "HTTP/1.1 204 No Content\r\nConnection: close\r\n"
2381 "Content-Length: 10\r\n\r\n0123456789";
2382 send(c, nocontentmsg, sizeof(nocontentmsg)-1, 0);
2384 if (strstr(buffer, "GET /test_no_content"))
2386 static const char nocontentmsg[] = "HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n"
2387 "0123456789";
2388 send(c, nocontentmsg, sizeof(nocontentmsg)-1, 0);
2390 if (strstr(buffer, "GET /test_not_modified_content_length"))
2392 static const char notmodifiedmsg[] = "HTTP/1.1 304 Not Modified\r\nConnection: close\r\n"
2393 "Content-Length: 10\r\n\r\n0123456789";
2394 send(c, notmodifiedmsg, sizeof(notmodifiedmsg)-1, 0);
2396 else if (strstr(buffer, "GET /test_not_modified"))
2398 static const char notmodifiedmsg[] = "HTTP/1.1 304 Not Modified\r\nConnection: close\r\n"
2399 "\r\n0123456789";
2400 send(c, notmodifiedmsg, sizeof(notmodifiedmsg)-1, 0);
2402 if (strstr(buffer, "HEAD /head_content_length"))
2404 static const char headmsg[] = "HTTP/1.1 200 OK\r\nConnection: close\r\n"
2405 "Content-Length: 10\r\n\r\n0123456789";
2406 send(c, headmsg, sizeof(headmsg)-1, 0);
2408 else if (strstr(buffer, "HEAD /head"))
2410 static const char headmsg[] = "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n0123456789";
2411 send(c, headmsg, sizeof(headmsg)-1, 0);
2413 if (strstr(buffer, "GET /test_large_header"))
2415 static const char allokmsg[] = "HTTP/1.1 200 OK\r\nServer: winetest\r\n";
2416 char header[4000 + sizeof("wine-header: ") - 1];
2418 memset(header, 'A', sizeof(header));
2419 memcpy(header, "wine-header: ", sizeof("wine-header: ") - 1);
2420 send(c, allokmsg, sizeof(allokmsg) - 1, 0);
2421 send(c, header, sizeof(header), 0);
2422 send(c, "\r\n\r\n", 4, 0);
2424 if (strstr(buffer, "GET /test_conn_close"))
2426 static const char conn_close_response[] = "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nsome content";
2427 send(c, conn_close_response, sizeof(conn_close_response)-1, 0);
2428 WaitForSingleObject(conn_close_event, INFINITE);
2429 trace("closing connection\n");
2431 if (strstr(buffer, "GET /test_cache_control_no_cache"))
2433 static const char no_cache_response[] = "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\n\r\nsome content";
2434 if(!test_no_cache++)
2435 send(c, no_cache_response, sizeof(no_cache_response)-1, 0);
2436 else
2437 send(c, okmsg, sizeof(okmsg)-1, 0);
2439 if (strstr(buffer, "GET /test_cache_control_no_store"))
2441 static const char no_cache_response[] = "HTTP/1.1 200 OK\r\nCache-Control: junk, \t No-StOrE\r\n\r\nsome content";
2442 send(c, no_cache_response, sizeof(no_cache_response)-1, 0);
2444 if (strstr(buffer, "GET /test_cache_gzip"))
2446 static const char gzip_response[] = "HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\nContent-Type: text/html\r\n\r\n"
2447 "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x4b\xaf\xca\x2c\x50\x28"
2448 "\x49\x2d\x2e\xe1\x02\x00\x62\x92\xc7\x6c\x0a\x00\x00\x00";
2449 if(!test_cache_gzip++)
2450 send(c, gzip_response, sizeof(gzip_response), 0);
2451 else
2452 send(c, notokmsg, sizeof(notokmsg)-1, 0);
2454 if (strstr(buffer, "HEAD /test_head")) {
2455 static const char head_response[] =
2456 "HTTP/1.1 200 OK\r\n"
2457 "Connection: Keep-Alive\r\n"
2458 "Content-Length: 100\r\n"
2459 "\r\n";
2461 send(c, head_response, sizeof(head_response), 0);
2462 continue;
2464 if (strstr(buffer, "GET /send_from_buffer"))
2465 send(c, send_buffer, strlen(send_buffer), 0);
2466 if (strstr(buffer, "/test_cache_control_verb"))
2468 if (!memcmp(buffer, "GET ", sizeof("GET ")-1) &&
2469 !strstr(buffer, "Cache-Control: no-cache\r\n")) send(c, okmsg, sizeof(okmsg)-1, 0);
2470 else if (strstr(buffer, "Cache-Control: no-cache\r\n")) send(c, okmsg, sizeof(okmsg)-1, 0);
2471 else send(c, notokmsg, sizeof(notokmsg)-1, 0);
2473 if (strstr(buffer, "/test_request_content_length"))
2475 static char msg[] = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\n\r\n";
2476 static int seen_content_length;
2478 if (!seen_content_length)
2480 if (strstr(buffer, "Content-Length: 0"))
2482 seen_content_length = 1;
2483 send(c, msg, sizeof msg-1, 0);
2485 else send(c, notokmsg, sizeof notokmsg-1, 0);
2486 WaitForSingleObject(complete_event, 5000);
2488 else
2490 if (strstr(buffer, "Content-Length: 0")) send(c, msg, sizeof msg-1, 0);
2491 else send(c, notokmsg, sizeof notokmsg-1, 0);
2492 WaitForSingleObject(complete_event, 5000);
2495 if (strstr(buffer, "GET /test_premature_disconnect"))
2496 trace("closing connection\n");
2497 if (strstr(buffer, "HEAD /upload.txt"))
2499 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2500 send(c, okmsg, sizeof okmsg-1, 0);
2501 else
2502 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2504 if (strstr(buffer, "PUT /upload2.txt"))
2506 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2507 send(c, okmsg, sizeof okmsg-1, 0);
2508 else
2509 send(c, notokmsg, sizeof notokmsg-1, 0);
2511 if (strstr(buffer, "HEAD /upload3.txt"))
2513 if (strstr(buffer, "Authorization: Basic dXNlcjE6cHdkMQ=="))
2514 send(c, okmsg, sizeof okmsg-1, 0);
2515 else
2516 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2518 if (strstr(buffer, "HEAD /upload4.txt"))
2520 if (strstr(buffer, "Authorization: Bearer dXNlcjE6cHdkMQ=="))
2521 send(c, okmsg, sizeof okmsg-1, 0);
2522 else if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2523 send(c, okmsg201, sizeof okmsg-1, 0);
2524 else
2525 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2527 if (strstr(buffer, "/test_host_override"))
2529 if (strstr(buffer, host_header_override))
2530 send(c, okmsg, sizeof okmsg-1, 0);
2531 else
2532 send(c, notokmsg, sizeof notokmsg-1, 0);
2534 if (strstr(buffer, "/async_read"))
2536 const char *page1_mid = page1 + (sizeof page1 - 1)/2;
2537 const char *page1_end = page1 + sizeof page1 - 1;
2538 send(c, okmsg, sizeof okmsg-1, 0);
2539 send(c, page1, page1_mid - page1, 0);
2540 WaitForSingleObject(conn_wait_event, INFINITE);
2541 send(c, page1_mid, page1_end - page1_mid, 0);
2543 if (strstr(buffer, "/socket"))
2545 server_socket = c;
2546 SetEvent(server_req_rec_event);
2547 WaitForSingleObject(conn_wait_event, INFINITE);
2549 if (strstr(buffer, "/echo_request"))
2551 send(c, okmsg, sizeof(okmsg)-1, 0);
2552 send(c, buffer, strlen(buffer), 0);
2554 if (strstr(buffer, "GET /test_remove_dot_segments"))
2556 send(c, okmsg, sizeof(okmsg)-1, 0);
2558 if (strstr(buffer, "HEAD /test_large_content"))
2560 char msg[sizeof(largemsg) + 16];
2561 sprintf(msg, largemsg, content_length);
2562 send(c, msg, strlen(msg), 0);
2564 shutdown(c, 2);
2565 closesocket(c);
2566 c = -1;
2567 } while (!last_request);
2569 closesocket(s);
2570 HeapFree(GetProcessHeap(), 0, buffer);
2572 return 0;
2575 static void test_basic_request(int port, const char *verb, const char *url)
2577 test_request_t req;
2578 DWORD r, count, error;
2579 char buffer[0x100];
2581 trace("basic request %s %s\n", verb, url);
2583 open_simple_request(&req, "localhost", port, verb, url);
2585 SetLastError(0xdeadbeef);
2586 r = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
2587 error = GetLastError();
2588 ok(error == ERROR_SUCCESS || broken(error != ERROR_SUCCESS), "expected ERROR_SUCCESS, got %u\n", error);
2589 ok(r, "HttpSendRequest failed: %u\n", GetLastError());
2591 count = 0;
2592 memset(buffer, 0, sizeof buffer);
2593 SetLastError(0xdeadbeef);
2594 r = InternetReadFile(req.request, buffer, sizeof buffer, &count);
2595 ok(r, "InternetReadFile failed %u\n", GetLastError());
2596 ok(count == sizeof page1 - 1, "count was wrong\n");
2597 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong, got: %s\n", buffer);
2599 close_request(&req);
2602 static void test_proxy_indirect(int port)
2604 test_request_t req;
2605 DWORD r, sz;
2606 char buffer[0x40];
2608 open_simple_request(&req, "localhost", port, NULL, "/test2");
2610 r = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
2611 ok(r, "HttpSendRequest failed %u\n", GetLastError());
2613 sz = sizeof buffer;
2614 r = HttpQueryInfoA(req.request, HTTP_QUERY_PROXY_AUTHENTICATE, buffer, &sz, NULL);
2615 ok(r || GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo failed: %d\n", GetLastError());
2616 if (!r)
2618 skip("missing proxy header, not testing remaining proxy headers\n");
2619 goto out;
2621 ok(!strcmp(buffer, "Basic realm=\"placebo\""), "proxy auth info wrong\n");
2623 test_status_code(req.request, 407);
2624 test_request_flags(req.request, 0);
2626 sz = sizeof buffer;
2627 r = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &sz, NULL);
2628 ok(r, "HttpQueryInfo failed\n");
2629 ok(!strcmp(buffer, "Proxy Authentication Required"), "proxy text wrong\n");
2631 sz = sizeof buffer;
2632 r = HttpQueryInfoA(req.request, HTTP_QUERY_VERSION, buffer, &sz, NULL);
2633 ok(r, "HttpQueryInfo failed\n");
2634 ok(!strcmp(buffer, "HTTP/1.1"), "http version wrong\n");
2636 sz = sizeof buffer;
2637 r = HttpQueryInfoA(req.request, HTTP_QUERY_SERVER, buffer, &sz, NULL);
2638 ok(r, "HttpQueryInfo failed\n");
2639 ok(!strcmp(buffer, "winetest"), "http server wrong\n");
2641 sz = sizeof buffer;
2642 r = HttpQueryInfoA(req.request, HTTP_QUERY_CONTENT_ENCODING, buffer, &sz, NULL);
2643 ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo should fail\n");
2644 ok(r == FALSE, "HttpQueryInfo failed\n");
2646 out:
2647 close_request(&req);
2650 static void test_proxy_direct(int port)
2652 HINTERNET hi, hc, hr;
2653 DWORD r, sz, error;
2654 char buffer[0x40], *url;
2655 WCHAR bufferW[0x40];
2656 static const char url_fmt[] = "http://test.winehq.org:%u/test2";
2657 static CHAR username[] = "mike",
2658 password[] = "1101",
2659 useragent[] = "winetest";
2660 static const WCHAR usernameW[] = {'m','i','k','e',0},
2661 passwordW[] = {'1','1','0','1',0},
2662 useragentW[] = {'w','i','n','e','t','e','s','t',0};
2664 /* specify proxy type without the proxy and bypass */
2665 SetLastError(0xdeadbeef);
2666 hi = InternetOpenW(NULL, INTERNET_OPEN_TYPE_PROXY, NULL, NULL, 0);
2667 error = GetLastError();
2668 ok(error == ERROR_INVALID_PARAMETER ||
2669 broken(error == ERROR_SUCCESS) /* WinXPProSP2 */, "got %u\n", error);
2670 ok(hi == NULL || broken(!!hi) /* WinXPProSP2 */, "open should have failed\n");
2672 sprintf(buffer, "localhost:%d\n", port);
2673 hi = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0);
2674 ok(hi != NULL, "open failed\n");
2676 /* try connect without authorization */
2677 hc = InternetConnectA(hi, "test.winehq.org", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2678 ok(hc != NULL, "connect failed\n");
2680 hr = HttpOpenRequestA(hc, NULL, "/test2", NULL, NULL, NULL, 0, 0);
2681 ok(hr != NULL, "HttpOpenRequest failed\n");
2683 sz = 0;
2684 SetLastError(0xdeadbeef);
2685 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, NULL, &sz);
2686 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2687 ok(!r, "unexpected success\n");
2688 ok(sz == 1, "got %u\n", sz);
2690 sz = 0;
2691 SetLastError(0xdeadbeef);
2692 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, NULL, &sz);
2693 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2694 ok(!r, "unexpected success\n");
2695 ok(sz == 1, "got %u\n", sz);
2697 sz = sizeof(buffer);
2698 SetLastError(0xdeadbeef);
2699 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz);
2700 ok(r, "unexpected failure %u\n", GetLastError());
2701 ok(!sz, "got %u\n", sz);
2703 sz = sizeof(buffer);
2704 SetLastError(0xdeadbeef);
2705 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2706 ok(r, "unexpected failure %u\n", GetLastError());
2707 ok(!sz, "got %u\n", sz);
2709 sz = 0;
2710 SetLastError(0xdeadbeef);
2711 r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, NULL, &sz);
2712 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2713 ok(!r, "unexpected success\n");
2714 ok(sz == 1, "got %u\n", sz);
2716 sz = 0;
2717 SetLastError(0xdeadbeef);
2718 r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, NULL, &sz);
2719 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2720 ok(!r, "unexpected success\n");
2721 ok(sz == 1, "got %u\n", sz);
2723 sz = sizeof(buffer);
2724 SetLastError(0xdeadbeef);
2725 r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, buffer, &sz);
2726 ok(r, "unexpected failure %u\n", GetLastError());
2727 ok(!sz, "got %u\n", sz);
2729 sz = sizeof(buffer);
2730 SetLastError(0xdeadbeef);
2731 r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, buffer, &sz);
2732 ok(r, "unexpected failure %u\n", GetLastError());
2733 ok(!sz, "got %u\n", sz);
2735 sz = 0;
2736 SetLastError(0xdeadbeef);
2737 r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, NULL, &sz);
2738 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2739 ok(!r, "unexpected success\n");
2740 ok(sz == 34, "got %u\n", sz);
2742 sz = sizeof(buffer);
2743 SetLastError(0xdeadbeef);
2744 r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, buffer, &sz);
2745 ok(r, "unexpected failure %u\n", GetLastError());
2746 ok(sz == 33, "got %u\n", sz);
2748 r = HttpSendRequestW(hr, NULL, 0, NULL, 0);
2749 ok(r || broken(!r), "HttpSendRequest failed %u\n", GetLastError());
2750 if (!r)
2752 win_skip("skipping proxy tests on broken wininet\n");
2753 goto done;
2756 test_status_code(hr, 407);
2758 /* set the user + password then try again */
2759 r = InternetSetOptionA(hi, INTERNET_OPTION_PROXY_USERNAME, username, 4);
2760 ok(!r, "unexpected success\n");
2762 r = InternetSetOptionA(hc, INTERNET_OPTION_PROXY_USERNAME, username, 4);
2763 ok(r, "failed to set user\n");
2765 r = InternetSetOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, username, 4);
2766 ok(r, "failed to set user\n");
2768 buffer[0] = 0;
2769 sz = 3;
2770 SetLastError(0xdeadbeef);
2771 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2772 ok(!r, "unexpected failure %u\n", GetLastError());
2773 ok(!buffer[0], "got %s\n", buffer);
2774 ok(sz == strlen(username) + 1, "got %u\n", sz);
2776 buffer[0] = 0;
2777 sz = 0;
2778 SetLastError(0xdeadbeef);
2779 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2780 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2781 ok(!r, "unexpected success\n");
2782 ok(sz == strlen(username) + 1, "got %u\n", sz);
2784 bufferW[0] = 0;
2785 sz = 0;
2786 SetLastError(0xdeadbeef);
2787 r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_USERNAME, bufferW, &sz);
2788 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2789 ok(!r, "unexpected success\n");
2790 ok(sz == (lstrlenW(usernameW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2792 buffer[0] = 0;
2793 sz = sizeof(buffer);
2794 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2795 ok(r, "failed to get username\n");
2796 ok(!strcmp(buffer, username), "got %s\n", buffer);
2797 ok(sz == strlen(username), "got %u\n", sz);
2799 buffer[0] = 0;
2800 sz = sizeof(bufferW);
2801 r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_USERNAME, bufferW, &sz);
2802 ok(r, "failed to get username\n");
2803 ok(!lstrcmpW(bufferW, usernameW), "wrong username\n");
2804 ok(sz == lstrlenW(usernameW), "got %u\n", sz);
2806 r = InternetSetOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, username, 1);
2807 ok(r, "failed to set user\n");
2809 buffer[0] = 0;
2810 sz = sizeof(buffer);
2811 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2812 ok(r, "failed to get username\n");
2813 ok(!strcmp(buffer, username), "got %s\n", buffer);
2814 ok(sz == strlen(username), "got %u\n", sz);
2816 r = InternetSetOptionA(hi, INTERNET_OPTION_USER_AGENT, useragent, 1);
2817 ok(r, "failed to set useragent\n");
2819 buffer[0] = 0;
2820 sz = 0;
2821 SetLastError(0xdeadbeef);
2822 r = InternetQueryOptionA(hi, INTERNET_OPTION_USER_AGENT, buffer, &sz);
2823 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2824 ok(!r, "unexpected success\n");
2825 ok(sz == strlen(useragent) + 1, "got %u\n", sz);
2827 buffer[0] = 0;
2828 sz = sizeof(buffer);
2829 r = InternetQueryOptionA(hi, INTERNET_OPTION_USER_AGENT, buffer, &sz);
2830 ok(r, "failed to get user agent\n");
2831 ok(!strcmp(buffer, useragent), "got %s\n", buffer);
2832 ok(sz == strlen(useragent), "got %u\n", sz);
2834 bufferW[0] = 0;
2835 sz = 0;
2836 SetLastError(0xdeadbeef);
2837 r = InternetQueryOptionW(hi, INTERNET_OPTION_USER_AGENT, bufferW, &sz);
2838 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2839 ok(!r, "unexpected success\n");
2840 ok(sz == (lstrlenW(useragentW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2842 bufferW[0] = 0;
2843 sz = sizeof(bufferW);
2844 r = InternetQueryOptionW(hi, INTERNET_OPTION_USER_AGENT, bufferW, &sz);
2845 ok(r, "failed to get user agent\n");
2846 ok(!lstrcmpW(bufferW, useragentW), "wrong user agent\n");
2847 ok(sz == lstrlenW(useragentW), "got %u\n", sz);
2849 r = InternetSetOptionA(hr, INTERNET_OPTION_USERNAME, username, 1);
2850 ok(r, "failed to set user\n");
2852 buffer[0] = 0;
2853 sz = 0;
2854 SetLastError(0xdeadbeef);
2855 r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, buffer, &sz);
2856 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2857 ok(!r, "unexpected success\n");
2858 ok(sz == strlen(username) + 1, "got %u\n", sz);
2860 buffer[0] = 0;
2861 sz = sizeof(buffer);
2862 r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, buffer, &sz);
2863 ok(r, "failed to get user\n");
2864 ok(!strcmp(buffer, username), "got %s\n", buffer);
2865 ok(sz == strlen(username), "got %u\n", sz);
2867 bufferW[0] = 0;
2868 sz = 0;
2869 SetLastError(0xdeadbeef);
2870 r = InternetQueryOptionW(hr, INTERNET_OPTION_USERNAME, bufferW, &sz);
2871 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2872 ok(!r, "unexpected success\n");
2873 ok(sz == (lstrlenW(usernameW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2875 bufferW[0] = 0;
2876 sz = sizeof(bufferW);
2877 r = InternetQueryOptionW(hr, INTERNET_OPTION_USERNAME, bufferW, &sz);
2878 ok(r, "failed to get user\n");
2879 ok(!lstrcmpW(bufferW, usernameW), "wrong user\n");
2880 ok(sz == lstrlenW(usernameW), "got %u\n", sz);
2882 r = InternetSetOptionA(hr, INTERNET_OPTION_PASSWORD, password, 1);
2883 ok(r, "failed to set password\n");
2885 buffer[0] = 0;
2886 sz = 0;
2887 SetLastError(0xdeadbeef);
2888 r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, buffer, &sz);
2889 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2890 ok(!r, "unexpected success\n");
2891 ok(sz == strlen(password) + 1, "got %u\n", sz);
2893 buffer[0] = 0;
2894 sz = sizeof(buffer);
2895 r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, buffer, &sz);
2896 ok(r, "failed to get password\n");
2897 ok(!strcmp(buffer, password), "got %s\n", buffer);
2898 ok(sz == strlen(password), "got %u\n", sz);
2900 bufferW[0] = 0;
2901 sz = 0;
2902 SetLastError(0xdeadbeef);
2903 r = InternetQueryOptionW(hr, INTERNET_OPTION_PASSWORD, bufferW, &sz);
2904 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2905 ok(!r, "unexpected success\n");
2906 ok(sz == (lstrlenW(passwordW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2908 bufferW[0] = 0;
2909 sz = sizeof(bufferW);
2910 r = InternetQueryOptionW(hr, INTERNET_OPTION_PASSWORD, bufferW, &sz);
2911 ok(r, "failed to get password\n");
2912 ok(!lstrcmpW(bufferW, passwordW), "wrong password\n");
2913 ok(sz == lstrlenW(passwordW), "got %u\n", sz);
2915 url = HeapAlloc(GetProcessHeap(), 0, strlen(url_fmt) + 11);
2916 sprintf(url, url_fmt, port);
2917 buffer[0] = 0;
2918 sz = 0;
2919 SetLastError(0xdeadbeef);
2920 r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, buffer, &sz);
2921 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2922 ok(!r, "unexpected success\n");
2923 ok(sz == strlen(url) + 1, "got %u\n", sz);
2925 buffer[0] = 0;
2926 sz = sizeof(buffer);
2927 r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, buffer, &sz);
2928 ok(r, "failed to get url\n");
2929 ok(!strcmp(buffer, url), "got %s\n", buffer);
2930 ok(sz == strlen(url), "got %u\n", sz);
2932 bufferW[0] = 0;
2933 sz = 0;
2934 SetLastError(0xdeadbeef);
2935 r = InternetQueryOptionW(hr, INTERNET_OPTION_URL, bufferW, &sz);
2936 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2937 ok(!r, "unexpected success\n");
2938 ok(sz == (strlen(url) + 1) * sizeof(WCHAR), "got %u\n", sz);
2940 bufferW[0] = 0;
2941 sz = sizeof(bufferW);
2942 r = InternetQueryOptionW(hr, INTERNET_OPTION_URL, bufferW, &sz);
2943 ok(r, "failed to get url\n");
2944 ok(!strcmp_wa(bufferW, url), "wrong url\n");
2945 ok(sz == strlen(url), "got %u\n", sz);
2946 HeapFree(GetProcessHeap(), 0, url);
2948 r = InternetSetOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, password, 4);
2949 ok(r, "failed to set password\n");
2951 buffer[0] = 0;
2952 sz = 0;
2953 SetLastError(0xdeadbeef);
2954 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz);
2955 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2956 ok(!r, "unexpected success\n");
2957 ok(sz == strlen(password) + 1, "got %u\n", sz);
2959 buffer[0] = 0;
2960 sz = sizeof(buffer);
2961 r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz);
2962 ok(r, "failed to get password\n");
2963 ok(!strcmp(buffer, password), "got %s\n", buffer);
2964 ok(sz == strlen(password), "got %u\n", sz);
2966 bufferW[0] = 0;
2967 sz = 0;
2968 SetLastError(0xdeadbeef);
2969 r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_PASSWORD, bufferW, &sz);
2970 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2971 ok(!r, "unexpected success\n");
2972 ok(sz == (lstrlenW(passwordW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2974 bufferW[0] = 0;
2975 sz = sizeof(bufferW);
2976 r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_PASSWORD, bufferW, &sz);
2977 ok(r, "failed to get password\n");
2978 ok(!lstrcmpW(bufferW, passwordW), "wrong password\n");
2979 ok(sz == lstrlenW(passwordW), "got %u\n", sz);
2981 r = HttpSendRequestW(hr, NULL, 0, NULL, 0);
2982 if (!r)
2984 win_skip("skipping proxy tests on broken wininet\n");
2985 goto done;
2987 ok(r, "HttpSendRequest failed %u\n", GetLastError());
2988 sz = sizeof buffer;
2989 r = HttpQueryInfoA(hr, HTTP_QUERY_STATUS_CODE, buffer, &sz, NULL);
2990 ok(r, "HttpQueryInfo failed\n");
2991 ok(!strcmp(buffer, "200"), "proxy code wrong\n");
2993 InternetCloseHandle(hr);
2994 InternetCloseHandle(hc);
2995 InternetCloseHandle(hi);
2997 sprintf(buffer, "localhost:%d\n", port);
2998 hi = InternetOpenA("winetest", INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0);
2999 ok(hi != NULL, "InternetOpen failed\n");
3001 hc = InternetConnectA(hi, "test.winehq.org", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3002 ok(hc != NULL, "InternetConnect failed\n");
3004 hr = HttpOpenRequestA(hc, "POST", "/test2", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
3005 ok(hr != NULL, "HttpOpenRequest failed\n");
3007 r = HttpSendRequestA(hr, NULL, 0, (char *)"data", sizeof("data"));
3008 ok(r, "HttpSendRequest failed %u\n", GetLastError());
3010 test_status_code(hr, 407);
3012 done:
3013 InternetCloseHandle(hr);
3014 InternetCloseHandle(hc);
3015 InternetCloseHandle(hi);
3018 static void test_header_handling_order(int port)
3020 static const char authorization[] = "Authorization: Basic dXNlcjpwd2Q=";
3021 static const char connection[] = "Connection: Close";
3022 static const char *types[2] = { "*", NULL };
3023 char data[32];
3024 HINTERNET session, connect, request;
3025 DWORD size, status, data_len;
3026 BOOL ret;
3028 session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3029 ok(session != NULL, "InternetOpen failed\n");
3031 connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3032 ok(connect != NULL, "InternetConnect failed\n");
3034 request = HttpOpenRequestA(connect, NULL, "/test3", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3035 ok(request != NULL, "HttpOpenRequest failed\n");
3037 ret = HttpAddRequestHeadersA(request, authorization, ~0u, HTTP_ADDREQ_FLAG_ADD);
3038 ok(ret, "HttpAddRequestHeaders failed\n");
3040 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
3041 ok(ret, "HttpSendRequest failed\n");
3043 test_status_code(request, 200);
3044 test_request_flags(request, 0);
3046 InternetCloseHandle(request);
3048 request = HttpOpenRequestA(connect, NULL, "/test4", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3049 ok(request != NULL, "HttpOpenRequest failed\n");
3051 ret = HttpSendRequestA(request, connection, ~0u, NULL, 0);
3052 ok(ret, "HttpSendRequest failed\n");
3054 status = 0;
3055 size = sizeof(status);
3056 ret = HttpQueryInfoA( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
3057 ok(ret, "HttpQueryInfo failed\n");
3058 ok(status == 200 || status == 400 /* IE6 */, "got status %u, expected 200 or 400\n", status);
3060 InternetCloseHandle(request);
3061 InternetCloseHandle(connect);
3063 connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3064 ok(connect != NULL, "InternetConnect failed\n");
3066 request = HttpOpenRequestA(connect, "POST", "/test7", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3067 ok(request != NULL, "HttpOpenRequest failed\n");
3069 ret = HttpAddRequestHeadersA(request, "Content-Length: 100\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
3070 ok(ret, "HttpAddRequestHeaders failed\n");
3072 ret = HttpSendRequestA(request, connection, ~0u, NULL, 0);
3073 ok(ret, "HttpSendRequest failed\n");
3075 status = 0;
3076 size = sizeof(status);
3077 ret = HttpQueryInfoA( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
3078 ok(ret, "HttpQueryInfo failed\n");
3079 ok(status == 200, "got status %u, expected 200\n", status);
3081 InternetCloseHandle(request);
3082 InternetCloseHandle(connect);
3084 connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3085 ok(connect != NULL, "InternetConnect failed\n");
3087 request = HttpOpenRequestA(connect, "POST", "/test7b", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3088 ok(request != NULL, "HttpOpenRequest failed\n");
3090 ret = HttpAddRequestHeadersA(request, "Content-Length: 100\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
3091 ok(ret, "HttpAddRequestHeaders failed\n");
3093 data_len = sizeof(data);
3094 memset(data, 'a', sizeof(data));
3095 ret = HttpSendRequestA(request, NULL, 0, data, data_len);
3096 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3098 status = 0;
3099 size = sizeof(status);
3100 ret = HttpQueryInfoA( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
3101 ok(ret, "HttpQueryInfo failed\n");
3102 ok(status == 200, "got status %u, expected 200\n", status);
3104 InternetCloseHandle(request);
3105 InternetCloseHandle(connect);
3106 InternetCloseHandle(session);
3109 static void test_connection_header(int port)
3111 HINTERNET ses, con, req;
3112 BOOL ret;
3114 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3115 ok(ses != NULL, "InternetOpen failed\n");
3117 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3118 ok(con != NULL, "InternetConnect failed\n");
3120 req = HttpOpenRequestA(con, NULL, "/test8", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3121 ok(req != NULL, "HttpOpenRequest failed\n");
3123 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3124 ok(ret, "HttpSendRequest failed\n");
3126 test_status_code(req, 200);
3128 InternetCloseHandle(req);
3130 req = HttpOpenRequestA(con, NULL, "/test9", NULL, NULL, NULL, 0, 0);
3131 ok(req != NULL, "HttpOpenRequest failed\n");
3133 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3134 ok(ret, "HttpSendRequest failed\n");
3136 test_status_code(req, 200);
3138 InternetCloseHandle(req);
3140 req = HttpOpenRequestA(con, NULL, "/test9", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
3141 ok(req != NULL, "HttpOpenRequest failed\n");
3143 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3144 ok(ret, "HttpSendRequest failed\n");
3146 test_status_code(req, 200);
3148 InternetCloseHandle(req);
3150 req = HttpOpenRequestA(con, "POST", "/testA", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
3151 ok(req != NULL, "HttpOpenRequest failed\n");
3153 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3154 ok(ret, "HttpSendRequest failed\n");
3156 test_status_code(req, 200);
3158 InternetCloseHandle(req);
3159 InternetCloseHandle(con);
3160 InternetCloseHandle(ses);
3163 static void test_header_override(int port)
3165 char buffer[128], host_header_override[30], full_url[128];
3166 HINTERNET ses, con, req;
3167 DWORD size, count, err;
3168 BOOL ret;
3170 sprintf(host_header_override, "Host: test.local:%d\r\n", port);
3171 sprintf(full_url, "http://localhost:%d/test_host_override", port);
3173 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3174 ok(ses != NULL, "InternetOpen failed\n");
3176 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3177 ok(con != NULL, "InternetConnect failed\n");
3179 req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3180 ok(req != NULL, "HttpOpenRequest failed\n");
3182 size = sizeof(buffer) - 1;
3183 count = 0;
3184 memset(buffer, 0, sizeof(buffer));
3185 ret = HttpQueryInfoA(req, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &count);
3186 err = GetLastError();
3187 ok(!ret, "HttpQueryInfo succeeded\n");
3188 ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "Expected error ERROR_HTTP_HEADER_NOT_FOUND, got %d\n", err);
3190 test_request_url(req, full_url);
3192 ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_COALESCE);
3193 ok(ret, "HttpAddRequestHeaders failed\n");
3195 size = sizeof(buffer) - 1;
3196 count = 0;
3197 memset(buffer, 0, sizeof(buffer));
3198 ret = HttpQueryInfoA(req, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &count);
3199 ok(ret, "HttpQueryInfo failed\n");
3201 test_request_url(req, full_url);
3203 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3204 ok(ret, "HttpSendRequest failed\n");
3206 test_status_code(req, 200);
3208 InternetCloseHandle(req);
3209 req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3210 ok(req != NULL, "HttpOpenRequest failed\n");
3212 ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_COALESCE);
3213 ok(ret, "HttpAddRequestHeaders failed\n");
3215 ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_COALESCE);
3216 ok(ret, "HttpAddRequestHeaders failed\n");
3218 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3219 ok(ret, "HttpSendRequest failed\n");
3221 test_status_code(req, 400);
3223 InternetCloseHandle(req);
3224 req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3225 ok(req != NULL, "HttpOpenRequest failed\n");
3227 ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3228 ok(ret, "HttpAddRequestHeaders failed\n");
3230 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3231 ok(ret, "HttpSendRequest failed\n");
3233 test_status_code(req, 200);
3235 InternetCloseHandle(req);
3236 req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3237 ok(req != NULL, "HttpOpenRequest failed\n");
3239 ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_REPLACE);
3240 if(ret) { /* win10 returns success */
3241 trace("replacing host header is supported.\n");
3243 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3244 ok(ret, "HttpSendRequest failed\n");
3246 test_status_code(req, 200);
3247 }else {
3248 trace("replacing host header is not supported.\n");
3250 err = GetLastError();
3251 ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "Expected error ERROR_HTTP_HEADER_NOT_FOUND, got %d\n", err);
3253 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3254 ok(ret, "HttpSendRequest failed\n");
3256 test_status_code(req, 400);
3259 InternetCloseHandle(req);
3260 InternetCloseHandle(con);
3261 InternetCloseHandle(ses);
3264 static void test_connection_closing(int port)
3266 HINTERNET session, connection, req;
3267 DWORD res;
3269 reset_events();
3271 session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3272 ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3274 pInternetSetStatusCallbackA(session, callback);
3276 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3277 connection = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3278 ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3279 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3281 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3282 req = HttpOpenRequestA(connection, "GET", "/testJ", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0xdeadbeaf);
3283 ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3284 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3286 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3287 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3288 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3289 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3290 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3291 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3292 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3293 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3294 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION);
3295 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED);
3296 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3298 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3299 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3300 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3301 WaitForSingleObject(complete_event, INFINITE);
3302 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3304 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3305 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3306 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3307 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3308 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3309 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3310 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3311 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3312 CLEAR_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3313 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3314 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3316 test_status_code(req, 200);
3318 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3319 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3320 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3321 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3322 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3323 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3324 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3325 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3326 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3328 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3329 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3330 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3331 WaitForSingleObject(complete_event, INFINITE);
3332 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3334 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3335 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3336 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3337 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3338 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3339 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3340 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3341 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3342 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3344 test_status_code(req, 210);
3346 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3347 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3348 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3349 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3350 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3351 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3352 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3353 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3354 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION);
3355 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED);
3356 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3358 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3359 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3360 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3361 WaitForSingleObject(complete_event, INFINITE);
3362 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3364 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3365 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3366 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3367 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3368 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3369 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3370 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3371 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3372 CLEAR_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3373 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3374 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3376 test_status_code(req, 200);
3378 SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
3379 SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
3381 close_async_handle(session, 2);
3384 static void test_successive_HttpSendRequest(int port)
3386 HINTERNET session, connection, req;
3387 DWORD res;
3389 reset_events();
3391 session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3392 ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3394 pInternetSetStatusCallbackA(session, callback);
3396 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3397 connection = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3398 ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3399 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3401 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3402 req = HttpOpenRequestA(connection, "GET", "/testH", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0xdeadbeaf);
3403 ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3404 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3406 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3407 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3408 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3409 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3410 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3411 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3412 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3413 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3414 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3416 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3417 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3418 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3419 WaitForSingleObject(complete_event, INFINITE);
3420 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3422 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3423 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3424 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3425 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3426 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3427 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3428 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3429 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3430 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3432 test_status_code(req, 210);
3434 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3435 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3436 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3437 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3438 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3439 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3440 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION);
3441 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED);
3442 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3444 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3445 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3446 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3447 WaitForSingleObject(complete_event, INFINITE);
3448 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3450 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3451 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3452 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3453 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3454 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3455 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3456 CLEAR_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3457 CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3458 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3460 test_status_code(req, 200);
3462 SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
3463 SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
3465 close_async_handle(session, 2);
3468 static void test_no_content(int port)
3470 HINTERNET session, connection, req;
3471 DWORD res;
3473 trace("Testing 204 no content response...\n");
3475 reset_events();
3477 session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3478 ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3480 pInternetSetStatusCallbackA(session, callback);
3482 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3483 connection = InternetConnectA(session, "localhost", port,
3484 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3485 ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3486 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3488 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3489 req = HttpOpenRequestA(connection, "GET", "/test_no_content", NULL, NULL, NULL,
3490 INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
3491 ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3492 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3494 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3495 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3496 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3497 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3498 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3499 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3500 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3501 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
3502 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
3503 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3505 res = HttpSendRequestA(req, NULL, -1, NULL, 0);
3506 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3507 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3508 WaitForSingleObject(complete_event, INFINITE);
3509 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3511 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3512 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3513 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3514 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3515 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3516 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3517 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3518 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3520 close_async_handle(session, 2);
3523 * The connection should be closed before closing handle. This is true for most
3524 * wininet versions (including Wine), but some old win2k versions fail to do that.
3526 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3527 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3530 static void test_not_modified(int port)
3532 DWORD avail;
3533 HINTERNET ses, con, req;
3534 BOOL ret;
3536 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3537 ok(ses != NULL, "InternetOpen failed\n");
3539 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3540 ok(con != NULL, "InternetConnect failed\n");
3542 req = HttpOpenRequestA(con, NULL, "/test_not_modified", NULL, NULL, NULL, 0, 0);
3543 ok(req != NULL, "HttpOpenRequest failed\n");
3545 SetLastError(0xdeadbeef);
3546 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3547 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3548 test_status_code(req, 304);
3550 avail = 0xdeadbeef;
3551 ret = InternetQueryDataAvailable(req, &avail, 0, 0);
3552 ok(ret, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3553 ok(!avail, "got %d\n", avail);
3554 InternetCloseHandle(req);
3556 req = HttpOpenRequestA(con, NULL, "/test_not_modified_content_length", NULL, NULL, NULL, 0, 0);
3557 ok(req != NULL, "HttpOpenRequest failed\n");
3559 SetLastError(0xdeadbeef);
3560 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3561 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3562 test_status_code(req, 304);
3564 avail = 0xdeadbeef;
3565 ret = InternetQueryDataAvailable(req, &avail, 0, 0);
3566 ok(ret, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3567 ok(avail == 10, "got %d\n", avail);
3568 InternetCloseHandle(req);
3570 req = HttpOpenRequestA(con, NULL, "/test_no_content", NULL, NULL, NULL, 0, 0);
3571 ok(req != NULL, "HttpOpenRequest failed\n");
3573 SetLastError(0xdeadbeef);
3574 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3575 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3576 test_status_code(req, 204);
3578 avail = 0xdeadbeef;
3579 ret = InternetQueryDataAvailable(req, &avail, 0, 0);
3580 ok(ret, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3581 ok(!avail, "got %d\n", avail);
3582 InternetCloseHandle(req);
3584 req = HttpOpenRequestA(con, NULL, "/test_no_content_content_length", NULL, NULL, NULL, 0, 0);
3585 ok(req != NULL, "HttpOpenRequest failed\n");
3587 SetLastError(0xdeadbeef);
3588 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3589 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3590 test_status_code(req, 204);
3592 avail = 0xdeadbeef;
3593 ret = InternetQueryDataAvailable(req, &avail, 0, 0);
3594 ok(ret, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3595 ok(avail == 10, "got %d\n", avail);
3596 InternetCloseHandle(req);
3598 req = HttpOpenRequestA(con, "HEAD", "/head", NULL, NULL, NULL, 0, 0);
3599 ok(req != NULL, "HttpOpenRequest failed\n");
3601 SetLastError(0xdeadbeef);
3602 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3603 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3604 test_status_code(req, 200);
3606 avail = 0xdeadbeef;
3607 ret = InternetQueryDataAvailable(req, &avail, 0, 0);
3608 ok(ret, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3609 ok(!avail, "got %d\n", avail);
3610 InternetCloseHandle(req);
3612 req = HttpOpenRequestA(con, "HEAD", "/head_content_length", NULL, NULL, NULL, 0, 0);
3613 ok(req != NULL, "HttpOpenRequest failed\n");
3615 SetLastError(0xdeadbeef);
3616 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3617 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3618 test_status_code(req, 200);
3620 avail = 0xdeadbeef;
3621 ret = InternetQueryDataAvailable(req, &avail, 0, 0);
3622 ok(ret, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3623 ok(!avail, "got %d\n", avail);
3625 InternetCloseHandle(req);
3626 InternetCloseHandle(con);
3627 InternetCloseHandle(ses);
3630 static void test_large_header(int port)
3632 HINTERNET ses, con, req;
3633 BOOL ret;
3634 DWORD size, index, error;
3635 char buffer[13];
3637 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3638 ok(ses != NULL, "InternetOpen failed\n");
3640 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3641 ok(con != NULL, "InternetConnect failed\n");
3643 req = HttpOpenRequestA(con, NULL, "/test_large_header", NULL, NULL, NULL, 0, 0);
3644 ok(req != NULL, "HttpOpenRequest failed\n");
3646 SetLastError(0xdeadbeef);
3647 ret = HttpSendRequestW(req, NULL, 0, NULL, 0);
3648 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3649 test_status_code(req, 200);
3651 index = 0;
3652 size = sizeof(buffer);
3653 strcpy(buffer, "wine-header");
3654 ret = HttpQueryInfoA(req, HTTP_QUERY_CUSTOM, buffer, &size, &index);
3655 error = GetLastError();
3656 ok(!ret, "HttpQueryInfoA succeeded\n");
3657 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
3658 ok(size == 4001, "got %u\n", size);
3660 InternetCloseHandle(req);
3661 InternetCloseHandle(con);
3662 InternetCloseHandle(ses);
3665 static void test_conn_close(int port)
3667 HINTERNET session, connection, req;
3668 DWORD res, avail, size;
3669 BYTE buf[1024];
3671 trace("Testing connection close connection...\n");
3673 reset_events();
3675 session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3676 ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3678 pInternetSetStatusCallbackA(session, callback);
3680 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3681 connection = InternetConnectA(session, "localhost", port,
3682 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3683 ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3684 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3686 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3687 req = HttpOpenRequestA(connection, "GET", "/test_conn_close", NULL, NULL, NULL,
3688 INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
3689 ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3690 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3692 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3693 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3694 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3695 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3696 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3697 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3698 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3699 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3701 res = HttpSendRequestA(req, NULL, -1, NULL, 0);
3702 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3703 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3704 WaitForSingleObject(complete_event, INFINITE);
3705 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3707 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3708 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3709 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3710 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3711 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3712 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3713 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3714 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3716 avail = 0;
3717 res = InternetQueryDataAvailable(req, &avail, 0, 0);
3718 ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3719 ok(avail != 0, "avail = 0\n");
3721 size = 0;
3722 res = InternetReadFile(req, buf, avail, &size);
3723 ok(res, "InternetReadFile failed: %u\n", GetLastError());
3725 /* IE11 calls those in InternetQueryDataAvailable call. */
3726 SET_OPTIONAL(INTERNET_STATUS_RECEIVING_RESPONSE);
3727 SET_OPTIONAL(INTERNET_STATUS_RESPONSE_RECEIVED);
3729 res = InternetQueryDataAvailable(req, &avail, 0, 0);
3730 ok(!res && (GetLastError() == ERROR_IO_PENDING),
3731 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3732 ok(!avail, "avail = %u, expected 0\n", avail);
3734 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3736 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
3737 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
3738 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3739 SetEvent(conn_close_event);
3740 WaitForSingleObject(complete_event, INFINITE);
3741 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3742 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3743 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3744 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3745 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3747 close_async_handle(session, 2);
3750 static void test_no_cache(int port)
3752 static const char cache_control_no_cache[] = "/test_cache_control_no_cache";
3753 static const char cache_control_no_store[] = "/test_cache_control_no_store";
3754 static const char cache_url_fmt[] = "http://localhost:%d%s";
3756 char cache_url[256], buf[256];
3757 HINTERNET ses, con, req;
3758 DWORD read, size;
3759 BOOL ret;
3761 trace("Testing no-cache header\n");
3763 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3764 ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3766 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3767 ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3769 req = HttpOpenRequestA(con, NULL, cache_control_no_cache, NULL, NULL, NULL, 0, 0);
3770 ok(req != NULL, "HttpOpenRequest failed\n");
3772 sprintf(cache_url, cache_url_fmt, port, cache_control_no_cache);
3773 DeleteUrlCacheEntryA(cache_url);
3775 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3776 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3777 size = 0;
3778 while(InternetReadFile(req, buf, sizeof(buf), &read) && read)
3779 size += read;
3780 ok(size == 12, "read %d bytes of data\n", size);
3781 InternetCloseHandle(req);
3783 req = HttpOpenRequestA(con, NULL, cache_control_no_cache, NULL, NULL, NULL, 0, 0);
3784 ok(req != NULL, "HttpOpenRequest failed\n");
3786 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3787 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3788 size = 0;
3789 while(InternetReadFile(req, buf, sizeof(buf), &read) && read)
3790 size += read;
3791 ok(size == 0, "read %d bytes of data\n", size);
3792 InternetCloseHandle(req);
3793 DeleteUrlCacheEntryA(cache_url);
3795 req = HttpOpenRequestA(con, NULL, cache_control_no_store, NULL, NULL, NULL, 0, 0);
3796 ok(req != NULL, "HttpOpenRequest failed\n");
3798 sprintf(cache_url, cache_url_fmt, port, cache_control_no_store);
3799 DeleteUrlCacheEntryA(cache_url);
3801 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3802 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3803 size = 0;
3804 while(InternetReadFile(req, buf, sizeof(buf), &read) && read)
3805 size += read;
3806 ok(size == 12, "read %d bytes of data\n", size);
3807 InternetCloseHandle(req);
3809 ret = DeleteUrlCacheEntryA(cache_url);
3810 ok(!ret && GetLastError()==ERROR_FILE_NOT_FOUND, "cache entry should not exist\n");
3812 InternetCloseHandle(con);
3813 InternetCloseHandle(ses);
3816 static void test_cache_read_gzipped(int port)
3818 static const char cache_url_fmt[] = "http://localhost:%d%s";
3819 static const char get_gzip[] = "/test_cache_gzip";
3820 static const char content[] = "gzip test\n";
3821 static const char text_html[] = "text/html";
3822 static const char raw_header[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
3824 HINTERNET ses, con, req;
3825 DWORD read, size;
3826 char cache_url[256], buf[256];
3827 BOOL ret;
3829 trace("Testing reading compressed content from cache\n");
3831 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3832 ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3834 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3835 ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3837 req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3838 ok(req != NULL, "HttpOpenRequest failed\n");
3840 ret = TRUE;
3841 ret = InternetSetOptionA(req, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3842 if(!ret && GetLastError()==ERROR_INTERNET_INVALID_OPTION) {
3843 win_skip("INTERNET_OPTION_HTTP_DECODING not supported\n");
3844 InternetCloseHandle(req);
3845 InternetCloseHandle(con);
3846 InternetCloseHandle(ses);
3847 return;
3849 ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3851 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3852 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3853 size = 0;
3854 while(InternetReadFile(req, buf+size, sizeof(buf)-size, &read) && read)
3855 size += read;
3856 ok(size == 10, "read %d bytes of data\n", size);
3857 buf[size] = 0;
3858 ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3860 size = sizeof(buf)-1;
3861 ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_TYPE, buf, &size, 0);
3862 ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) failed: %d\n", GetLastError());
3863 buf[size] = 0;
3864 ok(!strncmp(text_html, buf, size), "buf = %s\n", buf);
3866 size = sizeof(buf)-1;
3867 ret = HttpQueryInfoA(req, HTTP_QUERY_RAW_HEADERS_CRLF, buf, &size, 0);
3868 ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) failed: %d\n", GetLastError());
3869 buf[size] = 0;
3870 ok(!strncmp(raw_header, buf, size), "buf = %s\n", buf);
3871 InternetCloseHandle(req);
3873 req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
3874 ok(req != NULL, "HttpOpenRequest failed\n");
3876 ret = TRUE;
3877 ret = InternetSetOptionA(req, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3878 ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3880 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3881 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3882 size = 0;
3883 while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3884 size += read;
3885 todo_wine ok(size == 10, "read %d bytes of data\n", size);
3886 buf[size] = 0;
3887 ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3889 size = sizeof(buf);
3890 ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_ENCODING, buf, &size, 0);
3891 ok(!ret && GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND,
3892 "HttpQueryInfo(HTTP_QUERY_CONTENT_ENCODING) returned %d, %d\n",
3893 ret, GetLastError());
3895 size = sizeof(buf)-1;
3896 ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_TYPE, buf, &size, 0);
3897 todo_wine ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) failed: %d\n", GetLastError());
3898 buf[size] = 0;
3899 todo_wine ok(!strncmp(text_html, buf, size), "buf = %s\n", buf);
3900 InternetCloseHandle(req);
3902 /* Decompression doesn't work while reading from cache */
3903 test_cache_gzip = 0;
3904 sprintf(cache_url, cache_url_fmt, port, get_gzip);
3905 DeleteUrlCacheEntryA(cache_url);
3907 req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3908 ok(req != NULL, "HttpOpenRequest failed\n");
3910 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3911 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3912 size = 0;
3913 while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3914 size += read;
3915 ok(size == 31, "read %d bytes of data\n", size);
3916 InternetCloseHandle(req);
3918 req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
3919 ok(req != NULL, "HttpOpenRequest failed\n");
3921 ret = TRUE;
3922 ret = InternetSetOptionA(req, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3923 ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3925 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3926 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3927 size = 0;
3928 while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3929 size += read;
3930 todo_wine ok(size == 31, "read %d bytes of data\n", size);
3932 size = sizeof(buf);
3933 ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_ENCODING, buf, &size, 0);
3934 todo_wine ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_ENCODING) failed: %d\n", GetLastError());
3935 InternetCloseHandle(req);
3937 InternetCloseHandle(con);
3938 InternetCloseHandle(ses);
3940 /* Decompression doesn't work while reading from cache */
3941 test_cache_gzip = 0;
3942 sprintf(cache_url, cache_url_fmt, port, get_gzip);
3943 DeleteUrlCacheEntryA(cache_url);
3945 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3946 ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3948 ret = TRUE;
3949 ret = InternetSetOptionA(ses, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3950 ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3952 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3953 ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3955 req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3956 ok(req != NULL, "HttpOpenRequest failed\n");
3958 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3959 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3960 size = 0;
3961 while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3962 size += read;
3963 ok(size == 10, "read %d bytes of data\n", size);
3964 buf[size] = 0;
3965 ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3966 InternetCloseHandle(req);
3968 InternetCloseHandle(con);
3969 InternetCloseHandle(ses);
3971 /* Decompression doesn't work while reading from cache */
3972 test_cache_gzip = 0;
3973 sprintf(cache_url, cache_url_fmt, port, get_gzip);
3974 DeleteUrlCacheEntryA(cache_url);
3976 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3977 ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3979 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3980 ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3982 ret = TRUE;
3983 ret = InternetSetOptionA(con, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3984 ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3986 req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3987 ok(req != NULL, "HttpOpenRequest failed\n");
3989 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3990 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3991 size = 0;
3992 while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3993 size += read;
3994 ok(size == 10, "read %d bytes of data\n", size);
3995 buf[size] = 0;
3996 ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3997 InternetCloseHandle(req);
3999 InternetCloseHandle(con);
4000 InternetCloseHandle(ses);
4002 DeleteUrlCacheEntryA(cache_url);
4005 static void test_HttpSendRequestW(int port)
4007 static const WCHAR header[] = {'U','A','-','C','P','U',':',' ','x','8','6',0};
4008 HINTERNET ses, con, req;
4009 DWORD error;
4010 BOOL ret;
4012 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
4013 ok(ses != NULL, "InternetOpen failed\n");
4015 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4016 ok(con != NULL, "InternetConnect failed\n");
4018 req = HttpOpenRequestA(con, NULL, "/test1", NULL, NULL, NULL, 0, 0);
4019 ok(req != NULL, "HttpOpenRequest failed\n");
4021 SetLastError(0xdeadbeef);
4022 ret = HttpSendRequestW(req, header, ~0u, NULL, 0);
4023 error = GetLastError();
4024 ok(!ret, "HttpSendRequestW succeeded\n");
4025 ok(error == ERROR_IO_PENDING ||
4026 broken(error == ERROR_HTTP_HEADER_NOT_FOUND) || /* IE6 */
4027 broken(error == ERROR_INVALID_PARAMETER), /* IE5 */
4028 "got %u expected ERROR_IO_PENDING\n", error);
4030 InternetCloseHandle(req);
4031 InternetCloseHandle(con);
4032 InternetCloseHandle(ses);
4035 static void test_cookie_header(int port)
4037 HINTERNET ses, con, req;
4038 DWORD size, error;
4039 BOOL ret;
4040 char buffer[64];
4042 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4043 ok(ses != NULL, "InternetOpen failed\n");
4045 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4046 ok(con != NULL, "InternetConnect failed\n");
4048 InternetSetCookieA("http://localhost", "cookie", "biscuit");
4050 req = HttpOpenRequestA(con, NULL, "/testC", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4051 ok(req != NULL, "HttpOpenRequest failed\n");
4053 buffer[0] = 0;
4054 size = sizeof(buffer);
4055 SetLastError(0xdeadbeef);
4056 ret = HttpQueryInfoA(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
4057 error = GetLastError();
4058 ok(!ret, "HttpQueryInfo succeeded\n");
4059 ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "got %u expected ERROR_HTTP_HEADER_NOT_FOUND\n", error);
4061 ret = HttpAddRequestHeadersA(req, "Cookie: cookie=not biscuit\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD);
4062 ok(ret, "HttpAddRequestHeaders failed: %u\n", GetLastError());
4064 buffer[0] = 0;
4065 size = sizeof(buffer);
4066 ret = HttpQueryInfoA(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
4067 ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
4068 ok(!strcmp(buffer, "cookie=not biscuit"), "got '%s' expected \'cookie=not biscuit\'\n", buffer);
4070 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4071 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
4073 test_status_code(req, 200);
4075 buffer[0] = 0;
4076 size = sizeof(buffer);
4077 ret = HttpQueryInfoA(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
4078 ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
4079 ok(!strcmp(buffer, "cookie=biscuit"), "got '%s' expected \'cookie=biscuit\'\n", buffer);
4081 InternetCloseHandle(req);
4082 InternetCloseHandle(con);
4083 InternetCloseHandle(ses);
4086 static void test_basic_authentication(int port)
4088 HINTERNET session, connect, request;
4089 BOOL ret;
4091 session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4092 ok(session != NULL, "InternetOpen failed\n");
4094 connect = InternetConnectA(session, "localhost", port, "user", "pwd", INTERNET_SERVICE_HTTP, 0, 0);
4095 ok(connect != NULL, "InternetConnect failed\n");
4097 request = HttpOpenRequestA(connect, NULL, "/test3", NULL, NULL, NULL, 0, 0);
4098 ok(request != NULL, "HttpOpenRequest failed\n");
4100 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4101 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4103 test_status_code(request, 200);
4104 test_request_flags(request, 0);
4106 InternetCloseHandle(request);
4107 InternetCloseHandle(connect);
4108 InternetCloseHandle(session);
4111 static void test_premature_disconnect(int port)
4113 test_request_t req;
4114 DWORD err;
4115 BOOL ret;
4117 open_simple_request(&req, "localhost", port, NULL, "/premature_disconnect");
4119 SetLastError(0xdeadbeef);
4120 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4121 err = GetLastError();
4122 todo_wine ok(!ret, "HttpSendRequest succeeded\n");
4123 todo_wine ok(err == ERROR_HTTP_INVALID_SERVER_RESPONSE, "got %u\n", err);
4125 close_request(&req);
4128 static void test_invalid_response_headers(int port)
4130 test_request_t req;
4131 DWORD size;
4132 BOOL ret;
4133 char buffer[256];
4135 open_simple_request(&req, "localhost", port, NULL, "/testE");
4137 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4138 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4140 test_status_code(req.request, 401);
4141 test_request_flags(req.request, 0);
4143 buffer[0] = 0;
4144 size = sizeof(buffer);
4145 ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL);
4146 ok(ret, "HttpQueryInfo failed\n");
4147 ok(!strcmp(buffer, "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"),
4148 "headers wrong \"%s\"\n", buffer);
4150 buffer[0] = 0;
4151 size = sizeof(buffer);
4152 ret = HttpQueryInfoA(req.request, HTTP_QUERY_SERVER, buffer, &size, NULL);
4153 ok(ret, "HttpQueryInfo failed\n");
4154 ok(!strcmp(buffer, "winetest"), "server wrong \"%s\"\n", buffer);
4156 close_request(&req);
4159 static void test_response_without_headers(int port)
4161 test_request_t req;
4162 DWORD r, count, size;
4163 char buffer[1024];
4165 open_simple_request(&req, "localhost", port, NULL, "/testG");
4167 test_request_flags(req.request, INTERNET_REQFLAG_NO_HEADERS);
4169 r = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4170 ok(r, "HttpSendRequest failed %u\n", GetLastError());
4172 test_request_flags_todo(req.request, INTERNET_REQFLAG_NO_HEADERS);
4174 count = 0;
4175 memset(buffer, 0, sizeof buffer);
4176 r = InternetReadFile(req.request, buffer, sizeof buffer, &count);
4177 ok(r, "InternetReadFile failed %u\n", GetLastError());
4178 todo_wine ok(count == sizeof page1 - 1, "count was wrong\n");
4179 todo_wine ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
4181 test_status_code(req.request, 200);
4182 test_request_flags_todo(req.request, INTERNET_REQFLAG_NO_HEADERS);
4184 buffer[0] = 0;
4185 size = sizeof(buffer);
4186 r = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &size, NULL );
4187 ok(r, "HttpQueryInfo failed %u\n", GetLastError());
4188 ok(!strcmp(buffer, "OK"), "expected OK got: \"%s\"\n", buffer);
4190 buffer[0] = 0;
4191 size = sizeof(buffer);
4192 r = HttpQueryInfoA(req.request, HTTP_QUERY_VERSION, buffer, &size, NULL);
4193 ok(r, "HttpQueryInfo failed %u\n", GetLastError());
4194 ok(!strcmp(buffer, "HTTP/1.0"), "expected HTTP/1.0 got: \"%s\"\n", buffer);
4196 buffer[0] = 0;
4197 size = sizeof(buffer);
4198 r = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL);
4199 ok(r, "HttpQueryInfo failed %u\n", GetLastError());
4200 ok(!strcmp(buffer, "HTTP/1.0 200 OK"), "raw headers wrong: \"%s\"\n", buffer);
4202 close_request(&req);
4205 static void test_head_request(int port)
4207 DWORD len, content_length;
4208 test_request_t req;
4209 BYTE buf[100];
4210 BOOL ret;
4212 open_simple_request(&req, "localhost", port, "HEAD", "/test_head");
4214 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4215 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
4217 len = sizeof(content_length);
4218 content_length = -1;
4219 ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &content_length, &len, 0);
4220 ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
4221 ok(len == sizeof(DWORD), "len = %u\n", len);
4222 ok(content_length == 100, "content_length = %u\n", content_length);
4224 len = -1;
4225 ret = InternetReadFile(req.request, buf, sizeof(buf), &len);
4226 ok(ret, "InternetReadFile failed: %u\n", GetLastError());
4228 len = -1;
4229 ret = InternetReadFile(req.request, buf, sizeof(buf), &len);
4230 ok(ret, "InternetReadFile failed: %u\n", GetLastError());
4232 close_request(&req);
4235 static void test_HttpQueryInfo(int port)
4237 test_request_t req;
4238 DWORD size, index, error;
4239 char buffer[1024];
4240 BOOL ret;
4242 open_simple_request(&req, "localhost", port, NULL, "/testD");
4244 size = sizeof(buffer);
4245 ret = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &size, &index);
4246 error = GetLastError();
4247 ok(!ret || broken(ret), "HttpQueryInfo succeeded\n");
4248 if (!ret) ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "got %u expected ERROR_HTTP_HEADER_NOT_FOUND\n", error);
4250 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4251 ok(ret, "HttpSendRequest failed\n");
4253 index = 0;
4254 size = sizeof(buffer);
4255 ret = HttpQueryInfoA(req.request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &index);
4256 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4257 ok(index == 1, "expected 1 got %u\n", index);
4259 index = 0;
4260 size = sizeof(buffer);
4261 ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
4262 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4263 ok(index == 1, "expected 1 got %u\n", index);
4265 index = 0;
4266 size = sizeof(buffer);
4267 ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
4268 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4269 ok(index == 0, "expected 0 got %u\n", index);
4271 size = sizeof(buffer);
4272 ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
4273 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4274 ok(index == 0, "expected 0 got %u\n", index);
4276 index = 0xdeadbeef; /* invalid start index */
4277 size = sizeof(buffer);
4278 ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
4279 todo_wine ok(!ret, "HttpQueryInfo should have failed\n");
4280 todo_wine ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
4281 "Expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", GetLastError());
4283 index = 0;
4284 size = sizeof(buffer);
4285 ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer, &size, &index);
4286 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4287 ok(index == 0, "expected 0 got %u\n", index);
4289 size = sizeof(buffer);
4290 ret = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &size, &index);
4291 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4292 ok(index == 0, "expected 0 got %u\n", index);
4294 size = sizeof(buffer);
4295 ret = HttpQueryInfoA(req.request, HTTP_QUERY_VERSION, buffer, &size, &index);
4296 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4297 ok(index == 0, "expected 0 got %u\n", index);
4299 test_status_code(req.request, 200);
4301 index = 0xdeadbeef;
4302 size = sizeof(buffer);
4303 ret = HttpQueryInfoA(req.request, HTTP_QUERY_FORWARDED, buffer, &size, &index);
4304 ok(!ret, "HttpQueryInfo succeeded\n");
4305 ok(index == 0xdeadbeef, "expected 0xdeadbeef got %u\n", index);
4307 index = 0;
4308 size = sizeof(buffer);
4309 ret = HttpQueryInfoA(req.request, HTTP_QUERY_SERVER, buffer, &size, &index);
4310 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4311 ok(index == 1, "expected 1 got %u\n", index);
4313 index = 0;
4314 size = sizeof(buffer);
4315 strcpy(buffer, "Server");
4316 ret = HttpQueryInfoA(req.request, HTTP_QUERY_CUSTOM, buffer, &size, &index);
4317 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4318 ok(index == 1, "expected 1 got %u\n", index);
4320 index = 0;
4321 size = sizeof(buffer);
4322 ret = HttpQueryInfoA(req.request, HTTP_QUERY_SET_COOKIE, buffer, &size, &index);
4323 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4324 ok(index == 1, "expected 1 got %u\n", index);
4326 size = sizeof(buffer);
4327 ret = HttpQueryInfoA(req.request, HTTP_QUERY_SET_COOKIE, buffer, &size, &index);
4328 ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4329 ok(index == 2, "expected 2 got %u\n", index);
4331 close_request(&req);
4334 static void test_options(int port)
4336 INTERNET_DIAGNOSTIC_SOCKET_INFO idsi;
4337 HINTERNET ses, con, req;
4338 DWORD size, error;
4339 DWORD_PTR ctx;
4340 BOOL ret;
4342 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4343 ok(ses != NULL, "InternetOpen failed\n");
4345 SetLastError(0xdeadbeef);
4346 ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, 0);
4347 error = GetLastError();
4348 ok(!ret, "InternetSetOption succeeded\n");
4349 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4351 SetLastError(0xdeadbeef);
4352 ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, sizeof(ctx));
4353 ok(!ret, "InternetSetOption succeeded\n");
4354 error = GetLastError();
4355 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4357 SetLastError(0xdeadbeef);
4358 ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, 0);
4359 ok(!ret, "InternetSetOption succeeded\n");
4360 error = GetLastError();
4361 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4363 ctx = 1;
4364 ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
4365 ok(ret, "InternetSetOption failed %u\n", GetLastError());
4367 SetLastError(0xdeadbeef);
4368 ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, NULL);
4369 error = GetLastError();
4370 ok(!ret, "InternetQueryOption succeeded\n");
4371 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4373 SetLastError(0xdeadbeef);
4374 ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, NULL);
4375 error = GetLastError();
4376 ok(!ret, "InternetQueryOption succeeded\n");
4377 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4379 size = 0;
4380 SetLastError(0xdeadbeef);
4381 ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, &size);
4382 error = GetLastError();
4383 ok(!ret, "InternetQueryOption succeeded\n");
4384 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
4386 size = sizeof(ctx);
4387 SetLastError(0xdeadbeef);
4388 ret = InternetQueryOptionA(NULL, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4389 error = GetLastError();
4390 ok(!ret, "InternetQueryOption succeeded\n");
4391 ok(error == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %u\n", error);
4393 ctx = 0xdeadbeef;
4394 size = sizeof(ctx);
4395 ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4396 ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4397 ok(ctx == 1, "expected 1 got %lu\n", ctx);
4399 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4400 ok(con != NULL, "InternetConnect failed\n");
4402 ctx = 0xdeadbeef;
4403 size = sizeof(ctx);
4404 ret = InternetQueryOptionA(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4405 ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4406 ok(ctx == 0, "expected 0 got %lu\n", ctx);
4408 ctx = 2;
4409 ret = InternetSetOptionA(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
4410 ok(ret, "InternetSetOption failed %u\n", GetLastError());
4412 ctx = 0xdeadbeef;
4413 size = sizeof(ctx);
4414 ret = InternetQueryOptionA(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4415 ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4416 ok(ctx == 2, "expected 2 got %lu\n", ctx);
4418 req = HttpOpenRequestA(con, NULL, "/test1", NULL, NULL, NULL, 0, 0);
4419 ok(req != NULL, "HttpOpenRequest failed\n");
4421 ctx = 0xdeadbeef;
4422 size = sizeof(ctx);
4423 ret = InternetQueryOptionA(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4424 ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4425 ok(ctx == 0, "expected 0 got %lu\n", ctx);
4427 ctx = 3;
4428 ret = InternetSetOptionA(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
4429 ok(ret, "InternetSetOption failed %u\n", GetLastError());
4431 ctx = 0xdeadbeef;
4432 size = sizeof(ctx);
4433 ret = InternetQueryOptionA(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4434 ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4435 ok(ctx == 3, "expected 3 got %lu\n", ctx);
4437 size = sizeof(idsi);
4438 ret = InternetQueryOptionA(req, INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, &idsi, &size);
4439 ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4441 size = 0;
4442 SetLastError(0xdeadbeef);
4443 ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, NULL, &size);
4444 error = GetLastError();
4445 ok(!ret, "InternetQueryOption succeeded\n");
4446 ok(error == ERROR_INTERNET_INVALID_OPERATION, "expected ERROR_INTERNET_INVALID_OPERATION, got %u\n", error);
4448 /* INTERNET_OPTION_PROXY */
4449 SetLastError(0xdeadbeef);
4450 ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, NULL, NULL);
4451 error = GetLastError();
4452 ok(!ret, "InternetQueryOption succeeded\n");
4453 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4455 SetLastError(0xdeadbeef);
4456 ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, &ctx, NULL);
4457 error = GetLastError();
4458 ok(!ret, "InternetQueryOption succeeded\n");
4459 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4461 size = 0;
4462 SetLastError(0xdeadbeef);
4463 ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, NULL, &size);
4464 error = GetLastError();
4465 ok(!ret, "InternetQueryOption succeeded\n");
4466 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
4467 ok(size >= sizeof(INTERNET_PROXY_INFOA), "expected size to be greater or equal to the struct size\n");
4469 InternetCloseHandle(req);
4470 InternetCloseHandle(con);
4471 InternetCloseHandle(ses);
4474 typedef struct {
4475 const char *response_text;
4476 int status_code;
4477 const char *status_text;
4478 const char *raw_headers;
4479 } http_status_test_t;
4481 static const http_status_test_t http_status_tests[] = {
4483 "HTTP/1.1 200 OK\r\n"
4484 "Content-Length: 1\r\n"
4485 "\r\nx",
4486 200,
4487 "OK"
4490 "HTTP/1.1 404 Fail\r\n"
4491 "Content-Length: 1\r\n"
4492 "\r\nx",
4493 404,
4494 "Fail"
4497 "HTTP/1.1 200\r\n"
4498 "Content-Length: 1\r\n"
4499 "\r\nx",
4500 200,
4504 "HTTP/1.1 410 \r\n"
4505 "Content-Length: 1\r\n"
4506 "\r\nx",
4507 410,
4512 static void test_http_status(int port)
4514 test_request_t req;
4515 char buf[1000];
4516 DWORD i, size;
4517 BOOL res;
4519 for(i = 0; i < ARRAY_SIZE(http_status_tests); i++) {
4520 send_buffer = http_status_tests[i].response_text;
4522 open_simple_request(&req, "localhost", port, NULL, "/send_from_buffer");
4524 res = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4525 ok(res, "HttpSendRequest failed\n");
4527 test_status_code(req.request, http_status_tests[i].status_code);
4529 size = sizeof(buf);
4530 res = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buf, &size, NULL);
4531 ok(res, "HttpQueryInfo failed: %u\n", GetLastError());
4532 ok(!strcmp(buf, http_status_tests[i].status_text), "[%u] Unexpected status text \"%s\", expected \"%s\"\n",
4533 i, buf, http_status_tests[i].status_text);
4535 close_request(&req);
4539 static void test_cache_control_verb(int port)
4541 HINTERNET session, connect, request;
4542 BOOL ret;
4544 session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4545 ok(session != NULL, "InternetOpen failed\n");
4547 connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4548 ok(connect != NULL, "InternetConnect failed\n");
4550 request = HttpOpenRequestA(connect, "RPC_OUT_DATA", "/test_cache_control_verb", NULL, NULL, NULL,
4551 INTERNET_FLAG_NO_CACHE_WRITE, 0);
4552 ok(request != NULL, "HttpOpenRequest failed\n");
4553 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4554 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4555 test_status_code(request, 200);
4556 InternetCloseHandle(request);
4558 request = HttpOpenRequestA(connect, "POST", "/test_cache_control_verb", NULL, NULL, NULL,
4559 INTERNET_FLAG_NO_CACHE_WRITE, 0);
4560 ok(request != NULL, "HttpOpenRequest failed\n");
4561 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4562 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4563 test_status_code(request, 200);
4564 InternetCloseHandle(request);
4566 request = HttpOpenRequestA(connect, "HEAD", "/test_cache_control_verb", NULL, NULL, NULL,
4567 INTERNET_FLAG_NO_CACHE_WRITE, 0);
4568 ok(request != NULL, "HttpOpenRequest failed\n");
4569 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4570 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4571 test_status_code(request, 200);
4572 InternetCloseHandle(request);
4574 request = HttpOpenRequestA(connect, "GET", "/test_cache_control_verb", NULL, NULL, NULL,
4575 INTERNET_FLAG_NO_CACHE_WRITE, 0);
4576 ok(request != NULL, "HttpOpenRequest failed\n");
4577 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4578 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4579 test_status_code(request, 200);
4580 InternetCloseHandle(request);
4582 InternetCloseHandle(connect);
4583 InternetCloseHandle(session);
4586 static void test_request_content_length(int port)
4588 char data[] = {'t','e','s','t'};
4589 test_request_t req;
4590 BOOL ret;
4592 reset_events();
4593 open_simple_request(&req, "localhost", port, "POST", "/test_request_content_length");
4595 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4596 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4597 test_status_code(req.request, 200);
4599 SetEvent(complete_event);
4601 ret = HttpSendRequestA(req.request, NULL, 0, data, sizeof(data));
4602 ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4603 test_status_code(req.request, 200);
4605 SetEvent(complete_event);
4606 close_request(&req);
4609 static void test_accept_encoding(int port)
4611 HINTERNET ses, con, req;
4612 char buf[1000];
4613 BOOL ret;
4615 ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4616 ok(ses != NULL, "InternetOpen failed\n");
4618 con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4619 ok(con != NULL, "InternetConnect failed\n");
4621 req = HttpOpenRequestA(con, "GET", "/echo_request", "HTTP/1.0", NULL, NULL, 0, 0);
4622 ok(req != NULL, "HttpOpenRequest failed\n");
4624 ret = HttpAddRequestHeadersA(req, "Accept-Encoding: gzip\r\n", ~0u, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
4625 ok(ret, "HttpAddRequestHeaders failed\n");
4627 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4628 ok(ret, "HttpSendRequestA failed\n");
4630 test_status_code(req, 200);
4631 receive_simple_request(req, buf, sizeof(buf));
4632 ok(strstr(buf, "Accept-Encoding: gzip") != NULL, "Accept-Encoding header not found in %s\n", buf);
4634 InternetCloseHandle(req);
4636 req = HttpOpenRequestA(con, "GET", "/echo_request", "HTTP/1.0", NULL, NULL, 0, 0);
4637 ok(req != NULL, "HttpOpenRequest failed\n");
4639 ret = HttpSendRequestA(req, "Accept-Encoding: gzip", ~0u, NULL, 0);
4640 ok(ret, "HttpSendRequestA failed\n");
4642 test_status_code(req, 200);
4643 receive_simple_request(req, buf, sizeof(buf));
4644 ok(strstr(buf, "Accept-Encoding: gzip") != NULL, "Accept-Encoding header not found in %s\n", buf);
4646 InternetCloseHandle(req);
4647 InternetCloseHandle(con);
4648 InternetCloseHandle(ses);
4651 static void test_basic_auth_credentials_reuse(int port)
4653 HINTERNET ses, con, req;
4654 DWORD status, size;
4655 BOOL ret;
4656 char buffer[0x40];
4658 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4659 ok( ses != NULL, "InternetOpenA failed\n" );
4661 con = InternetConnectA( ses, "localhost", port, "user", "pwd",
4662 INTERNET_SERVICE_HTTP, 0, 0 );
4663 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4665 req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4666 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4668 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4669 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4671 size = sizeof(buffer);
4672 SetLastError(0xdeadbeef);
4673 ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4674 ok(ret, "unexpected failure %u\n", GetLastError());
4675 ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4676 ok(size == 4, "got %u\n", size);
4678 size = sizeof(buffer);
4679 SetLastError(0xdeadbeef);
4680 ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4681 ok(ret, "unexpected failure %u\n", GetLastError());
4682 ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4683 ok(size == 3, "got %u\n", size);
4685 status = 0xdeadbeef;
4686 size = sizeof(status);
4687 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4688 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4689 ok( status == 200, "got %u\n", status );
4691 InternetCloseHandle( req );
4692 InternetCloseHandle( con );
4693 InternetCloseHandle( ses );
4695 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4696 ok( ses != NULL, "InternetOpenA failed\n" );
4698 con = InternetConnectA( ses, "localhost", port, NULL, NULL,
4699 INTERNET_SERVICE_HTTP, 0, 0 );
4700 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4702 req = HttpOpenRequestA( con, "PUT", "/upload2.txt", NULL, NULL, NULL, 0, 0 );
4703 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4705 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4706 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4708 size = sizeof(buffer);
4709 SetLastError(0xdeadbeef);
4710 ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4711 ok(ret, "unexpected failure %u\n", GetLastError());
4712 ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4713 ok(size == 4, "got %u\n", size);
4715 size = sizeof(buffer);
4716 SetLastError(0xdeadbeef);
4717 ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4718 ok(ret, "unexpected failure %u\n", GetLastError());
4719 ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4720 ok(size == 3, "got %u\n", size);
4722 status = 0xdeadbeef;
4723 size = sizeof(status);
4724 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4725 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4726 ok( status == 200, "got %u\n", status );
4728 InternetCloseHandle( req );
4729 InternetCloseHandle( con );
4730 InternetCloseHandle( ses );
4733 static void test_basic_auth_credentials_end_session(int port)
4735 HINTERNET ses, con, req;
4736 DWORD status, size;
4737 BOOL ret;
4738 char buffer[0x40];
4740 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4741 ok( ses != NULL, "InternetOpenA failed\n" );
4743 con = InternetConnectA( ses, "localhost", port, "user", "pwd",
4744 INTERNET_SERVICE_HTTP, 0, 0 );
4745 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4747 req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4748 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4750 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4751 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4753 size = sizeof(buffer);
4754 SetLastError(0xdeadbeef);
4755 ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4756 ok(ret, "unexpected failure %u\n", GetLastError());
4757 ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4758 ok(size == 4, "got %u\n", size);
4760 size = sizeof(buffer);
4761 SetLastError(0xdeadbeef);
4762 ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4763 ok(ret, "unexpected failure %u\n", GetLastError());
4764 ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4765 ok(size == 3, "got %u\n", size);
4767 status = 0xdeadbeef;
4768 size = sizeof(status);
4769 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4770 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4771 ok( status == HTTP_STATUS_OK, "got %u\n", status );
4773 InternetCloseHandle( req );
4774 InternetCloseHandle( con );
4775 InternetCloseHandle( ses );
4777 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4778 ok( ses != NULL, "InternetOpenA failed\n" );
4780 /* Clear the cached credentials */
4781 ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
4782 ok(ret, "unexpected failure %u\n", GetLastError());
4784 con = InternetConnectA( ses, "localhost", port, NULL, NULL,
4785 INTERNET_SERVICE_HTTP, 0, 0 );
4786 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4788 req = HttpOpenRequestA( con, "PUT", "/upload2.txt", NULL, NULL, NULL, 0, 0 );
4789 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4791 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4792 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4794 size = sizeof(buffer);
4795 SetLastError(0xdeadbeef);
4796 ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4797 ok(ret, "unexpected failure %u\n", GetLastError());
4798 ok(!strcmp(buffer, ""), "got %s\n", buffer);
4799 ok(size == 0, "got %u\n", size);
4801 size = sizeof(buffer);
4802 SetLastError(0xdeadbeef);
4803 ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4804 ok(ret, "unexpected failure %u\n", GetLastError());
4805 ok(!strcmp(buffer, ""), "got %s\n", buffer);
4806 ok(size == 0, "got %u\n", size);
4808 status = 0xdeadbeef;
4809 size = sizeof(status);
4810 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4811 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4812 ok( status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status );
4814 InternetCloseHandle( req );
4815 InternetCloseHandle( con );
4816 InternetCloseHandle( ses );
4819 static void test_basic_auth_credentials_different(int port)
4821 HINTERNET ses, con, req;
4822 DWORD status, size;
4823 BOOL ret;
4824 char buffer[0x40];
4826 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4827 ok( ses != NULL, "InternetOpenA failed\n" );
4829 con = InternetConnectA( ses, "localhost", port, "user", "pwd",
4830 INTERNET_SERVICE_HTTP, 0, 0 );
4831 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4833 req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4834 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4836 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4837 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4839 size = sizeof(buffer);
4840 SetLastError(0xdeadbeef);
4841 ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4842 ok(ret, "unexpected failure %u\n", GetLastError());
4843 ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4844 ok(size == 4, "got %u\n", size);
4846 size = sizeof(buffer);
4847 SetLastError(0xdeadbeef);
4848 ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4849 ok(ret, "unexpected failure %u\n", GetLastError());
4850 ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4851 ok(size == 3, "got %u\n", size);
4853 status = 0xdeadbeef;
4854 size = sizeof(status);
4855 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4856 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4857 ok( status == 200, "got %u\n", status );
4859 InternetCloseHandle( req );
4860 InternetCloseHandle( con );
4861 InternetCloseHandle( ses );
4863 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4864 ok( ses != NULL, "InternetOpenA failed\n" );
4866 con = InternetConnectA( ses, "localhost", port, "user1", "pwd1",
4867 INTERNET_SERVICE_HTTP, 0, 0 );
4868 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4870 req = HttpOpenRequestA( con, "HEAD", "/upload3.txt", NULL, NULL, NULL, 0, 0 );
4871 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4873 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4874 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4876 size = sizeof(buffer);
4877 SetLastError(0xdeadbeef);
4878 ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4879 ok(ret, "unexpected failure %u\n", GetLastError());
4880 ok(!strcmp(buffer, "user1"), "got %s\n", buffer);
4881 ok(size == 5, "got %u\n", size);
4883 size = sizeof(buffer);
4884 SetLastError(0xdeadbeef);
4885 ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4886 ok(ret, "unexpected failure %u\n", GetLastError());
4887 ok(!strcmp(buffer, "pwd1"), "got %s\n", buffer);
4888 ok(size == 4, "got %u\n", size);
4890 status = 0xdeadbeef;
4891 size = sizeof(status);
4892 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4893 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4894 ok( status == 200, "got %u\n", status );
4896 InternetCloseHandle( req );
4897 InternetCloseHandle( con );
4898 InternetCloseHandle( ses );
4902 * Manually set the Authorization for both calls.
4904 static void test_basic_auth_credentials_manual(int port)
4906 HINTERNET ses, con, req;
4907 DWORD status, size;
4908 BOOL ret;
4910 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4911 ok( ses != NULL, "InternetOpenA failed\n" );
4913 /* Clear the cached credentials */
4914 ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
4915 ok(ret, "unexpected failure %u\n", GetLastError());
4917 con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
4918 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4920 req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4921 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4923 /* Set Authorization Header */
4924 ret = HttpAddRequestHeadersA(req, "Authorization: Basic dXNlcjpwd2Q=\r\n", ~0u,
4925 HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
4926 ok(ret, "HttpAddRequestHeaders Failed\n");
4928 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4929 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4931 status = 0xdeadbeef;
4932 size = sizeof(status);
4933 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4934 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4935 ok( status == 200, "got %u\n", status );
4937 InternetCloseHandle( req );
4938 InternetCloseHandle( con );
4939 InternetCloseHandle( ses );
4941 /* Show manual headers are cached. */
4942 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4943 ok( ses != NULL, "InternetOpenA failed\n" );
4945 con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
4946 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4948 req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4949 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4951 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4952 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4954 status = 0xdeadbeef;
4955 size = sizeof(status);
4956 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4957 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4958 ok( status == 401, "got %u\n", status );
4960 InternetCloseHandle( req );
4961 InternetCloseHandle( con );
4962 InternetCloseHandle( ses );
4964 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4965 ok( ses != NULL, "InternetOpenA failed\n" );
4967 con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
4968 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4970 req = HttpOpenRequestA( con, "HEAD", "/upload4.txt", NULL, NULL, NULL, 0, 0 );
4971 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4973 /* Set Authorization Header */
4974 ret = HttpAddRequestHeadersA(req, "Authorization: Bearer dXNlcjE6cHdkMQ==\r\n", ~0u,
4975 HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
4976 ok(ret, "HttpAddRequestHeaders Failed\n");
4978 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4979 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4981 status = 0xdeadbeef;
4982 size = sizeof(status);
4983 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4984 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4985 ok( status == 200, "got %u\n", status );
4987 InternetCloseHandle( req );
4988 InternetCloseHandle( con );
4989 InternetCloseHandle( ses );
4993 * Manually set the Authorization for the bearer call, which shows the cached is used.
4995 static void test_basic_auth_credentials_cached_manual(int port)
4997 HINTERNET ses, con, req;
4998 DWORD status, size;
4999 BOOL ret;
5001 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
5002 ok( ses != NULL, "InternetOpenA failed\n" );
5004 /* Clear the cached credentials */
5005 ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
5006 ok(ret, "unexpected failure %u\n", GetLastError());
5008 con = InternetConnectA( ses, "localhost", port, "user", "pwd",
5009 INTERNET_SERVICE_HTTP, 0, 0 );
5010 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5012 req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
5013 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5015 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5016 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
5018 status = 0xdeadbeef;
5019 size = sizeof(status);
5020 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5021 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5022 ok( status == 200, "got %u\n", status );
5024 InternetCloseHandle( req );
5025 InternetCloseHandle( con );
5026 InternetCloseHandle( ses );
5028 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
5029 ok( ses != NULL, "InternetOpenA failed\n" );
5031 con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
5032 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5034 req = HttpOpenRequestA( con, "HEAD", "/upload4.txt", NULL, NULL, NULL, 0, 0 );
5035 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5037 /* Setting an Authorization Header doesn't override the cached one. */
5038 ret = HttpAddRequestHeadersA(req, "Authorization: Bearer dXNlcjE6cHdkMQ==\r\n", ~0u,
5039 HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
5040 ok(ret, "HttpAddRequestHeaders Failed\n");
5042 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5043 ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
5045 status = 0xdeadbeef;
5046 size = sizeof(status);
5047 ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5048 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5049 ok( status == 201, "got %u\n", status );
5051 InternetCloseHandle( req );
5052 InternetCloseHandle( con );
5053 InternetCloseHandle( ses );
5056 static void test_async_read(int port)
5058 HINTERNET ses, con, req;
5059 INTERNET_BUFFERSA ib;
5060 char buffer[0x100];
5061 DWORD pending_reads;
5062 DWORD res, count, bytes;
5063 BOOL ret;
5065 reset_events();
5067 /* test asynchronous InternetReadFileEx */
5068 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
5069 ok( ses != NULL, "InternetOpenA failed\n" );
5070 pInternetSetStatusCallbackA( ses, &callback );
5072 SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5073 con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
5074 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5075 CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5077 SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5078 req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
5079 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5080 CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5082 SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
5083 SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
5084 SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
5085 SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
5086 SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
5087 SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
5088 SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5089 SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5090 SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
5091 SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
5092 SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5094 SetLastError( 0xdeadbeef );
5095 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5096 ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
5097 ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5098 WaitForSingleObject( complete_event, INFINITE );
5099 ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5101 CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
5102 CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
5103 CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
5104 CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
5105 CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
5106 CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
5107 CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5108 CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5109 CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
5110 CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
5111 CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5113 pending_reads = 0;
5114 memset( &ib, 0, sizeof(ib) );
5115 memset( buffer, 0, sizeof(buffer) );
5116 ib.dwStructSize = sizeof(ib);
5117 for (count = 0; count < sizeof(buffer); count += ib.dwBufferLength)
5119 ib.lpvBuffer = buffer + count;
5120 ib.dwBufferLength = min(16, sizeof(buffer) - count);
5122 SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5123 SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5125 ret = InternetReadFileExA( req, &ib, 0, 0xdeadbeef );
5126 if (!count) /* the first part should arrive immediately */
5127 ok( ret, "InternetReadFileExA failed %u\n", GetLastError() );
5128 if (!ret)
5130 ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5131 CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5132 SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5133 if (!pending_reads++)
5135 res = WaitForSingleObject( complete_event, 0 );
5136 ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
5137 SetEvent( conn_wait_event );
5139 res = WaitForSingleObject( complete_event, INFINITE );
5140 ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res );
5141 ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5142 todo_wine_if( pending_reads > 1 )
5143 ok( ib.dwBufferLength != 0, "expected ib.dwBufferLength != 0\n" );
5144 CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5145 CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5148 CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5149 CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5150 if (!ib.dwBufferLength) break;
5153 ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads );
5154 ok( !strcmp(buffer, page1), "unexpected buffer content\n" );
5155 close_async_handle( ses, 2 );
5156 ResetEvent( conn_wait_event );
5158 /* test asynchronous InternetReadFile */
5159 ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
5160 ok( ses != NULL, "InternetOpenA failed\n" );
5161 pInternetSetStatusCallbackA( ses, &callback );
5163 SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5164 con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
5165 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5166 CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5168 SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5169 req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
5170 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5171 CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5173 SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
5174 SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
5175 SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
5176 SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
5177 SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
5178 SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
5179 SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5180 SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5181 SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
5182 SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
5183 SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5185 SetLastError( 0xdeadbeef );
5186 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5187 ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
5188 ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5189 WaitForSingleObject( complete_event, INFINITE );
5190 ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5192 CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
5193 CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
5194 CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
5195 CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
5196 CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
5197 CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
5198 CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5199 CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5200 CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
5201 CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
5202 CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5204 pending_reads = 0;
5205 memset( buffer, 0, sizeof(buffer) );
5206 for (count = 0; count < sizeof(buffer); count += bytes)
5208 SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5209 SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5211 bytes = 0xdeadbeef;
5212 ret = InternetReadFile( req, buffer + count, min(16, sizeof(buffer) - count), &bytes );
5213 if (!count) /* the first part should arrive immediately */
5214 ok( ret, "InternetReadFile failed %u\n", GetLastError() );
5215 if (!ret)
5217 ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5218 ok( bytes == 0, "expected 0, got %u\n", bytes );
5219 CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5220 SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5221 if (!pending_reads++)
5223 res = WaitForSingleObject( complete_event, 0 );
5224 ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
5225 SetEvent( conn_wait_event );
5227 res = WaitForSingleObject( complete_event, INFINITE );
5228 ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res );
5229 ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5230 todo_wine_if( pending_reads > 1 )
5231 ok( bytes != 0, "expected bytes != 0\n" );
5232 CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5233 CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5236 CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5237 CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5238 if (!bytes) break;
5241 ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads );
5242 ok( !strcmp(buffer, page1), "unexpected buffer content\n" );
5243 close_async_handle( ses, 2 );
5246 static void server_send_string(const char *msg)
5248 send(server_socket, msg, strlen(msg), 0);
5251 static size_t server_read_data(char *buf, size_t buf_size)
5253 return recv(server_socket, buf, buf_size, 0);
5256 #define server_read_request(a) _server_read_request(__LINE__,a)
5257 static void _server_read_request(unsigned line, const char *expected_request)
5259 char buf[4000], *p;
5260 size_t size;
5262 size = server_read_data(buf, sizeof(buf) - 1);
5263 buf[size] = 0;
5264 p = strstr(buf, "\r\n");
5265 if(p) *p = 0;
5266 ok_(__FILE__,line)(p && !strcmp(buf, expected_request), "unexpected request %s\n", buf);
5269 static BOOL skip_receive_notification_tests;
5270 static DWORD received_response_size;
5272 static void WINAPI readex_callback(HINTERNET handle, DWORD_PTR context, DWORD status, void *info, DWORD info_size)
5274 switch(status) {
5275 case INTERNET_STATUS_RECEIVING_RESPONSE:
5276 if(!skip_receive_notification_tests)
5277 callback(handle, context, status, info, info_size);
5278 break;
5279 case INTERNET_STATUS_RESPONSE_RECEIVED:
5280 if(!skip_receive_notification_tests)
5281 callback(handle, context, status, info, info_size);
5282 received_response_size = *(DWORD*)info;
5283 break;
5284 case INTERNET_STATUS_REQUEST_SENT:
5285 callback(handle, context, status, info, info_size);
5286 SetEvent(request_sent_event);
5287 break;
5288 default:
5289 callback(handle, context, status, info, info_size);
5293 static void send_socket_request(test_request_t *req, BOOL new_connection)
5295 BOOL ret;
5297 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
5298 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
5299 if(new_connection) {
5300 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
5301 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
5303 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
5304 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
5305 if(!skip_receive_notification_tests)
5306 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5308 SetLastError(0xdeadbeef);
5309 ret = HttpSendRequestA(req->request, NULL, 0, NULL, 0);
5310 ok(!ret, "HttpSendRequestA unexpectedly succeeded\n");
5311 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError());
5313 if(new_connection)
5314 WaitForSingleObject(server_req_rec_event, INFINITE);
5315 WaitForSingleObject(request_sent_event, INFINITE);
5317 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
5318 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
5319 if(new_connection) {
5320 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
5321 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
5323 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
5324 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
5327 static void open_socket_request(int port, test_request_t *req, const char *verb)
5329 /* We're connecting to new socket */
5330 if(!verb)
5331 reset_events();
5333 req->session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
5334 ok(req->session != NULL, "InternetOpenA failed\n");
5335 pInternetSetStatusCallbackA(req->session, readex_callback);
5337 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
5338 req->connection = InternetConnectA(req->session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef);
5339 ok(req->connection != NULL, "InternetConnectA failed %u\n", GetLastError());
5340 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED );
5342 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
5343 req->request = HttpOpenRequestA(req->connection, "GET", verb ? verb : "/socket",
5344 NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef);
5345 ok(req->request != NULL, "HttpOpenRequestA failed %u\n", GetLastError());
5346 CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5348 send_socket_request(req, !verb);
5351 static void open_read_test_request(int port, test_request_t *req, const char *response)
5353 if(!skip_receive_notification_tests)
5354 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5356 open_socket_request(port, req, NULL);
5358 if(!skip_receive_notification_tests) {
5359 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5360 received_response_size = 0xdeadbeef;
5362 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5364 server_send_string(response);
5365 WaitForSingleObject(complete_event, INFINITE);
5367 if(!skip_receive_notification_tests) {
5368 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5369 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5370 todo_wine
5371 ok(received_response_size == strlen(response), "received_response_size = %u\n", received_response_size);
5373 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5374 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5377 #define readex_expect_sync_data_len(a,b,c,d,e,f,g) _readex_expect_sync_data_len(__LINE__,a,b,c,d,e,f,g)
5378 static void _readex_expect_sync_data_len(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
5379 DWORD buf_size, const char *exdata, DWORD len, DWORD expect_receive)
5381 BOOL ret;
5383 if(!skip_receive_notification_tests && expect_receive) {
5384 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5385 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5386 received_response_size = 0xdeadbeef;
5389 memset(buf->lpvBuffer, 0xff, buf_size);
5390 buf->dwBufferLength = buf_size;
5391 ret = InternetReadFileExW(req, buf, flags, 0xdeadbeef);
5392 ok_(__FILE__,line)(ret, "InternetReadFileExW failed: %u\n", GetLastError());
5393 ok_(__FILE__,line)(buf->dwBufferLength == len, "dwBufferLength = %u, expected %u\n", buf->dwBufferLength, len);
5394 if(len && exdata)
5395 ok_(__FILE__,line)(!memcmp(buf->lpvBuffer, exdata, len), "Unexpected data\n");
5397 if(!skip_receive_notification_tests && expect_receive) {
5398 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5399 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5400 ok_(__FILE__,line)(received_response_size == len, "received_response_size = %u\n", received_response_size);
5404 #define readex_expect_sync_data(a,b,c,d,e,f) _readex_expect_sync_data(__LINE__,a,b,c,d,e,f)
5405 static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
5406 DWORD buf_size, const char *exdata, DWORD expect_receive)
5408 _readex_expect_sync_data_len(line, req, flags, buf, buf_size, exdata, strlen(exdata), expect_receive);
5411 #define read_expect_sync_data_len(a,b,c,d,e) _read_expect_sync_data_len(__LINE__,a,b,c,d,e)
5412 static void _read_expect_sync_data_len(unsigned line, HINTERNET req, void *buf, DWORD buf_size,
5413 const char *exdata, DWORD len)
5415 DWORD ret_size = 0xdeadbeef;
5416 BOOL ret;
5418 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5419 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5420 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5421 received_response_size = 0xdeadbeef;
5423 memset(buf, 0xff, buf_size);
5424 ret = InternetReadFile(req, buf, buf_size, &ret_size);
5425 ok_(__FILE__,line)(ret, "InternetReadFileExW failed: %u\n", GetLastError());
5426 ok_(__FILE__,line)(ret_size == len, "dwBufferLength = %u, expected %u\n", ret_size, len);
5427 if(len && exdata)
5428 ok_(__FILE__,line)(!memcmp(buf, exdata, len), "Unexpected data\n");
5430 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5431 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5432 CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5433 ok_(__FILE__,line)(received_response_size == len, "received_response_size = %u\n", received_response_size);
5434 ok_(__FILE__,line)(!req_error, "req_error = %u\n", req_error);
5437 #define read_expect_sync_data(a,b,c,d) _read_expect_sync_data(__LINE__,a,b,c,d)
5438 static void _read_expect_sync_data(unsigned line, HINTERNET req, void *buf,
5439 DWORD buf_size, const char *exdata)
5441 _read_expect_sync_data_len(line, req, buf, buf_size, exdata, strlen(exdata));
5444 static void close_connection(void)
5446 char c;
5447 SetEvent(conn_wait_event);
5448 recv(server_socket, &c, 1, 0);
5451 #define send_response_and_wait(a,b,c,d,e,f,g,h) _send_response_and_wait(__LINE__,a,b,c,d,e,f,g,h)
5452 static void _send_response_and_wait(unsigned line, const char *response, BOOL do_close_connection,
5453 void *buf, DWORD *ret_size, const char *exdata,
5454 DWORD expected_size, DWORD expected_req_error, DWORD expected_receive_size)
5456 if(!skip_receive_notification_tests)
5457 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5458 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5460 if(response)
5461 server_send_string(response);
5463 if(do_close_connection)
5464 close_connection();
5466 WaitForSingleObject(complete_event, INFINITE);
5468 if(!skip_receive_notification_tests)
5469 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5470 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5471 if(!skip_receive_notification_tests && expected_receive_size != -1)
5472 todo_wine_if(received_response_size != expected_receive_size) /* FIXME! remove when wine is fixed */
5473 ok_(__FILE__,line)(received_response_size == expected_receive_size,
5474 "received_response_size = %u\n", received_response_size);
5475 ok_(__FILE__,line)(req_error == expected_req_error, "req_error = %u, expected %u\n", req_error, expected_req_error);
5477 /* If IRF_NO_WAIT is used, buffer is not changed. */
5478 ok_(__FILE__,line)(*ret_size == expected_size, "dwBufferLength = %u\n", *ret_size);
5479 if(exdata)
5480 ok_(__FILE__,line)(!memcmp(buf, exdata, strlen(exdata)), "unexpected buffer data\n");
5481 else if(buf)
5482 ok_(__FILE__,line)(!*(DWORD*)buf, "buffer data changed\n");
5485 #define send_response_ex_and_wait(a,b,c,d,e,f) _send_response_ex_and_wait(__LINE__,a,b,c,d,e,f)
5486 static void _send_response_ex_and_wait(unsigned line, const char *response, BOOL close_connection,
5487 INTERNET_BUFFERSW *buf, const char *exdata, DWORD expected_req_error,
5488 DWORD expected_receive_size)
5490 _send_response_and_wait(line, response, close_connection, buf->lpvBuffer, &buf->dwBufferLength,
5491 exdata, exdata ? strlen(exdata) : buf->dwBufferLength, expected_req_error,
5492 expected_receive_size);
5495 static void send_response_len_and_wait(unsigned len, BOOL close_connection, INTERNET_BUFFERSW *buf)
5497 char *response;
5499 response = HeapAlloc(GetProcessHeap(), 0, len+1);
5500 memset(response, 'x', len);
5501 response[len] = 0;
5502 send_response_ex_and_wait(response, close_connection, buf, NULL, 0, -1);
5503 HeapFree(GetProcessHeap(), 0, response);
5506 #define readex_expect_async(a,b,c,d,e) _readex_expect_async(__LINE__,a,b,c,d,e)
5507 static void _readex_expect_async(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
5508 DWORD buf_size, const char *exdata)
5510 unsigned len = 0;
5511 BOOL ret;
5513 if(!skip_receive_notification_tests)
5514 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5516 memset(buf->lpvBuffer, 0, max(buf_size, sizeof(DWORD)));
5517 buf->dwBufferLength = buf_size;
5518 ret = InternetReadFileExW(req, buf, flags, 0xdeadbeef);
5519 ok_(__FILE__,line)(!ret && GetLastError() == ERROR_IO_PENDING, "InternetReadFileExW returned %x (%u)\n", ret, GetLastError());
5520 ok_(__FILE__,line)(buf->dwBufferLength == buf_size, "dwBufferLength = %u, expected %u\n", buf->dwBufferLength, buf_size);
5521 if(exdata) {
5522 len = strlen(exdata);
5523 ok_(__FILE__,line)(!memcmp(buf->lpvBuffer, exdata, len), "unexpected buffer data\n");
5524 }else {
5525 ok_(__FILE__,line)(!*(DWORD*)buf->lpvBuffer, "buffer data changed\n");
5528 if(!skip_receive_notification_tests)
5529 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5532 static void read_expect_async(HINTERNET req, void *buf, DWORD buf_size, DWORD *ret_size, const char *exdata)
5534 unsigned len = 0;
5535 const char *p;
5536 BOOL ret;
5538 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5540 *ret_size = 0xdeadbeef;
5541 memset(buf, 0, buf_size);
5542 ret = InternetReadFile(req, buf, buf_size, ret_size);
5543 ok(!ret && GetLastError() == ERROR_IO_PENDING, "InternetReadFileExW returned %x (%u)\n", ret, GetLastError());
5544 ok(*ret_size == 0, "dwBufferLength = %u\n", *ret_size);
5545 if(exdata) {
5546 len = strlen(exdata);
5547 ok(!memcmp(buf, exdata, len), "unexpected buffer data\n");
5549 for(p = (const char*)buf + len; p < (const char*)buf + buf_size; p++) {
5550 if(*p)
5551 ok(0, "buffer data changed\n");
5554 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5557 #define expect_data_available(a,b) _expect_data_available(__LINE__,a,b)
5558 static DWORD _expect_data_available(unsigned line, HINTERNET req, int exsize)
5560 DWORD size = 0;
5561 BOOL res;
5563 res = InternetQueryDataAvailable(req, &size, 0, 0);
5564 ok_(__FILE__,line)(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
5565 if(exsize != -1)
5566 ok_(__FILE__,line)(size == exsize, "size = %u, expected %u\n", size, exsize);
5568 return size;
5571 #define async_query_data_available(a,b) _async_query_data_available(__LINE__,a,b)
5572 static void _async_query_data_available(unsigned line, HINTERNET req, DWORD *size)
5574 BOOL res;
5576 if(!skip_receive_notification_tests)
5577 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5579 *size = 0xdeadbeef;
5580 res = InternetQueryDataAvailable(req, size, 0, 0);
5581 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING,
5582 "InternetQueryDataAvailable returned: %x(%u)\n", res, GetLastError());
5583 ok_(__FILE__,line)(!*size, "size = %u\n", *size);
5585 if(!skip_receive_notification_tests)
5586 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5589 static void test_http_read(int port)
5591 INTERNET_BUFFERSW ib;
5592 test_request_t req;
5593 DWORD read_size;
5594 char buf[24000];
5595 DWORD avail, i;
5597 if(!is_ie7plus)
5598 return;
5600 memset(&ib, 0, sizeof(ib));
5601 ib.dwStructSize = sizeof(ib);
5602 ib.lpvBuffer = buf;
5604 trace("Testing InternetReadFileExW with IRF_ASYNC flag...\n");
5606 open_read_test_request(port, &req,
5607 "HTTP/1.1 200 OK\r\n"
5608 "Server: winetest\r\n"
5609 "\r\n"
5610 "xx");
5612 readex_expect_async(req.request, IRF_ASYNC, &ib, 4, "xx");
5614 send_response_ex_and_wait("yy1234567890", FALSE, &ib, "xxyy", 0, 2);
5615 readex_expect_sync_data(req.request, IRF_ASYNC, &ib, 4, "1234", 4);
5616 readex_expect_sync_data(req.request, IRF_ASYNC, &ib, 5, "56789", 5);
5618 readex_expect_async(req.request, IRF_ASYNC, &ib, sizeof(buf), "0");
5619 send_response_ex_and_wait("123", TRUE, &ib, "0123", 0, 4);
5621 close_async_handle(req.session, 2);
5623 trace("Testing InternetReadFileExW with no flags...\n");
5625 open_read_test_request(port, &req,
5626 "HTTP/1.1 200 OK\r\n"
5627 "Server: winetest\r\n"
5628 "\r\n"
5629 "xx");
5631 readex_expect_async(req.request, 0, &ib, 4, "xx");
5633 send_response_ex_and_wait("yy1234567890", FALSE, &ib, "xxyy", 0, 2);
5634 readex_expect_sync_data(req.request, 0, &ib, 4, "1234", 4);
5635 readex_expect_sync_data(req.request, 0, &ib, 5, "56789", 5);
5637 readex_expect_async(req.request, 0, &ib, sizeof(buf), "0");
5638 send_response_ex_and_wait("123", TRUE, &ib, "0123", 0, 4);
5640 close_async_handle(req.session, 2);
5642 trace("Testing InternetReadFile...\n");
5644 open_read_test_request(port, &req,
5645 "HTTP/1.1 200 OK\r\n"
5646 "Server: winetest\r\n"
5647 "\r\n"
5648 "xx");
5650 read_expect_async(req.request, buf, 4, &read_size, "xx");
5652 send_response_and_wait("yy1234567890", FALSE, buf, &read_size, "xxyy", 4, 0, 2);
5653 read_expect_sync_data(req.request, buf, 4, "1234");
5654 read_expect_sync_data(req.request, buf, 5, "56789");
5656 read_expect_async(req.request, buf, sizeof(buf), &read_size, "0");
5657 send_response_and_wait("123", TRUE, buf, &read_size, "0123", 4, 0, 4);
5659 close_async_handle(req.session, 2);
5661 trace("Testing InternetReadFileExW with IRF_NO_WAIT flag...\n");
5663 open_read_test_request(port, &req,
5664 "HTTP/1.1 200 OK\r\n"
5665 "Server: winetest\r\n"
5666 "\r\n"
5667 "xx");
5669 SET_OPTIONAL(INTERNET_STATUS_RECEIVING_RESPONSE);
5671 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "xx", 0);
5673 if(notified[INTERNET_STATUS_RECEIVING_RESPONSE]) {
5674 win_skip("Skipping receive notification tests on too old Windows.\n");
5675 skip_receive_notification_tests = TRUE;
5677 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5679 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5680 send_response_ex_and_wait("1234567890", FALSE, &ib, NULL, 0, 10);
5681 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, 5, "12345", 0);
5682 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "67890", 0);
5684 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5685 send_response_ex_and_wait("12345", TRUE, &ib, NULL, 0, 5);
5687 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "12345", 0);
5688 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "", TRUE);
5690 close_async_handle(req.session, 2);
5692 open_read_test_request(port, &req,
5693 "HTTP/1.1 200 OK\r\n"
5694 "Server: winetest\r\n"
5695 "Transfer-Encoding: chunked\r\n"
5696 "\r\n"
5697 "9\r\n123456789");
5698 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123456789", 0);
5699 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5701 send_response_ex_and_wait("\r\n1\r\na\r\n1\r\nb\r", FALSE, &ib, NULL, 0, 13);
5702 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5703 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5705 send_response_ex_and_wait("\n3\r\nab", FALSE, &ib, NULL, 0, 6);
5706 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5707 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5709 send_response_ex_and_wait("c", FALSE, &ib, NULL, 0, 1);
5710 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "c", 0);
5711 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5713 send_response_ex_and_wait("\r\n1\r\nx\r\n0\r\n\r\n", TRUE, &ib, NULL, 0, 13);
5714 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "x", 0);
5715 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "", 0);
5717 close_async_handle(req.session, 2);
5719 open_read_test_request(port, &req,
5720 "HTTP/1.1 200 OK\r\n"
5721 "Server: winetest\r\n"
5722 "Transfer-Encoding: chunked\r\n"
5723 "\r\n"
5724 "3\r\n123\r\n");
5725 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123", 0);
5726 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5728 send_response_ex_and_wait("0\r\n\r\n", TRUE, &ib, NULL, 0, 5);
5729 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "", 0);
5731 close_async_handle(req.session, 2);
5733 open_read_test_request(port, &req,
5734 "HTTP/1.1 200 OK\r\n"
5735 "Server: winetest\r\n"
5736 "Connection: close\r\n"
5737 "\r\n");
5738 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5739 send_response_ex_and_wait("123", TRUE, &ib, NULL, 0, 3);
5740 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123", 0);
5742 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5743 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5744 close_async_handle(req.session, 2);
5745 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5746 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5748 trace("Testing InternetQueryDataAvailable...\n");
5750 open_read_test_request(port, &req,
5751 "HTTP/1.1 200 OK\r\n"
5752 "Server: winetest\r\n"
5753 "\r\n"
5754 "123");
5755 expect_data_available(req.request, 3);
5756 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123", 0);
5757 readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5759 send_response_len_and_wait(20000, TRUE, &ib);
5760 avail = expect_data_available(req.request, -1);
5761 ok(avail <= 20000, "avail = %u\n", avail);
5763 SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
5764 SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
5765 close_async_handle(req.session, 2);
5766 todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5767 todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5769 open_read_test_request(port, &req,
5770 "HTTP/1.1 200 OK\r\n"
5771 "Server: winetest\r\n"
5772 "Connection: close\r\n"
5773 "\r\n"
5774 "123");
5776 expect_data_available(req.request, 3);
5777 readex_expect_sync_data(req.request, 0, &ib, 3, "123", 0);
5779 async_query_data_available(req.request, &read_size);
5780 send_response_and_wait("1234567890", FALSE, NULL, &read_size, NULL, 10, 10, 10);
5782 readex_expect_sync_data(req.request, 0, &ib, 9, "123456789", 0);
5783 expect_data_available(req.request, 1);
5784 readex_expect_sync_data(req.request, 0, &ib, 1, "0", 0);
5786 async_query_data_available(req.request, &read_size);
5787 send_response_and_wait("1234567890", FALSE, NULL, &read_size, NULL, 10, 10, 10);
5788 expect_data_available(req.request, 10);
5789 for(i = 0; i < 10; i++)
5790 server_send_string("x");
5791 expect_data_available(req.request, 10);
5793 readex_expect_async(req.request, IRF_ASYNC, &ib, 21, "1234567890");
5794 send_response_ex_and_wait("X", FALSE, &ib, "1234567890xxxxxxxxxxX", 0, 11);
5795 async_query_data_available(req.request, &read_size);
5797 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5798 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5799 send_response_and_wait(NULL, TRUE, NULL, &read_size, NULL, 0, 0, 0);
5800 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5801 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5803 close_async_handle(req.session, 2);
5805 skip_receive_notification_tests = FALSE;
5808 static void test_connection_break(int port)
5810 INTERNET_BUFFERSW ib;
5811 test_request_t req;
5812 char buf[24000];
5814 if(!is_ie7plus)
5815 return;
5817 memset(&ib, 0, sizeof(ib));
5818 ib.dwStructSize = sizeof(ib);
5819 ib.lpvBuffer = buf;
5821 trace("Testing InternetReadFileExW on broken connection...\n");
5823 open_read_test_request(port, &req,
5824 "HTTP/1.1 200 OK\r\n"
5825 "Server: winetest\r\n"
5826 "Content-Length: 10000\r\n"
5827 "\r\n"
5828 "xx");
5830 /* close connection and make sure that it's closed on handle release. */
5831 close_connection();
5832 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5833 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5834 close_async_handle(req.session, 2);
5835 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5836 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5839 static void test_long_url(int port)
5841 char long_path[INTERNET_MAX_PATH_LENGTH*2] = "/echo_request?";
5842 char buf[sizeof(long_path)*2], url[sizeof(buf)];
5843 test_request_t req;
5844 DWORD size, len;
5845 BOOL ret;
5847 if(!is_ie7plus)
5848 return;
5850 memset(long_path+strlen(long_path), 'x', sizeof(long_path)-strlen(long_path));
5851 long_path[sizeof(long_path)-1] = 0;
5852 open_simple_request(&req, "localhost", port, NULL, long_path);
5854 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
5855 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
5856 test_status_code(req.request, 200);
5858 receive_simple_request(req.request, buf, sizeof(buf));
5859 ok(strstr(buf, long_path) != NULL, "long pathnot found in %s\n", buf);
5861 sprintf(url, "http://localhost:%u%s", port, long_path);
5863 size = sizeof(buf);
5864 ret = InternetQueryOptionA(req.request, INTERNET_OPTION_URL, buf, &size);
5865 ok(ret, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
5866 len = strlen(url);
5867 ok(size == len, "size = %u, expected %u\n", size, len);
5868 ok(!strcmp(buf, url), "Wrong URL %s, expected %s\n", buf, url);
5870 close_request(&req);
5873 static void test_persistent_connection(int port)
5875 INTERNET_BUFFERSW ib;
5876 test_request_t req;
5877 char buf[24000];
5879 if(!is_ie7plus)
5880 return;
5882 memset(&ib, 0, sizeof(ib));
5883 ib.dwStructSize = sizeof(ib);
5884 ib.lpvBuffer = buf;
5886 skip_receive_notification_tests = TRUE;
5888 trace("Testing persistent connection...\n");
5890 open_read_test_request(port, &req,
5891 "HTTP/1.1 200 OK\r\n"
5892 "Server: winetest\r\n"
5893 "Content-Length: 2\r\n"
5894 "\r\n"
5895 "xx");
5896 readex_expect_sync_data(req.request, IRF_ASYNC, &ib, 4, "xx", 0);
5897 close_async_handle(req.session, 2);
5899 open_socket_request(port, &req, "/test_simple_chunked");
5900 server_read_request("GET /test_simple_chunked HTTP/1.1");
5902 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5903 server_send_string("HTTP/1.1 200 OK\r\n"
5904 "Server: winetest\r\n"
5905 "Transfer-Encoding: chunked\r\n"
5906 "\r\n"
5907 "2\r\nab\r\n");
5908 WaitForSingleObject(complete_event, INFINITE);
5909 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5910 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5912 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5913 readex_expect_async(req.request, IRF_ASYNC, &ib, sizeof(buf), NULL);
5914 send_response_ex_and_wait("3\r\nabc\r\n0\r\n\r\n", FALSE, &ib, "abc", 0, 13);
5915 close_async_handle(req.session, 2);
5917 open_socket_request(port, &req, "/chunked");
5918 server_read_request("GET /chunked HTTP/1.1");
5920 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5921 server_send_string("HTTP/1.1 200 OK\r\n"
5922 "Server: winetest\r\n"
5923 "Transfer-Encoding: chunked\r\n"
5924 "\r\n"
5925 "2\r\nab\r\n");
5926 WaitForSingleObject(complete_event, INFINITE);
5927 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5928 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5930 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, 3, "ab", 0);
5931 readex_expect_async(req.request, IRF_ASYNC, &ib, 3, NULL);
5932 send_response_ex_and_wait("3\r\nabc\r\n", FALSE, &ib, "abc", 0, 13);
5934 /* send another request on the same request handle, it must drain remaining last chunk marker */
5935 server_send_string("0\r\n\r\n");
5937 send_socket_request(&req, FALSE);
5938 server_read_request("GET /chunked HTTP/1.1");
5940 ResetEvent(complete_event);
5941 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5942 server_send_string("HTTP/1.1 201 OK\r\n"
5943 "Server: winetest\r\n"
5944 "Content-Length: 0\r\n"
5945 "Connection: keep-alive\r\n"
5946 "\r\n");
5947 WaitForSingleObject(complete_event, INFINITE);
5948 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5949 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5951 test_status_code(req.request, 201);
5952 close_async_handle(req.session, 2);
5954 /* the connection is still valid */
5955 open_socket_request(port, &req, "/another_chunked");
5956 server_read_request("GET /another_chunked HTTP/1.1");
5958 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5959 server_send_string("HTTP/1.1 200 OK\r\n"
5960 "Server: winetest\r\n"
5961 "Transfer-Encoding: chunked\r\n"
5962 "\r\n"
5963 "2\r\nab\r\n");
5964 WaitForSingleObject(complete_event, INFINITE);
5965 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5966 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5968 readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5969 readex_expect_async(req.request, IRF_ASYNC, &ib, sizeof(buf), NULL);
5971 /* we're missing trailing '\n'; the connection can't be drained without blocking,
5972 * so it will be closed */
5973 send_response_ex_and_wait("3\r\nabc\r\n0\r\n\r", FALSE, &ib, "abc", 0, 13);
5975 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5976 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5977 close_async_handle(req.session, 2);
5978 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5979 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5981 close_connection();
5982 skip_receive_notification_tests = FALSE;
5985 static void test_redirect(int port)
5987 char buf[4000], expect_url[INTERNET_MAX_URL_LENGTH];
5988 INTERNET_BUFFERSW ib;
5989 test_request_t req;
5991 if(!is_ie7plus)
5992 return;
5994 skip_receive_notification_tests = TRUE;
5996 memset(&ib, 0, sizeof(ib));
5997 ib.dwStructSize = sizeof(ib);
5998 ib.lpvBuffer = buf;
6000 trace("Testing redirection...\n");
6002 open_socket_request(port, &req, NULL);
6004 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6005 SET_EXPECT(INTERNET_STATUS_REDIRECT);
6006 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6007 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6009 server_send_string("HTTP/1.1 302 Found\r\n"
6010 "Server: winetest\r\n"
6011 "Location: test_redirection\r\n"
6012 "Connection: keep-alive\r\n"
6013 "Content-Length: 0\r\n"
6014 "\r\n");
6016 server_read_request("GET /test_redirection HTTP/1.1");
6018 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6020 sprintf(expect_url, "http://localhost:%u/test_redirection", port);
6021 test_request_url(req.request, expect_url);
6023 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6025 server_send_string("HTTP/1.1 200 OK\r\n"
6026 "Server: winetest\r\n"
6027 "Content-Length: 3\r\n"
6028 "\r\n"
6029 "xxx");
6031 WaitForSingleObject(complete_event, INFINITE);
6033 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6034 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6035 CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
6036 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6037 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6039 test_status_code(req.request, 200);
6041 close_connection();
6042 close_async_handle(req.session, 2);
6044 trace("Test redirect to non-http URL...\n");
6046 open_socket_request(port, &req, NULL);
6048 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6050 server_send_string("HTTP/1.1 302 Found\r\n"
6051 "Server: winetest\r\n"
6052 "Location: test:non:http/url\r\n"
6053 "Connection: keep-alive\r\n"
6054 "Content-Length: 0\r\n"
6055 "\r\n");
6057 WaitForSingleObject(complete_event, INFINITE);
6059 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6060 ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6062 sprintf(expect_url, "http://localhost:%u/socket", port);
6063 test_request_url(req.request, expect_url);
6064 test_status_code(req.request, 302);
6066 close_connection();
6067 close_async_handle(req.session, 2);
6069 trace("Test redirect to http URL with no host name...\n");
6071 open_socket_request(port, &req, NULL);
6073 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6075 server_send_string("HTTP/1.1 302 Found\r\n"
6076 "Server: winetest\r\n"
6077 "Location: http:///nohost\r\n"
6078 "Connection: keep-alive\r\n"
6079 "Content-Length: 0\r\n"
6080 "\r\n");
6082 WaitForSingleObject(complete_event, INFINITE);
6084 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6085 ok(req_error == ERROR_INTERNET_INVALID_URL, "expected ERROR_INTERNET_INVALID_URL, got %u\n", req_error);
6087 sprintf(expect_url, "http://localhost:%u/socket", port);
6088 test_request_url(req.request, expect_url);
6089 test_status_code(req.request, 302);
6091 close_connection();
6092 close_async_handle(req.session, 2);
6094 skip_receive_notification_tests = FALSE;
6097 static void test_remove_dot_segments(int port)
6099 test_request_t req;
6100 BOOL ret;
6102 open_simple_request(&req, "localhost", port, NULL, "/A/../B/./C/../../test_remove_dot_segments");
6104 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
6105 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
6106 test_status_code(req.request, 200);
6108 close_request(&req);
6111 struct large_test
6113 DWORD64 content_length;
6114 BOOL ret;
6117 static void test_large_content(int port)
6119 struct large_test tests[] = {
6120 { 0, TRUE },
6121 { UINT_MAX-1, TRUE },
6122 { UINT_MAX, TRUE },
6123 { (DWORD64)UINT_MAX+1, FALSE },
6124 { ~0, FALSE },
6126 test_request_t req;
6127 DWORD sizelen, len;
6128 DWORD read_size;
6129 DWORD64 len64;
6130 char buf[16];
6131 BOOL ret;
6132 size_t i;
6134 open_simple_request(&req, "localhost", port, "HEAD", "/test_large_content");
6136 for (i = 0; i < ARRAY_SIZE(tests); i++)
6138 content_length = tests[i].content_length;
6139 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
6140 ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
6142 len = ~0;
6143 sizelen = sizeof(len);
6144 SetLastError(0xdeadbeef);
6145 ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
6146 &len, &sizelen, 0);
6147 if (tests[i].ret)
6149 ok(ret, "HttpQueryInfo should have succeeded\n");
6150 ok(GetLastError() == ERROR_SUCCESS ||
6151 broken(GetLastError() == 0xdeadbeef), /* xp, 2k8, vista */
6152 "expected ERROR_SUCCESS, got %x\n", GetLastError());
6153 ok(len == (DWORD)tests[i].content_length, "expected %u, got %u\n",
6154 (DWORD)tests[i].content_length, len);
6156 else
6158 ok(!ret, "HttpQueryInfo should have failed\n");
6159 ok(GetLastError() == ERROR_HTTP_INVALID_HEADER,
6160 "expected ERROR_HTTP_INVALID_HEADER, got %x\n", GetLastError());
6161 ok(len == ~0, "expected ~0, got %u\n", len);
6163 ok(sizelen == sizeof(DWORD), "sizelen %u\n", sizelen);
6166 /* test argument size */
6167 len64 = ~0;
6168 sizelen = sizeof(len64);
6169 SetLastError(0xdeadbeef);
6170 ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
6171 &len64, &len, 0);
6172 ok(!ret, "HttpQueryInfo should have failed\n");
6173 ok(GetLastError() == ERROR_HTTP_INVALID_HEADER,
6174 "expected ERROR_HTTP_INVALID_HEADER, got %x\n", GetLastError());
6175 ok(sizelen == sizeof(DWORD64), "sizelen %u\n", sizelen);
6176 ok(len64 == ~0, "len64 %x%08x\n", (DWORD)(len64 >> 32), (DWORD)len64);
6178 close_request(&req);
6180 /* test internal use of HttpQueryInfo on large size */
6181 open_read_test_request(port, &req,
6182 "HTTP/1.1 200 OK\r\n"
6183 "Server: winetest\r\n"
6184 "Content-Length: 4294967296\r\n"
6185 "\r\n"
6186 "xx");
6187 read_expect_async(req.request, buf, 4, &read_size, "xx");
6188 send_response_and_wait("yy1234567890", FALSE, buf, &read_size, "xxyy", 4, 0, 2);
6189 read_expect_sync_data(req.request, buf, 10, "1234567890");
6191 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6192 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6193 close_async_handle(req.session, 2);
6194 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6195 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6196 close_connection();
6199 static void test_http_connection(void)
6201 struct server_info si;
6202 HANDLE hThread;
6203 DWORD id = 0, r;
6205 si.hEvent = CreateEventW(NULL, 0, 0, NULL);
6206 si.port = 7531;
6208 hThread = CreateThread(NULL, 0, server_thread, &si, 0, &id);
6209 ok( hThread != NULL, "create thread failed\n");
6211 r = WaitForSingleObject(si.hEvent, 10000);
6212 ok (r == WAIT_OBJECT_0, "failed to start wininet test server\n");
6213 if (r != WAIT_OBJECT_0)
6215 CloseHandle(hThread);
6216 return;
6219 test_basic_request(si.port, "GET", "/test1");
6220 test_proxy_indirect(si.port);
6221 test_proxy_direct(si.port);
6222 test_header_handling_order(si.port);
6223 test_basic_request(si.port, "POST", "/test5");
6224 test_basic_request(si.port, "RPC_IN_DATA", "/test5");
6225 test_basic_request(si.port, "RPC_OUT_DATA", "/test5");
6226 test_basic_request(si.port, "GET", "/test6");
6227 test_basic_request(si.port, "GET", "/testF");
6228 test_connection_header(si.port);
6229 test_header_override(si.port);
6230 test_cookie_header(si.port);
6231 test_basic_authentication(si.port);
6232 test_invalid_response_headers(si.port);
6233 test_response_without_headers(si.port);
6234 test_HttpQueryInfo(si.port);
6235 test_HttpSendRequestW(si.port);
6236 test_options(si.port);
6237 test_no_content(si.port);
6238 test_not_modified(si.port);
6239 test_large_header(si.port);
6240 test_conn_close(si.port);
6241 test_no_cache(si.port);
6242 test_cache_read_gzipped(si.port);
6243 test_http_status(si.port);
6244 test_premature_disconnect(si.port);
6245 test_connection_closing(si.port);
6246 test_cache_control_verb(si.port);
6247 test_successive_HttpSendRequest(si.port);
6248 test_head_request(si.port);
6249 test_request_content_length(si.port);
6250 test_accept_encoding(si.port);
6251 test_basic_auth_credentials_reuse(si.port);
6252 test_basic_auth_credentials_end_session(si.port);
6253 test_basic_auth_credentials_different(si.port);
6254 test_basic_auth_credentials_manual(si.port);
6255 test_basic_auth_credentials_cached_manual(si.port);
6256 test_async_read(si.port);
6257 test_http_read(si.port);
6258 test_connection_break(si.port);
6259 test_long_url(si.port);
6260 test_redirect(si.port);
6261 test_persistent_connection(si.port);
6262 test_remove_dot_segments(si.port);
6263 test_large_content(si.port);
6265 /* send the basic request again to shutdown the server thread */
6266 test_basic_request(si.port, "GET", "/quit");
6268 r = WaitForSingleObject(hThread, 3000);
6269 ok( r == WAIT_OBJECT_0, "thread wait failed\n");
6270 CloseHandle(hThread);
6273 static void release_cert_info(INTERNET_CERTIFICATE_INFOA *info)
6275 LocalFree(info->lpszSubjectInfo);
6276 LocalFree(info->lpszIssuerInfo);
6277 LocalFree(info->lpszProtocolName);
6278 LocalFree(info->lpszSignatureAlgName);
6279 LocalFree(info->lpszEncryptionAlgName);
6282 typedef struct {
6283 const char *ex_subject;
6284 const char *ex_issuer;
6285 } cert_struct_test_t;
6287 static const cert_struct_test_t test_winehq_org_cert = {
6288 "US\r\n"
6289 "55114\r\n"
6290 "Minnesota\r\n"
6291 "Saint Paul\r\n"
6292 "Ste 120\r\n"
6293 "700 Raymond Ave\r\n"
6294 "CodeWeavers\r\n"
6295 "IT\r\n"
6296 "*.winehq.org",
6298 "US\r\n"
6299 "VA\r\n"
6300 "Herndon\r\n"
6301 "Network Solutions L.L.C.\r\n"
6302 "Network Solutions OV Server CA 2"
6305 static const cert_struct_test_t test_winehq_com_cert = {
6306 "US\r\n"
6307 "Minnesota\r\n"
6308 "Saint Paul\r\n"
6309 "WineHQ\r\n"
6310 "IT\r\n"
6311 "test.winehq.com\r\n"
6312 "webmaster@winehq.org",
6314 "US\r\n"
6315 "Minnesota\r\n"
6316 "Saint Paul\r\n"
6317 "WineHQ\r\n"
6318 "IT\r\n"
6319 "test.winehq.com\r\n"
6320 "webmaster@winehq.org"
6323 static const char *cert_string_fmt =
6324 "Subject:\r\n%s\r\n"
6325 "Issuer:\r\n%s\r\n"
6326 "Effective Date:\t%s %s\r\n"
6327 "Expiration Date:\t%s %s\r\n"
6328 "Security Protocol:\t%s\r\n"
6329 "Signature Type:\t%s\r\n"
6330 "Encryption Type:\t%s\r\n"
6331 "Privacy Strength:\t%s (%u bits)";
6333 static void test_cert_struct_string(HINTERNET req, const INTERNET_CERTIFICATE_INFOA *info)
6335 SYSTEMTIME start, expiry;
6336 char expiry_date[32];
6337 char expiry_time[32];
6338 char start_date[32];
6339 char start_time[32];
6340 char expect[512];
6341 char actual[512];
6342 DWORD size;
6343 BOOL res;
6345 size = sizeof(actual);
6346 SetLastError(0xdeadbeef);
6347 memset(actual, 0x55, sizeof(actual));
6348 res = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE, actual, &size);
6349 ok(res, "InternetQueryOption failed: %u\n", GetLastError());
6351 FileTimeToSystemTime(&info->ftStart, &start);
6352 FileTimeToSystemTime(&info->ftExpiry, &expiry);
6354 GetDateFormatA(LOCALE_USER_DEFAULT, 0, &start, NULL, start_date, sizeof(start_date));
6355 GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &start, NULL, start_time, sizeof(start_time));
6356 GetDateFormatA(LOCALE_USER_DEFAULT, 0, &expiry, NULL, expiry_date, sizeof(expiry_date));
6357 GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &expiry, NULL, expiry_time, sizeof(expiry_time));
6359 snprintf(expect, sizeof(expect), cert_string_fmt, info->lpszSubjectInfo, info->lpszIssuerInfo,
6360 start_date, start_time, expiry_date, expiry_time,
6361 info->lpszSignatureAlgName, info->lpszEncryptionAlgName, info->lpszProtocolName,
6362 info->dwKeySize >= 128 ? "High" : "Low", info->dwKeySize);
6363 ok(size == strlen(actual), "size = %u\n", size);
6364 ok(!strcmp(actual, expect), "expected:\n%s\nactual:\n%s\n", expect, actual);
6366 --size;
6367 SetLastError(0xdeadbeef);
6368 memset(actual, 0x55, sizeof(actual));
6369 res = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE, actual, &size);
6370 ok(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6371 ok(size == 1, "unexpected size: %u\n", size);
6372 ok(actual[0] == 0x55, "unexpected byte: %02x\n", actual[0]);
6375 static void test_cert_struct(HINTERNET req, const cert_struct_test_t *test)
6377 INTERNET_CERTIFICATE_INFOA info;
6378 DWORD size;
6379 BOOL res;
6381 memset(&info, 0x5, sizeof(info));
6383 size = sizeof(info);
6384 res = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size);
6385 if (!res)
6387 win_skip("Querying INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT failed, skipping tests\n");
6388 return;
6391 ok(res, "InternetQueryOption failed: %u\n", GetLastError());
6392 ok(size == sizeof(info), "size = %u\n", size);
6394 ok(!strcmp(info.lpszSubjectInfo, test->ex_subject), "lpszSubjectInfo = %s\n", info.lpszSubjectInfo);
6395 ok(!strcmp(info.lpszIssuerInfo, test->ex_issuer), "lpszIssuerInfo = %s\n", info.lpszIssuerInfo);
6396 ok(!info.lpszSignatureAlgName, "lpszSignatureAlgName = %s\n", info.lpszSignatureAlgName);
6397 ok(!info.lpszEncryptionAlgName, "lpszEncryptionAlgName = %s\n", info.lpszEncryptionAlgName);
6398 ok(!info.lpszProtocolName, "lpszProtocolName = %s\n", info.lpszProtocolName);
6399 ok(info.dwKeySize >= 128 && info.dwKeySize <= 256, "dwKeySize = %u\n", info.dwKeySize);
6401 if (is_lang_english())
6402 test_cert_struct_string(req, &info);
6403 else
6404 skip("Skipping tests that are English-only\n");
6405 release_cert_info(&info);
6408 #define test_security_info(a,b,c) _test_security_info(__LINE__,a,b,c)
6409 static void _test_security_info(unsigned line, const char *urlc, DWORD error, DWORD ex_flags)
6411 char url[INTERNET_MAX_URL_LENGTH];
6412 const CERT_CHAIN_CONTEXT *chain;
6413 DWORD flags;
6414 BOOL res;
6416 if(!pInternetGetSecurityInfoByURLA) {
6417 win_skip("pInternetGetSecurityInfoByURLA not available\n");
6418 return;
6421 strcpy(url, urlc);
6422 chain = (void*)0xdeadbeef;
6423 flags = 0xdeadbeef;
6424 res = pInternetGetSecurityInfoByURLA(url, &chain, &flags);
6425 if(error == ERROR_SUCCESS) {
6426 ok_(__FILE__,line)(res, "InternetGetSecurityInfoByURLA failed: %u\n", GetLastError());
6427 ok_(__FILE__,line)(chain != NULL, "chain = NULL\n");
6428 ok_(__FILE__,line)(flags == ex_flags, "flags = %x\n", flags);
6429 CertFreeCertificateChain(chain);
6431 SetLastError(0xdeadbeef);
6432 res = pInternetGetSecurityInfoByURLA(url, NULL, NULL);
6433 ok_(__FILE__,line)(!res && GetLastError() == ERROR_INVALID_PARAMETER,
6434 "InternetGetSecurityInfoByURLA returned: %x(%u)\n", res, GetLastError());
6436 res = pInternetGetSecurityInfoByURLA(url, &chain, NULL);
6437 ok_(__FILE__,line)(res, "InternetGetSecurityInfoByURLA failed: %u\n", GetLastError());
6438 CertFreeCertificateChain(chain);
6440 res = pInternetGetSecurityInfoByURLA(url, NULL, &flags);
6441 ok_(__FILE__,line)(res, "InternetGetSecurityInfoByURLA failed: %u\n", GetLastError());
6442 }else {
6443 ok_(__FILE__,line)(!res && GetLastError() == error,
6444 "InternetGetSecurityInfoByURLA returned: %x(%u), expected %u\n", res, GetLastError(), error);
6448 #define test_secflags_option(a,b,c) _test_secflags_option(__LINE__,a,b,c)
6449 static void _test_secflags_option(unsigned line, HINTERNET req, DWORD ex_flags, DWORD opt_flags)
6451 DWORD flags, size;
6452 BOOL res;
6454 flags = 0xdeadbeef;
6455 size = sizeof(flags);
6456 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
6457 ok_(__FILE__,line)(res, "InternetQueryOptionW(INTERNET_OPTION_SECURITY_FLAGS) failed: %u\n", GetLastError());
6458 ok_(__FILE__,line)((flags & ~opt_flags) == ex_flags, "INTERNET_OPTION_SECURITY_FLAGS flags = %x, expected %x\n",
6459 flags, ex_flags);
6461 /* Option 98 is undocumented and seems to be the same as INTERNET_OPTION_SECURITY_FLAGS */
6462 flags = 0xdeadbeef;
6463 size = sizeof(flags);
6464 res = InternetQueryOptionW(req, 98, &flags, &size);
6465 ok_(__FILE__,line)(res, "InternetQueryOptionW(98) failed: %u\n", GetLastError());
6466 ok_(__FILE__,line)((flags & ~opt_flags) == ex_flags, "INTERNET_OPTION_SECURITY_FLAGS(98) flags = %x, expected %x\n",
6467 flags, ex_flags);
6470 #define set_secflags(a,b,c) _set_secflags(__LINE__,a,b,c)
6471 static void _set_secflags(unsigned line, HINTERNET req, BOOL use_undoc, DWORD flags)
6473 BOOL res;
6475 res = InternetSetOptionW(req, use_undoc ? 99 : INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
6476 ok_(__FILE__,line)(res, "InternetSetOption(INTERNET_OPTION_SECURITY_FLAGS) failed: %u\n", GetLastError());
6479 static void test_security_flags(void)
6481 INTERNET_CERTIFICATE_INFOA *cert;
6482 HINTERNET ses, conn, req;
6483 DWORD size, flags;
6484 char buf[512];
6485 BOOL res;
6487 if (!https_support)
6489 win_skip("Can't make https connections, skipping security flags test\n");
6490 return;
6493 trace("Testing security flags...\n");
6494 reset_events();
6496 ses = InternetOpenA("WineTest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
6497 ok(ses != NULL, "InternetOpen failed\n");
6499 pInternetSetStatusCallbackA(ses, &callback);
6501 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6502 conn = InternetConnectA(ses, "test.winehq.com", INTERNET_DEFAULT_HTTPS_PORT,
6503 NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0xdeadbeef);
6504 ok(conn != NULL, "InternetConnect failed with error %u\n", GetLastError());
6505 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6507 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6508 req = HttpOpenRequestA(conn, "GET", "/tests/hello.html", NULL, NULL, NULL,
6509 INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE,
6510 0xdeadbeef);
6511 ok(req != NULL, "HttpOpenRequest failed\n");
6512 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6514 flags = 0xdeadbeef;
6515 size = sizeof(flags);
6516 res = InternetQueryOptionW(req, 98, &flags, &size);
6517 if(!res && GetLastError() == ERROR_INVALID_PARAMETER) {
6518 win_skip("Incomplete security flags support, skipping\n");
6520 close_async_handle(ses, 2);
6521 return;
6524 test_secflags_option(req, 0, 0);
6525 test_security_info("https://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6527 set_secflags(req, TRUE, SECURITY_FLAG_IGNORE_REVOCATION);
6528 test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION, 0);
6530 set_secflags(req, TRUE, SECURITY_FLAG_IGNORE_CERT_CN_INVALID);
6531 test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_CERT_CN_INVALID, 0);
6533 set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_UNKNOWN_CA);
6534 test_secflags_option(req, SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_CERT_CN_INVALID, 0);
6536 flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_SECURE;
6537 res = InternetSetOptionW(req, 99, &flags, sizeof(flags));
6538 ok(!res && GetLastError() == ERROR_INTERNET_OPTION_NOT_SETTABLE, "InternetSetOption(99) failed: %u\n", GetLastError());
6540 SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
6541 SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
6542 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6543 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6544 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6545 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6546 SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6547 SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6548 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6549 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6550 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
6551 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
6552 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6553 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6554 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6556 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6557 ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6559 WaitForSingleObject(complete_event, INFINITE);
6560 ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error);
6562 CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
6563 CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
6564 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6565 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6566 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6567 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6568 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6569 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6570 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
6571 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
6572 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6573 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6574 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6576 test_request_flags(req, 0);
6577 test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA
6578 |SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_STRENGTH_STRONG, 0);
6580 res = InternetReadFile(req, buf, sizeof(buf), &size);
6581 ok(res, "InternetReadFile failed: %u\n", GetLastError());
6582 ok(size, "size = 0\n");
6584 /* Collect all existing persistent connections */
6585 res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
6586 ok(res, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError());
6588 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6589 req = HttpOpenRequestA(conn, "GET", "/tests/hello.html", NULL, NULL, NULL,
6590 INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE,
6591 0xdeadbeef);
6592 ok(req != NULL, "HttpOpenRequest failed\n");
6593 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6595 flags = INTERNET_ERROR_MASK_COMBINED_SEC_CERT|INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY;
6596 res = InternetSetOptionA(req, INTERNET_OPTION_ERROR_MASK, (void*)&flags, sizeof(flags));
6597 ok(res, "InternetQueryOption(INTERNET_OPTION_ERROR_MASK failed: %u\n", GetLastError());
6599 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6600 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6601 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6602 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6603 SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6604 SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6605 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6606 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6607 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6608 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6609 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6611 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6612 ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6614 WaitForSingleObject(complete_event, INFINITE);
6615 todo_wine
6616 ok(req_error == ERROR_INTERNET_SEC_CERT_ERRORS,
6617 "req_error = %d\n", req_error);
6619 size = 0;
6620 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, NULL, &size);
6621 ok(res || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6622 ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %u\n", size);
6623 cert = HeapAlloc(GetProcessHeap(), 0, size);
6624 cert->lpszSubjectInfo = NULL;
6625 cert->lpszIssuerInfo = NULL;
6626 cert->lpszSignatureAlgName = (char *)0xdeadbeef;
6627 cert->lpszEncryptionAlgName = (char *)0xdeadbeef;
6628 cert->lpszProtocolName = (char *)0xdeadbeef;
6629 cert->dwKeySize = 0xdeadbeef;
6630 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, cert, &size);
6631 ok(res, "InternetQueryOption failed: %u\n", GetLastError());
6632 if (res)
6634 ok(cert->lpszSubjectInfo && strlen(cert->lpszSubjectInfo) > 1, "expected a non-empty subject name\n");
6635 ok(cert->lpszIssuerInfo && strlen(cert->lpszIssuerInfo) > 1, "expected a non-empty issuer name\n");
6636 ok(!cert->lpszSignatureAlgName, "unexpected signature algorithm name\n");
6637 ok(!cert->lpszEncryptionAlgName, "unexpected encryption algorithm name\n");
6638 ok(!cert->lpszProtocolName, "unexpected protocol name\n");
6639 ok(cert->dwKeySize != 0xdeadbeef, "unexpected key size\n");
6641 LocalFree(cert->lpszSubjectInfo);
6642 LocalFree(cert->lpszIssuerInfo);
6644 HeapFree(GetProcessHeap(), 0, cert);
6646 SetLastError(0xdeadbeef);
6647 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE, NULL, NULL);
6648 ok(!res && GetLastError() == ERROR_INVALID_PARAMETER, "InternetQueryOption failed: %d\n", GetLastError());
6650 size = 0;
6651 SetLastError(0xdeadbeef);
6652 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE, NULL, &size);
6653 ok(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6654 ok(size == 1, "unexpected size: %u\n", size);
6656 size = 42;
6657 SetLastError(0xdeadbeef);
6658 memset(buf, 0x55, sizeof(buf));
6659 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE, buf, &size);
6660 ok(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6661 ok(size == 1, "unexpected size: %u\n", size);
6662 ok(buf[0] == 0x55, "unexpected byte: %02x\n", buf[0]);
6664 size = sizeof(buf);
6665 SetLastError(0xdeadbeef);
6666 res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE, buf, &size);
6667 ok(res && GetLastError() == ERROR_SUCCESS, "InternetQueryOption failed: %d\n", GetLastError());
6668 ok(size < sizeof(buf), "unexpected size: %u\n", size);
6670 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6671 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6672 CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
6673 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
6674 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6675 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6676 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6678 if(req_error != ERROR_INTERNET_SEC_CERT_ERRORS) {
6679 skip("Unexpected cert errors %u, skipping security flags tests\n", req_error);
6681 close_async_handle(ses, 3);
6682 return;
6685 size = sizeof(buf);
6686 res = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_ENCODING, buf, &size, 0);
6687 ok(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfoA(HTTP_QUERY_CONTENT_ENCODING) failed: %u\n", GetLastError());
6689 test_request_flags(req, 8);
6690 /* IE11 finds both rev failure and invalid CA. Previous versions required rev failure
6691 to be ignored before invalid CA was reported. */
6692 test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA, _SECURITY_FLAG_CERT_REV_FAILED);
6694 set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_REVOCATION);
6695 test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA|SECURITY_FLAG_IGNORE_REVOCATION, _SECURITY_FLAG_CERT_REV_FAILED);
6697 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6698 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6699 SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6700 SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6701 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6702 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6703 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6705 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6706 ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6708 WaitForSingleObject(complete_event, INFINITE);
6709 ok(req_error == ERROR_INTERNET_INVALID_CA || req_error == ERROR_INTERNET_SEC_CERT_ERRORS, "req_error = %d\n", req_error);
6711 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
6712 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
6713 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6714 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6715 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6716 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6717 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6719 test_request_flags(req, INTERNET_REQFLAG_NO_HEADERS);
6720 test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6721 test_security_info("https://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6723 set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_UNKNOWN_CA);
6724 test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA
6725 |SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_UNKNOWN_CA, 0);
6726 test_http_version(req);
6728 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6729 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6730 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6731 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6732 SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6733 SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6734 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6735 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6736 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
6737 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
6738 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6739 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6740 SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6742 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6743 ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6745 WaitForSingleObject(complete_event, INFINITE);
6746 ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error);
6748 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6749 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6750 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6751 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6752 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6753 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6754 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
6755 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
6756 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6757 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6758 CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6760 test_request_flags(req, 0);
6761 test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION
6762 |SECURITY_FLAG_STRENGTH_STRONG|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6764 test_cert_struct(req, &test_winehq_com_cert);
6765 test_security_info("https://test.winehq.com/data/some_file.html?q", 0,
6766 _SECURITY_FLAG_CERT_INVALID_CA);
6768 res = InternetReadFile(req, buf, sizeof(buf), &size);
6769 ok(res, "InternetReadFile failed: %u\n", GetLastError());
6770 ok(size, "size = 0\n");
6772 close_async_handle(ses, 3);
6774 /* Collect all existing persistent connections */
6775 res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
6776 ok(res, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError());
6778 /* Make another request, without setting security flags */
6780 ses = InternetOpenA("WineTest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
6781 ok(ses != NULL, "InternetOpen failed\n");
6783 pInternetSetStatusCallbackA(ses, &callback);
6785 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6786 conn = InternetConnectA(ses, "test.winehq.com", INTERNET_DEFAULT_HTTPS_PORT,
6787 NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0xdeadbeef);
6788 ok(conn != NULL, "InternetConnect failed with error %u\n", GetLastError());
6789 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6791 SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6792 req = HttpOpenRequestA(conn, "GET", "/tests/hello.html", NULL, NULL, NULL,
6793 INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE,
6794 0xdeadbeef);
6795 ok(req != NULL, "HttpOpenRequest failed\n");
6796 CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6798 test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_STRENGTH_STRONG
6799 |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6800 test_http_version(req);
6802 SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6803 SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6804 SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6805 SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6806 SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6807 SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6808 SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6809 SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6810 SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
6811 SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
6812 SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6813 SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6815 res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6816 ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6818 WaitForSingleObject(complete_event, INFINITE);
6819 ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error);
6821 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6822 CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6823 CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6824 CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6825 CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6826 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6827 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
6828 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
6829 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6830 CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6832 test_request_flags(req, 0);
6833 test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_STRENGTH_STRONG
6834 |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6836 res = InternetReadFile(req, buf, sizeof(buf), &size);
6837 ok(res, "InternetReadFile failed: %u\n", GetLastError());
6838 ok(size, "size = 0\n");
6840 close_async_handle(ses, 2);
6842 test_security_info("http://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6843 test_security_info("file:///c:/dir/file.txt", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6844 test_security_info("xxx:///c:/dir/file.txt", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6847 static void test_secure_connection(void)
6849 static const WCHAR gizmo5[] = {'G','i','z','m','o','5',0};
6850 static const WCHAR testsite[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
6851 static const WCHAR get[] = {'G','E','T',0};
6852 static const WCHAR testpage[] = {'/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
6853 HINTERNET ses, con, req;
6854 DWORD size, size2, flags, err;
6855 INTERNET_CERTIFICATE_INFOA *certificate_structA = NULL;
6856 INTERNET_CERTIFICATE_INFOW *certificate_structW = NULL;
6857 char certstr1[512], certstr2[512];
6858 BOOL ret;
6859 PCCERT_CHAIN_CONTEXT chain;
6861 ses = InternetOpenA("Gizmo5", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
6862 ok(ses != NULL, "InternetOpen failed\n");
6864 con = InternetConnectA(ses, "test.winehq.org",
6865 INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL,
6866 INTERNET_SERVICE_HTTP, 0, 0);
6867 ok(con != NULL, "InternetConnect failed\n");
6869 req = HttpOpenRequestA(con, "GET", "/tests/hello.html", NULL, NULL, NULL,
6870 INTERNET_FLAG_SECURE, 0);
6871 ok(req != NULL, "HttpOpenRequest failed\n");
6873 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
6874 err = GetLastError();
6875 ok(ret || broken(err == ERROR_INTERNET_CANNOT_CONNECT) ||
6876 broken(err == ERROR_INTERNET_SECURITY_CHANNEL_ERROR), "HttpSendRequest failed: %u\n", err);
6877 if (!ret)
6879 win_skip("Cannot connect to https.\n");
6880 if (err == ERROR_INTERNET_SECURITY_CHANNEL_ERROR) https_support = FALSE;
6881 goto done;
6884 size = sizeof(flags);
6885 ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
6886 ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6887 ok(flags & SECURITY_FLAG_SECURE, "expected secure flag to be set\n");
6889 test_cert_struct(req, &test_winehq_org_cert);
6891 size = sizeof(chain);
6892 SetLastError(0xdeadbeef);
6893 ret = InternetQueryOptionA(req, INTERNET_OPTION_SERVER_CERT_CHAIN_CONTEXT, &chain, &size);
6894 ok(ret || GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE /* < IE8 */,
6895 "InternetQueryOption failed: %u\n", GetLastError());
6896 if (ret) CertFreeCertificateChain(chain);
6898 /* Querying the same option through InternetQueryOptionW still results in
6899 * ANSI strings being returned.
6901 size = 0;
6902 ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6903 NULL, &size);
6904 ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6905 ok(size == sizeof(INTERNET_CERTIFICATE_INFOW), "size = %d\n", size);
6906 certificate_structW = HeapAlloc(GetProcessHeap(), 0, size);
6907 ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6908 certificate_structW, &size);
6909 certificate_structA = (INTERNET_CERTIFICATE_INFOA *)certificate_structW;
6910 ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6911 if (ret)
6913 ok(certificate_structA->lpszSubjectInfo &&
6914 strlen(certificate_structA->lpszSubjectInfo) > 1,
6915 "expected a non-empty subject name\n");
6916 ok(certificate_structA->lpszIssuerInfo &&
6917 strlen(certificate_structA->lpszIssuerInfo) > 1,
6918 "expected a non-empty issuer name\n");
6919 ok(!certificate_structA->lpszSignatureAlgName,
6920 "unexpected signature algorithm name\n");
6921 ok(!certificate_structA->lpszEncryptionAlgName,
6922 "unexpected encryption algorithm name\n");
6923 ok(!certificate_structA->lpszProtocolName,
6924 "unexpected protocol name\n");
6925 ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
6926 release_cert_info(certificate_structA);
6928 HeapFree(GetProcessHeap(), 0, certificate_structW);
6930 SetLastError(0xdeadbeef);
6931 size = sizeof(certstr1);
6932 ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE, certstr1, &size);
6933 ok(ret && GetLastError() == ERROR_SUCCESS, "InternetQueryOption failed: %d\n", GetLastError());
6935 SetLastError(0xdeadbeef);
6936 size2 = sizeof(certstr2);
6937 ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE, certstr2, &size2);
6938 ok(ret && GetLastError() == ERROR_SUCCESS, "InternetQueryOption failed: %d\n", GetLastError());
6940 ok(size == size2, "expected same size\n");
6941 ok(!strcmp(certstr1, certstr2), "expected same string\n");
6943 InternetCloseHandle(req);
6944 InternetCloseHandle(con);
6945 InternetCloseHandle(ses);
6947 /* Repeating the tests with the W functions has the same result: */
6948 ses = InternetOpenW(gizmo5, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
6949 ok(ses != NULL, "InternetOpen failed\n");
6951 con = InternetConnectW(ses, testsite,
6952 INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL,
6953 INTERNET_SERVICE_HTTP, 0, 0);
6954 ok(con != NULL, "InternetConnect failed\n");
6956 req = HttpOpenRequestW(con, get, testpage, NULL, NULL, NULL,
6957 INTERNET_FLAG_SECURE|INTERNET_FLAG_RELOAD, 0);
6958 ok(req != NULL, "HttpOpenRequest failed\n");
6960 ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
6961 ok(ret, "HttpSendRequest failed: %d\n", GetLastError());
6963 size = sizeof(flags);
6964 ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
6965 ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6966 ok(flags & SECURITY_FLAG_SECURE, "expected secure flag to be set, got %x\n", flags);
6968 ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6969 NULL, &size);
6970 ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6971 ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %d\n", size);
6972 certificate_structA = HeapAlloc(GetProcessHeap(), 0, size);
6973 ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6974 certificate_structA, &size);
6975 ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6976 if (ret)
6978 ok(certificate_structA->lpszSubjectInfo &&
6979 strlen(certificate_structA->lpszSubjectInfo) > 1,
6980 "expected a non-empty subject name\n");
6981 ok(certificate_structA->lpszIssuerInfo &&
6982 strlen(certificate_structA->lpszIssuerInfo) > 1,
6983 "expected a non-empty issuer name\n");
6984 ok(!certificate_structA->lpszSignatureAlgName,
6985 "unexpected signature algorithm name\n");
6986 ok(!certificate_structA->lpszEncryptionAlgName,
6987 "unexpected encryption algorithm name\n");
6988 ok(!certificate_structA->lpszProtocolName,
6989 "unexpected protocol name\n");
6990 ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
6991 release_cert_info(certificate_structA);
6993 HeapFree(GetProcessHeap(), 0, certificate_structA);
6995 /* Again, querying the same option through InternetQueryOptionW still
6996 * results in ASCII strings being returned.
6998 size = 0;
6999 ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
7000 NULL, &size);
7001 ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
7002 ok(size == sizeof(INTERNET_CERTIFICATE_INFOW), "size = %d\n", size);
7003 certificate_structW = HeapAlloc(GetProcessHeap(), 0, size);
7004 ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
7005 certificate_structW, &size);
7006 certificate_structA = (INTERNET_CERTIFICATE_INFOA *)certificate_structW;
7007 ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
7008 if (ret)
7010 ok(certificate_structA->lpszSubjectInfo &&
7011 strlen(certificate_structA->lpszSubjectInfo) > 1,
7012 "expected a non-empty subject name\n");
7013 ok(certificate_structA->lpszIssuerInfo &&
7014 strlen(certificate_structA->lpszIssuerInfo) > 1,
7015 "expected a non-empty issuer name\n");
7016 ok(!certificate_structA->lpszSignatureAlgName,
7017 "unexpected signature algorithm name\n");
7018 ok(!certificate_structA->lpszEncryptionAlgName,
7019 "unexpected encryption algorithm name\n");
7020 ok(!certificate_structA->lpszProtocolName,
7021 "unexpected protocol name\n");
7022 ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
7023 release_cert_info(certificate_structA);
7025 HeapFree(GetProcessHeap(), 0, certificate_structW);
7027 done:
7028 InternetCloseHandle(req);
7029 InternetCloseHandle(con);
7030 InternetCloseHandle(ses);
7033 static void test_user_agent_header(void)
7035 HINTERNET ses, con, req;
7036 DWORD size, err;
7037 char buffer[64];
7038 BOOL ret;
7040 ses = InternetOpenA("Gizmo5", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
7041 ok(ses != NULL, "InternetOpen failed\n");
7043 con = InternetConnectA(ses, "test.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
7044 ok(con != NULL, "InternetConnect failed\n");
7046 req = HttpOpenRequestA(con, "GET", "/tests/hello.html", "HTTP/1.0", NULL, NULL, 0, 0);
7047 ok(req != NULL, "HttpOpenRequest failed\n");
7049 size = sizeof(buffer);
7050 ret = HttpQueryInfoA(req, HTTP_QUERY_USER_AGENT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7051 err = GetLastError();
7052 ok(!ret, "HttpQueryInfo succeeded\n");
7053 ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
7055 ret = HttpAddRequestHeadersA(req, "User-Agent: Gizmo Project\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
7056 ok(ret, "HttpAddRequestHeaders succeeded\n");
7058 size = sizeof(buffer);
7059 ret = HttpQueryInfoA(req, HTTP_QUERY_USER_AGENT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7060 err = GetLastError();
7061 ok(ret, "HttpQueryInfo failed\n");
7063 InternetCloseHandle(req);
7065 req = HttpOpenRequestA(con, "GET", "/", "HTTP/1.0", NULL, NULL, 0, 0);
7066 ok(req != NULL, "HttpOpenRequest failed\n");
7068 size = sizeof(buffer);
7069 ret = HttpQueryInfoA(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7070 err = GetLastError();
7071 ok(!ret, "HttpQueryInfo succeeded\n");
7072 ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
7074 ret = HttpAddRequestHeadersA(req, "Accept: audio/*, image/*, text/*\r\nUser-Agent: Gizmo Project\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
7075 ok(ret, "HttpAddRequestHeaders failed\n");
7077 buffer[0] = 0;
7078 size = sizeof(buffer);
7079 ret = HttpQueryInfoA(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7080 ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
7081 ok(!strcmp(buffer, "audio/*, image/*, text/*"), "got '%s' expected 'audio/*, image/*, text/*'\n", buffer);
7083 InternetCloseHandle(req);
7084 InternetCloseHandle(con);
7085 InternetCloseHandle(ses);
7088 static void test_bogus_accept_types_array(void)
7090 HINTERNET ses, con, req;
7091 static const char *types[] = { (const char *)6240, "*/*", "%p", "", (const char *)0xffffffff, "*/*", NULL };
7092 DWORD size, error;
7093 char buffer[32];
7094 BOOL ret;
7096 ses = InternetOpenA("MERONG(0.9/;p)", INTERNET_OPEN_TYPE_DIRECT, "", "", 0);
7097 con = InternetConnectA(ses, "www.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
7098 req = HttpOpenRequestA(con, "POST", "/post/post_action.php", "HTTP/1.0", "", types, INTERNET_FLAG_FORMS_SUBMIT, 0);
7100 ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
7102 buffer[0] = 0;
7103 size = sizeof(buffer);
7104 SetLastError(0xdeadbeef);
7105 ret = HttpQueryInfoA(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7106 error = GetLastError();
7107 ok(!ret || broken(ret), "HttpQueryInfo succeeded\n");
7108 if (!ret) ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", error);
7109 ok(broken(!strcmp(buffer, ", */*, %p, , , */*")) /* IE6 */ ||
7110 broken(!strcmp(buffer, "*/*, %p, */*")) /* IE7/8 */ ||
7111 !strcmp(buffer, ""), "got '%s' expected ''\n", buffer);
7113 InternetCloseHandle(req);
7114 InternetCloseHandle(con);
7115 InternetCloseHandle(ses);
7118 struct context
7120 HANDLE event;
7121 HINTERNET req;
7124 static void WINAPI cb(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID info, DWORD size)
7126 INTERNET_ASYNC_RESULT *result = info;
7127 struct context *ctx = (struct context *)context;
7129 if(winetest_debug > 1)
7130 trace("%p 0x%08lx %u %p 0x%08x\n", handle, context, status, info, size);
7132 switch(status) {
7133 case INTERNET_STATUS_REQUEST_COMPLETE:
7134 trace("request handle: 0x%08lx\n", result->dwResult);
7135 ctx->req = (HINTERNET)result->dwResult;
7136 SetEvent(ctx->event);
7137 break;
7138 case INTERNET_STATUS_HANDLE_CLOSING: {
7139 DWORD type = INTERNET_HANDLE_TYPE_CONNECT_HTTP, size = sizeof(type);
7141 if (InternetQueryOptionA(handle, INTERNET_OPTION_HANDLE_TYPE, &type, &size))
7142 ok(type != INTERNET_HANDLE_TYPE_CONNECT_HTTP, "unexpected callback\n");
7143 SetEvent(ctx->event);
7144 break;
7146 case INTERNET_STATUS_NAME_RESOLVED:
7147 case INTERNET_STATUS_CONNECTING_TO_SERVER:
7148 case INTERNET_STATUS_CONNECTED_TO_SERVER: {
7149 char *str = info;
7150 ok(str[0] && str[1], "Got string: %s\n", str);
7151 ok(size == strlen(str)+1, "unexpected size %u\n", size);
7156 static void test_open_url_async(void)
7158 BOOL ret;
7159 HINTERNET ses, req;
7160 DWORD size, error;
7161 struct context ctx;
7162 ULONG type;
7164 /* Collect all existing persistent connections */
7165 ret = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
7166 ok(ret, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError());
7169 * Some versions of IE6 fail those tests. They pass some notification data as UNICODE string, while
7170 * other versions never do. They also hang of following tests. We disable it for everything older
7171 * than IE7.
7173 if(!is_ie7plus)
7174 return;
7176 ctx.req = NULL;
7177 ctx.event = CreateEventA(NULL, TRUE, FALSE, "Z:_home_hans_jaman-installer.exe_ev1");
7179 ses = InternetOpenA("AdvancedInstaller", 0, NULL, NULL, INTERNET_FLAG_ASYNC);
7180 ok(ses != NULL, "InternetOpen failed\n");
7182 SetLastError(0xdeadbeef);
7183 ret = InternetSetOptionA(NULL, INTERNET_OPTION_CALLBACK, &cb, sizeof(DWORD_PTR));
7184 error = GetLastError();
7185 ok(!ret, "InternetSetOptionA succeeded\n");
7186 ok(error == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "got %u expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE\n", error);
7188 ret = InternetSetOptionA(ses, INTERNET_OPTION_CALLBACK, &cb, sizeof(DWORD_PTR));
7189 error = GetLastError();
7190 ok(!ret, "InternetSetOptionA failed\n");
7191 ok(error == ERROR_INTERNET_OPTION_NOT_SETTABLE, "got %u expected ERROR_INTERNET_OPTION_NOT_SETTABLE\n", error);
7193 pInternetSetStatusCallbackW(ses, cb);
7194 ResetEvent(ctx.event);
7196 req = InternetOpenUrlA(ses, "http://test.winehq.org", NULL, 0, 0, (DWORD_PTR)&ctx);
7197 ok(!req && GetLastError() == ERROR_IO_PENDING, "InternetOpenUrl failed\n");
7199 WaitForSingleObject(ctx.event, INFINITE);
7201 type = 0;
7202 size = sizeof(type);
7203 ret = InternetQueryOptionA(ctx.req, INTERNET_OPTION_HANDLE_TYPE, &type, &size);
7204 ok(ret, "InternetQueryOption failed: %u\n", GetLastError());
7205 ok(type == INTERNET_HANDLE_TYPE_HTTP_REQUEST,
7206 "expected INTERNET_HANDLE_TYPE_HTTP_REQUEST, got %u\n", type);
7208 size = 0;
7209 ret = HttpQueryInfoA(ctx.req, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &size, NULL);
7210 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "HttpQueryInfo failed\n");
7211 ok(size > 0, "expected size > 0\n");
7213 ResetEvent(ctx.event);
7214 InternetCloseHandle(ctx.req);
7215 WaitForSingleObject(ctx.event, INFINITE);
7217 InternetCloseHandle(ses);
7218 CloseHandle(ctx.event);
7221 enum api
7223 internet_connect = 1,
7224 http_open_request,
7225 http_send_request_ex,
7226 internet_writefile,
7227 http_end_request,
7228 internet_close_handle
7231 struct notification
7233 enum api function; /* api responsible for notification */
7234 unsigned int status; /* status received */
7235 BOOL async; /* delivered from another thread? */
7236 BOOL todo;
7237 BOOL optional;
7240 struct info
7242 enum api function;
7243 const struct notification *test;
7244 unsigned int count;
7245 unsigned int index;
7246 HANDLE wait;
7247 DWORD thread;
7248 unsigned int line;
7249 DWORD expect_result;
7250 BOOL is_aborted;
7253 static CRITICAL_SECTION notification_cs;
7255 static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD buflen )
7257 BOOL status_ok, function_ok;
7258 struct info *info = (struct info *)context;
7259 unsigned int i;
7261 EnterCriticalSection( &notification_cs );
7263 if(info->is_aborted) {
7264 LeaveCriticalSection(&notification_cs);
7265 return;
7268 if (status == INTERNET_STATUS_HANDLE_CREATED)
7270 DWORD size = sizeof(struct info *);
7271 HttpQueryInfoA( handle, INTERNET_OPTION_CONTEXT_VALUE, &info, &size, 0 );
7272 }else if(status == INTERNET_STATUS_REQUEST_COMPLETE) {
7273 INTERNET_ASYNC_RESULT *ar = (INTERNET_ASYNC_RESULT*)buffer;
7275 ok(buflen == sizeof(*ar), "unexpected buflen = %d\n", buflen);
7276 if(info->expect_result == ERROR_SUCCESS) {
7277 ok(ar->dwResult == 1, "ar->dwResult = %ld, expected 1\n", ar->dwResult);
7278 }else {
7279 ok(!ar->dwResult, "ar->dwResult = %ld, expected 1\n", ar->dwResult);
7280 ok(ar->dwError == info->expect_result, "ar->dwError = %d, expected %d\n", ar->dwError, info->expect_result);
7284 i = info->index;
7285 if (i >= info->count)
7287 LeaveCriticalSection( &notification_cs );
7288 return;
7291 while (info->test[i].status != status &&
7292 (info->test[i].optional || info->test[i].todo) &&
7293 i < info->count - 1 &&
7294 info->test[i].function == info->test[i + 1].function)
7296 i++;
7299 status_ok = (info->test[i].status == status);
7300 function_ok = (info->test[i].function == info->function);
7302 if (!info->test[i].todo)
7304 ok( status_ok, "%u: expected status %u got %u\n", info->line, info->test[i].status, status );
7305 ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function );
7307 if (info->test[i].async)
7308 ok(info->thread != GetCurrentThreadId(), "%u: expected thread %u got %u\n",
7309 info->line, info->thread, GetCurrentThreadId());
7311 else
7313 todo_wine ok( status_ok, "%u: expected status %u got %u\n", info->line, info->test[i].status, status );
7314 if (status_ok)
7315 todo_wine ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function );
7317 if (i == info->count - 1 || info->test[i].function != info->test[i + 1].function) SetEvent( info->wait );
7318 info->index = i+1;
7320 LeaveCriticalSection( &notification_cs );
7323 static void setup_test( struct info *info, enum api function, unsigned int line, DWORD expect_result )
7325 info->function = function;
7326 info->line = line;
7327 info->expect_result = expect_result;
7330 struct notification_data
7332 const struct notification *test;
7333 const unsigned int count;
7334 const char *method;
7335 const char *host;
7336 const char *path;
7337 const char *data;
7338 BOOL expect_conn_failure;
7341 static const struct notification async_send_request_ex_test[] =
7343 { internet_connect, INTERNET_STATUS_HANDLE_CREATED, FALSE },
7344 { http_open_request, INTERNET_STATUS_HANDLE_CREATED, FALSE },
7345 { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7346 { http_send_request_ex, INTERNET_STATUS_COOKIE_SENT, TRUE, FALSE, TRUE },
7347 { http_send_request_ex, INTERNET_STATUS_RESOLVING_NAME, TRUE, FALSE, TRUE },
7348 { http_send_request_ex, INTERNET_STATUS_NAME_RESOLVED, TRUE, FALSE, TRUE },
7349 { http_send_request_ex, INTERNET_STATUS_CONNECTING_TO_SERVER, TRUE },
7350 { http_send_request_ex, INTERNET_STATUS_CONNECTED_TO_SERVER, TRUE },
7351 { http_send_request_ex, INTERNET_STATUS_SENDING_REQUEST, TRUE },
7352 { http_send_request_ex, INTERNET_STATUS_REQUEST_SENT, TRUE },
7353 { http_send_request_ex, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7354 { internet_writefile, INTERNET_STATUS_SENDING_REQUEST, FALSE },
7355 { internet_writefile, INTERNET_STATUS_REQUEST_SENT, FALSE },
7356 { http_end_request, INTERNET_STATUS_RECEIVING_RESPONSE, TRUE },
7357 { http_end_request, INTERNET_STATUS_RESPONSE_RECEIVED, TRUE },
7358 { http_end_request, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7359 { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, FALSE, FALSE, TRUE },
7360 { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, FALSE, FALSE, TRUE },
7361 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, },
7362 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, }
7365 static const struct notification async_send_request_ex_test2[] =
7367 { internet_connect, INTERNET_STATUS_HANDLE_CREATED, FALSE },
7368 { http_open_request, INTERNET_STATUS_HANDLE_CREATED, FALSE },
7369 { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7370 { http_send_request_ex, INTERNET_STATUS_COOKIE_SENT, TRUE, FALSE, TRUE },
7371 { http_send_request_ex, INTERNET_STATUS_RESOLVING_NAME, TRUE, FALSE, TRUE },
7372 { http_send_request_ex, INTERNET_STATUS_NAME_RESOLVED, TRUE, FALSE, TRUE },
7373 { http_send_request_ex, INTERNET_STATUS_CONNECTING_TO_SERVER, TRUE, TRUE },
7374 { http_send_request_ex, INTERNET_STATUS_CONNECTED_TO_SERVER, TRUE, TRUE },
7375 { http_send_request_ex, INTERNET_STATUS_SENDING_REQUEST, TRUE },
7376 { http_send_request_ex, INTERNET_STATUS_REQUEST_SENT, TRUE },
7377 { http_send_request_ex, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7378 { http_end_request, INTERNET_STATUS_RECEIVING_RESPONSE, TRUE },
7379 { http_end_request, INTERNET_STATUS_RESPONSE_RECEIVED, TRUE },
7380 { http_end_request, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7381 { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, FALSE, FALSE, TRUE },
7382 { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, FALSE, FALSE, TRUE },
7383 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, },
7384 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, }
7387 static const struct notification async_send_request_ex_resolve_failure_test[] =
7389 { internet_connect, INTERNET_STATUS_HANDLE_CREATED, FALSE },
7390 { http_open_request, INTERNET_STATUS_HANDLE_CREATED, FALSE },
7391 { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7392 { http_send_request_ex, INTERNET_STATUS_RESOLVING_NAME, TRUE },
7393 { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7394 { http_send_request_ex, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7395 { http_end_request, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7396 { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, FALSE, FALSE, TRUE },
7397 { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, FALSE, FALSE, TRUE },
7398 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, },
7399 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, }
7402 static const struct notification async_send_request_ex_chunked_test[] =
7404 { internet_connect, INTERNET_STATUS_HANDLE_CREATED },
7405 { http_open_request, INTERNET_STATUS_HANDLE_CREATED },
7406 { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7407 { http_send_request_ex, INTERNET_STATUS_COOKIE_SENT, TRUE, FALSE, TRUE },
7408 { http_send_request_ex, INTERNET_STATUS_RESOLVING_NAME, TRUE, FALSE, TRUE },
7409 { http_send_request_ex, INTERNET_STATUS_NAME_RESOLVED, TRUE, FALSE, TRUE },
7410 { http_send_request_ex, INTERNET_STATUS_CONNECTING_TO_SERVER, TRUE },
7411 { http_send_request_ex, INTERNET_STATUS_CONNECTED_TO_SERVER, TRUE },
7412 { http_send_request_ex, INTERNET_STATUS_SENDING_REQUEST, TRUE },
7413 { http_send_request_ex, INTERNET_STATUS_REQUEST_SENT, TRUE },
7414 { http_send_request_ex, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7415 { http_end_request, INTERNET_STATUS_RECEIVING_RESPONSE, TRUE },
7416 { http_end_request, INTERNET_STATUS_RESPONSE_RECEIVED, TRUE },
7417 { http_end_request, INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7418 { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION },
7419 { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED },
7420 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING },
7421 { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING }
7424 static const struct notification_data notification_data[] = {
7426 async_send_request_ex_chunked_test,
7427 ARRAY_SIZE(async_send_request_ex_chunked_test),
7428 "GET",
7429 "test.winehq.org",
7430 "tests/data.php"
7433 async_send_request_ex_test,
7434 ARRAY_SIZE(async_send_request_ex_test),
7435 "POST",
7436 "test.winehq.org",
7437 "tests/post.php",
7438 "Public ID=codeweavers"
7441 async_send_request_ex_test2,
7442 ARRAY_SIZE(async_send_request_ex_test2),
7443 "POST",
7444 "test.winehq.org",
7445 "tests/post.php"
7448 async_send_request_ex_resolve_failure_test,
7449 ARRAY_SIZE(async_send_request_ex_resolve_failure_test),
7450 "GET",
7451 "brokenhost",
7452 "index.html",
7453 NULL,
7454 TRUE
7458 static void test_async_HttpSendRequestEx(const struct notification_data *nd)
7460 BOOL ret;
7461 HINTERNET ses, req, con;
7462 struct info info;
7463 DWORD size, written, error;
7464 INTERNET_BUFFERSA b;
7465 static const char *accept[2] = {"*/*", NULL};
7466 char buffer[32];
7468 trace("Async HttpSendRequestEx test (%s %s)\n", nd->method, nd->host);
7470 InitializeCriticalSection( &notification_cs );
7472 info.test = nd->test;
7473 info.count = nd->count;
7474 info.index = 0;
7475 info.wait = CreateEventW( NULL, FALSE, FALSE, NULL );
7476 info.thread = GetCurrentThreadId();
7477 info.is_aborted = FALSE;
7479 ses = InternetOpenA( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC );
7480 ok( ses != NULL, "InternetOpen failed\n" );
7482 pInternetSetStatusCallbackA( ses, check_notification );
7484 setup_test( &info, internet_connect, __LINE__, ERROR_SUCCESS );
7485 con = InternetConnectA( ses, nd->host, 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)&info );
7486 ok( con != NULL, "InternetConnect failed %u\n", GetLastError() );
7488 WaitForSingleObject( info.wait, 10000 );
7490 setup_test( &info, http_open_request, __LINE__, ERROR_SUCCESS );
7491 req = HttpOpenRequestA( con, nd->method, nd->path, NULL, NULL, accept, 0, (DWORD_PTR)&info );
7492 ok( req != NULL, "HttpOpenRequest failed %u\n", GetLastError() );
7494 WaitForSingleObject( info.wait, 10000 );
7496 if(nd->data) {
7497 memset( &b, 0, sizeof(INTERNET_BUFFERSA) );
7498 b.dwStructSize = sizeof(INTERNET_BUFFERSA);
7499 b.lpcszHeader = "Content-Type: application/x-www-form-urlencoded";
7500 b.dwHeadersLength = strlen( b.lpcszHeader );
7501 b.dwBufferTotal = nd->data ? strlen( nd->data ) : 0;
7504 setup_test( &info, http_send_request_ex, __LINE__,
7505 nd->expect_conn_failure ? ERROR_INTERNET_NAME_NOT_RESOLVED : ERROR_SUCCESS );
7506 ret = HttpSendRequestExA( req, nd->data ? &b : NULL, NULL, 0x28, 0 );
7507 ok( !ret && GetLastError() == ERROR_IO_PENDING, "HttpSendRequestExA failed %d %u\n", ret, GetLastError() );
7509 error = WaitForSingleObject( info.wait, 10000 );
7510 if(error != WAIT_OBJECT_0) {
7511 skip("WaitForSingleObject returned %d, assuming DNS problem\n", error);
7512 info.is_aborted = TRUE;
7513 goto abort;
7516 size = sizeof(buffer);
7517 SetLastError( 0xdeadbeef );
7518 ret = HttpQueryInfoA( req, HTTP_QUERY_CONTENT_ENCODING, buffer, &size, 0 );
7519 error = GetLastError();
7520 ok( !ret, "HttpQueryInfoA failed %u\n", GetLastError() );
7521 if(nd->expect_conn_failure) {
7522 ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND got %u\n", error );
7523 }else {
7524 todo_wine
7525 ok(error == ERROR_INTERNET_INCORRECT_HANDLE_STATE,
7526 "expected ERROR_INTERNET_INCORRECT_HANDLE_STATE got %u\n", error );
7529 if (nd->data)
7531 written = 0;
7532 size = strlen( nd->data );
7533 setup_test( &info, internet_writefile, __LINE__, ERROR_SUCCESS );
7534 ret = InternetWriteFile( req, nd->data, size, &written );
7535 ok( ret, "InternetWriteFile failed %u\n", GetLastError() );
7536 ok( written == size, "expected %u got %u\n", written, size );
7538 WaitForSingleObject( info.wait, 10000 );
7540 SetLastError( 0xdeadbeef );
7541 ret = HttpEndRequestA( req, (void *)nd->data, 0x28, 0 );
7542 error = GetLastError();
7543 ok( !ret, "HttpEndRequestA succeeded\n" );
7544 ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error );
7547 SetLastError( 0xdeadbeef );
7548 setup_test( &info, http_end_request, __LINE__,
7549 nd->expect_conn_failure ? ERROR_INTERNET_OPERATION_CANCELLED : ERROR_SUCCESS);
7550 ret = HttpEndRequestA( req, NULL, 0x28, 0 );
7551 error = GetLastError();
7552 ok( !ret, "HttpEndRequestA succeeded\n" );
7553 ok( error == ERROR_IO_PENDING, "expected ERROR_IO_PENDING got %u\n", error );
7555 WaitForSingleObject( info.wait, 10000 );
7557 setup_test( &info, internet_close_handle, __LINE__, ERROR_SUCCESS );
7558 abort:
7559 InternetCloseHandle( req );
7560 InternetCloseHandle( con );
7561 InternetCloseHandle( ses );
7563 WaitForSingleObject( info.wait, 10000 );
7564 Sleep(100);
7565 CloseHandle( info.wait );
7566 DeleteCriticalSection( &notification_cs );
7569 static HINTERNET closetest_session, closetest_req, closetest_conn;
7570 static BOOL closetest_closed;
7572 static void WINAPI closetest_callback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
7573 LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
7575 DWORD len, type;
7576 BOOL res;
7578 if(winetest_debug > 1)
7579 trace("closetest_callback %p: %d\n", hInternet, dwInternetStatus);
7581 ok(hInternet == closetest_session || hInternet == closetest_conn || hInternet == closetest_req,
7582 "Unexpected hInternet %p\n", hInternet);
7583 if(!closetest_closed)
7584 return;
7586 len = sizeof(type);
7587 res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_HANDLE_TYPE, &type, &len);
7588 ok(!res && GetLastError() == ERROR_INVALID_HANDLE,
7589 "InternetQueryOptionA(%p INTERNET_OPTION_HANDLE_TYPE) failed: %x %u, expected TRUE ERROR_INVALID_HANDLE\n",
7590 closetest_req, res, GetLastError());
7593 static void test_InternetCloseHandle(void)
7595 DWORD len, flags;
7596 BOOL res;
7598 closetest_session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
7599 ok(closetest_session != NULL,"InternetOpen failed with error %u\n", GetLastError());
7601 pInternetSetStatusCallbackA(closetest_session, closetest_callback);
7603 closetest_conn = InternetConnectA(closetest_session, "source.winehq.org", INTERNET_INVALID_PORT_NUMBER,
7604 NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
7605 ok(closetest_conn != NULL,"InternetConnect failed with error %u\n", GetLastError());
7607 closetest_req = HttpOpenRequestA(closetest_conn, "GET", "winegecko.php", NULL, NULL, NULL,
7608 INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
7610 res = HttpSendRequestA(closetest_req, NULL, -1, NULL, 0);
7611 ok(!res && (GetLastError() == ERROR_IO_PENDING),
7612 "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
7614 test_request_flags(closetest_req, INTERNET_REQFLAG_NO_HEADERS);
7616 res = InternetCloseHandle(closetest_session);
7617 ok(res, "InternetCloseHandle failed: %u\n", GetLastError());
7618 closetest_closed = TRUE;
7619 trace("Closed session handle\n");
7621 res = InternetCloseHandle(closetest_conn);
7622 ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "InternetCloseConnection(conn) failed: %x %u\n",
7623 res, GetLastError());
7625 res = InternetCloseHandle(closetest_req);
7626 ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "InternetCloseConnection(req) failed: %x %u\n",
7627 res, GetLastError());
7629 len = sizeof(flags);
7630 res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_REQUEST_FLAGS, &flags, &len);
7631 ok(!res && GetLastError() == ERROR_INVALID_HANDLE,
7632 "InternetQueryOptionA(%p INTERNET_OPTION_REQUEST_FLAGS) failed: %x %u, expected TRUE ERROR_INVALID_HANDLE\n",
7633 closetest_req, res, GetLastError());
7636 static void test_connection_failure(void)
7638 test_request_t req;
7639 DWORD error;
7640 BOOL ret;
7642 open_simple_request(&req, "localhost", 1, NULL, "/");
7644 SetLastError(0xdeadbeef);
7645 ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
7646 error = GetLastError();
7647 ok(!ret, "unexpected success\n");
7648 ok(error == ERROR_INTERNET_CANNOT_CONNECT, "wrong error %u\n", error);
7650 close_request(&req);
7653 static void test_default_service_port(void)
7655 HINTERNET session, connect, request;
7656 DWORD size, error;
7657 char buffer[128];
7658 BOOL ret;
7660 if(!is_ie7plus)
7661 return;
7663 session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
7664 ok(session != NULL, "InternetOpen failed\n");
7666 connect = InternetConnectA(session, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, NULL, NULL,
7667 INTERNET_SERVICE_HTTP, 0, 0);
7668 ok(connect != NULL, "InternetConnect failed\n");
7670 request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
7671 ok(request != NULL, "HttpOpenRequest failed\n");
7673 SetLastError(0xdeadbeef);
7674 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
7675 error = GetLastError();
7676 ok(!ret, "HttpSendRequest succeeded\n");
7677 ok(error == ERROR_INTERNET_SECURITY_CHANNEL_ERROR || error == ERROR_INTERNET_CANNOT_CONNECT,
7678 "got %u\n", error);
7680 size = sizeof(buffer);
7681 memset(buffer, 0, sizeof(buffer));
7682 ret = HttpQueryInfoA(request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7683 ok(ret, "HttpQueryInfo failed with error %u\n", GetLastError());
7684 ok(!strcmp(buffer, "test.winehq.org:80"), "Expected test.winehg.org:80, got '%s'\n", buffer);
7686 InternetCloseHandle(request);
7687 InternetCloseHandle(connect);
7689 connect = InternetConnectA(session, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, NULL, NULL,
7690 INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
7691 ok(connect != NULL, "InternetConnect failed\n");
7693 request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
7694 ok(request != NULL, "HttpOpenRequest failed\n");
7696 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
7697 if (!ret && GetLastError() == ERROR_INTERNET_SECURITY_CHANNEL_ERROR)
7699 win_skip("Can't make https connection\n");
7700 goto done;
7702 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
7704 size = sizeof(buffer);
7705 memset(buffer, 0, sizeof(buffer));
7706 ret = HttpQueryInfoA(request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7707 ok(ret, "HttpQueryInfo failed with error %u\n", GetLastError());
7708 ok(!strcmp(buffer, "test.winehq.org"), "Expected test.winehg.org, got '%s'\n", buffer);
7710 InternetCloseHandle(request);
7711 InternetCloseHandle(connect);
7713 connect = InternetConnectA(session, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, NULL, NULL,
7714 INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
7715 ok(connect != NULL, "InternetConnect failed\n");
7717 request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, NULL, 0, 0);
7718 ok(request != NULL, "HttpOpenRequest failed\n");
7720 ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
7721 ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
7723 size = sizeof(buffer);
7724 memset(buffer, 0, sizeof(buffer));
7725 ret = HttpQueryInfoA(request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7726 ok(ret, "HttpQueryInfo failed with error %u\n", GetLastError());
7727 ok(!strcmp(buffer, "test.winehq.org:443"), "Expected test.winehg.org:443, got '%s'\n", buffer);
7729 done:
7730 InternetCloseHandle(request);
7731 InternetCloseHandle(connect);
7732 InternetCloseHandle(session);
7735 static void init_status_tests(void)
7737 memset(expect, 0, sizeof(expect));
7738 memset(optional, 0, sizeof(optional));
7739 memset(wine_allow, 0, sizeof(wine_allow));
7740 memset(notified, 0, sizeof(notified));
7741 memset(status_string, 0, sizeof(status_string));
7743 #define STATUS_STRING(status) status_string[status] = #status
7744 STATUS_STRING(INTERNET_STATUS_RESOLVING_NAME);
7745 STATUS_STRING(INTERNET_STATUS_NAME_RESOLVED);
7746 STATUS_STRING(INTERNET_STATUS_CONNECTING_TO_SERVER);
7747 STATUS_STRING(INTERNET_STATUS_CONNECTED_TO_SERVER);
7748 STATUS_STRING(INTERNET_STATUS_SENDING_REQUEST);
7749 STATUS_STRING(INTERNET_STATUS_REQUEST_SENT);
7750 STATUS_STRING(INTERNET_STATUS_RECEIVING_RESPONSE);
7751 STATUS_STRING(INTERNET_STATUS_RESPONSE_RECEIVED);
7752 STATUS_STRING(INTERNET_STATUS_CTL_RESPONSE_RECEIVED);
7753 STATUS_STRING(INTERNET_STATUS_PREFETCH);
7754 STATUS_STRING(INTERNET_STATUS_CLOSING_CONNECTION);
7755 STATUS_STRING(INTERNET_STATUS_CONNECTION_CLOSED);
7756 STATUS_STRING(INTERNET_STATUS_HANDLE_CREATED);
7757 STATUS_STRING(INTERNET_STATUS_HANDLE_CLOSING);
7758 STATUS_STRING(INTERNET_STATUS_DETECTING_PROXY);
7759 STATUS_STRING(INTERNET_STATUS_REQUEST_COMPLETE);
7760 STATUS_STRING(INTERNET_STATUS_REDIRECT);
7761 STATUS_STRING(INTERNET_STATUS_INTERMEDIATE_RESPONSE);
7762 STATUS_STRING(INTERNET_STATUS_USER_INPUT_REQUIRED);
7763 STATUS_STRING(INTERNET_STATUS_STATE_CHANGE);
7764 STATUS_STRING(INTERNET_STATUS_COOKIE_SENT);
7765 STATUS_STRING(INTERNET_STATUS_COOKIE_RECEIVED);
7766 STATUS_STRING(INTERNET_STATUS_PRIVACY_IMPACTED);
7767 STATUS_STRING(INTERNET_STATUS_P3P_HEADER);
7768 STATUS_STRING(INTERNET_STATUS_P3P_POLICYREF);
7769 STATUS_STRING(INTERNET_STATUS_COOKIE_HISTORY);
7770 #undef STATUS_STRING
7773 static void WINAPI header_cb( HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD len )
7775 BOOL ret;
7776 DWORD index, size;
7777 char buf[256];
7779 if (status == INTERNET_STATUS_SENDING_REQUEST)
7781 ret = HttpAddRequestHeadersA( handle, "winetest: winetest", ~0u, HTTP_ADDREQ_FLAG_ADD );
7782 ok( ret, "HttpAddRequestHeadersA failed %u\n", GetLastError() );
7783 SetEvent( (HANDLE)ctx );
7785 else if (status == INTERNET_STATUS_REQUEST_SENT)
7787 index = 0;
7788 size = sizeof(buf);
7789 ret = HttpQueryInfoA( handle, HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
7790 buf, &size, &index );
7791 ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
7792 ok( strstr( buf, "winetest: winetest" ) != NULL, "header missing\n" );
7793 SetEvent( (HANDLE)ctx );
7797 static void test_concurrent_header_access(void)
7799 HINTERNET ses, con, req;
7800 DWORD err;
7801 BOOL ret;
7802 HANDLE wait = CreateEventW( NULL, FALSE, FALSE, NULL );
7804 ses = InternetOpenA( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC );
7805 ok( ses != NULL, "InternetOpenA failed\n" );
7807 con = InternetConnectA( ses, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
7808 INTERNET_SERVICE_HTTP, 0, 0 );
7809 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
7811 req = HttpOpenRequestA( con, NULL, "/", NULL, NULL, NULL, 0, (DWORD_PTR)wait );
7812 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
7814 pInternetSetStatusCallbackA( req, header_cb );
7816 SetLastError( 0xdeadbeef );
7817 ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
7818 err = GetLastError();
7819 ok( !ret, "HttpSendRequestA succeeded\n" );
7820 ok( err == ERROR_IO_PENDING, "got %u\n", ERROR_IO_PENDING );
7822 WaitForSingleObject( wait, 5000 );
7823 WaitForSingleObject( wait, 5000 );
7825 InternetCloseHandle( req );
7826 InternetCloseHandle( con );
7827 InternetCloseHandle( ses );
7828 CloseHandle( wait );
7831 static void test_cert_string(void)
7833 HINTERNET ses, con, req;
7834 char actual[512];
7835 DWORD size;
7836 BOOL res;
7837 PCCERT_CHAIN_CONTEXT chain;
7839 ses = InternetOpenA( "winetest", 0, NULL, NULL, 0 );
7840 ok( ses != NULL, "InternetOpenA failed\n" );
7842 con = InternetConnectA( ses, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
7843 INTERNET_SERVICE_HTTP, 0, 0 );
7844 ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
7846 req = HttpOpenRequestA( con, NULL, "/", NULL, NULL, NULL, 0, 0 );
7847 ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
7849 size = sizeof(actual);
7850 SetLastError( 0xdeadbeef );
7851 memset( actual, 0x55, sizeof(actual) );
7852 res = InternetQueryOptionA( req, INTERNET_OPTION_SECURITY_CERTIFICATE, actual, &size );
7853 ok( !res && GetLastError() == ERROR_INTERNET_INVALID_OPERATION,
7854 "InternetQueryOption failed: %u\n", GetLastError() );
7855 ok( size == 0, "unexpected size: %u\n", size );
7856 ok( actual[0] == 0x55, "unexpected byte: %02x\n", actual[0] );
7858 size = sizeof(chain);
7859 SetLastError(0xdeadbeef);
7860 res = InternetQueryOptionA(req, INTERNET_OPTION_SERVER_CERT_CHAIN_CONTEXT, &chain, &size);
7861 ok(!res && (GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_STATE),
7862 "InternetQueryOption failed: %u\n", GetLastError());
7864 InternetCloseHandle( req );
7865 InternetCloseHandle( con );
7866 InternetCloseHandle( ses );
7869 START_TEST(http)
7871 HMODULE hdll;
7872 hdll = GetModuleHandleA("wininet.dll");
7874 if(!GetProcAddress(hdll, "InternetGetCookieExW")) {
7875 win_skip("Too old IE (older than 6.0)\n");
7876 return;
7879 pInternetSetStatusCallbackA = (void*)GetProcAddress(hdll, "InternetSetStatusCallbackA");
7880 pInternetSetStatusCallbackW = (void*)GetProcAddress(hdll, "InternetSetStatusCallbackW");
7881 pInternetGetSecurityInfoByURLA = (void*)GetProcAddress(hdll, "InternetGetSecurityInfoByURLA");
7883 if(!pInternetGetSecurityInfoByURLA) {
7884 is_ie7plus = FALSE;
7885 win_skip("IE6 found. It's too old for some tests.\n");
7888 init_events();
7889 init_status_tests();
7890 test_InternetCloseHandle();
7891 InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[0]);
7892 InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[1]);
7893 InternetReadFile_test(0, &test_data[1]);
7894 InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[2]);
7895 test_secure_connection();
7896 test_security_flags();
7897 InternetReadFile_test(0, &test_data[2]);
7898 InternetReadFileExA_test(INTERNET_FLAG_ASYNC);
7899 test_open_url_async();
7900 test_async_HttpSendRequestEx(&notification_data[0]);
7901 test_async_HttpSendRequestEx(&notification_data[1]);
7902 test_async_HttpSendRequestEx(&notification_data[2]);
7903 test_async_HttpSendRequestEx(&notification_data[3]);
7904 InternetOpenRequest_test();
7905 test_http_cache();
7906 InternetLockRequestFile_test();
7907 InternetOpenUrlA_test();
7908 HttpHeaders_test();
7909 test_http_connection();
7910 test_user_agent_header();
7911 test_bogus_accept_types_array();
7912 InternetReadFile_chunked_test();
7913 HttpSendRequestEx_test();
7914 InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[3]);
7915 test_connection_failure();
7916 test_default_service_port();
7917 test_concurrent_header_access();
7918 test_cert_string();
7919 free_events();