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
30 #include "wine/test.h"
32 static const WCHAR test_useragent
[] =
33 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
34 static const WCHAR test_server
[] = {'w','i','n','e','h','q','.','o','r','g',0};
35 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
37 static void test_QueryOption(void)
40 HINTERNET session
, request
, connection
;
43 SetLastError(0xdeadbeef);
44 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
45 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
47 SetLastError(0xdeadbeef);
48 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
49 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
50 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
51 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
54 SetLastError(0xdeadbeef);
55 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
56 ok(!ret
, "should fail to query option\n");
57 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
58 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
59 ok(size
== 4, "expected 4, got %u\n", size
);
62 size
= sizeof(feature
) - 1;
63 SetLastError(0xdeadbeef);
64 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
65 ok(!ret
, "should fail to query option\n");
66 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
67 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
68 ok(size
== 4, "expected 4, got %u\n", size
);
71 size
= sizeof(feature
) + 1;
72 SetLastError(0xdeadbeef);
73 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
74 ok(ret
, "failed to query option %u\n", GetLastError());
75 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
76 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
77 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
79 SetLastError(0xdeadbeef);
80 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
81 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
82 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
83 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
85 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
86 SetLastError(0xdeadbeef);
87 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
88 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
89 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
90 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
92 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
93 SetLastError(0xdeadbeef);
94 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
95 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
96 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
97 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
99 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
100 SetLastError(0xdeadbeef);
101 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
102 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
104 feature
= 0xdeadbeef;
105 size
= sizeof(feature
);
106 SetLastError(0xdeadbeef);
107 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
108 ok(ret
, "failed to query option %u\n", GetLastError());
109 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
110 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
112 feature
= WINHTTP_DISABLE_COOKIES
;
113 SetLastError(0xdeadbeef);
114 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
115 ok(!ret
, "should fail to set disable feature for a session\n");
116 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
117 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
119 SetLastError(0xdeadbeef);
120 connection
= WinHttpConnect(session
, test_server
, INTERNET_DEFAULT_HTTP_PORT
, 0);
121 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
123 feature
= WINHTTP_DISABLE_COOKIES
;
124 SetLastError(0xdeadbeef);
125 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
126 ok(!ret
, "should fail to set disable feature for a connection\n");
127 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
128 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
130 SetLastError(0xdeadbeef);
131 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
132 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
133 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
135 skip("Network unreachable, skipping the test\n");
139 feature
= 0xdeadbeef;
140 size
= sizeof(feature
);
141 SetLastError(0xdeadbeef);
142 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
143 ok(!ret
, "should fail to query disable feature for a request\n");
144 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
145 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
148 size
= sizeof(feature
);
149 SetLastError(0xdeadbeef);
150 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
151 ok(ret
, "failed to set feature %u\n", GetLastError());
153 feature
= 0xffffffff;
154 size
= sizeof(feature
);
155 SetLastError(0xdeadbeef);
156 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
157 ok(ret
, "failed to set feature %u\n", GetLastError());
159 feature
= WINHTTP_DISABLE_COOKIES
;
160 size
= sizeof(feature
);
161 SetLastError(0xdeadbeef);
162 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
163 ok(ret
, "failed to set feature %u\n", GetLastError());
166 SetLastError(0xdeadbeef);
167 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
168 ok(!ret
, "should fail to query disable feature for a request\n");
169 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
170 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
172 SetLastError(0xdeadbeef);
173 ret
= WinHttpCloseHandle(request
);
174 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
177 SetLastError(0xdeadbeef);
178 ret
= WinHttpCloseHandle(connection
);
179 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
180 SetLastError(0xdeadbeef);
181 ret
= WinHttpCloseHandle(session
);
182 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
185 static void test_OpenRequest (void)
188 HINTERNET session
, request
, connection
;
190 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
191 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
192 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
194 /* Test with a bad server name */
195 SetLastError(0xdeadbeef);
196 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
197 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
198 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
200 /* Test with a valid server name */
201 connection
= WinHttpConnect (session
, test_server
, INTERNET_DEFAULT_HTTP_PORT
, 0);
202 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
204 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
205 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
206 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
208 skip("Network unreachable, skipping.\n");
211 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
213 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
214 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
215 ret
= WinHttpCloseHandle(request
);
216 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
219 ret
= WinHttpCloseHandle(connection
);
220 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
221 ret
= WinHttpCloseHandle(session
);
222 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
226 static void test_empty_headers_param(void)
228 static const WCHAR winehq
[] = {'w','i','n','e','h','q','.','o','r','g',0};
229 static const WCHAR empty
[] = {0};
230 HINTERNET ses
, con
, req
;
233 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
234 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
236 con
= WinHttpConnect(ses
, winehq
, 80, 0);
237 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
239 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
240 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
242 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
243 ok(ret
, "failed to send request %u\n", GetLastError());
245 WinHttpCloseHandle(req
);
246 WinHttpCloseHandle(con
);
247 WinHttpCloseHandle(ses
);
250 static void test_SendRequest (void)
252 HINTERNET session
, request
, connection
;
253 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
;
259 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
260 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
261 static const WCHAR content_type
[] =
262 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
263 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
264 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
265 static const WCHAR test_verb
[] = {'P','O','S','T',0};
266 static CHAR post_data
[] = "mode=Test";
267 static CHAR test_post
[] = "mode => Test\\0\n";
270 total_len
= optional_len
= sizeof(post_data
);
271 memset(buffer
, 0xff, sizeof(buffer
));
273 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
274 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
275 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
277 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
278 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
280 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
281 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
282 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
284 skip("Network unreachable, skipping.\n");
287 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
288 if (!request
) goto done
;
290 context
= 0xdeadbeef;
291 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
292 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
295 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
296 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
299 size
= sizeof(context
);
300 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
301 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
302 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
304 for (i
= 3; post_data
[i
]; i
++)
307 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
309 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
310 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
312 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
313 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
317 ret
= WinHttpReceiveResponse(request
, NULL
);
318 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
321 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
322 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
324 ok(bytes_rw
== strlen(test_post
), "Read %u bytes instead of %d.\n", bytes_rw
, lstrlen(test_post
));
325 ok(strncmp(buffer
, test_post
, bytes_rw
) == 0, "Data read did not match, got '%s'.\n", buffer
);
327 ret
= WinHttpCloseHandle(request
);
328 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
330 ret
= WinHttpCloseHandle(connection
);
331 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
332 ret
= WinHttpCloseHandle(session
);
333 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
336 static void test_WinHttpTimeFromSystemTime(void)
339 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
340 static const WCHAR expected_string
[] =
341 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
342 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
343 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
345 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
346 ok(ret
== TRUE
, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
347 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
348 "Time string returned did not match expected time string.\n");
351 static void test_WinHttpTimeToSystemTime(void)
355 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
356 static const WCHAR time_string1
[] =
357 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
358 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
359 static const WCHAR time_string2
[] =
360 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
361 '1','0',' ','0','5',' ','5','2','\n',0};
363 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
364 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
365 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
366 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
368 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
369 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
370 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
371 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
374 static void test_WinHttpAddHeaders(void)
376 HINTERNET session
, request
, connection
;
378 WCHAR buffer
[MAX_PATH
];
379 WCHAR check_buffer
[MAX_PATH
];
380 DWORD index
, len
, oldlen
;
382 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
383 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
384 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
385 static const WCHAR test_verb
[] = {'P','O','S','T',0};
387 static const WCHAR test_header_begin
[] =
388 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
389 static const WCHAR full_path_test_header_begin
[] =
390 {'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'};
391 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
392 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
394 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
395 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
396 static const WCHAR test_flag_coalesce_comma
[] =
397 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
398 static const WCHAR test_flag_coalesce_comma_reverse
[] =
399 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
400 static const WCHAR test_flag_coalesce_semicolon
[] =
401 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
402 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
403 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
405 static const WCHAR field
[] = {'f','i','e','l','d',0};
406 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
407 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
409 static const WCHAR test_headers
[][14] =
411 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
412 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
413 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
414 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
415 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
416 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
417 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
423 {' ','e',' ',':','f',0},
424 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
426 static const WCHAR test_indices
[][6] =
428 {'t','e','s','t','1',0},
429 {'t','e','s','t','2',0},
430 {'t','e','s','t','3',0},
431 {'t','e','s','t','4',0}
434 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
435 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
436 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
438 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
439 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
441 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
442 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
443 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
445 skip("Network unreachable, skipping.\n");
448 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
451 len
= sizeof(buffer
);
452 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
453 test_header_name
, buffer
, &len
, &index
);
454 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
455 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
456 ok(ret
== TRUE
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, GetLastError());
459 len
= sizeof(buffer
);
460 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
461 test_header_name
, buffer
, &len
, &index
);
462 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
463 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
464 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
465 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
467 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
468 test_header_name
, buffer
, &len
, &index
);
469 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
471 /* Try to fetch the header info with a buffer that's big enough to fit the
472 * string but not the NULL terminator.
475 len
= 5*sizeof(WCHAR
);
476 memset(check_buffer
, 0xab, sizeof(check_buffer
));
477 memcpy(buffer
, check_buffer
, sizeof(buffer
));
478 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
479 test_header_name
, buffer
, &len
, &index
);
480 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
481 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
482 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
483 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
485 /* Try with a NULL buffer */
487 len
= sizeof(buffer
);
488 SetLastError(0xdeadbeef);
489 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
490 test_header_name
, NULL
, &len
, &index
);
491 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
492 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
493 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
494 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
496 /* Try with a NULL buffer and a length that's too small */
499 SetLastError(0xdeadbeef);
500 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
501 test_header_name
, NULL
, &len
, &index
);
502 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
503 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
504 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
505 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
506 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
510 SetLastError(0xdeadbeef);
511 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
512 test_header_name
, NULL
, &len
, &index
);
513 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
514 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
515 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
516 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
517 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
522 len
= sizeof(buffer
);
523 memset(buffer
, 0xff, sizeof(buffer
));
524 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
525 test_header_name
, buffer
, &len
, &index
);
526 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
527 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
528 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
529 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
530 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
531 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
532 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
533 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
534 "WinHttpQueryHeaders returned invalid end of header string.\n");
535 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
539 SetLastError(0xdeadbeef);
540 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
541 test_header_name
, NULL
, &len
, &index
);
542 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
543 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
544 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
545 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
546 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
550 len
= sizeof(buffer
);
551 memset(buffer
, 0xff, sizeof(buffer
));
552 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
553 test_header_name
, buffer
, &len
, &index
);
554 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
555 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
556 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
557 "no double NULL terminator\n");
558 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
559 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
560 "invalid beginning of header string.\n");
561 ok(index
== 0, "header index was incremented\n");
563 /* tests for more indices */
564 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
565 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
568 len
= sizeof(buffer
);
569 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
570 test_header_name
, buffer
, &len
, &index
);
571 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
572 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
573 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
575 len
= sizeof(buffer
);
576 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
577 test_header_name
, buffer
, &len
, &index
);
578 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
579 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
580 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
582 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
583 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
586 len
= sizeof(buffer
);
587 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
588 test_header_name
, buffer
, &len
, &index
);
589 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
590 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
591 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
592 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
594 len
= sizeof(buffer
);
595 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
596 test_header_name
, buffer
, &len
, &index
);
597 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
598 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
599 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
601 /* add if new flag */
602 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
603 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
610 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
611 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
613 len
= sizeof(buffer
);
614 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
615 test_header_name
, buffer
, &len
, &index
);
616 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
617 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
618 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
620 len
= sizeof(buffer
);
621 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
622 test_header_name
, buffer
, &len
, &index
);
623 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
626 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
627 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
634 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
635 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");
637 len
= sizeof(buffer
);
638 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
639 test_header_name
, buffer
, &len
, &index
);
640 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
641 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
642 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
644 len
= sizeof(buffer
);
645 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
646 test_header_name
, buffer
, &len
, &index
);
647 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
649 /* coalesce with comma flag */
650 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
651 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
654 len
= sizeof(buffer
);
655 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
656 test_header_name
, buffer
, &len
, &index
);
657 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
658 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
659 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,
660 "WinHttpQueryHeaders returned incorrect string.\n");
662 len
= sizeof(buffer
);
663 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
664 test_header_name
, buffer
, &len
, &index
);
665 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
666 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
667 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
669 len
= sizeof(buffer
);
670 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
671 test_header_name
, buffer
, &len
, &index
);
672 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
675 /* coalesce with semicolon flag */
676 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
677 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
680 len
= sizeof(buffer
);
681 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
682 test_header_name
, buffer
, &len
, &index
);
683 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
684 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
685 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,
686 "WinHttpQueryHeaders returned incorrect string.\n");
688 len
= sizeof(buffer
);
689 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
690 test_header_name
, buffer
, &len
, &index
);
691 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
692 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
693 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
695 len
= sizeof(buffer
);
696 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
697 test_header_name
, buffer
, &len
, &index
);
698 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
700 /* add and replace flags */
701 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
702 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
709 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
710 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
712 len
= sizeof(buffer
);
713 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
714 test_header_name
, buffer
, &len
, &index
);
715 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
716 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
717 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
719 len
= sizeof(buffer
);
720 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
721 test_header_name
, buffer
, &len
, &index
);
722 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
724 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
725 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
727 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
728 ok(ret
, "WinHttpAddRequestHeaders failed\n");
730 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
731 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
733 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
734 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
736 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
737 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
739 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
740 ok(ret
, "WinHttpAddRequestHeaders failed\n");
744 len
= sizeof(buffer
);
745 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
746 field
, buffer
, &len
, &index
);
747 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
748 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
750 ret
= WinHttpCloseHandle(request
);
751 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
753 ret
= WinHttpCloseHandle(connection
);
754 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
755 ret
= WinHttpCloseHandle(session
);
756 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
760 static void test_secure_connection(void)
762 static const WCHAR google
[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
764 HINTERNET ses
, con
, req
;
765 DWORD size
, status
, policy
, bitness
;
769 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
770 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
772 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
773 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
774 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
776 con
= WinHttpConnect(ses
, google
, 443, 0);
777 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
779 /* try without setting WINHTTP_FLAG_SECURE */
780 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
781 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
783 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
784 ok(ret
, "failed to send request %u\n", GetLastError());
786 ret
= WinHttpReceiveResponse(req
, NULL
);
787 ok(!ret
, "succeeded unexpectedly\n");
790 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
791 ok(!ret
, "succeeded unexpectedly\n");
793 WinHttpCloseHandle(req
);
795 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
796 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
798 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
799 ok(ret
, "failed to send request %u\n", GetLastError());
802 skip("secure connection failed, skipping remaining secure tests\n");
807 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
808 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
810 CertFreeCertificateContext(cert
);
812 size
= sizeof(bitness
);
813 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
814 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
816 ret
= WinHttpReceiveResponse(req
, NULL
);
817 ok(ret
, "failed to receive response %u\n", GetLastError());
819 size
= sizeof(status
);
820 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
821 ok(ret
, "failed unexpectedly %u\n", GetLastError());
822 ok(status
== 200, "request failed unexpectedly %u\n", status
);
825 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
826 ok(!ret
, "succeeded unexpectedly\n");
829 WinHttpCloseHandle(req
);
830 WinHttpCloseHandle(con
);
831 WinHttpCloseHandle(ses
);
834 static void test_request_parameter_defaults(void)
836 static const WCHAR empty
[] = {0};
837 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
839 HINTERNET ses
, con
, req
;
840 DWORD size
, status
, error
;
844 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
845 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
847 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
848 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
850 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
851 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
853 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
854 ok(ret
, "failed to send request %u\n", GetLastError());
856 ret
= WinHttpReceiveResponse(req
, NULL
);
857 ok(ret
, "failed to receive response %u\n", GetLastError());
859 size
= sizeof(status
);
860 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
861 ok(ret
, "failed unexpectedly %u\n", GetLastError());
862 ok(status
== 200, "request failed unexpectedly %u\n", status
);
864 WinHttpCloseHandle(req
);
866 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
867 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
869 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
870 ok(ret
, "failed to send request %u\n", GetLastError());
872 ret
= WinHttpReceiveResponse(req
, NULL
);
873 ok(ret
, "failed to receive response %u\n", GetLastError());
876 SetLastError(0xdeadbeef);
877 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
878 error
= GetLastError();
879 ok(!ret
, "succeeded unexpectedly\n");
880 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
882 version
= HeapAlloc(GetProcessHeap(), 0, size
);
883 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
884 ok(ret
, "failed unexpectedly %u\n", GetLastError());
885 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
886 HeapFree(GetProcessHeap(), 0, version
);
888 size
= sizeof(status
);
889 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
890 ok(ret
, "failed unexpectedly %u\n", GetLastError());
891 ok(status
== 200, "request failed unexpectedly %u\n", status
);
893 WinHttpCloseHandle(req
);
894 WinHttpCloseHandle(con
);
895 WinHttpCloseHandle(ses
);
898 static const WCHAR Connections
[] = {
899 'S','o','f','t','w','a','r','e','\\',
900 'M','i','c','r','o','s','o','f','t','\\',
901 'W','i','n','d','o','w','s','\\',
902 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
903 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
904 'C','o','n','n','e','c','t','i','o','n','s',0 };
905 static const WCHAR WinHttpSettings
[] = {
906 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
908 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
914 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
919 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
923 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
933 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
938 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
939 KEY_WRITE
, NULL
, &key
, NULL
);
943 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
945 RegDeleteValueW( key
, WinHttpSettings
);
950 static void test_set_default_proxy_config(void)
952 static const WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
953 static const WCHAR normalString
[] = { 'f','o','o',0 };
955 BYTE
*saved_proxy_settings
= NULL
;
956 WINHTTP_PROXY_INFO info
;
959 /* FIXME: it would be simpler to read the current settings using
960 * WinHttpGetDefaultProxyConfiguration and save them using
961 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
963 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
964 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
965 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
966 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
967 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
968 * the lpszProxy and lpszProxyBypass values are ignored.
969 * Thus, if a proxy is set with proxycfg, then calling
970 * WinHttpGetDefaultProxyConfiguration followed by
971 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
972 * getting deleted from the registry.
974 * Instead I read the current registry value and restore it directly.
976 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
979 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
980 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
985 /* Crashes on Vista and higher */
986 SetLastError(0xdeadbeef);
987 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
988 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
989 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
992 /* test with invalid access type */
993 info
.dwAccessType
= 0xdeadbeef;
994 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
995 SetLastError(0xdeadbeef);
996 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
997 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
998 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1000 /* at a minimum, the proxy server must be set */
1001 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1002 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1003 SetLastError(0xdeadbeef);
1004 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1005 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1006 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1007 info
.lpszProxyBypass
= normalString
;
1008 SetLastError(0xdeadbeef);
1009 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1010 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1011 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1013 /* the proxy server can't have wide characters */
1014 info
.lpszProxy
= wideString
;
1015 SetLastError(0xdeadbeef);
1016 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1017 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1018 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1019 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1021 info
.lpszProxy
= normalString
;
1022 SetLastError(0xdeadbeef);
1023 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1026 ok(ret
, "always true\n");
1027 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1029 else if (GetLastError() == ERROR_ACCESS_DENIED
)
1030 skip("couldn't set default proxy configuration: access denied\n");
1032 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1036 static void test_Timeouts (void)
1040 HINTERNET ses
, req
, con
;
1041 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1044 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1045 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1047 SetLastError(0xdeadbeef);
1048 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1049 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1050 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1052 SetLastError(0xdeadbeef);
1053 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1054 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1055 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1057 SetLastError(0xdeadbeef);
1058 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1059 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1060 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1062 SetLastError(0xdeadbeef);
1063 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1064 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1065 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1067 SetLastError(0xdeadbeef);
1068 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1069 ok(ret
, "%u\n", GetLastError());
1071 SetLastError(0xdeadbeef);
1072 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1073 ok(ret
, "%u\n", GetLastError());
1075 SetLastError(0xdeadbeef);
1076 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1077 ok(ret
, "%u\n", GetLastError());
1079 SetLastError(0xdeadbeef);
1081 size
= sizeof(DWORD
);
1082 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1083 ok(ret
, "%u\n", GetLastError());
1084 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1086 SetLastError(0xdeadbeef);
1088 size
= sizeof(DWORD
);
1089 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1090 ok(ret
, "%u\n", GetLastError());
1091 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1093 SetLastError(0xdeadbeef);
1095 size
= sizeof(DWORD
);
1096 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1097 ok(ret
, "%u\n", GetLastError());
1098 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1100 SetLastError(0xdeadbeef);
1102 size
= sizeof(DWORD
);
1103 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1104 ok(ret
, "%u\n", GetLastError());
1105 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1107 SetLastError(0xdeadbeef);
1109 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1110 ok(ret
, "%u\n", GetLastError());
1112 SetLastError(0xdeadbeef);
1114 size
= sizeof(DWORD
);
1115 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1116 ok(ret
, "%u\n", GetLastError());
1117 ok(value
== 0, "Expected 0, got %u\n", value
);
1119 SetLastError(0xdeadbeef);
1121 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1122 ok(ret
, "%u\n", GetLastError());
1124 SetLastError(0xdeadbeef);
1126 size
= sizeof(DWORD
);
1127 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1128 ok(ret
, "%u\n", GetLastError());
1129 ok(value
== 0, "Expected 0, got %u\n", value
);
1131 SetLastError(0xdeadbeef);
1133 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1134 ok(ret
, "%u\n", GetLastError());
1136 SetLastError(0xdeadbeef);
1138 size
= sizeof(DWORD
);
1139 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1140 ok(ret
, "%u\n", GetLastError());
1141 ok(value
== 0, "Expected 0, got %u\n", value
);
1143 SetLastError(0xdeadbeef);
1145 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1146 ok(ret
, "%u\n", GetLastError());
1148 SetLastError(0xdeadbeef);
1150 size
= sizeof(DWORD
);
1151 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1152 ok(ret
, "%u\n", GetLastError());
1153 ok(value
== 0, "Expected 0, got %u\n", value
);
1155 SetLastError(0xdeadbeef);
1157 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1158 ok(ret
, "%u\n", GetLastError());
1160 SetLastError(0xdeadbeef);
1162 size
= sizeof(DWORD
);
1163 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1164 ok(ret
, "%u\n", GetLastError());
1165 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1167 SetLastError(0xdeadbeef);
1169 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1170 ok(ret
, "%u\n", GetLastError());
1172 SetLastError(0xdeadbeef);
1174 size
= sizeof(DWORD
);
1175 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1176 ok(ret
, "%u\n", GetLastError());
1177 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1179 SetLastError(0xdeadbeef);
1181 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1182 ok(ret
, "%u\n", GetLastError());
1184 SetLastError(0xdeadbeef);
1186 size
= sizeof(DWORD
);
1187 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1188 ok(ret
, "%u\n", GetLastError());
1189 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1191 SetLastError(0xdeadbeef);
1193 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1194 ok(ret
, "%u\n", GetLastError());
1196 SetLastError(0xdeadbeef);
1198 size
= sizeof(DWORD
);
1199 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1200 ok(ret
, "%u\n", GetLastError());
1201 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1203 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1204 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1206 /* Timeout values should match the last one set for session */
1207 SetLastError(0xdeadbeef);
1209 size
= sizeof(DWORD
);
1210 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1211 ok(ret
, "%u\n", GetLastError());
1212 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1214 SetLastError(0xdeadbeef);
1216 size
= sizeof(DWORD
);
1217 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1218 ok(ret
, "%u\n", GetLastError());
1219 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1221 SetLastError(0xdeadbeef);
1223 size
= sizeof(DWORD
);
1224 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1225 ok(ret
, "%u\n", GetLastError());
1226 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1228 SetLastError(0xdeadbeef);
1230 size
= sizeof(DWORD
);
1231 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1232 ok(ret
, "%u\n", GetLastError());
1233 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1235 SetLastError(0xdeadbeef);
1236 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1237 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1238 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1240 SetLastError(0xdeadbeef);
1241 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1242 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1243 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1245 SetLastError(0xdeadbeef);
1246 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1247 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1248 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1250 SetLastError(0xdeadbeef);
1251 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1252 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1253 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1255 SetLastError(0xdeadbeef);
1256 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1257 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1258 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1260 SetLastError(0xdeadbeef);
1261 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1262 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1263 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1265 SetLastError(0xdeadbeef);
1267 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1268 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1269 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1271 SetLastError(0xdeadbeef);
1273 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1274 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1275 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1277 SetLastError(0xdeadbeef);
1279 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1280 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1281 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1283 SetLastError(0xdeadbeef);
1285 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1286 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1287 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1289 /* Changing timeout values for session should affect the values for connection */
1290 SetLastError(0xdeadbeef);
1292 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1293 ok(ret
, "%u\n", GetLastError());
1295 SetLastError(0xdeadbeef);
1297 size
= sizeof(DWORD
);
1298 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1299 ok(ret
, "%u\n", GetLastError());
1300 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1302 SetLastError(0xdeadbeef);
1304 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1305 ok(ret
, "%u\n", GetLastError());
1307 SetLastError(0xdeadbeef);
1309 size
= sizeof(DWORD
);
1310 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1311 ok(ret
, "%u\n", GetLastError());
1312 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1314 SetLastError(0xdeadbeef);
1316 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1317 ok(ret
, "%u\n", GetLastError());
1319 SetLastError(0xdeadbeef);
1321 size
= sizeof(DWORD
);
1322 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1323 ok(ret
, "%u\n", GetLastError());
1324 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1326 SetLastError(0xdeadbeef);
1328 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1329 ok(ret
, "%u\n", GetLastError());
1331 SetLastError(0xdeadbeef);
1333 size
= sizeof(DWORD
);
1334 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1335 ok(ret
, "%u\n", GetLastError());
1336 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1338 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1339 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1341 /* Timeout values should match the last one set for session */
1342 SetLastError(0xdeadbeef);
1344 size
= sizeof(DWORD
);
1345 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1346 ok(ret
, "%u\n", GetLastError());
1347 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1349 SetLastError(0xdeadbeef);
1351 size
= sizeof(DWORD
);
1352 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1353 ok(ret
, "%u\n", GetLastError());
1354 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1356 SetLastError(0xdeadbeef);
1358 size
= sizeof(DWORD
);
1359 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1360 ok(ret
, "%u\n", GetLastError());
1361 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1363 SetLastError(0xdeadbeef);
1365 size
= sizeof(DWORD
);
1366 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1367 ok(ret
, "%u\n", GetLastError());
1368 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1370 SetLastError(0xdeadbeef);
1371 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1372 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1373 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1375 SetLastError(0xdeadbeef);
1376 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1377 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1378 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1380 SetLastError(0xdeadbeef);
1381 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1382 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1383 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1385 SetLastError(0xdeadbeef);
1386 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1387 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1388 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1390 SetLastError(0xdeadbeef);
1391 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1392 ok(ret
, "%u\n", GetLastError());
1394 SetLastError(0xdeadbeef);
1395 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1396 ok(ret
, "%u\n", GetLastError());
1398 SetLastError(0xdeadbeef);
1399 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1400 ok(ret
, "%u\n", GetLastError());
1402 SetLastError(0xdeadbeef);
1404 size
= sizeof(DWORD
);
1405 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1406 ok(ret
, "%u\n", GetLastError());
1407 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1409 SetLastError(0xdeadbeef);
1411 size
= sizeof(DWORD
);
1412 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1413 ok(ret
, "%u\n", GetLastError());
1414 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1416 SetLastError(0xdeadbeef);
1418 size
= sizeof(DWORD
);
1419 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1420 ok(ret
, "%u\n", GetLastError());
1421 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1423 SetLastError(0xdeadbeef);
1425 size
= sizeof(DWORD
);
1426 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1427 ok(ret
, "%u\n", GetLastError());
1428 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1430 SetLastError(0xdeadbeef);
1432 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1433 ok(ret
, "%u\n", GetLastError());
1435 SetLastError(0xdeadbeef);
1437 size
= sizeof(DWORD
);
1438 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1439 ok(ret
, "%u\n", GetLastError());
1440 ok(value
== 0, "Expected 0, got %u\n", value
);
1442 SetLastError(0xdeadbeef);
1444 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1445 ok(ret
, "%u\n", GetLastError());
1447 SetLastError(0xdeadbeef);
1449 size
= sizeof(DWORD
);
1450 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1451 ok(ret
, "%u\n", GetLastError());
1452 ok(value
== 0, "Expected 0, got %u\n", value
);
1454 SetLastError(0xdeadbeef);
1456 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1457 ok(ret
, "%u\n", GetLastError());
1459 SetLastError(0xdeadbeef);
1461 size
= sizeof(DWORD
);
1462 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1463 ok(ret
, "%u\n", GetLastError());
1464 ok(value
== 0, "Expected 0, got %u\n", value
);
1466 SetLastError(0xdeadbeef);
1468 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1469 ok(ret
, "%u\n", GetLastError());
1471 SetLastError(0xdeadbeef);
1473 size
= sizeof(DWORD
);
1474 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1475 ok(ret
, "%u\n", GetLastError());
1476 ok(value
== 0, "Expected 0, got %u\n", value
);
1478 SetLastError(0xdeadbeef);
1480 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1481 ok(ret
, "%u\n", GetLastError());
1483 SetLastError(0xdeadbeef);
1485 size
= sizeof(DWORD
);
1486 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1487 ok(ret
, "%u\n", GetLastError());
1488 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1490 SetLastError(0xdeadbeef);
1492 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1493 ok(ret
, "%u\n", GetLastError());
1495 SetLastError(0xdeadbeef);
1497 size
= sizeof(DWORD
);
1498 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1499 ok(ret
, "%u\n", GetLastError());
1500 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1502 SetLastError(0xdeadbeef);
1504 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1505 ok(ret
, "%u\n", GetLastError());
1507 SetLastError(0xdeadbeef);
1509 size
= sizeof(DWORD
);
1510 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1511 ok(ret
, "%u\n", GetLastError());
1512 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1514 SetLastError(0xdeadbeef);
1516 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1517 ok(ret
, "%u\n", GetLastError());
1519 SetLastError(0xdeadbeef);
1521 size
= sizeof(DWORD
);
1522 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1523 ok(ret
, "%u\n", GetLastError());
1524 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1526 /* Changing timeout values for session should not affect the values for a request,
1527 * neither should the other way around.
1529 SetLastError(0xdeadbeef);
1531 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1532 ok(ret
, "%u\n", GetLastError());
1534 SetLastError(0xdeadbeef);
1536 size
= sizeof(DWORD
);
1537 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1538 ok(ret
, "%u\n", GetLastError());
1539 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1541 SetLastError(0xdeadbeef);
1543 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1544 ok(ret
, "%u\n", GetLastError());
1546 SetLastError(0xdeadbeef);
1548 size
= sizeof(DWORD
);
1549 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1550 ok(ret
, "%u\n", GetLastError());
1551 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1553 SetLastError(0xdeadbeef);
1555 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1556 ok(ret
, "%u\n", GetLastError());
1558 SetLastError(0xdeadbeef);
1560 size
= sizeof(DWORD
);
1561 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1562 ok(ret
, "%u\n", GetLastError());
1563 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1565 SetLastError(0xdeadbeef);
1567 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1568 ok(ret
, "%u\n", GetLastError());
1570 SetLastError(0xdeadbeef);
1572 size
= sizeof(DWORD
);
1573 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1574 ok(ret
, "%u\n", GetLastError());
1575 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1577 SetLastError(0xdeadbeef);
1579 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1580 ok(ret
, "%u\n", GetLastError());
1582 SetLastError(0xdeadbeef);
1584 size
= sizeof(DWORD
);
1585 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1586 ok(ret
, "%u\n", GetLastError());
1587 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1589 SetLastError(0xdeadbeef);
1591 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1592 ok(ret
, "%u\n", GetLastError());
1594 SetLastError(0xdeadbeef);
1596 size
= sizeof(DWORD
);
1597 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1598 ok(ret
, "%u\n", GetLastError());
1599 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1601 SetLastError(0xdeadbeef);
1603 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1604 ok(ret
, "%u\n", GetLastError());
1606 SetLastError(0xdeadbeef);
1608 size
= sizeof(DWORD
);
1609 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1610 ok(ret
, "%u\n", GetLastError());
1611 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1613 SetLastError(0xdeadbeef);
1615 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1616 ok(ret
, "%u\n", GetLastError());
1618 SetLastError(0xdeadbeef);
1620 size
= sizeof(DWORD
);
1621 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1622 ok(ret
, "%u\n", GetLastError());
1623 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1625 WinHttpCloseHandle(req
);
1626 WinHttpCloseHandle(con
);
1627 WinHttpCloseHandle(ses
);
1630 static void test_resolve_timeout(void)
1632 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1633 static const WCHAR srevaewedoc
[] = {'s','r','e','v','a','e','w','e','d','o','c','.','m','o','c',0};
1635 HINTERNET ses
, con
, req
;
1639 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1640 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1643 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1644 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1646 con
= WinHttpConnect(ses
, srevaewedoc
, 0, 0);
1647 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1649 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1650 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1652 SetLastError(0xdeadbeef);
1653 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1654 ok(!ret
, "sent request\n");
1655 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
, "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", ret
);
1657 WinHttpCloseHandle(req
);
1658 WinHttpCloseHandle(con
);
1659 WinHttpCloseHandle(ses
);
1661 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1662 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1665 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1666 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1668 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1669 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1671 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1672 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1674 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1675 ok(ret
, "failed to send request\n");
1677 WinHttpCloseHandle(req
);
1678 WinHttpCloseHandle(con
);
1679 WinHttpCloseHandle(ses
);
1682 static const char page1
[] =
1684 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1685 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1688 static const char okmsg
[] =
1689 "HTTP/1.1 200 OK\r\n"
1690 "Server: winetest\r\n"
1693 static const char notokmsg
[] =
1694 "HTTP/1.1 400 Bad Request\r\n"
1695 "Server: winetest\r\n"
1698 static const char noauthmsg
[] =
1699 "HTTP/1.1 401 Unauthorized\r\n"
1700 "Server: winetest\r\n"
1701 "Connection: close\r\n"
1702 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1705 static const char proxymsg
[] =
1706 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1707 "Server: winetest\r\n"
1708 "Proxy-Connection: close\r\n"
1709 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1718 static DWORD CALLBACK
server_thread(LPVOID param
)
1720 struct server_info
*si
= param
;
1723 struct sockaddr_in sa
;
1726 int last_request
= 0;
1728 WSAStartup(MAKEWORD(1,1), &wsaData
);
1730 s
= socket(AF_INET
, SOCK_STREAM
, 0);
1731 if (s
== INVALID_SOCKET
)
1735 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
1737 memset(&sa
, 0, sizeof sa
);
1738 sa
.sin_family
= AF_INET
;
1739 sa
.sin_port
= htons(si
->port
);
1740 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
1742 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
1747 SetEvent(si
->event
);
1750 c
= accept(s
, NULL
, NULL
);
1752 memset(buffer
, 0, sizeof buffer
);
1753 for(i
= 0; i
< sizeof buffer
- 1; i
++)
1755 r
= recv(c
, &buffer
[i
], 1, 0);
1758 if (i
< 4) continue;
1759 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
1760 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
1763 if (strstr(buffer
, "GET /basic"))
1765 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1766 send(c
, page1
, sizeof page1
- 1, 0);
1768 if (strstr(buffer
, "/auth"))
1770 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
1771 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1773 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
1775 if (strstr(buffer
, "/no_headers"))
1777 send(c
, page1
, sizeof page1
- 1, 0);
1779 if (strstr(buffer
, "GET /quit"))
1781 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1782 send(c
, page1
, sizeof page1
- 1, 0);
1788 } while (!last_request
);
1794 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
1796 HINTERNET ses
, con
, req
;
1798 DWORD count
, status
, size
;
1801 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1802 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1804 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1805 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1807 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
1808 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1810 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1811 ok(ret
, "failed to send request %u\n", GetLastError());
1813 ret
= WinHttpReceiveResponse(req
, NULL
);
1814 ok(ret
, "failed to receive response %u\n", GetLastError());
1816 size
= sizeof(status
);
1817 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1818 ok(ret
, "failed to query status code %u\n", GetLastError());
1819 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1822 memset(buffer
, 0, sizeof(buffer
));
1823 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
1824 ok(ret
, "failed to read data %u\n", GetLastError());
1825 ok(count
== sizeof page1
- 1, "count was wrong\n");
1826 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
1828 WinHttpCloseHandle(req
);
1829 WinHttpCloseHandle(con
);
1830 WinHttpCloseHandle(ses
);
1833 static void test_basic_authentication(int port
)
1835 static const WCHAR authW
[] = {'/','a','u','t','h',0};
1836 static const WCHAR userW
[] = {'u','s','e','r',0};
1837 static const WCHAR passW
[] = {'p','w','d',0};
1838 HINTERNET ses
, con
, req
;
1839 DWORD status
, size
, error
;
1842 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1843 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1845 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1846 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1848 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
1849 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1851 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1852 ok(ret
, "failed to send request %u\n", GetLastError());
1854 ret
= WinHttpReceiveResponse(req
, NULL
);
1855 ok(ret
, "failed to receive response %u\n", GetLastError());
1857 size
= sizeof(status
);
1858 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1859 ok(ret
, "failed to query status code %u\n", GetLastError());
1860 ok(status
== 401, "request failed unexpectedly %u\n", status
);
1862 SetLastError(0xdeadbeef);
1863 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
1864 error
= GetLastError();
1865 ok(!ret
, "expected failure\n");
1866 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
1868 SetLastError(0xdeadbeef);
1869 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
1870 error
= GetLastError();
1871 ok(!ret
, "expected failure\n");
1872 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
1874 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
1875 ok(ret
, "failed to set credentials %u\n", GetLastError());
1877 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1878 ok(ret
, "failed to send request %u\n", GetLastError());
1880 ret
= WinHttpReceiveResponse(req
, NULL
);
1881 ok(ret
, "failed to receive response %u\n", GetLastError());
1883 size
= sizeof(status
);
1884 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1885 ok(ret
, "failed to query status code %u\n", GetLastError());
1886 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1888 WinHttpCloseHandle(req
);
1889 WinHttpCloseHandle(con
);
1890 WinHttpCloseHandle(ses
);
1893 static void test_no_headers(int port
)
1895 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1896 HINTERNET ses
, con
, req
;
1899 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1900 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1902 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1903 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1905 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
1906 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1908 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1909 ok(ret
, "failed to send request %u\n", GetLastError());
1911 ret
= WinHttpReceiveResponse(req
, NULL
);
1912 ok(!ret
, "expected failure\n");
1914 WinHttpCloseHandle(req
);
1915 WinHttpCloseHandle(con
);
1916 WinHttpCloseHandle(ses
);
1919 static void test_credentials(void)
1921 static WCHAR userW
[] = {'u','s','e','r',0};
1922 static WCHAR passW
[] = {'p','a','s','s',0};
1923 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
1924 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
1925 HINTERNET ses
, con
, req
;
1930 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
1931 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1933 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
1934 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1936 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1937 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1939 size
= sizeof(buffer
)/sizeof(WCHAR
);
1940 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
1941 ok(ret
, "failed to query proxy username %u\n", GetLastError());
1942 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1943 ok(!size
, "expected 0, got %u\n", size
);
1945 size
= sizeof(buffer
)/sizeof(WCHAR
);
1946 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
1947 ok(ret
, "failed to query proxy password %u\n", GetLastError());
1948 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1949 ok(!size
, "expected 0, got %u\n", size
);
1951 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
1952 ok(ret
, "failed to set username %u\n", GetLastError());
1954 size
= sizeof(buffer
)/sizeof(WCHAR
);
1955 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
1956 ok(ret
, "failed to query proxy username %u\n", GetLastError());
1957 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
1958 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
1960 size
= sizeof(buffer
)/sizeof(WCHAR
);
1961 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
1962 ok(ret
, "failed to query username %u\n", GetLastError());
1963 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1964 ok(!size
, "expected 0, got %u\n", size
);
1966 size
= sizeof(buffer
)/sizeof(WCHAR
);
1967 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
1968 ok(ret
, "failed to query password %u\n", GetLastError());
1969 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1970 ok(!size
, "expected 0, got %u\n", size
);
1972 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
1973 ok(ret
, "failed to set proxy password %u\n", GetLastError());
1975 size
= sizeof(buffer
)/sizeof(WCHAR
);
1976 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
1977 ok(ret
, "failed to query proxy password %u\n", GetLastError());
1978 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
1979 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
1981 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
1982 ok(ret
, "failed to set username %u\n", GetLastError());
1984 size
= sizeof(buffer
)/sizeof(WCHAR
);
1985 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
1986 ok(ret
, "failed to query username %u\n", GetLastError());
1987 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
1988 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
1990 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
1991 ok(ret
, "failed to set password %u\n", GetLastError());
1993 size
= sizeof(buffer
)/sizeof(WCHAR
);
1994 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
1995 ok(ret
, "failed to query password %u\n", GetLastError());
1996 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
1997 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
1999 WinHttpCloseHandle(req
);
2001 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2002 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2004 SetLastError(0xdeadbeef);
2005 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2006 error
= GetLastError();
2007 ok(!ret
, "expected failure\n");
2008 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2010 SetLastError(0xdeadbeef);
2011 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2012 error
= GetLastError();
2013 ok(!ret
, "expected failure\n");
2014 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2016 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2017 ok(ret
, "failed to set credentials %u\n", GetLastError());
2019 size
= sizeof(buffer
)/sizeof(WCHAR
);
2020 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2021 ok(ret
, "failed to query username %u\n", GetLastError());
2023 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2024 ok(!size
, "expected 0, got %u\n", size
);
2027 size
= sizeof(buffer
)/sizeof(WCHAR
);
2028 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2029 ok(ret
, "failed to query password %u\n", GetLastError());
2031 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2032 ok(!size
, "expected 0, got %u\n", size
);
2035 WinHttpCloseHandle(req
);
2036 WinHttpCloseHandle(con
);
2037 WinHttpCloseHandle(ses
);
2040 START_TEST (winhttp
)
2042 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2043 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
2044 struct server_info si
;
2050 test_WinHttpTimeFromSystemTime();
2051 test_WinHttpTimeToSystemTime();
2052 test_WinHttpAddHeaders();
2053 test_secure_connection();
2054 test_request_parameter_defaults();
2056 test_set_default_proxy_config();
2057 test_empty_headers_param();
2059 test_resolve_timeout();
2062 si
.event
= CreateEvent(NULL
, 0, 0, NULL
);
2065 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
2066 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
2068 ret
= WaitForSingleObject(si
.event
, 10000);
2069 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
2070 if (ret
!= WAIT_OBJECT_0
)
2073 test_basic_request(si
.port
, NULL
, basicW
);
2074 test_no_headers(si
.port
);
2075 test_basic_authentication(si
.port
);
2077 /* send the basic request again to shutdown the server thread */
2078 test_basic_request(si
.port
, NULL
, quitW
);
2080 WaitForSingleObject(thread
, 3000);