push 5b1efc32b5a8acb1d5b5e60584746392dd0c436e
[wine/hacks.git] / dlls / winhttp / tests / winhttp.c
blob342dde2b87b38056024a0dcc1588606e7f1764a9
1 /*
2 * WinHTTP - tests
4 * Copyright 2008 Google (Zac Brown)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winhttp.h>
26 #include <wincrypt.h>
27 #include <winreg.h>
29 #include "wine/test.h"
31 static const WCHAR test_useragent[] =
32 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
33 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
35 static void test_QueryOption(void)
37 BOOL ret;
38 HINTERNET session, request, connection;
39 DWORD feature, size;
41 SetLastError(0xdeadbeef);
42 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
43 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
45 SetLastError(0xdeadbeef);
46 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
47 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
48 ok(GetLastError() == ERROR_INVALID_PARAMETER,
49 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
51 size = 0xdeadbeef;
52 SetLastError(0xdeadbeef);
53 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
54 ok(!ret, "should fail to query option\n");
55 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
56 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
57 ok(size == 4, "expected 4, got %u\n", size);
59 feature = 0xdeadbeef;
60 size = sizeof(feature) - 1;
61 SetLastError(0xdeadbeef);
62 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
63 ok(!ret, "should fail to query option\n");
64 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
65 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
66 ok(size == 4, "expected 4, got %u\n", size);
68 feature = 0xdeadbeef;
69 size = sizeof(feature) + 1;
70 SetLastError(0xdeadbeef);
71 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
72 ok(ret, "failed to query option %u\n", GetLastError());
73 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
74 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
75 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
77 SetLastError(0xdeadbeef);
78 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
79 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
80 ok(GetLastError() == ERROR_INVALID_PARAMETER,
81 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
83 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
84 SetLastError(0xdeadbeef);
85 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
86 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
90 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
91 SetLastError(0xdeadbeef);
92 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
93 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
94 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
95 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
97 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
98 SetLastError(0xdeadbeef);
99 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
100 ok(ret, "failed to set redirect policy %u\n", GetLastError());
102 feature = 0xdeadbeef;
103 size = sizeof(feature);
104 SetLastError(0xdeadbeef);
105 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
106 ok(ret, "failed to query option %u\n", GetLastError());
107 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
108 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
110 feature = WINHTTP_DISABLE_COOKIES;
111 SetLastError(0xdeadbeef);
112 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
113 ok(!ret, "should fail to set disable feature for a session\n");
114 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
115 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
117 SetLastError(0xdeadbeef);
118 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
119 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
121 feature = WINHTTP_DISABLE_COOKIES;
122 SetLastError(0xdeadbeef);
123 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
124 ok(!ret, "should fail to set disable feature for a connection\n");
125 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
126 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
128 SetLastError(0xdeadbeef);
129 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
130 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
131 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
133 skip("Network unreachable, skipping the test\n");
134 goto done;
137 feature = 0xdeadbeef;
138 size = sizeof(feature);
139 SetLastError(0xdeadbeef);
140 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
141 ok(!ret, "should fail to query disable feature for a request\n");
142 ok(GetLastError() == ERROR_INVALID_PARAMETER,
143 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
145 feature = 0;
146 size = sizeof(feature);
147 SetLastError(0xdeadbeef);
148 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
149 ok(ret, "failed to set feature %u\n", GetLastError());
151 feature = 0xffffffff;
152 size = sizeof(feature);
153 SetLastError(0xdeadbeef);
154 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
155 ok(ret, "failed to set feature %u\n", GetLastError());
157 feature = WINHTTP_DISABLE_COOKIES;
158 size = sizeof(feature);
159 SetLastError(0xdeadbeef);
160 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
161 ok(ret, "failed to set feature %u\n", GetLastError());
163 size = 0;
164 SetLastError(0xdeadbeef);
165 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
166 ok(!ret, "should fail to query disable feature for a request\n");
167 ok(GetLastError() == ERROR_INVALID_PARAMETER,
168 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
170 SetLastError(0xdeadbeef);
171 ret = WinHttpCloseHandle(request);
172 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
174 done:
175 SetLastError(0xdeadbeef);
176 ret = WinHttpCloseHandle(connection);
177 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
178 SetLastError(0xdeadbeef);
179 ret = WinHttpCloseHandle(session);
180 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
183 static void test_OpenRequest (void)
185 BOOL ret;
186 HINTERNET session, request, connection;
188 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
189 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
190 ok(session != NULL, "WinHttpOpen failed to open session.\n");
192 /* Test with a bad server name */
193 SetLastError(0xdeadbeef);
194 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
195 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
196 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
198 /* Test with a valid server name */
199 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
200 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
202 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
203 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
204 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
206 skip("Network unreachable, skipping.\n");
207 goto done;
209 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
211 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
212 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
213 ret = WinHttpCloseHandle(request);
214 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
216 done:
217 ret = WinHttpCloseHandle(connection);
218 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
219 ret = WinHttpCloseHandle(session);
220 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
224 static void test_empty_headers_param(void)
226 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
227 static const WCHAR empty[] = {0};
228 HANDLE ses, con, req;
229 BOOL ret;
231 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
232 ok(ses != NULL, "failed to open session %u\n", GetLastError());
234 con = WinHttpConnect(ses, winehq, 80, 0);
235 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
237 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
238 ok(req != NULL, "failed to open a request %u\n", GetLastError());
240 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
241 ok(ret, "failed to send request %u\n", GetLastError());
243 WinHttpCloseHandle(req);
244 WinHttpCloseHandle(con);
245 WinHttpCloseHandle(ses);
248 static void test_SendRequest (void)
250 HINTERNET session, request, connection;
251 DWORD header_len, optional_len, total_len;
252 DWORD bytes_rw;
253 BOOL ret;
254 CHAR buffer[256];
255 int i;
257 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
258 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
259 static const WCHAR content_type[] =
260 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
261 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
262 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
263 static const WCHAR test_verb[] = {'P','O','S','T',0};
264 static CHAR post_data[] = "mode=Test";
265 static CHAR test_post[] = "mode => Test\\0\n";
267 header_len = -1L;
268 total_len = optional_len = sizeof(post_data);
269 memset(buffer, 0xff, sizeof(buffer));
271 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
272 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
273 ok(session != NULL, "WinHttpOpen failed to open session.\n");
275 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
276 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
278 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
279 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
280 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
282 skip("Network unreachable, skipping.\n");
283 goto done;
285 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
287 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, 0);
288 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
290 for (i = 3; post_data[i]; i++)
292 bytes_rw = -1;
293 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
294 if (ret)
295 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
296 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
298 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
299 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
303 ret = WinHttpReceiveResponse(request, NULL);
304 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
306 bytes_rw = -1;
307 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
308 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
310 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
311 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
313 ret = WinHttpCloseHandle(request);
314 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
315 done:
316 ret = WinHttpCloseHandle(connection);
317 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
318 ret = WinHttpCloseHandle(session);
319 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
322 static void test_WinHttpTimeFromSystemTime(void)
324 BOOL ret;
325 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
326 static const WCHAR expected_string[] =
327 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
328 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
329 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
331 ret = WinHttpTimeFromSystemTime(&time, time_string);
332 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
333 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
334 "Time string returned did not match expected time string.\n");
337 static void test_WinHttpTimeToSystemTime(void)
339 BOOL ret;
340 SYSTEMTIME time;
341 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
342 static const WCHAR time_string1[] =
343 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
344 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
345 static const WCHAR time_string2[] =
346 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
347 '1','0',' ','0','5',' ','5','2','\n',0};
349 ret = WinHttpTimeToSystemTime(time_string1, &time);
350 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
351 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
352 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
354 ret = WinHttpTimeToSystemTime(time_string2, &time);
355 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
356 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
357 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
360 static void test_WinHttpAddHeaders(void)
362 HINTERNET session, request, connection;
363 BOOL ret, reverse;
364 WCHAR buffer[MAX_PATH];
365 WCHAR check_buffer[MAX_PATH];
366 DWORD index, len, oldlen;
368 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
369 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
370 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
371 static const WCHAR test_verb[] = {'P','O','S','T',0};
373 static const WCHAR test_header_begin[] =
374 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
375 static const WCHAR full_path_test_header_begin[] =
376 {'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'};
377 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
378 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
380 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
381 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
382 static const WCHAR test_flag_coalesce_comma[] =
383 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
384 static const WCHAR test_flag_coalesce_comma_reverse[] =
385 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
386 static const WCHAR test_flag_coalesce_semicolon[] =
387 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
388 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
389 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
391 static const WCHAR field[] = {'f','i','e','l','d',0};
392 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
393 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
395 static const WCHAR test_headers[][14] =
397 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
398 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
399 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
400 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
401 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
402 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
403 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
404 {0},
405 {':',0},
406 {'a',':',0},
407 {':','b',0},
408 {'c','d',0},
409 {' ','e',' ',':','f',0},
410 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
412 static const WCHAR test_indices[][6] =
414 {'t','e','s','t','1',0},
415 {'t','e','s','t','2',0},
416 {'t','e','s','t','3',0},
417 {'t','e','s','t','4',0}
420 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
421 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
422 ok(session != NULL, "WinHttpOpen failed to open session.\n");
424 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
425 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
427 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
428 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
429 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
431 skip("Network unreachable, skipping.\n");
432 goto done;
434 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
436 index = 0;
437 len = sizeof(buffer);
438 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
439 test_header_name, buffer, &len, &index);
440 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
441 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
442 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
444 index = 0;
445 len = sizeof(buffer);
446 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
447 test_header_name, buffer, &len, &index);
448 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
449 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
450 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
451 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
453 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
454 test_header_name, buffer, &len, &index);
455 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
457 /* Try to fetch the header info with a buffer that's big enough to fit the
458 * string but not the NULL terminator.
460 index = 0;
461 len = 5*sizeof(WCHAR);
462 memset(check_buffer, 0xab, sizeof(check_buffer));
463 memcpy(buffer, check_buffer, sizeof(buffer));
464 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
465 test_header_name, buffer, &len, &index);
466 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
467 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
468 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
469 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
471 /* Try with a NULL buffer */
472 index = 0;
473 len = sizeof(buffer);
474 SetLastError(0xdeadbeef);
475 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
476 test_header_name, NULL, &len, &index);
477 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
478 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
479 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
480 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
482 /* Try with a NULL buffer and a length that's too small */
483 index = 0;
484 len = 10;
485 SetLastError(0xdeadbeef);
486 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
487 test_header_name, NULL, &len, &index);
488 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
489 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
490 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
491 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
492 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
494 index = 0;
495 len = 0;
496 SetLastError(0xdeadbeef);
497 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
498 test_header_name, NULL, &len, &index);
499 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
500 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
501 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
502 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
503 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
505 /* valid query */
506 oldlen = len;
507 index = 0;
508 len = sizeof(buffer);
509 memset(buffer, 0xff, sizeof(buffer));
510 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
511 test_header_name, buffer, &len, &index);
512 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
513 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
514 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
515 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
516 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
517 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
518 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
519 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
520 "WinHttpQueryHeaders returned invalid end of header string.\n");
521 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
523 index = 0;
524 len = 0;
525 SetLastError(0xdeadbeef);
526 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
527 test_header_name, NULL, &len, &index);
528 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
529 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
530 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
531 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
532 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
534 oldlen = len;
535 index = 0;
536 len = sizeof(buffer);
537 memset(buffer, 0xff, sizeof(buffer));
538 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
539 test_header_name, buffer, &len, &index);
540 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
541 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
542 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
543 "no double NULL terminator\n");
544 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
545 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
546 "invalid beginning of header string.\n");
547 ok(index == 0, "header index was incremented\n");
549 /* tests for more indices */
550 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
551 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
553 index = 0;
554 len = sizeof(buffer);
555 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
556 test_header_name, buffer, &len, &index);
557 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
558 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
559 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
561 len = sizeof(buffer);
562 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
563 test_header_name, buffer, &len, &index);
564 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
565 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
566 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
568 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
569 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
571 index = 0;
572 len = sizeof(buffer);
573 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
574 test_header_name, buffer, &len, &index);
575 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
576 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
577 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
578 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
580 len = sizeof(buffer);
581 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
582 test_header_name, buffer, &len, &index);
583 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
584 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
585 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
587 /* add if new flag */
588 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
589 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
591 index = 0;
592 len = sizeof(buffer);
593 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
594 test_header_name, buffer, &len, &index);
595 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
596 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
597 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
599 len = sizeof(buffer);
600 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
601 test_header_name, buffer, &len, &index);
602 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
603 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
604 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
606 len = sizeof(buffer);
607 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
608 test_header_name, buffer, &len, &index);
609 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
611 /* coalesce flag */
612 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
613 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
615 index = 0;
616 len = sizeof(buffer);
617 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
618 test_header_name, buffer, &len, &index);
619 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
620 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
621 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");
623 len = sizeof(buffer);
624 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
625 test_header_name, buffer, &len, &index);
626 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
627 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
628 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
630 len = sizeof(buffer);
631 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
632 test_header_name, buffer, &len, &index);
633 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
635 /* coalesce with comma flag */
636 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
637 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
639 index = 0;
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 == 1, "WinHttpQueryHeaders failed to increment index.\n");
645 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,
646 "WinHttpQueryHeaders returned incorrect string.\n");
648 len = sizeof(buffer);
649 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
650 test_header_name, buffer, &len, &index);
651 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
652 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
653 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
655 len = sizeof(buffer);
656 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
657 test_header_name, buffer, &len, &index);
658 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
661 /* coalesce with semicolon flag */
662 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
663 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
665 index = 0;
666 len = sizeof(buffer);
667 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
668 test_header_name, buffer, &len, &index);
669 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
670 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
671 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,
672 "WinHttpQueryHeaders returned incorrect string.\n");
674 len = sizeof(buffer);
675 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
676 test_header_name, buffer, &len, &index);
677 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
678 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
679 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
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 == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
686 /* add and replace flags */
687 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
688 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
690 index = 0;
691 len = sizeof(buffer);
692 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
693 test_header_name, buffer, &len, &index);
694 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
698 len = sizeof(buffer);
699 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
700 test_header_name, buffer, &len, &index);
701 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
702 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
703 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
705 len = sizeof(buffer);
706 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
707 test_header_name, buffer, &len, &index);
708 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
710 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
711 ok(!ret, "WinHttpAddRequestHeaders failed\n");
713 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
714 ok(ret, "WinHttpAddRequestHeaders failed\n");
716 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
717 ok(!ret, "WinHttpAddRequestHeaders failed\n");
719 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
720 ok(!ret, "WinHttpAddRequestHeaders failed\n");
722 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
723 ok(!ret, "WinHttpAddRequestHeaders failed\n");
725 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
726 ok(ret, "WinHttpAddRequestHeaders failed\n");
728 index = 0;
729 buffer[0] = 0;
730 len = sizeof(buffer);
731 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
732 field, buffer, &len, &index);
733 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
734 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
736 ret = WinHttpCloseHandle(request);
737 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
738 done:
739 ret = WinHttpCloseHandle(connection);
740 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
741 ret = WinHttpCloseHandle(session);
742 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
746 static void test_secure_connection(void)
748 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
750 HANDLE ses, con, req;
751 DWORD size, status, policy, bitness;
752 BOOL ret;
753 CERT_CONTEXT *cert;
755 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
756 ok(ses != NULL, "failed to open session %u\n", GetLastError());
758 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
759 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
760 ok(ret, "failed to set redirect policy %u\n", GetLastError());
762 con = WinHttpConnect(ses, google, 443, 0);
763 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
765 /* try without setting WINHTTP_FLAG_SECURE */
766 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
767 ok(req != NULL, "failed to open a request %u\n", GetLastError());
769 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
770 ok(ret, "failed to send request %u\n", GetLastError());
772 ret = WinHttpReceiveResponse(req, NULL);
773 ok(!ret, "succeeded unexpectedly\n");
775 size = 0;
776 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
777 ok(!ret, "succeeded unexpectedly\n");
779 WinHttpCloseHandle(req);
781 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
782 ok(req != NULL, "failed to open a request %u\n", GetLastError());
784 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
785 ok(ret, "failed to send request %u\n", GetLastError());
787 size = sizeof(cert);
788 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
789 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
790 if (ret)
791 CertFreeCertificateContext(cert);
793 size = sizeof(bitness);
794 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
795 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
797 ret = WinHttpReceiveResponse(req, NULL);
798 ok(ret, "failed to receive response %u\n", GetLastError());
800 size = sizeof(status);
801 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
802 ok(ret, "failed unexpectedly %u\n", GetLastError());
803 ok(status == 200, "request failed unexpectedly %u\n", status);
805 size = 0;
806 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
807 ok(!ret, "succeeded unexpectedly\n");
809 WinHttpCloseHandle(req);
810 WinHttpCloseHandle(con);
811 WinHttpCloseHandle(ses);
814 static void test_request_parameter_defaults(void)
816 static const WCHAR empty[] = {0};
817 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
819 HANDLE ses, con, req;
820 DWORD size, status, error;
821 WCHAR *version;
822 BOOL ret;
824 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
825 ok(ses != NULL, "failed to open session %u\n", GetLastError());
827 con = WinHttpConnect(ses, codeweavers, 0, 0);
828 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
830 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
831 ok(req != NULL, "failed to open a request %u\n", GetLastError());
833 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
834 ok(ret, "failed to send request %u\n", GetLastError());
836 ret = WinHttpReceiveResponse(req, NULL);
837 ok(ret, "failed to receive response %u\n", GetLastError());
839 size = sizeof(status);
840 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
841 ok(ret, "failed unexpectedly %u\n", GetLastError());
842 ok(status == 200, "request failed unexpectedly %u\n", status);
844 WinHttpCloseHandle(req);
846 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
847 ok(req != NULL, "failed to open a request %u\n", GetLastError());
849 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
850 ok(ret, "failed to send request %u\n", GetLastError());
852 ret = WinHttpReceiveResponse(req, NULL);
853 ok(ret, "failed to receive response %u\n", GetLastError());
855 size = 0;
856 SetLastError(0xdeadbeef);
857 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
858 error = GetLastError();
859 ok(!ret, "succeeded unexpectedly\n");
860 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
862 version = HeapAlloc(GetProcessHeap(), 0, size);
863 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
864 ok(ret, "failed unexpectedly %u\n", GetLastError());
865 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
866 HeapFree(GetProcessHeap(), 0, version);
868 size = sizeof(status);
869 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
870 ok(ret, "failed unexpectedly %u\n", GetLastError());
871 ok(status == 200, "request failed unexpectedly %u\n", status);
873 WinHttpCloseHandle(req);
874 WinHttpCloseHandle(con);
875 WinHttpCloseHandle(ses);
878 static const WCHAR Connections[] = {
879 'S','o','f','t','w','a','r','e','\\',
880 'M','i','c','r','o','s','o','f','t','\\',
881 'W','i','n','d','o','w','s','\\',
882 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
883 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
884 'C','o','n','n','e','c','t','i','o','n','s',0 };
885 static const WCHAR WinHttpSettings[] = {
886 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
888 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
890 LONG l;
891 HKEY key;
892 DWORD ret = 0;
894 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
895 if (!l)
897 DWORD size = 0;
899 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
900 if (!l)
902 if (size <= len)
903 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
904 &size );
905 if (!l)
906 ret = size;
908 RegCloseKey( key );
910 return ret;
913 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
915 LONG l;
916 HKEY key;
918 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
919 KEY_WRITE, NULL, &key, NULL );
920 if (!l)
922 if (len)
923 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
924 else
925 RegDeleteValueW( key, WinHttpSettings );
926 RegCloseKey( key );
930 static void test_set_default_proxy_config(void)
932 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
933 static const WCHAR normalString[] = { 'f','o','o',0 };
934 DWORD type, len;
935 BYTE *saved_proxy_settings = NULL;
936 WINHTTP_PROXY_INFO info;
937 BOOL ret;
939 /* FIXME: it would be simpler to read the current settings using
940 * WinHttpGetDefaultProxyConfiguration and save them using
941 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
943 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
944 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
945 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
946 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
947 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
948 * the lpszProxy and lpszProxyBypass values are ignored.
949 * Thus, if a proxy is set with proxycfg, then calling
950 * WinHttpGetDefaultProxyConfiguration followed by
951 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
952 * getting deleted from the registry.
954 * Instead I read the current registry value and restore it directly.
956 len = get_default_proxy_reg_value( NULL, 0, &type );
957 if (len)
959 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
960 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
963 if (0)
965 /* Crashes on Vista and higher */
966 SetLastError(0xdeadbeef);
967 ret = WinHttpSetDefaultProxyConfiguration(NULL);
968 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
969 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
972 /* test with invalid access type */
973 info.dwAccessType = 0xdeadbeef;
974 info.lpszProxy = info.lpszProxyBypass = NULL;
975 SetLastError(0xdeadbeef);
976 ret = WinHttpSetDefaultProxyConfiguration(&info);
977 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
978 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
980 /* at a minimum, the proxy server must be set */
981 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
982 info.lpszProxy = info.lpszProxyBypass = NULL;
983 SetLastError(0xdeadbeef);
984 ret = WinHttpSetDefaultProxyConfiguration(&info);
985 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
986 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
987 info.lpszProxyBypass = normalString;
988 SetLastError(0xdeadbeef);
989 ret = WinHttpSetDefaultProxyConfiguration(&info);
990 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
991 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
993 /* the proxy server can't have wide characters */
994 info.lpszProxy = wideString;
995 SetLastError(0xdeadbeef);
996 ret = WinHttpSetDefaultProxyConfiguration(&info);
997 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
998 broken(ret), /* Earlier winhttp versions on W2K/XP */
999 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1001 info.lpszProxy = normalString;
1002 SetLastError(0xdeadbeef);
1003 ret = WinHttpSetDefaultProxyConfiguration(&info);
1004 if (ret)
1006 ok(ret, "always true\n");
1007 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1009 else if (GetLastError() == ERROR_ACCESS_DENIED)
1010 skip("couldn't set default proxy configuration: access denied\n");
1011 else
1012 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1013 GetLastError());
1016 START_TEST (winhttp)
1018 test_OpenRequest();
1019 test_SendRequest();
1020 test_WinHttpTimeFromSystemTime();
1021 test_WinHttpTimeToSystemTime();
1022 test_WinHttpAddHeaders();
1023 test_secure_connection();
1024 test_request_parameter_defaults();
1025 test_QueryOption();
1026 test_set_default_proxy_config();
1027 test_empty_headers_param();