wined3d: Explicitly specify the resource location to context_attach_depth_stencil_fbo().
[wine] / dlls / winhttp / tests / winhttp.c
1 /*
2  * WinHTTP - tests
3  *
4  * Copyright 2008 Google (Zac Brown)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winhttp.h>
27 #include <wincrypt.h>
28 #include <winreg.h>
29 #include <winsock.h>
30 #include "initguid.h"
31 #include <httprequest.h>
32
33 #include "wine/test.h"
34
35 static const WCHAR test_useragent[] =
36     {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
37 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
38 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
39
40 static BOOL proxy_active(void)
41 {
42     WINHTTP_PROXY_INFO proxy_info;
43     BOOL active = FALSE;
44
45     if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
46     {
47         active = (proxy_info.lpszProxy != NULL);
48         if (active)
49             GlobalFree((HGLOBAL) proxy_info.lpszProxy);
50         if (proxy_info.lpszProxyBypass != NULL)
51             GlobalFree((HGLOBAL) proxy_info.lpszProxyBypass);
52     }
53     else
54        active = FALSE;
55
56     return active;
57 }
58
59 static void test_QueryOption(void)
60 {
61     BOOL ret;
62     HINTERNET session, request, connection;
63     DWORD feature, size;
64
65     SetLastError(0xdeadbeef);
66     session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
67     ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
68
69     SetLastError(0xdeadbeef);
70     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
71     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
72     ok(GetLastError() == ERROR_INVALID_PARAMETER,
73        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
74
75     size = 0xdeadbeef;
76     SetLastError(0xdeadbeef);
77     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
78     ok(!ret, "should fail to query option\n");
79     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
80        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
81     ok(size == 4, "expected 4, got %u\n", size);
82
83     feature = 0xdeadbeef;
84     size = sizeof(feature) - 1;
85     SetLastError(0xdeadbeef);
86     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
87     ok(!ret, "should fail to query option\n");
88     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
89        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
90     ok(size == 4, "expected 4, got %u\n", size);
91
92     feature = 0xdeadbeef;
93     size = sizeof(feature) + 1;
94     SetLastError(0xdeadbeef);
95     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
96     ok(ret, "failed to query option %u\n", GetLastError());
97     ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
98     ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
99        "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
100
101     SetLastError(0xdeadbeef);
102     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
103     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
104     ok(GetLastError() == ERROR_INVALID_PARAMETER,
105        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
106
107     feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
108     SetLastError(0xdeadbeef);
109     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
110     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
111     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
112        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
113
114     feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
115     SetLastError(0xdeadbeef);
116     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
117     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
118     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
119        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
120
121     feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
122     SetLastError(0xdeadbeef);
123     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
124     ok(ret, "failed to set redirect policy %u\n", GetLastError());
125
126     feature = 0xdeadbeef;
127     size = sizeof(feature);
128     SetLastError(0xdeadbeef);
129     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
130     ok(ret, "failed to query option %u\n", GetLastError());
131     ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
132        "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
133
134     feature = WINHTTP_DISABLE_COOKIES;
135     SetLastError(0xdeadbeef);
136     ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
137     ok(!ret, "should fail to set disable feature for a session\n");
138     ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
139        "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
140
141     SetLastError(0xdeadbeef);
142     connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
143     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
144
145     feature = WINHTTP_DISABLE_COOKIES;
146     SetLastError(0xdeadbeef);
147     ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
148     ok(!ret, "should fail to set disable feature for a connection\n");
149     ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
150        "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151
152     SetLastError(0xdeadbeef);
153     request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
154                                  WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
155     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
156     {
157         skip("Network unreachable, skipping the test\n");
158         goto done;
159     }
160
161     feature = 0xdeadbeef;
162     size = sizeof(feature);
163     SetLastError(0xdeadbeef);
164     ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
165     ok(!ret, "should fail to query disable feature for a request\n");
166     ok(GetLastError() == ERROR_INVALID_PARAMETER,
167        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
168
169     feature = 0;
170     size = sizeof(feature);
171     SetLastError(0xdeadbeef);
172     ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
173     ok(ret, "failed to set feature %u\n", GetLastError());
174
175     feature = 0xffffffff;
176     size = sizeof(feature);
177     SetLastError(0xdeadbeef);
178     ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
179     ok(ret, "failed to set feature %u\n", GetLastError());
180
181     feature = WINHTTP_DISABLE_COOKIES;
182     size = sizeof(feature);
183     SetLastError(0xdeadbeef);
184     ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
185     ok(ret, "failed to set feature %u\n", GetLastError());
186
187     size = 0;
188     SetLastError(0xdeadbeef);
189     ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
190     ok(!ret, "should fail to query disable feature for a request\n");
191     ok(GetLastError() == ERROR_INVALID_PARAMETER,
192        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
193
194     SetLastError(0xdeadbeef);
195     ret = WinHttpCloseHandle(request);
196     ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
197
198 done:
199     SetLastError(0xdeadbeef);
200     ret = WinHttpCloseHandle(connection);
201     ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
202     SetLastError(0xdeadbeef);
203     ret = WinHttpCloseHandle(session);
204     ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
205 }
206
207 static void test_OpenRequest (void)
208 {
209     BOOL ret;
210     HINTERNET session, request, connection;
211
212     session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
213         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
214     ok(session != NULL, "WinHttpOpen failed to open session.\n");
215
216     /* Test with a bad server name */
217     SetLastError(0xdeadbeef);
218     connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
219     ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
220     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
221
222     /* Test with a valid server name */
223     connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
224     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
225
226     request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
227         WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
228     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
229     {
230         skip("Network unreachable, skipping.\n");
231         goto done;
232     }
233     ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
234
235     ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
236     if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
237     {
238         skip("Connection failed, skipping.\n");
239         goto done;
240     }
241     ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
242     ret = WinHttpCloseHandle(request);
243     ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
244
245  done:
246     ret = WinHttpCloseHandle(connection);
247     ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
248     ret = WinHttpCloseHandle(session);
249     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
250
251 }
252
253 static void test_empty_headers_param(void)
254 {
255     static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
256     static const WCHAR empty[]  = {0};
257     HINTERNET ses, con, req;
258     BOOL ret;
259
260     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
261     ok(ses != NULL, "failed to open session %u\n", GetLastError());
262
263     con = WinHttpConnect(ses, winehq, 80, 0);
264     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
265
266     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
267     ok(req != NULL, "failed to open a request %u\n", GetLastError());
268
269     ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
270     ok(ret, "failed to send request %u\n", GetLastError());
271
272     WinHttpCloseHandle(req);
273     WinHttpCloseHandle(con);
274     WinHttpCloseHandle(ses);
275 }
276
277 static void test_SendRequest (void)
278 {
279     HINTERNET session, request, connection;
280     DWORD header_len, optional_len, total_len, bytes_rw, size;
281     DWORD_PTR context;
282     BOOL ret;
283     CHAR buffer[256];
284     int i;
285
286     static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
287                                 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
288     static const WCHAR content_type[] =
289         {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
290          '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
291     static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
292     static const WCHAR test_verb[] = {'P','O','S','T',0};
293     static CHAR post_data[] = "mode=Test";
294     static CHAR test_post[] = "mode => Test\\0\n";
295
296     header_len = -1L;
297     total_len = optional_len = sizeof(post_data);
298     memset(buffer, 0xff, sizeof(buffer));
299
300     session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
301         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
302     ok(session != NULL, "WinHttpOpen failed to open session.\n");
303
304     connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
305     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
306
307     request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
308         WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
309     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
310     {
311         skip("Network unreachable, skipping.\n");
312         goto done;
313     }
314     ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
315     if (!request) goto done;
316
317     context = 0xdeadbeef;
318     ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
319     ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
320
321     context++;
322     ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
323     ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
324
325     context = 0;
326     size = sizeof(context);
327     ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
328     ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
329     ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
330
331     for (i = 3; post_data[i]; i++)
332     {
333         bytes_rw = -1;
334         ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
335         if (ret)
336           ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
337         else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
338         {
339           ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
340           ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
341         }
342     }
343
344     ret = WinHttpReceiveResponse(request, NULL);
345     ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
346
347     bytes_rw = -1;
348     ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
349     ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
350
351     ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
352     ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
353
354     ret = WinHttpCloseHandle(request);
355     ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
356  done:
357     ret = WinHttpCloseHandle(connection);
358     ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
359     ret = WinHttpCloseHandle(session);
360     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
361 }
362
363 static void test_WinHttpTimeFromSystemTime(void)
364 {
365     BOOL ret;
366     static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
367     static const WCHAR expected_string[] =
368         {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
369          '1','0',':','0','5',':','5','2',' ','G','M','T',0};
370     WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
371
372     ret = WinHttpTimeFromSystemTime(&time, time_string);
373     ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
374     ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
375         "Time string returned did not match expected time string.\n");
376 }
377
378 static void test_WinHttpTimeToSystemTime(void)
379 {
380     BOOL ret;
381     SYSTEMTIME time;
382     static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
383     static const WCHAR time_string1[] =
384         {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
385          +          '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
386     static const WCHAR time_string2[] =
387         {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
388          '1','0',' ','0','5',' ','5','2','\n',0};
389
390     ret = WinHttpTimeToSystemTime(time_string1, &time);
391     ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
392     ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
393         "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
394
395     ret = WinHttpTimeToSystemTime(time_string2, &time);
396     ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
397     ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
398         "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
399 }
400
401 static void test_WinHttpAddHeaders(void)
402 {
403     HINTERNET session, request, connection;
404     BOOL ret, reverse;
405     WCHAR buffer[MAX_PATH];
406     WCHAR check_buffer[MAX_PATH];
407     DWORD index, len, oldlen;
408
409     static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
410                                 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
411     static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
412     static const WCHAR test_verb[] = {'P','O','S','T',0};
413
414     static const WCHAR test_header_begin[] =
415         {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
416     static const WCHAR full_path_test_header_begin[] =
417         {'P','O','S','T',' ','h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',':','8','0','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
418     static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
419     static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
420
421     static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
422     static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
423     static const WCHAR test_flag_coalesce_comma[] =
424         {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
425     static const WCHAR test_flag_coalesce_comma_reverse[] =
426         {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
427     static const WCHAR test_flag_coalesce_semicolon[] =
428         {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429     static const WCHAR test_flag_coalesce_semicolon_reverse[] =
430         {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
431
432     static const WCHAR field[] = {'f','i','e','l','d',0};
433     static const WCHAR value[] = {'v','a','l','u','e',' ',0};
434     static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
435
436     static const WCHAR test_headers[][14] =
437         {
438             {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
439             {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
440             {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
441             {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
442             {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
443             {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
444             {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
445             {0},
446             {':',0},
447             {'a',':',0},
448             {':','b',0},
449             {'c','d',0},
450             {' ','e',' ',':','f',0},
451             {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
452         };
453     static const WCHAR test_indices[][6] =
454         {
455             {'t','e','s','t','1',0},
456             {'t','e','s','t','2',0},
457             {'t','e','s','t','3',0},
458             {'t','e','s','t','4',0}
459         };
460
461     session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
462         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
463     ok(session != NULL, "WinHttpOpen failed to open session.\n");
464
465     connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
466     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
467
468     request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
469         WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
470     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
471     {
472         skip("Network unreachable, skipping.\n");
473         goto done;
474     }
475     ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
476
477     index = 0;
478     len = sizeof(buffer);
479     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
480         test_header_name, buffer, &len, &index);
481     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
482     ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
483     ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
484
485     index = 0;
486     len = sizeof(buffer);
487     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
488         test_header_name, buffer, &len, &index);
489     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
490     ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
491     ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
492     ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
493
494     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
495         test_header_name, buffer, &len, &index);
496     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
497
498     /* Try to fetch the header info with a buffer that's big enough to fit the
499      * string but not the NULL terminator.
500      */
501     index = 0;
502     len = 5*sizeof(WCHAR);
503     memset(check_buffer, 0xab, sizeof(check_buffer));
504     memcpy(buffer, check_buffer, sizeof(buffer));
505     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
506         test_header_name, buffer, &len, &index);
507     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
508     ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
509             "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
510     ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
511
512     /* Try with a NULL buffer */
513     index = 0;
514     len = sizeof(buffer);
515     SetLastError(0xdeadbeef);
516     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
517         test_header_name, NULL, &len, &index);
518     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
520     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
521     ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
522
523     /* Try with a NULL buffer and a length that's too small */
524     index = 0;
525     len = 10;
526     SetLastError(0xdeadbeef);
527     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
528         test_header_name, NULL, &len, &index);
529     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
530     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
531         "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
532     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
533     ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
534
535     index = 0;
536     len = 0;
537     SetLastError(0xdeadbeef);
538     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
539         test_header_name, NULL, &len, &index);
540     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
541     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
542         "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
543     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
544     ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
545
546     /* valid query */
547     oldlen = len;
548     index = 0;
549     len = sizeof(buffer);
550     memset(buffer, 0xff, sizeof(buffer));
551     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
552         test_header_name, buffer, &len, &index);
553     ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
554     ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
555     ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
556     ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
557     ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
558         memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
559         "WinHttpQueryHeaders returned invalid beginning of header string.\n");
560     ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
561         "WinHttpQueryHeaders returned invalid end of header string.\n");
562     ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
563
564     index = 0;
565     len = 0;
566     SetLastError(0xdeadbeef);
567     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
568         test_header_name, NULL, &len, &index);
569     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
570     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
571         "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
572     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
573     ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
574
575     oldlen = len;
576     index = 0;
577     len = sizeof(buffer);
578     memset(buffer, 0xff, sizeof(buffer));
579     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
580         test_header_name, buffer, &len, &index);
581     ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
582     ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
583     ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
584         "no double NULL terminator\n");
585     ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
586         memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
587         "invalid beginning of header string.\n");
588     ok(index == 0, "header index was incremented\n");
589
590     /* tests for more indices */
591     ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
592     ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
593
594     index = 0;
595     len = sizeof(buffer);
596     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
597         test_header_name, buffer, &len, &index);
598     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
599     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
600     ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
601
602     len = sizeof(buffer);
603     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
604         test_header_name, buffer, &len, &index);
605     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
606     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
607     ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
608
609     ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
610     ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
611
612     index = 0;
613     len = sizeof(buffer);
614     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
615         test_header_name, buffer, &len, &index);
616     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
617     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
618     reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
619     ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
620
621     len = sizeof(buffer);
622     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
623         test_header_name, buffer, &len, &index);
624     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
625     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
626     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
627
628     /* add if new flag */
629     ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
630     ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
631
632     index = 0;
633     len = sizeof(buffer);
634     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
635         test_header_name, buffer, &len, &index);
636     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
637     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
638     ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
639
640     len = sizeof(buffer);
641     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
642         test_header_name, buffer, &len, &index);
643     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
644     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
645     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
646
647     len = sizeof(buffer);
648     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
649         test_header_name, buffer, &len, &index);
650     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
651
652     /* coalesce flag */
653     ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
654     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
655
656     index = 0;
657     len = sizeof(buffer);
658     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
659         test_header_name, buffer, &len, &index);
660     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
661     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
662     ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce, sizeof(reverse ? test_flag_coalesce_reverse : test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
663
664     len = sizeof(buffer);
665     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
666         test_header_name, buffer, &len, &index);
667     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
668     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
669     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
670
671     len = sizeof(buffer);
672     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
673         test_header_name, buffer, &len, &index);
674     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
675
676     /* coalesce with comma flag */
677     ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
678     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
679
680     index = 0;
681     len = sizeof(buffer);
682     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
683         test_header_name, buffer, &len, &index);
684     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
685     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
686     ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma, sizeof(reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma)) == 0,
687         "WinHttpQueryHeaders returned incorrect string.\n");
688
689     len = sizeof(buffer);
690     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
691         test_header_name, buffer, &len, &index);
692     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
693     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
694     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
695
696     len = sizeof(buffer);
697     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
698         test_header_name, buffer, &len, &index);
699     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
700
701
702     /* coalesce with semicolon flag */
703     ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
704     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
705
706     index = 0;
707     len = sizeof(buffer);
708     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
709         test_header_name, buffer, &len, &index);
710     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
711     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
712     ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon, sizeof(reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon)) == 0,
713             "WinHttpQueryHeaders returned incorrect string.\n");
714
715     len = sizeof(buffer);
716     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
717         test_header_name, buffer, &len, &index);
718     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
719     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
720     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
721
722     len = sizeof(buffer);
723     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
724         test_header_name, buffer, &len, &index);
725     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
726
727     /* add and replace flags */
728     ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
729     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
730
731     index = 0;
732     len = sizeof(buffer);
733     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
734         test_header_name, buffer, &len, &index);
735     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
736     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
737     ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
738
739     len = sizeof(buffer);
740     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
741         test_header_name, buffer, &len, &index);
742     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
743     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
744     ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
745
746     len = sizeof(buffer);
747     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
748         test_header_name, buffer, &len, &index);
749     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
750
751     ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
752     ok(!ret, "WinHttpAddRequestHeaders failed\n");
753
754     ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
755     ok(ret, "WinHttpAddRequestHeaders failed\n");
756
757     ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
758     ok(!ret, "WinHttpAddRequestHeaders failed\n");
759
760     ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
761     ok(!ret, "WinHttpAddRequestHeaders failed\n");
762
763     ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
764     ok(!ret, "WinHttpAddRequestHeaders failed\n");
765
766     ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
767     ok(ret, "WinHttpAddRequestHeaders failed\n");
768
769     index = 0;
770     buffer[0] = 0;
771     len = sizeof(buffer);
772     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
773         field, buffer, &len, &index);
774     ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
775     ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
776
777     ret = WinHttpCloseHandle(request);
778     ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
779  done:
780     ret = WinHttpCloseHandle(connection);
781     ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
782     ret = WinHttpCloseHandle(session);
783     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
784
785 }
786
787 static void test_secure_connection(void)
788 {
789     static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
790
791     HINTERNET ses, con, req;
792     DWORD size, status, policy, bitness;
793     BOOL ret;
794     CERT_CONTEXT *cert;
795     WINHTTP_CERTIFICATE_INFO info;
796     char buffer[32];
797
798     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
799     ok(ses != NULL, "failed to open session %u\n", GetLastError());
800
801     policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
802     ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
803     ok(ret, "failed to set redirect policy %u\n", GetLastError());
804
805     con = WinHttpConnect(ses, google, 443, 0);
806     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
807
808     /* try without setting WINHTTP_FLAG_SECURE */
809     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
810     ok(req != NULL, "failed to open a request %u\n", GetLastError());
811
812     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
813     if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
814     {
815         skip("Connection failed, skipping.\n");
816         goto cleanup;
817     }
818     ok(ret, "failed to send request %u\n", GetLastError());
819
820     ret = WinHttpReceiveResponse(req, NULL);
821     ok(!ret || proxy_active(), "succeeded unexpectedly\n");
822
823     size = 0;
824     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
825     ok(!ret, "succeeded unexpectedly\n");
826
827     WinHttpCloseHandle(req);
828
829     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
830     ok(req != NULL, "failed to open a request %u\n", GetLastError());
831
832     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
833     ok(ret, "failed to send request %u\n", GetLastError());
834     if (!ret)
835     {
836         skip("secure connection failed, skipping remaining secure tests\n");
837         goto cleanup;
838     }
839
840     size = sizeof(cert);
841     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
842     ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
843     if (ret)
844         CertFreeCertificateContext(cert);
845
846     size = sizeof(bitness);
847     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
848     ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
849
850     size = sizeof(info);
851     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
852     ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
853
854     trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
855     trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
856     trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
857     trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
858     trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
859     trace("dwKeySize %u\n", info.dwKeySize);
860
861     ret = WinHttpReceiveResponse(req, NULL);
862     ok(ret, "failed to receive response %u\n", GetLastError());
863
864     size = sizeof(status);
865     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
866     ok(ret, "failed unexpectedly %u\n", GetLastError());
867     ok(status == 200, "request failed unexpectedly %u\n", status);
868
869     size = 0;
870     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
871     ok(!ret, "succeeded unexpectedly\n");
872
873     for (;;)
874     {
875         size = 0;
876         ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
877         ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
878         if (!size) break;
879     }
880
881 cleanup:
882     WinHttpCloseHandle(req);
883     WinHttpCloseHandle(con);
884     WinHttpCloseHandle(ses);
885 }
886
887 static void test_request_parameter_defaults(void)
888 {
889     static const WCHAR empty[] = {0};
890     static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
891
892     HINTERNET ses, con, req;
893     DWORD size, status, error;
894     WCHAR *version;
895     BOOL ret;
896
897     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
898     ok(ses != NULL, "failed to open session %u\n", GetLastError());
899
900     con = WinHttpConnect(ses, codeweavers, 0, 0);
901     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
902
903     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
904     ok(req != NULL, "failed to open a request %u\n", GetLastError());
905
906     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
907     ok(ret, "failed to send request %u\n", GetLastError());
908
909     ret = WinHttpReceiveResponse(req, NULL);
910     ok(ret, "failed to receive response %u\n", GetLastError());
911
912     size = sizeof(status);
913     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
914     ok(ret, "failed unexpectedly %u\n", GetLastError());
915     ok(status == 200, "request failed unexpectedly %u\n", status);
916
917     WinHttpCloseHandle(req);
918
919     req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
920     ok(req != NULL, "failed to open a request %u\n", GetLastError());
921
922     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
923     ok(ret, "failed to send request %u\n", GetLastError());
924
925     ret = WinHttpReceiveResponse(req, NULL);
926     ok(ret, "failed to receive response %u\n", GetLastError());
927
928     size = 0;
929     SetLastError(0xdeadbeef);
930     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
931     error = GetLastError();
932     ok(!ret, "succeeded unexpectedly\n");
933     ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
934
935     version = HeapAlloc(GetProcessHeap(), 0, size);
936     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
937     ok(ret, "failed unexpectedly %u\n", GetLastError());
938     ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
939     HeapFree(GetProcessHeap(), 0, version);
940
941     size = sizeof(status);
942     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
943     ok(ret, "failed unexpectedly %u\n", GetLastError());
944     ok(status == 200, "request failed unexpectedly %u\n", status);
945
946     WinHttpCloseHandle(req);
947     WinHttpCloseHandle(con);
948     WinHttpCloseHandle(ses);
949 }
950
951 static const WCHAR Connections[] = {
952     'S','o','f','t','w','a','r','e','\\',
953     'M','i','c','r','o','s','o','f','t','\\',
954     'W','i','n','d','o','w','s','\\',
955     'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
956     'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
957     'C','o','n','n','e','c','t','i','o','n','s',0 };
958 static const WCHAR WinHttpSettings[] = {
959     'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
960
961 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
962 {
963     LONG l;
964     HKEY key;
965     DWORD ret = 0;
966
967     l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
968     if (!l)
969     {
970         DWORD size = 0;
971
972         l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
973         if (!l)
974         {
975             if (size <= len)
976                 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
977                     &size );
978             if (!l)
979                 ret = size;
980         }
981         RegCloseKey( key );
982     }
983     return ret;
984 }
985
986 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
987 {
988     LONG l;
989     HKEY key;
990
991     l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
992         KEY_WRITE, NULL, &key, NULL );
993     if (!l)
994     {
995         if (len)
996             RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
997         else
998             RegDeleteValueW( key, WinHttpSettings );
999         RegCloseKey( key );
1000     }
1001 }
1002
1003 static void test_set_default_proxy_config(void)
1004 {
1005     static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1006     static const WCHAR normalString[] = { 'f','o','o',0 };
1007     DWORD type, len;
1008     BYTE *saved_proxy_settings = NULL;
1009     WINHTTP_PROXY_INFO info;
1010     BOOL ret;
1011
1012     /* FIXME: it would be simpler to read the current settings using
1013      * WinHttpGetDefaultProxyConfiguration and save them using
1014      * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1015      *
1016      * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1017      * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1018      * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1019      * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1020      * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1021      * the lpszProxy and lpszProxyBypass values are ignored.
1022      * Thus, if a proxy is set with proxycfg, then calling
1023      * WinHttpGetDefaultProxyConfiguration followed by
1024      * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1025      * getting deleted from the registry.
1026      *
1027      * Instead I read the current registry value and restore it directly.
1028      */
1029     len = get_default_proxy_reg_value( NULL, 0, &type );
1030     if (len)
1031     {
1032         saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1033         len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1034     }
1035
1036     if (0)
1037     {
1038         /* Crashes on Vista and higher */
1039         SetLastError(0xdeadbeef);
1040         ret = WinHttpSetDefaultProxyConfiguration(NULL);
1041         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1042             "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1043     }
1044
1045     /* test with invalid access type */
1046     info.dwAccessType = 0xdeadbeef;
1047     info.lpszProxy = info.lpszProxyBypass = NULL;
1048     SetLastError(0xdeadbeef);
1049     ret = WinHttpSetDefaultProxyConfiguration(&info);
1050     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1051         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1052
1053     /* at a minimum, the proxy server must be set */
1054     info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1055     info.lpszProxy = info.lpszProxyBypass = NULL;
1056     SetLastError(0xdeadbeef);
1057     ret = WinHttpSetDefaultProxyConfiguration(&info);
1058     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1059         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1060     info.lpszProxyBypass = normalString;
1061     SetLastError(0xdeadbeef);
1062     ret = WinHttpSetDefaultProxyConfiguration(&info);
1063     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1064         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1065
1066     /* the proxy server can't have wide characters */
1067     info.lpszProxy = wideString;
1068     SetLastError(0xdeadbeef);
1069     ret = WinHttpSetDefaultProxyConfiguration(&info);
1070     ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1071         broken(ret), /* Earlier winhttp versions on W2K/XP */
1072         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1073
1074     info.lpszProxy = normalString;
1075     SetLastError(0xdeadbeef);
1076     ret = WinHttpSetDefaultProxyConfiguration(&info);
1077     if (ret)
1078     {
1079         ok(ret, "always true\n");
1080         set_default_proxy_reg_value( saved_proxy_settings, len, type );
1081     }
1082     else if (GetLastError() == ERROR_ACCESS_DENIED)
1083         skip("couldn't set default proxy configuration: access denied\n");
1084     else
1085         ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1086            GetLastError());
1087 }
1088
1089 static void test_Timeouts (void)
1090 {
1091     BOOL ret;
1092     DWORD value, size;
1093     HINTERNET ses, req, con;
1094     static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1095
1096
1097     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1098     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1099
1100     SetLastError(0xdeadbeef);
1101     ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1102     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1103        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1104
1105     SetLastError(0xdeadbeef);
1106     ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1107     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1108        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1109
1110     SetLastError(0xdeadbeef);
1111     ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1112     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1113        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1114
1115     SetLastError(0xdeadbeef);
1116     ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1117     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1118        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1119
1120     SetLastError(0xdeadbeef);
1121     ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1122     ok(ret, "%u\n", GetLastError());
1123
1124     SetLastError(0xdeadbeef);
1125     ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1126     ok(ret, "%u\n", GetLastError());
1127
1128     SetLastError(0xdeadbeef);
1129     ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1130     ok(ret, "%u\n", GetLastError());
1131
1132     SetLastError(0xdeadbeef);
1133     value = 0xdeadbeef;
1134     size  = sizeof(DWORD);
1135     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1136     ok(ret, "%u\n", GetLastError());
1137     ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1138
1139     SetLastError(0xdeadbeef);
1140     value = 0xdeadbeef;
1141     size  = sizeof(DWORD);
1142     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1143     ok(ret, "%u\n", GetLastError());
1144     ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1145
1146     SetLastError(0xdeadbeef);
1147     value = 0xdeadbeef;
1148     size  = sizeof(DWORD);
1149     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1150     ok(ret, "%u\n", GetLastError());
1151     ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1152
1153     SetLastError(0xdeadbeef);
1154     value = 0xdeadbeef;
1155     size  = sizeof(DWORD);
1156     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1157     ok(ret, "%u\n", GetLastError());
1158     ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1159
1160     SetLastError(0xdeadbeef);
1161     value = 0;
1162     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1163     ok(ret, "%u\n", GetLastError());
1164
1165     SetLastError(0xdeadbeef);
1166     value = 0xdeadbeef;
1167     size  = sizeof(DWORD);
1168     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1169     ok(ret, "%u\n", GetLastError());
1170     ok(value == 0, "Expected 0, got %u\n", value);
1171
1172     SetLastError(0xdeadbeef);
1173     value = 0;
1174     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1175     ok(ret, "%u\n", GetLastError());
1176
1177     SetLastError(0xdeadbeef);
1178     value = 0xdeadbeef;
1179     size  = sizeof(DWORD);
1180     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1181     ok(ret, "%u\n", GetLastError());
1182     ok(value == 0, "Expected 0, got %u\n", value);
1183
1184     SetLastError(0xdeadbeef);
1185     value = 0;
1186     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1187     ok(ret, "%u\n", GetLastError());
1188
1189     SetLastError(0xdeadbeef);
1190     value = 0xdeadbeef;
1191     size  = sizeof(DWORD);
1192     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1193     ok(ret, "%u\n", GetLastError());
1194     ok(value == 0, "Expected 0, got %u\n", value);
1195
1196     SetLastError(0xdeadbeef);
1197     value = 0;
1198     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1199     ok(ret, "%u\n", GetLastError());
1200
1201     SetLastError(0xdeadbeef);
1202     value = 0xdeadbeef;
1203     size  = sizeof(DWORD);
1204     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1205     ok(ret, "%u\n", GetLastError());
1206     ok(value == 0, "Expected 0, got %u\n", value);
1207
1208     SetLastError(0xdeadbeef);
1209     value = 0xbeefdead;
1210     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1211     ok(ret, "%u\n", GetLastError());
1212
1213     SetLastError(0xdeadbeef);
1214     value = 0xdeadbeef;
1215     size  = sizeof(DWORD);
1216     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1217     ok(ret, "%u\n", GetLastError());
1218     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1219
1220     SetLastError(0xdeadbeef);
1221     value = 0xbeefdead;
1222     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1223     ok(ret, "%u\n", GetLastError());
1224
1225     SetLastError(0xdeadbeef);
1226     value = 0xdeadbeef;
1227     size  = sizeof(DWORD);
1228     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1229     ok(ret, "%u\n", GetLastError());
1230     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1231
1232     SetLastError(0xdeadbeef);
1233     value = 0xbeefdead;
1234     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1235     ok(ret, "%u\n", GetLastError());
1236
1237     SetLastError(0xdeadbeef);
1238     value = 0xdeadbeef;
1239     size  = sizeof(DWORD);
1240     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1241     ok(ret, "%u\n", GetLastError());
1242     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1243
1244     SetLastError(0xdeadbeef);
1245     value = 0xbeefdead;
1246     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1247     ok(ret, "%u\n", GetLastError());
1248
1249     SetLastError(0xdeadbeef);
1250     value = 0xdeadbeef;
1251     size  = sizeof(DWORD);
1252     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1253     ok(ret, "%u\n", GetLastError());
1254     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1255
1256     con = WinHttpConnect(ses, codeweavers, 0, 0);
1257     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1258
1259     /* Timeout values should match the last one set for session */
1260     SetLastError(0xdeadbeef);
1261     value = 0xdeadbeef;
1262     size  = sizeof(DWORD);
1263     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1264     ok(ret, "%u\n", GetLastError());
1265     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1266
1267     SetLastError(0xdeadbeef);
1268     value = 0xdeadbeef;
1269     size  = sizeof(DWORD);
1270     ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1271     ok(ret, "%u\n", GetLastError());
1272     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1273
1274     SetLastError(0xdeadbeef);
1275     value = 0xdeadbeef;
1276     size  = sizeof(DWORD);
1277     ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1278     ok(ret, "%u\n", GetLastError());
1279     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1280
1281     SetLastError(0xdeadbeef);
1282     value = 0xdeadbeef;
1283     size  = sizeof(DWORD);
1284     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1285     ok(ret, "%u\n", GetLastError());
1286     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1287
1288     SetLastError(0xdeadbeef);
1289     ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1290     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1291        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1292
1293     SetLastError(0xdeadbeef);
1294     ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1295     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1296        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1297
1298     SetLastError(0xdeadbeef);
1299     ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1300     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1301        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1302
1303     SetLastError(0xdeadbeef);
1304     ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1305     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1306        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1307
1308     SetLastError(0xdeadbeef);
1309     ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1310     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1311        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1312
1313     SetLastError(0xdeadbeef);
1314     ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1315     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1316        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1317
1318     SetLastError(0xdeadbeef);
1319     value = 0;
1320     ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1321     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1322        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1323
1324     SetLastError(0xdeadbeef);
1325     value = 0;
1326     ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1327     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1328        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1329
1330     SetLastError(0xdeadbeef);
1331     value = 0;
1332     ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1333     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1334        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1335
1336     SetLastError(0xdeadbeef);
1337     value = 0;
1338     ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1339     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1340        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1341
1342     /* Changing timeout values for session should affect the values for connection */
1343     SetLastError(0xdeadbeef);
1344     value = 0xdead;
1345     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1346     ok(ret, "%u\n", GetLastError());
1347
1348     SetLastError(0xdeadbeef);
1349     value = 0xdeadbeef;
1350     size  = sizeof(DWORD);
1351     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1352     ok(ret, "%u\n", GetLastError());
1353     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1354
1355     SetLastError(0xdeadbeef);
1356     value = 0xdead;
1357     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1358     ok(ret, "%u\n", GetLastError());
1359
1360     SetLastError(0xdeadbeef);
1361     value = 0xdeadbeef;
1362     size  = sizeof(DWORD);
1363     ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1364     ok(ret, "%u\n", GetLastError());
1365     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1366
1367     SetLastError(0xdeadbeef);
1368     value = 0xdead;
1369     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1370     ok(ret, "%u\n", GetLastError());
1371
1372     SetLastError(0xdeadbeef);
1373     value = 0xdeadbeef;
1374     size  = sizeof(DWORD);
1375     ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1376     ok(ret, "%u\n", GetLastError());
1377     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1378
1379     SetLastError(0xdeadbeef);
1380     value = 0xdead;
1381     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1382     ok(ret, "%u\n", GetLastError());
1383
1384     SetLastError(0xdeadbeef);
1385     value = 0xdeadbeef;
1386     size  = sizeof(DWORD);
1387     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1388     ok(ret, "%u\n", GetLastError());
1389     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1390
1391     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1392     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1393
1394     /* Timeout values should match the last one set for session */
1395     SetLastError(0xdeadbeef);
1396     value = 0xdeadbeef;
1397     size  = sizeof(DWORD);
1398     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1399     ok(ret, "%u\n", GetLastError());
1400     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1401
1402     SetLastError(0xdeadbeef);
1403     value = 0xdeadbeef;
1404     size  = sizeof(DWORD);
1405     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1406     ok(ret, "%u\n", GetLastError());
1407     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1408
1409     SetLastError(0xdeadbeef);
1410     value = 0xdeadbeef;
1411     size  = sizeof(DWORD);
1412     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1413     ok(ret, "%u\n", GetLastError());
1414     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1415
1416     SetLastError(0xdeadbeef);
1417     value = 0xdeadbeef;
1418     size  = sizeof(DWORD);
1419     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1420     ok(ret, "%u\n", GetLastError());
1421     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1422
1423     SetLastError(0xdeadbeef);
1424     ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1425     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1426        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1427
1428     SetLastError(0xdeadbeef);
1429     ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1430     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1431        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1432
1433     SetLastError(0xdeadbeef);
1434     ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1435     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1436        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1437
1438     SetLastError(0xdeadbeef);
1439     ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1440     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1441        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1442
1443     SetLastError(0xdeadbeef);
1444     ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1445     ok(ret, "%u\n", GetLastError());
1446
1447     SetLastError(0xdeadbeef);
1448     ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1449     ok(ret, "%u\n", GetLastError());
1450
1451     SetLastError(0xdeadbeef);
1452     ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1453     ok(ret, "%u\n", GetLastError());
1454
1455     SetLastError(0xdeadbeef);
1456     value = 0xdeadbeef;
1457     size  = sizeof(DWORD);
1458     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1459     ok(ret, "%u\n", GetLastError());
1460     ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1461
1462     SetLastError(0xdeadbeef);
1463     value = 0xdeadbeef;
1464     size  = sizeof(DWORD);
1465     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1466     ok(ret, "%u\n", GetLastError());
1467     ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1468
1469     SetLastError(0xdeadbeef);
1470     value = 0xdeadbeef;
1471     size  = sizeof(DWORD);
1472     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1473     ok(ret, "%u\n", GetLastError());
1474     ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1475
1476     SetLastError(0xdeadbeef);
1477     value = 0xdeadbeef;
1478     size  = sizeof(DWORD);
1479     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1480     ok(ret, "%u\n", GetLastError());
1481     ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1482
1483     SetLastError(0xdeadbeef);
1484     value = 0;
1485     ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1486     ok(ret, "%u\n", GetLastError());
1487
1488     SetLastError(0xdeadbeef);
1489     value = 0xdeadbeef;
1490     size  = sizeof(DWORD);
1491     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1492     ok(ret, "%u\n", GetLastError());
1493     ok(value == 0, "Expected 0, got %u\n", value);
1494
1495     SetLastError(0xdeadbeef);
1496     value = 0;
1497     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1498     ok(ret, "%u\n", GetLastError());
1499
1500     SetLastError(0xdeadbeef);
1501     value = 0xdeadbeef;
1502     size  = sizeof(DWORD);
1503     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1504     ok(ret, "%u\n", GetLastError());
1505     ok(value == 0, "Expected 0, got %u\n", value);
1506
1507     SetLastError(0xdeadbeef);
1508     value = 0;
1509     ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1510     ok(ret, "%u\n", GetLastError());
1511
1512     SetLastError(0xdeadbeef);
1513     value = 0xdeadbeef;
1514     size  = sizeof(DWORD);
1515     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1516     ok(ret, "%u\n", GetLastError());
1517     ok(value == 0, "Expected 0, got %u\n", value);
1518
1519     SetLastError(0xdeadbeef);
1520     value = 0;
1521     ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1522     ok(ret, "%u\n", GetLastError());
1523
1524     SetLastError(0xdeadbeef);
1525     value = 0xdeadbeef;
1526     size  = sizeof(DWORD);
1527     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1528     ok(ret, "%u\n", GetLastError());
1529     ok(value == 0, "Expected 0, got %u\n", value);
1530
1531     SetLastError(0xdeadbeef);
1532     value = 0xbeefdead;
1533     ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1534     ok(ret, "%u\n", GetLastError());
1535
1536     SetLastError(0xdeadbeef);
1537     value = 0xdeadbeef;
1538     size  = sizeof(DWORD);
1539     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1540     ok(ret, "%u\n", GetLastError());
1541     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1542
1543     SetLastError(0xdeadbeef);
1544     value = 0xbeefdead;
1545     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1546     ok(ret, "%u\n", GetLastError());
1547
1548     SetLastError(0xdeadbeef);
1549     value = 0xdeadbeef;
1550     size  = sizeof(DWORD);
1551     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1552     ok(ret, "%u\n", GetLastError());
1553     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1554
1555     SetLastError(0xdeadbeef);
1556     value = 0xbeefdead;
1557     ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1558     ok(ret, "%u\n", GetLastError());
1559
1560     SetLastError(0xdeadbeef);
1561     value = 0xdeadbeef;
1562     size  = sizeof(DWORD);
1563     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1564     ok(ret, "%u\n", GetLastError());
1565     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1566
1567     SetLastError(0xdeadbeef);
1568     value = 0xbeefdead;
1569     ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1570     ok(ret, "%u\n", GetLastError());
1571
1572     SetLastError(0xdeadbeef);
1573     value = 0xdeadbeef;
1574     size  = sizeof(DWORD);
1575     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1576     ok(ret, "%u\n", GetLastError());
1577     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1578
1579     /* Changing timeout values for session should not affect the values for a request,
1580      * neither should the other way around.
1581      */
1582     SetLastError(0xdeadbeef);
1583     value = 0xbeefdead;
1584     ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1585     ok(ret, "%u\n", GetLastError());
1586
1587     SetLastError(0xdeadbeef);
1588     value = 0xdeadbeef;
1589     size  = sizeof(DWORD);
1590     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1591     ok(ret, "%u\n", GetLastError());
1592     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1593
1594     SetLastError(0xdeadbeef);
1595     value = 0xbeefdead;
1596     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1597     ok(ret, "%u\n", GetLastError());
1598
1599     SetLastError(0xdeadbeef);
1600     value = 0xdeadbeef;
1601     size  = sizeof(DWORD);
1602     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1603     ok(ret, "%u\n", GetLastError());
1604     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1605
1606     SetLastError(0xdeadbeef);
1607     value = 0xbeefdead;
1608     ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1609     ok(ret, "%u\n", GetLastError());
1610
1611     SetLastError(0xdeadbeef);
1612     value = 0xdeadbeef;
1613     size  = sizeof(DWORD);
1614     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1615     ok(ret, "%u\n", GetLastError());
1616     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1617
1618     SetLastError(0xdeadbeef);
1619     value = 0xbeefdead;
1620     ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1621     ok(ret, "%u\n", GetLastError());
1622
1623     SetLastError(0xdeadbeef);
1624     value = 0xdeadbeef;
1625     size  = sizeof(DWORD);
1626     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1627     ok(ret, "%u\n", GetLastError());
1628     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1629
1630     SetLastError(0xdeadbeef);
1631     value = 0xbeef;
1632     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1633     ok(ret, "%u\n", GetLastError());
1634
1635     SetLastError(0xdeadbeef);
1636     value = 0xdeadbeef;
1637     size  = sizeof(DWORD);
1638     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1639     ok(ret, "%u\n", GetLastError());
1640     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1641
1642     SetLastError(0xdeadbeef);
1643     value = 0xbeef;
1644     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1645     ok(ret, "%u\n", GetLastError());
1646
1647     SetLastError(0xdeadbeef);
1648     value = 0xdeadbeef;
1649     size  = sizeof(DWORD);
1650     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1651     ok(ret, "%u\n", GetLastError());
1652     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1653
1654     SetLastError(0xdeadbeef);
1655     value = 0xbeef;
1656     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1657     ok(ret, "%u\n", GetLastError());
1658
1659     SetLastError(0xdeadbeef);
1660     value = 0xdeadbeef;
1661     size  = sizeof(DWORD);
1662     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1663     ok(ret, "%u\n", GetLastError());
1664     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1665
1666     SetLastError(0xdeadbeef);
1667     value = 0xbeef;
1668     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1669     ok(ret, "%u\n", GetLastError());
1670
1671     SetLastError(0xdeadbeef);
1672     value = 0xdeadbeef;
1673     size  = sizeof(DWORD);
1674     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1675     ok(ret, "%u\n", GetLastError());
1676     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1677
1678     WinHttpCloseHandle(req);
1679     WinHttpCloseHandle(con);
1680     WinHttpCloseHandle(ses);
1681 }
1682
1683 static void test_resolve_timeout(void)
1684 {
1685     static const WCHAR codeweavers[] =
1686         {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1687     static const WCHAR nxdomain[] =
1688         {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1689
1690     HINTERNET ses, con, req;
1691     DWORD timeout;
1692     BOOL ret;
1693
1694     if (! proxy_active())
1695     {
1696         ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1697         ok(ses != NULL, "failed to open session %u\n", GetLastError());
1698
1699         timeout = 10000;
1700         ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1701         ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1702
1703         con = WinHttpConnect(ses, nxdomain, 0, 0);
1704         ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1705
1706         req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1707         ok(req != NULL, "failed to open a request %u\n", GetLastError());
1708
1709         SetLastError(0xdeadbeef);
1710         ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1711         ok(!ret, "sent request\n");
1712         ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1713            "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1714
1715         WinHttpCloseHandle(req);
1716         WinHttpCloseHandle(con);
1717         WinHttpCloseHandle(ses);
1718     }
1719     else
1720        skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1721
1722     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1723     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1724
1725     timeout = 10000;
1726     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1727     ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1728
1729     con = WinHttpConnect(ses, codeweavers, 0, 0);
1730     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1731
1732     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1733     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1734
1735     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1736     ok(ret, "failed to send request\n");
1737
1738     WinHttpCloseHandle(req);
1739     WinHttpCloseHandle(con);
1740     WinHttpCloseHandle(ses);
1741 }
1742
1743 static const char page1[] =
1744 "<HTML>\r\n"
1745 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1746 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1747 "</HTML>\r\n\r\n";
1748
1749 static const char okmsg[] =
1750 "HTTP/1.1 200 OK\r\n"
1751 "Server: winetest\r\n"
1752 "\r\n";
1753
1754 static const char notokmsg[] =
1755 "HTTP/1.1 400 Bad Request\r\n"
1756 "Server: winetest\r\n"
1757 "\r\n";
1758
1759 static const char noauthmsg[] =
1760 "HTTP/1.1 401 Unauthorized\r\n"
1761 "Server: winetest\r\n"
1762 "Connection: close\r\n"
1763 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1764 "\r\n";
1765
1766 static const char proxymsg[] =
1767 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1768 "Server: winetest\r\n"
1769 "Proxy-Connection: close\r\n"
1770 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1771 "\r\n";
1772
1773 struct server_info
1774 {
1775     HANDLE event;
1776     int port;
1777 };
1778
1779 static DWORD CALLBACK server_thread(LPVOID param)
1780 {
1781     struct server_info *si = param;
1782     int r, c, i, on;
1783     SOCKET s;
1784     struct sockaddr_in sa;
1785     char buffer[0x100];
1786     WSADATA wsaData;
1787     int last_request = 0;
1788
1789     WSAStartup(MAKEWORD(1,1), &wsaData);
1790
1791     s = socket(AF_INET, SOCK_STREAM, 0);
1792     if (s == INVALID_SOCKET)
1793         return 1;
1794
1795     on = 1;
1796     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1797
1798     memset(&sa, 0, sizeof sa);
1799     sa.sin_family = AF_INET;
1800     sa.sin_port = htons(si->port);
1801     sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1802
1803     r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1804     if (r < 0)
1805         return 1;
1806
1807     listen(s, 0);
1808     SetEvent(si->event);
1809     do
1810     {
1811         c = accept(s, NULL, NULL);
1812
1813         memset(buffer, 0, sizeof buffer);
1814         for(i = 0; i < sizeof buffer - 1; i++)
1815         {
1816             r = recv(c, &buffer[i], 1, 0);
1817             if (r != 1)
1818                 break;
1819             if (i < 4) continue;
1820             if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1821                 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1822                 break;
1823         }
1824         if (strstr(buffer, "GET /basic"))
1825         {
1826             send(c, okmsg, sizeof okmsg - 1, 0);
1827             send(c, page1, sizeof page1 - 1, 0);
1828         }
1829         if (strstr(buffer, "/auth"))
1830         {
1831             if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1832                 send(c, okmsg, sizeof okmsg - 1, 0);
1833             else
1834                 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1835         }
1836         if (strstr(buffer, "/no_headers"))
1837         {
1838             send(c, page1, sizeof page1 - 1, 0);
1839         }
1840         if (strstr(buffer, "GET /quit"))
1841         {
1842             send(c, okmsg, sizeof okmsg - 1, 0);
1843             send(c, page1, sizeof page1 - 1, 0);
1844             last_request = 1;
1845         }
1846         shutdown(c, 2);
1847         closesocket(c);
1848
1849     } while (!last_request);
1850
1851     closesocket(s);
1852     return 0;
1853 }
1854
1855 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1856 {
1857     HINTERNET ses, con, req;
1858     char buffer[0x100];
1859     DWORD count, status, size;
1860     BOOL ret;
1861
1862     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1863     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1864
1865     con = WinHttpConnect(ses, localhostW, port, 0);
1866     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1867
1868     req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1869     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1870
1871     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1872     ok(ret, "failed to send request %u\n", GetLastError());
1873
1874     ret = WinHttpReceiveResponse(req, NULL);
1875     ok(ret, "failed to receive response %u\n", GetLastError());
1876
1877     size = sizeof(status);
1878     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1879     ok(ret, "failed to query status code %u\n", GetLastError());
1880     ok(status == 200, "request failed unexpectedly %u\n", status);
1881
1882     count = 0;
1883     memset(buffer, 0, sizeof(buffer));
1884     ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1885     ok(ret, "failed to read data %u\n", GetLastError());
1886     ok(count == sizeof page1 - 1, "count was wrong\n");
1887     ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1888
1889     WinHttpCloseHandle(req);
1890     WinHttpCloseHandle(con);
1891     WinHttpCloseHandle(ses);
1892 }
1893
1894 static void test_basic_authentication(int port)
1895 {
1896     static const WCHAR authW[] = {'/','a','u','t','h',0};
1897     static const WCHAR userW[] = {'u','s','e','r',0};
1898     static const WCHAR passW[] = {'p','w','d',0};
1899     HINTERNET ses, con, req;
1900     DWORD status, size, error;
1901     BOOL ret;
1902
1903     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1904     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1905
1906     con = WinHttpConnect(ses, localhostW, port, 0);
1907     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1908
1909     req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1910     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1911
1912     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1913     ok(ret, "failed to send request %u\n", GetLastError());
1914
1915     ret = WinHttpReceiveResponse(req, NULL);
1916     ok(ret, "failed to receive response %u\n", GetLastError());
1917
1918     size = sizeof(status);
1919     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1920     ok(ret, "failed to query status code %u\n", GetLastError());
1921     ok(status == 401, "request failed unexpectedly %u\n", status);
1922
1923     SetLastError(0xdeadbeef);
1924     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1925     error = GetLastError();
1926     ok(!ret, "expected failure\n");
1927     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1928
1929     SetLastError(0xdeadbeef);
1930     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1931     error = GetLastError();
1932     ok(!ret, "expected failure\n");
1933     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1934
1935     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1936     ok(ret, "failed to set credentials %u\n", GetLastError());
1937
1938     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1939     ok(ret, "failed to send request %u\n", GetLastError());
1940
1941     ret = WinHttpReceiveResponse(req, NULL);
1942     ok(ret, "failed to receive response %u\n", GetLastError());
1943
1944     size = sizeof(status);
1945     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1946     ok(ret, "failed to query status code %u\n", GetLastError());
1947     ok(status == 200, "request failed unexpectedly %u\n", status);
1948
1949     WinHttpCloseHandle(req);
1950     WinHttpCloseHandle(con);
1951     WinHttpCloseHandle(ses);
1952 }
1953
1954 static void test_no_headers(int port)
1955 {
1956     static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1957     HINTERNET ses, con, req;
1958     DWORD error;
1959     BOOL ret;
1960
1961     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1962     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1963
1964     con = WinHttpConnect(ses, localhostW, port, 0);
1965     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1966
1967     req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1968     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1969
1970     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1971     ok(ret, "failed to send request %u\n", GetLastError());
1972
1973     SetLastError(0xdeadbeef);
1974     ret = WinHttpReceiveResponse(req, NULL);
1975     error = GetLastError();
1976     ok(!ret, "expected failure\n");
1977     ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
1978
1979     WinHttpCloseHandle(req);
1980     WinHttpCloseHandle(con);
1981     WinHttpCloseHandle(ses);
1982 }
1983
1984 static void test_credentials(void)
1985 {
1986     static WCHAR userW[] = {'u','s','e','r',0};
1987     static WCHAR passW[] = {'p','a','s','s',0};
1988     static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
1989     static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
1990     HINTERNET ses, con, req;
1991     DWORD size, error;
1992     WCHAR buffer[32];
1993     BOOL ret;
1994
1995     ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
1996     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1997
1998     con = WinHttpConnect(ses, localhostW, 0, 0);
1999     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2000
2001     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2002     ok(req != NULL, "failed to open a request %u\n", GetLastError());
2003
2004     size = sizeof(buffer)/sizeof(WCHAR);
2005     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2006     ok(ret, "failed to query proxy username %u\n", GetLastError());
2007     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2008     ok(!size, "expected 0, got %u\n", size);
2009
2010     size = sizeof(buffer)/sizeof(WCHAR);
2011     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2012     ok(ret, "failed to query proxy password %u\n", GetLastError());
2013     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2014     ok(!size, "expected 0, got %u\n", size);
2015
2016     ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2017     ok(ret, "failed to set username %u\n", GetLastError());
2018
2019     size = sizeof(buffer)/sizeof(WCHAR);
2020     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2021     ok(ret, "failed to query proxy username %u\n", GetLastError());
2022     ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2023     ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2024
2025     size = sizeof(buffer)/sizeof(WCHAR);
2026     ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2027     ok(ret, "failed to query username %u\n", GetLastError());
2028     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2029     ok(!size, "expected 0, got %u\n", size);
2030
2031     size = sizeof(buffer)/sizeof(WCHAR);
2032     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2033     ok(ret, "failed to query password %u\n", GetLastError());
2034     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2035     ok(!size, "expected 0, got %u\n", size);
2036
2037     ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2038     ok(ret, "failed to set proxy password %u\n", GetLastError());
2039
2040     size = sizeof(buffer)/sizeof(WCHAR);
2041     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2042     ok(ret, "failed to query proxy password %u\n", GetLastError());
2043     ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2044     ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2045
2046     ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2047     ok(ret, "failed to set username %u\n", GetLastError());
2048
2049     size = sizeof(buffer)/sizeof(WCHAR);
2050     ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2051     ok(ret, "failed to query username %u\n", GetLastError());
2052     ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2053     ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2054
2055     ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2056     ok(ret, "failed to set password %u\n", GetLastError());
2057
2058     size = sizeof(buffer)/sizeof(WCHAR);
2059     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2060     ok(ret, "failed to query password %u\n", GetLastError());
2061     ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2062     ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2063
2064     WinHttpCloseHandle(req);
2065
2066     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2067     ok(req != NULL, "failed to open a request %u\n", GetLastError());
2068
2069     SetLastError(0xdeadbeef);
2070     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2071     error = GetLastError();
2072     ok(!ret, "expected failure\n");
2073     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2074
2075     SetLastError(0xdeadbeef);
2076     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2077     error = GetLastError();
2078     ok(!ret, "expected failure\n");
2079     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2080
2081     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2082     ok(ret, "failed to set credentials %u\n", GetLastError());
2083
2084     size = sizeof(buffer)/sizeof(WCHAR);
2085     ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2086     ok(ret, "failed to query username %u\n", GetLastError());
2087     todo_wine {
2088     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2089     ok(!size, "expected 0, got %u\n", size);
2090     }
2091
2092     size = sizeof(buffer)/sizeof(WCHAR);
2093     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2094     ok(ret, "failed to query password %u\n", GetLastError());
2095     todo_wine {
2096     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2097     ok(!size, "expected 0, got %u\n", size);
2098     }
2099
2100     WinHttpCloseHandle(req);
2101     WinHttpCloseHandle(con);
2102     WinHttpCloseHandle(ses);
2103 }
2104
2105 static void test_IWinHttpRequest(void)
2106 {
2107     static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2108     static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2109     static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2110     static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
2111     static const WCHAR method1W[] = {'G','E','T',0};
2112     static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2113     static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2114     static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2115     static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2116     static const WCHAR dateW[] = {'D','a','t','e',0};
2117     HRESULT hr;
2118     IWinHttpRequest *req;
2119     BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2120     BSTR date, today, connection, value = NULL;
2121     VARIANT async, empty, timeout, body, proxy_server, bypass_list;
2122     VARIANT_BOOL succeeded;
2123     LONG status;
2124     WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2125     SYSTEMTIME st;
2126
2127     GetSystemTime( &st );
2128     WinHttpTimeFromSystemTime( &st, todayW );
2129
2130     CoInitialize( NULL );
2131     hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2132     ok( hr == S_OK, "got %08x\n", hr );
2133
2134     VariantInit( &empty );
2135     V_VT( &empty ) = VT_ERROR;
2136
2137     V_VT( &async ) = VT_BOOL;
2138     V_BOOL( &async ) = VARIANT_FALSE;
2139
2140     hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2141     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2142
2143     method = SysAllocString( method1W );
2144     hr = IWinHttpRequest_Open( req, method, NULL, empty );
2145     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2146
2147     hr = IWinHttpRequest_Open( req, method, NULL, async );
2148     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2149
2150     url = SysAllocString( url1W );
2151     hr = IWinHttpRequest_Open( req, NULL, url, empty );
2152     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2153
2154     hr = IWinHttpRequest_Abort( req );
2155     ok( hr == S_OK, "got %08x\n", hr );
2156
2157     hr = IWinHttpRequest_Open( req, method, url, empty );
2158     ok( hr == S_OK, "got %08x\n", hr );
2159
2160     hr = IWinHttpRequest_Abort( req );
2161     ok( hr == S_OK, "got %08x\n", hr );
2162
2163     hr = IWinHttpRequest_Release( req );
2164     ok( hr == S_OK, "got %08x\n", hr );
2165
2166     hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2167     ok( hr == S_OK, "got %08x\n", hr );
2168
2169     SysFreeString( url );
2170     url = SysAllocString( url2W );
2171     hr = IWinHttpRequest_Open( req, method, url, async );
2172     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2173
2174     SysFreeString( method );
2175     method = SysAllocString( method2W );
2176     hr = IWinHttpRequest_Open( req, method, url, async );
2177     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2178
2179     SysFreeString( method );
2180     method = SysAllocString( method1W );
2181     SysFreeString( url );
2182     url = SysAllocString( url1W );
2183     hr = IWinHttpRequest_Open( req, method, url, async );
2184     ok( hr == S_OK, "got %08x\n", hr );
2185
2186     hr = IWinHttpRequest_Abort( req );
2187     ok( hr == S_OK, "got %08x\n", hr );
2188
2189     hr = IWinHttpRequest_Send( req, empty );
2190     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2191
2192     hr = IWinHttpRequest_Abort( req );
2193     ok( hr == S_OK, "got %08x\n", hr );
2194
2195     hr = IWinHttpRequest_Release( req );
2196     ok( hr == S_OK, "got %08x\n", hr );
2197
2198     hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2199     ok( hr == S_OK, "got %08x\n", hr );
2200
2201     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2202     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2203
2204     hr = IWinHttpRequest_get_ResponseText( req, &response );
2205     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2206
2207     hr = IWinHttpRequest_get_Status( req, NULL );
2208     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2209
2210     hr = IWinHttpRequest_get_Status( req, &status );
2211     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2212
2213     hr = IWinHttpRequest_get_StatusText( req, NULL );
2214     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2215
2216     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2217     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2218
2219     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2220     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2221
2222     hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2223     ok( hr == S_OK, "got %08x\n", hr );
2224
2225     hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2226     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2227
2228     VariantInit( &proxy_server );
2229     V_VT( &proxy_server ) = VT_ERROR;
2230     VariantInit( &bypass_list );
2231     V_VT( &bypass_list ) = VT_ERROR;
2232     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2233     ok( hr == S_OK, "got %08x\n", hr );
2234
2235     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2236     ok( hr == S_OK, "got %08x\n", hr );
2237
2238     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2239     ok( hr == S_OK, "got %08x\n", hr );
2240
2241     hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2242     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2243
2244     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2245     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2246
2247     hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2248     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2249
2250     connection = SysAllocString( connectionW );
2251     hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2252     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2253
2254     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2255     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2256
2257     hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2258     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2259
2260     date = SysAllocString( dateW );
2261     hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2262     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2263
2264     today = SysAllocString( todayW );
2265     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2266     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2267
2268     hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2269     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2270
2271     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2272     ok( hr == S_OK, "got %08x\n", hr );
2273
2274     SysFreeString( method );
2275     method = SysAllocString( method1W );
2276     SysFreeString( url );
2277     url = SysAllocString( url1W );
2278     hr = IWinHttpRequest_Open( req, method, url, async );
2279     ok( hr == S_OK, "got %08x\n", hr );
2280
2281     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2282     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2283
2284     hr = IWinHttpRequest_get_ResponseText( req, &response );
2285     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2286
2287     hr = IWinHttpRequest_get_Status( req, &status );
2288     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2289
2290     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2291     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2292
2293     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2294     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2295
2296     hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2297     ok( hr == S_OK, "got %08x\n", hr );
2298
2299     hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2300     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2301
2302     username = SysAllocString( usernameW );
2303     hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2304     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2305
2306     password = SysAllocString( passwordW );
2307     hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2308     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2309
2310     hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2311     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2312
2313     hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2314     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2315
2316     hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2317     ok( hr == S_OK, "got %08x\n", hr );
2318
2319     V_VT( &proxy_server ) = VT_BSTR;
2320     V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2321     V_VT( &bypass_list ) = VT_BSTR;
2322     V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2323     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2324     ok( hr == S_OK, "got %08x\n", hr );
2325
2326     hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2327     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2328
2329     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2330     ok( hr == S_OK, "got %08x\n", hr );
2331
2332     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2333     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2334
2335     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2336     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2337
2338     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2339     ok( hr == S_OK, "got %08x\n", hr );
2340
2341     hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2342     ok( hr == S_OK, "got %08x\n", hr );
2343
2344     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2345     ok( hr == S_OK, "got %08x\n", hr );
2346
2347     hr = IWinHttpRequest_Send( req, empty );
2348     ok( hr == S_OK, "got %08x\n", hr );
2349
2350     hr = IWinHttpRequest_Send( req, empty );
2351     ok( hr == S_OK, "got %08x\n", hr );
2352
2353     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2354     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2355
2356     hr = IWinHttpRequest_get_ResponseText( req, &response );
2357     ok( hr == S_OK, "got %08x\n", hr );
2358     SysFreeString( response );
2359
2360     hr = IWinHttpRequest_get_Status( req, NULL );
2361     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2362
2363     status = 0;
2364     hr = IWinHttpRequest_get_Status( req, &status );
2365     ok( hr == S_OK, "got %08x\n", hr );
2366     trace("%d\n", status);
2367
2368     hr = IWinHttpRequest_get_StatusText( req, NULL );
2369     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2370
2371     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2372     ok( hr == S_OK, "got %08x\n", hr );
2373     trace("%s\n", wine_dbgstr_w(status_text));
2374     SysFreeString( status_text );
2375
2376     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2377     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2378
2379     hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2380     ok( hr == S_OK, "got %08x\n", hr );
2381
2382     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2383     ok( hr == S_OK, "got %08x\n", hr );
2384
2385     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2386     ok( hr == S_OK, "got %08x\n", hr );
2387
2388     hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2389     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2390
2391     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2392     ok( hr == S_OK, "got %08x\n", hr );
2393     SysFreeString( headers );
2394
2395     hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2396     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2397
2398     hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2399     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2400
2401     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2402     ok( hr == S_OK, "got %08x\n", hr );
2403     SysFreeString( value );
2404
2405     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2406     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2407
2408     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2409     ok( hr == S_OK, "got %08x\n", hr );
2410
2411     VariantInit( &timeout );
2412     V_VT( &timeout ) = VT_I4;
2413     V_I4( &timeout ) = 10;
2414     hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2415     ok( hr == S_OK, "got %08x\n", hr );
2416
2417     hr = IWinHttpRequest_get_Status( req, &status );
2418     ok( hr == S_OK, "got %08x\n", hr );
2419
2420     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2421     ok( hr == S_OK, "got %08x\n", hr );
2422     SysFreeString( status_text );
2423
2424     hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2425     ok( hr == S_OK, "got %08x\n", hr );
2426
2427     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2428     ok( hr == S_OK, "got %08x\n", hr );
2429
2430     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2431     ok( hr == S_OK, "got %08x\n", hr );
2432
2433     hr = IWinHttpRequest_Send( req, empty );
2434     ok( hr == S_OK, "got %08x\n", hr );
2435
2436     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2437     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2438
2439     hr = IWinHttpRequest_get_ResponseText( req, &response );
2440     ok( hr == S_OK, "got %08x\n", hr );
2441     SysFreeString( response );
2442
2443     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2444     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2445
2446     VariantInit( &body );
2447     V_VT( &body ) = VT_ERROR;
2448     hr = IWinHttpRequest_get_ResponseBody( req, &body );
2449     ok( hr == S_OK, "got %08x\n", hr );
2450     ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2451
2452     hr = VariantClear( &body );
2453     ok( hr == S_OK, "got %08x\n", hr );
2454
2455     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2456     ok( hr == S_OK, "got %08x\n", hr );
2457
2458     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2459     ok( hr == S_OK, "got %08x\n", hr );
2460
2461     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2462     ok( hr == S_OK, "got %08x\n", hr );
2463     SysFreeString( headers );
2464
2465     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2466     ok( hr == S_OK, "got %08x\n", hr );
2467     SysFreeString( value );
2468
2469     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2470     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2471
2472     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2473     ok( hr == S_OK, "got %08x\n", hr );
2474
2475     hr = IWinHttpRequest_Send( req, empty );
2476     ok( hr == S_OK, "got %08x\n", hr );
2477
2478     hr = IWinHttpRequest_Abort( req );
2479     ok( hr == S_OK, "got %08x\n", hr );
2480
2481     hr = IWinHttpRequest_Abort( req );
2482     ok( hr == S_OK, "got %08x\n", hr );
2483
2484     hr = IWinHttpRequest_Release( req );
2485     ok( hr == S_OK, "got %08x\n", hr );
2486
2487     SysFreeString( method );
2488     SysFreeString( url );
2489     SysFreeString( username );
2490     SysFreeString( password );
2491     SysFreeString( connection );
2492     SysFreeString( date );
2493     SysFreeString( today );
2494     VariantClear( &proxy_server );
2495     VariantClear( &bypass_list );
2496     CoUninitialize();
2497 }
2498
2499 START_TEST (winhttp)
2500 {
2501     static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2502     static const WCHAR quitW[] = {'/','q','u','i','t',0};
2503     struct server_info si;
2504     HANDLE thread;
2505     DWORD ret;
2506
2507     test_OpenRequest();
2508     test_SendRequest();
2509     test_WinHttpTimeFromSystemTime();
2510     test_WinHttpTimeToSystemTime();
2511     test_WinHttpAddHeaders();
2512     test_secure_connection();
2513     test_request_parameter_defaults();
2514     test_QueryOption();
2515     test_set_default_proxy_config();
2516     test_empty_headers_param();
2517     test_Timeouts();
2518     test_resolve_timeout();
2519     test_credentials();
2520     test_IWinHttpRequest();
2521
2522     si.event = CreateEvent(NULL, 0, 0, NULL);
2523     si.port = 7532;
2524
2525     thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2526     ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2527
2528     ret = WaitForSingleObject(si.event, 10000);
2529     ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2530     if (ret != WAIT_OBJECT_0)
2531         return;
2532
2533     test_basic_request(si.port, NULL, basicW);
2534     test_no_headers(si.port);
2535     test_basic_authentication(si.port);
2536
2537     /* send the basic request again to shutdown the server thread */
2538     test_basic_request(si.port, NULL, quitW);
2539
2540     WaitForSingleObject(thread, 3000);
2541 }