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
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)
38 HINTERNET session, request, connection;
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());
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);
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);
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");
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());
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());
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());
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)
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");
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);
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;
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, bytes_rw, size;
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";
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");
285 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
286 if (!request) goto done;
288 context = 0xdeadbeef;
289 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
290 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
293 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
294 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
297 size = sizeof(context);
298 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
299 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
300 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
302 for (i = 3; post_data[i]; i++)
305 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
307 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
308 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
310 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
311 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
315 ret = WinHttpReceiveResponse(request, NULL);
316 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
319 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
320 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
322 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
323 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
325 ret = WinHttpCloseHandle(request);
326 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
328 ret = WinHttpCloseHandle(connection);
329 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
330 ret = WinHttpCloseHandle(session);
331 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
334 static void test_WinHttpTimeFromSystemTime(void)
337 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
338 static const WCHAR expected_string[] =
339 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
340 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
341 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
343 ret = WinHttpTimeFromSystemTime(&time, time_string);
344 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
345 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
346 "Time string returned did not match expected time string.\n");
349 static void test_WinHttpTimeToSystemTime(void)
353 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
354 static const WCHAR time_string1[] =
355 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
356 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
357 static const WCHAR time_string2[] =
358 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
359 '1','0',' ','0','5',' ','5','2','\n',0};
361 ret = WinHttpTimeToSystemTime(time_string1, &time);
362 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
363 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
364 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
366 ret = WinHttpTimeToSystemTime(time_string2, &time);
367 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
368 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
369 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
372 static void test_WinHttpAddHeaders(void)
374 HINTERNET session, request, connection;
376 WCHAR buffer[MAX_PATH];
377 WCHAR check_buffer[MAX_PATH];
378 DWORD index, len, oldlen;
380 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
381 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
382 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
383 static const WCHAR test_verb[] = {'P','O','S','T',0};
385 static const WCHAR test_header_begin[] =
386 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
387 static const WCHAR full_path_test_header_begin[] =
388 {'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'};
389 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
390 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
392 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
393 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
394 static const WCHAR test_flag_coalesce_comma[] =
395 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
396 static const WCHAR test_flag_coalesce_comma_reverse[] =
397 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
398 static const WCHAR test_flag_coalesce_semicolon[] =
399 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
400 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
401 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
403 static const WCHAR field[] = {'f','i','e','l','d',0};
404 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
405 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
407 static const WCHAR test_headers[][14] =
409 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
410 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
411 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
412 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
413 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
414 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
415 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
421 {' ','e',' ',':','f',0},
422 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
424 static const WCHAR test_indices[][6] =
426 {'t','e','s','t','1',0},
427 {'t','e','s','t','2',0},
428 {'t','e','s','t','3',0},
429 {'t','e','s','t','4',0}
432 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
433 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
434 ok(session != NULL, "WinHttpOpen failed to open session.\n");
436 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
437 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
439 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
440 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
441 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
443 skip("Network unreachable, skipping.\n");
446 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
449 len = sizeof(buffer);
450 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
451 test_header_name, buffer, &len, &index);
452 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
453 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
454 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
457 len = sizeof(buffer);
458 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
459 test_header_name, buffer, &len, &index);
460 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
461 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
462 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
463 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
465 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
466 test_header_name, buffer, &len, &index);
467 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
469 /* Try to fetch the header info with a buffer that's big enough to fit the
470 * string but not the NULL terminator.
473 len = 5*sizeof(WCHAR);
474 memset(check_buffer, 0xab, sizeof(check_buffer));
475 memcpy(buffer, check_buffer, sizeof(buffer));
476 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
477 test_header_name, buffer, &len, &index);
478 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
479 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
480 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
481 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
483 /* Try with a NULL buffer */
485 len = sizeof(buffer);
486 SetLastError(0xdeadbeef);
487 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
488 test_header_name, NULL, &len, &index);
489 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
490 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %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 /* Try with a NULL buffer and a length that's too small */
497 SetLastError(0xdeadbeef);
498 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
499 test_header_name, NULL, &len, &index);
500 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
501 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
502 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
503 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
504 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
508 SetLastError(0xdeadbeef);
509 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
510 test_header_name, NULL, &len, &index);
511 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
512 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
513 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
514 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
515 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
520 len = sizeof(buffer);
521 memset(buffer, 0xff, sizeof(buffer));
522 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
523 test_header_name, buffer, &len, &index);
524 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
525 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
526 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
527 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
528 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
529 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
530 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
531 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
532 "WinHttpQueryHeaders returned invalid end of header string.\n");
533 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
537 SetLastError(0xdeadbeef);
538 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | 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");
548 len = sizeof(buffer);
549 memset(buffer, 0xff, sizeof(buffer));
550 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
551 test_header_name, buffer, &len, &index);
552 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
553 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
554 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
555 "no double NULL terminator\n");
556 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
557 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
558 "invalid beginning of header string.\n");
559 ok(index == 0, "header index was incremented\n");
561 /* tests for more indices */
562 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
563 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
566 len = sizeof(buffer);
567 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
568 test_header_name, buffer, &len, &index);
569 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
570 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
571 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
573 len = sizeof(buffer);
574 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
575 test_header_name, buffer, &len, &index);
576 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
577 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
578 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
580 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
581 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
584 len = sizeof(buffer);
585 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
586 test_header_name, buffer, &len, &index);
587 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
588 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
589 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
590 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
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 == 2, "WinHttpQueryHeaders failed to increment index.\n");
597 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
599 /* add if new flag */
600 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
601 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
604 len = sizeof(buffer);
605 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
606 test_header_name, buffer, &len, &index);
607 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
608 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
609 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
611 len = sizeof(buffer);
612 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
613 test_header_name, buffer, &len, &index);
614 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
615 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
616 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
618 len = sizeof(buffer);
619 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
620 test_header_name, buffer, &len, &index);
621 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
624 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
625 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
628 len = sizeof(buffer);
629 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
630 test_header_name, buffer, &len, &index);
631 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
632 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
633 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");
635 len = sizeof(buffer);
636 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
637 test_header_name, buffer, &len, &index);
638 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
639 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
640 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
642 len = sizeof(buffer);
643 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
644 test_header_name, buffer, &len, &index);
645 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
647 /* coalesce with comma flag */
648 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
649 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
652 len = sizeof(buffer);
653 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
654 test_header_name, buffer, &len, &index);
655 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
656 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
657 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,
658 "WinHttpQueryHeaders returned incorrect string.\n");
660 len = sizeof(buffer);
661 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
662 test_header_name, buffer, &len, &index);
663 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
664 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
665 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
667 len = sizeof(buffer);
668 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
669 test_header_name, buffer, &len, &index);
670 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
673 /* coalesce with semicolon flag */
674 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
675 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
678 len = sizeof(buffer);
679 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
680 test_header_name, buffer, &len, &index);
681 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
682 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
683 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,
684 "WinHttpQueryHeaders returned incorrect string.\n");
686 len = sizeof(buffer);
687 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
688 test_header_name, buffer, &len, &index);
689 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
690 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
691 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
693 len = sizeof(buffer);
694 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
695 test_header_name, buffer, &len, &index);
696 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
698 /* add and replace flags */
699 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
700 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
703 len = sizeof(buffer);
704 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
705 test_header_name, buffer, &len, &index);
706 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
707 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
708 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
710 len = sizeof(buffer);
711 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
712 test_header_name, buffer, &len, &index);
713 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
714 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
717 len = sizeof(buffer);
718 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
719 test_header_name, buffer, &len, &index);
720 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
722 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
723 ok(!ret, "WinHttpAddRequestHeaders failed\n");
725 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
726 ok(ret, "WinHttpAddRequestHeaders failed\n");
728 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
729 ok(!ret, "WinHttpAddRequestHeaders failed\n");
731 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
732 ok(!ret, "WinHttpAddRequestHeaders failed\n");
734 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
735 ok(!ret, "WinHttpAddRequestHeaders failed\n");
737 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
738 ok(ret, "WinHttpAddRequestHeaders failed\n");
742 len = sizeof(buffer);
743 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
744 field, buffer, &len, &index);
745 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
746 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
748 ret = WinHttpCloseHandle(request);
749 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
751 ret = WinHttpCloseHandle(connection);
752 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
753 ret = WinHttpCloseHandle(session);
754 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
758 static void test_secure_connection(void)
760 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
762 HANDLE ses, con, req;
763 DWORD size, status, policy, bitness;
767 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
768 ok(ses != NULL, "failed to open session %u\n", GetLastError());
770 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
771 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
772 ok(ret, "failed to set redirect policy %u\n", GetLastError());
774 con = WinHttpConnect(ses, google, 443, 0);
775 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
777 /* try without setting WINHTTP_FLAG_SECURE */
778 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
779 ok(req != NULL, "failed to open a request %u\n", GetLastError());
781 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
782 ok(ret, "failed to send request %u\n", GetLastError());
784 ret = WinHttpReceiveResponse(req, NULL);
785 ok(!ret, "succeeded unexpectedly\n");
788 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
789 ok(!ret, "succeeded unexpectedly\n");
791 WinHttpCloseHandle(req);
793 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
794 ok(req != NULL, "failed to open a request %u\n", GetLastError());
796 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
797 ok(ret, "failed to send request %u\n", GetLastError());
800 skip("secure connection failed, skipping remaining secure tests\n");
805 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
806 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
808 CertFreeCertificateContext(cert);
810 size = sizeof(bitness);
811 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
812 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
814 ret = WinHttpReceiveResponse(req, NULL);
815 ok(ret, "failed to receive response %u\n", GetLastError());
817 size = sizeof(status);
818 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
819 ok(ret, "failed unexpectedly %u\n", GetLastError());
820 ok(status == 200, "request failed unexpectedly %u\n", status);
823 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
824 ok(!ret, "succeeded unexpectedly\n");
827 WinHttpCloseHandle(req);
828 WinHttpCloseHandle(con);
829 WinHttpCloseHandle(ses);
832 static void test_request_parameter_defaults(void)
834 static const WCHAR empty[] = {0};
835 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
837 HANDLE ses, con, req;
838 DWORD size, status, error;
842 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
843 ok(ses != NULL, "failed to open session %u\n", GetLastError());
845 con = WinHttpConnect(ses, codeweavers, 0, 0);
846 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
848 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
849 ok(req != NULL, "failed to open a request %u\n", GetLastError());
851 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
852 ok(ret, "failed to send request %u\n", GetLastError());
854 ret = WinHttpReceiveResponse(req, NULL);
855 ok(ret, "failed to receive response %u\n", GetLastError());
857 size = sizeof(status);
858 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
859 ok(ret, "failed unexpectedly %u\n", GetLastError());
860 ok(status == 200, "request failed unexpectedly %u\n", status);
862 WinHttpCloseHandle(req);
864 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
865 ok(req != NULL, "failed to open a request %u\n", GetLastError());
867 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
868 ok(ret, "failed to send request %u\n", GetLastError());
870 ret = WinHttpReceiveResponse(req, NULL);
871 ok(ret, "failed to receive response %u\n", GetLastError());
874 SetLastError(0xdeadbeef);
875 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
876 error = GetLastError();
877 ok(!ret, "succeeded unexpectedly\n");
878 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
880 version = HeapAlloc(GetProcessHeap(), 0, size);
881 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
882 ok(ret, "failed unexpectedly %u\n", GetLastError());
883 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
884 HeapFree(GetProcessHeap(), 0, version);
886 size = sizeof(status);
887 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
888 ok(ret, "failed unexpectedly %u\n", GetLastError());
889 ok(status == 200, "request failed unexpectedly %u\n", status);
891 WinHttpCloseHandle(req);
892 WinHttpCloseHandle(con);
893 WinHttpCloseHandle(ses);
896 static const WCHAR Connections[] = {
897 'S','o','f','t','w','a','r','e','\\',
898 'M','i','c','r','o','s','o','f','t','\\',
899 'W','i','n','d','o','w','s','\\',
900 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
901 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
902 'C','o','n','n','e','c','t','i','o','n','s',0 };
903 static const WCHAR WinHttpSettings[] = {
904 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
906 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
912 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
917 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
921 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
931 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
936 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
937 KEY_WRITE, NULL, &key, NULL );
941 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
943 RegDeleteValueW( key, WinHttpSettings );
948 static void test_set_default_proxy_config(void)
950 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
951 static const WCHAR normalString[] = { 'f','o','o',0 };
953 BYTE *saved_proxy_settings = NULL;
954 WINHTTP_PROXY_INFO info;
957 /* FIXME: it would be simpler to read the current settings using
958 * WinHttpGetDefaultProxyConfiguration and save them using
959 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
961 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
962 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
963 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
964 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
965 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
966 * the lpszProxy and lpszProxyBypass values are ignored.
967 * Thus, if a proxy is set with proxycfg, then calling
968 * WinHttpGetDefaultProxyConfiguration followed by
969 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
970 * getting deleted from the registry.
972 * Instead I read the current registry value and restore it directly.
974 len = get_default_proxy_reg_value( NULL, 0, &type );
977 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
978 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
983 /* Crashes on Vista and higher */
984 SetLastError(0xdeadbeef);
985 ret = WinHttpSetDefaultProxyConfiguration(NULL);
986 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
987 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
990 /* test with invalid access type */
991 info.dwAccessType = 0xdeadbeef;
992 info.lpszProxy = info.lpszProxyBypass = NULL;
993 SetLastError(0xdeadbeef);
994 ret = WinHttpSetDefaultProxyConfiguration(&info);
995 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
996 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
998 /* at a minimum, the proxy server must be set */
999 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1000 info.lpszProxy = info.lpszProxyBypass = NULL;
1001 SetLastError(0xdeadbeef);
1002 ret = WinHttpSetDefaultProxyConfiguration(&info);
1003 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1004 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1005 info.lpszProxyBypass = normalString;
1006 SetLastError(0xdeadbeef);
1007 ret = WinHttpSetDefaultProxyConfiguration(&info);
1008 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1009 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1011 /* the proxy server can't have wide characters */
1012 info.lpszProxy = wideString;
1013 SetLastError(0xdeadbeef);
1014 ret = WinHttpSetDefaultProxyConfiguration(&info);
1015 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1016 broken(ret), /* Earlier winhttp versions on W2K/XP */
1017 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1019 info.lpszProxy = normalString;
1020 SetLastError(0xdeadbeef);
1021 ret = WinHttpSetDefaultProxyConfiguration(&info);
1024 ok(ret, "always true\n");
1025 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1027 else if (GetLastError() == ERROR_ACCESS_DENIED)
1028 skip("couldn't set default proxy configuration: access denied\n");
1030 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1034 static void test_Timeouts (void)
1037 HINTERNET ses, req, con;
1038 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1041 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1042 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1044 SetLastError(0xdeadbeef);
1045 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1046 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1047 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1049 SetLastError(0xdeadbeef);
1050 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1051 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1052 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1054 SetLastError(0xdeadbeef);
1055 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1056 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1057 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1059 SetLastError(0xdeadbeef);
1060 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1061 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1062 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1064 SetLastError(0xdeadbeef);
1065 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1066 todo_wine ok(ret, "%u\n", GetLastError());
1068 SetLastError(0xdeadbeef);
1069 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1070 todo_wine ok(ret, "%u\n", GetLastError());
1072 con = WinHttpConnect(ses, codeweavers, 0, 0);
1073 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1075 SetLastError(0xdeadbeef);
1076 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1077 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1078 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1080 SetLastError(0xdeadbeef);
1081 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1082 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1083 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1085 SetLastError(0xdeadbeef);
1086 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1087 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1088 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1090 SetLastError(0xdeadbeef);
1091 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1092 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1093 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1095 SetLastError(0xdeadbeef);
1096 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1097 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1098 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1100 SetLastError(0xdeadbeef);
1101 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1102 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1103 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1105 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1106 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1108 SetLastError(0xdeadbeef);
1109 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1110 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1111 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1113 SetLastError(0xdeadbeef);
1114 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1115 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1116 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1118 SetLastError(0xdeadbeef);
1119 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1120 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1121 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1123 SetLastError(0xdeadbeef);
1124 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1125 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1126 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1128 SetLastError(0xdeadbeef);
1129 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1130 ok(ret, "%u\n", GetLastError());
1132 SetLastError(0xdeadbeef);
1133 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1134 ok(ret, "%u\n", GetLastError());
1136 WinHttpCloseHandle(req);
1137 WinHttpCloseHandle(con);
1138 WinHttpCloseHandle(ses);
1141 START_TEST (winhttp)
1145 test_WinHttpTimeFromSystemTime();
1146 test_WinHttpTimeToSystemTime();
1147 test_WinHttpAddHeaders();
1148 test_secure_connection();
1149 test_request_parameter_defaults();
1151 test_set_default_proxy_config();
1152 test_empty_headers_param();