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 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
216 skip("Connection failed, skipping.\n");
219 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
220 ret
= WinHttpCloseHandle(request
);
221 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
224 ret
= WinHttpCloseHandle(connection
);
225 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
226 ret
= WinHttpCloseHandle(session
);
227 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
231 static void test_empty_headers_param(void)
233 static const WCHAR winehq
[] = {'w','i','n','e','h','q','.','o','r','g',0};
234 static const WCHAR empty
[] = {0};
235 HINTERNET ses
, con
, req
;
238 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
239 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
241 con
= WinHttpConnect(ses
, winehq
, 80, 0);
242 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
244 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
245 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
247 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
248 ok(ret
, "failed to send request %u\n", GetLastError());
250 WinHttpCloseHandle(req
);
251 WinHttpCloseHandle(con
);
252 WinHttpCloseHandle(ses
);
255 static void test_SendRequest (void)
257 HINTERNET session
, request
, connection
;
258 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
;
264 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
265 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
266 static const WCHAR content_type
[] =
267 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
268 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
269 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
270 static const WCHAR test_verb
[] = {'P','O','S','T',0};
271 static CHAR post_data
[] = "mode=Test";
272 static CHAR test_post
[] = "mode => Test\\0\n";
275 total_len
= optional_len
= sizeof(post_data
);
276 memset(buffer
, 0xff, sizeof(buffer
));
278 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
279 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
280 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
282 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
283 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
285 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
286 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
287 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
289 skip("Network unreachable, skipping.\n");
292 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
293 if (!request
) goto done
;
295 context
= 0xdeadbeef;
296 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
297 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
300 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
301 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
304 size
= sizeof(context
);
305 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
306 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
307 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
309 for (i
= 3; post_data
[i
]; i
++)
312 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
314 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
315 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
317 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
318 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
322 ret
= WinHttpReceiveResponse(request
, NULL
);
323 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
326 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
327 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
329 ok(bytes_rw
== strlen(test_post
), "Read %u bytes instead of %d.\n", bytes_rw
, lstrlen(test_post
));
330 ok(strncmp(buffer
, test_post
, bytes_rw
) == 0, "Data read did not match, got '%s'.\n", buffer
);
332 ret
= WinHttpCloseHandle(request
);
333 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
335 ret
= WinHttpCloseHandle(connection
);
336 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
337 ret
= WinHttpCloseHandle(session
);
338 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
341 static void test_WinHttpTimeFromSystemTime(void)
344 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
345 static const WCHAR expected_string
[] =
346 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
347 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
348 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
350 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
351 ok(ret
== TRUE
, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
352 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
353 "Time string returned did not match expected time string.\n");
356 static void test_WinHttpTimeToSystemTime(void)
360 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
361 static const WCHAR time_string1
[] =
362 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
363 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
364 static const WCHAR time_string2
[] =
365 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
366 '1','0',' ','0','5',' ','5','2','\n',0};
368 ret
= WinHttpTimeToSystemTime(time_string1
, &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");
373 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
374 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
375 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
376 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
379 static void test_WinHttpAddHeaders(void)
381 HINTERNET session
, request
, connection
;
383 WCHAR buffer
[MAX_PATH
];
384 WCHAR check_buffer
[MAX_PATH
];
385 DWORD index
, len
, oldlen
;
387 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
388 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
389 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
390 static const WCHAR test_verb
[] = {'P','O','S','T',0};
392 static const WCHAR test_header_begin
[] =
393 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
394 static const WCHAR full_path_test_header_begin
[] =
395 {'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'};
396 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
397 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
399 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
400 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
401 static const WCHAR test_flag_coalesce_comma
[] =
402 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
403 static const WCHAR test_flag_coalesce_comma_reverse
[] =
404 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
405 static const WCHAR test_flag_coalesce_semicolon
[] =
406 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
407 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
408 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
410 static const WCHAR field
[] = {'f','i','e','l','d',0};
411 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
412 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
414 static const WCHAR test_headers
[][14] =
416 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
417 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
418 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
419 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
420 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
421 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
422 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
428 {' ','e',' ',':','f',0},
429 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
431 static const WCHAR test_indices
[][6] =
433 {'t','e','s','t','1',0},
434 {'t','e','s','t','2',0},
435 {'t','e','s','t','3',0},
436 {'t','e','s','t','4',0}
439 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
440 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
441 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
443 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
444 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
446 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
447 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
448 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
450 skip("Network unreachable, skipping.\n");
453 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
456 len
= sizeof(buffer
);
457 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
458 test_header_name
, buffer
, &len
, &index
);
459 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
460 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
461 ok(ret
== TRUE
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, GetLastError());
464 len
= sizeof(buffer
);
465 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
466 test_header_name
, buffer
, &len
, &index
);
467 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
468 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
469 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
470 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
472 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
473 test_header_name
, buffer
, &len
, &index
);
474 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
476 /* Try to fetch the header info with a buffer that's big enough to fit the
477 * string but not the NULL terminator.
480 len
= 5*sizeof(WCHAR
);
481 memset(check_buffer
, 0xab, sizeof(check_buffer
));
482 memcpy(buffer
, check_buffer
, sizeof(buffer
));
483 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
484 test_header_name
, buffer
, &len
, &index
);
485 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
486 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
487 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
488 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
490 /* Try with a NULL buffer */
492 len
= sizeof(buffer
);
493 SetLastError(0xdeadbeef);
494 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
495 test_header_name
, NULL
, &len
, &index
);
496 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
497 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
498 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
499 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
501 /* Try with a NULL buffer and a length that's too small */
504 SetLastError(0xdeadbeef);
505 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
506 test_header_name
, NULL
, &len
, &index
);
507 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
508 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
509 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
510 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
511 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
515 SetLastError(0xdeadbeef);
516 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
517 test_header_name
, NULL
, &len
, &index
);
518 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
520 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
521 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
522 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
527 len
= sizeof(buffer
);
528 memset(buffer
, 0xff, sizeof(buffer
));
529 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
530 test_header_name
, buffer
, &len
, &index
);
531 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
532 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
533 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
534 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
535 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
536 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
537 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
538 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
539 "WinHttpQueryHeaders returned invalid end of header string.\n");
540 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
544 SetLastError(0xdeadbeef);
545 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
546 test_header_name
, NULL
, &len
, &index
);
547 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
548 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
549 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
550 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
551 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
555 len
= sizeof(buffer
);
556 memset(buffer
, 0xff, sizeof(buffer
));
557 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
558 test_header_name
, buffer
, &len
, &index
);
559 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
560 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
561 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
562 "no double NULL terminator\n");
563 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
564 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
565 "invalid beginning of header string.\n");
566 ok(index
== 0, "header index was incremented\n");
568 /* tests for more indices */
569 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
570 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
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
== 1, "WinHttpQueryHeaders failed to increment index.\n");
578 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
580 len
= sizeof(buffer
);
581 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
582 test_header_name
, buffer
, &len
, &index
);
583 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
584 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
585 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
587 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
588 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
591 len
= sizeof(buffer
);
592 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
593 test_header_name
, buffer
, &len
, &index
);
594 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
595 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
596 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
597 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
599 len
= sizeof(buffer
);
600 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
601 test_header_name
, buffer
, &len
, &index
);
602 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
603 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
604 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
606 /* add if new flag */
607 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
608 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\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
== 1, "WinHttpQueryHeaders failed to increment index.\n");
616 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
622 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
623 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
625 len
= sizeof(buffer
);
626 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
627 test_header_name
, buffer
, &len
, &index
);
628 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
631 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
632 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\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
== 1, "WinHttpQueryHeaders failed to increment index.\n");
640 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");
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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
646 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
647 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
649 len
= sizeof(buffer
);
650 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
651 test_header_name
, buffer
, &len
, &index
);
652 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
654 /* coalesce with comma flag */
655 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
656 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
659 len
= sizeof(buffer
);
660 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
661 test_header_name
, buffer
, &len
, &index
);
662 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
663 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
664 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,
665 "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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
671 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
672 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
674 len
= sizeof(buffer
);
675 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
676 test_header_name
, buffer
, &len
, &index
);
677 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
680 /* coalesce with semicolon flag */
681 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
682 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
685 len
= sizeof(buffer
);
686 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
687 test_header_name
, buffer
, &len
, &index
);
688 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
689 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
690 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,
691 "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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
697 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
698 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
700 len
= sizeof(buffer
);
701 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
702 test_header_name
, buffer
, &len
, &index
);
703 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
705 /* add and replace flags */
706 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
707 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\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
== 1, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
721 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
722 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
724 len
= sizeof(buffer
);
725 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
726 test_header_name
, buffer
, &len
, &index
);
727 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
729 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
730 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
732 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
733 ok(ret
, "WinHttpAddRequestHeaders failed\n");
735 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
736 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
738 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
739 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
741 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
742 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
744 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
745 ok(ret
, "WinHttpAddRequestHeaders failed\n");
749 len
= sizeof(buffer
);
750 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
751 field
, buffer
, &len
, &index
);
752 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
753 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
755 ret
= WinHttpCloseHandle(request
);
756 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
758 ret
= WinHttpCloseHandle(connection
);
759 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
760 ret
= WinHttpCloseHandle(session
);
761 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
765 static void test_secure_connection(void)
767 static const WCHAR google
[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
769 HINTERNET ses
, con
, req
;
770 DWORD size
, status
, policy
, bitness
;
774 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
775 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
777 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
778 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
779 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
781 con
= WinHttpConnect(ses
, google
, 443, 0);
782 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
784 /* try without setting WINHTTP_FLAG_SECURE */
785 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
786 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
788 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
789 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
791 skip("Connection failed, skipping.\n");
794 ok(ret
, "failed to send request %u\n", GetLastError());
796 ret
= WinHttpReceiveResponse(req
, NULL
);
797 ok(!ret
, "succeeded unexpectedly\n");
800 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
801 ok(!ret
, "succeeded unexpectedly\n");
803 WinHttpCloseHandle(req
);
805 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
806 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
808 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
809 ok(ret
, "failed to send request %u\n", GetLastError());
812 skip("secure connection failed, skipping remaining secure tests\n");
817 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
818 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
820 CertFreeCertificateContext(cert
);
822 size
= sizeof(bitness
);
823 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
824 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
826 ret
= WinHttpReceiveResponse(req
, NULL
);
827 ok(ret
, "failed to receive response %u\n", GetLastError());
829 size
= sizeof(status
);
830 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
831 ok(ret
, "failed unexpectedly %u\n", GetLastError());
832 ok(status
== 200, "request failed unexpectedly %u\n", status
);
835 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
836 ok(!ret
, "succeeded unexpectedly\n");
839 WinHttpCloseHandle(req
);
840 WinHttpCloseHandle(con
);
841 WinHttpCloseHandle(ses
);
844 static void test_request_parameter_defaults(void)
846 static const WCHAR empty
[] = {0};
847 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
849 HINTERNET ses
, con
, req
;
850 DWORD size
, status
, error
;
854 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
855 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
857 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
858 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
860 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
861 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
863 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
864 ok(ret
, "failed to send request %u\n", GetLastError());
866 ret
= WinHttpReceiveResponse(req
, NULL
);
867 ok(ret
, "failed to receive response %u\n", GetLastError());
869 size
= sizeof(status
);
870 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
871 ok(ret
, "failed unexpectedly %u\n", GetLastError());
872 ok(status
== 200, "request failed unexpectedly %u\n", status
);
874 WinHttpCloseHandle(req
);
876 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
877 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
879 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
880 ok(ret
, "failed to send request %u\n", GetLastError());
882 ret
= WinHttpReceiveResponse(req
, NULL
);
883 ok(ret
, "failed to receive response %u\n", GetLastError());
886 SetLastError(0xdeadbeef);
887 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
888 error
= GetLastError();
889 ok(!ret
, "succeeded unexpectedly\n");
890 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
892 version
= HeapAlloc(GetProcessHeap(), 0, size
);
893 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
894 ok(ret
, "failed unexpectedly %u\n", GetLastError());
895 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
896 HeapFree(GetProcessHeap(), 0, version
);
898 size
= sizeof(status
);
899 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
900 ok(ret
, "failed unexpectedly %u\n", GetLastError());
901 ok(status
== 200, "request failed unexpectedly %u\n", status
);
903 WinHttpCloseHandle(req
);
904 WinHttpCloseHandle(con
);
905 WinHttpCloseHandle(ses
);
908 static const WCHAR Connections
[] = {
909 'S','o','f','t','w','a','r','e','\\',
910 'M','i','c','r','o','s','o','f','t','\\',
911 'W','i','n','d','o','w','s','\\',
912 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
913 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
914 'C','o','n','n','e','c','t','i','o','n','s',0 };
915 static const WCHAR WinHttpSettings
[] = {
916 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
918 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
924 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
929 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
933 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
943 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
948 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
949 KEY_WRITE
, NULL
, &key
, NULL
);
953 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
955 RegDeleteValueW( key
, WinHttpSettings
);
960 static void test_set_default_proxy_config(void)
962 static const WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
963 static const WCHAR normalString
[] = { 'f','o','o',0 };
965 BYTE
*saved_proxy_settings
= NULL
;
966 WINHTTP_PROXY_INFO info
;
969 /* FIXME: it would be simpler to read the current settings using
970 * WinHttpGetDefaultProxyConfiguration and save them using
971 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
973 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
974 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
975 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
976 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
977 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
978 * the lpszProxy and lpszProxyBypass values are ignored.
979 * Thus, if a proxy is set with proxycfg, then calling
980 * WinHttpGetDefaultProxyConfiguration followed by
981 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
982 * getting deleted from the registry.
984 * Instead I read the current registry value and restore it directly.
986 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
989 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
990 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
995 /* Crashes on Vista and higher */
996 SetLastError(0xdeadbeef);
997 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
998 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
999 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1002 /* test with invalid access type */
1003 info
.dwAccessType
= 0xdeadbeef;
1004 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1005 SetLastError(0xdeadbeef);
1006 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1007 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1008 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1010 /* at a minimum, the proxy server must be set */
1011 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1012 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1013 SetLastError(0xdeadbeef);
1014 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1015 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1016 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1017 info
.lpszProxyBypass
= normalString
;
1018 SetLastError(0xdeadbeef);
1019 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1020 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1021 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1023 /* the proxy server can't have wide characters */
1024 info
.lpszProxy
= wideString
;
1025 SetLastError(0xdeadbeef);
1026 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1027 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1028 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1029 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1031 info
.lpszProxy
= normalString
;
1032 SetLastError(0xdeadbeef);
1033 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1036 ok(ret
, "always true\n");
1037 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1039 else if (GetLastError() == ERROR_ACCESS_DENIED
)
1040 skip("couldn't set default proxy configuration: access denied\n");
1042 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1046 static void test_Timeouts (void)
1050 HINTERNET ses
, req
, con
;
1051 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1054 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1055 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1057 SetLastError(0xdeadbeef);
1058 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 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, -2, 0, 0);
1064 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1065 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1067 SetLastError(0xdeadbeef);
1068 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1069 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1070 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1072 SetLastError(0xdeadbeef);
1073 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1074 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1075 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1077 SetLastError(0xdeadbeef);
1078 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1079 ok(ret
, "%u\n", GetLastError());
1081 SetLastError(0xdeadbeef);
1082 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1083 ok(ret
, "%u\n", GetLastError());
1085 SetLastError(0xdeadbeef);
1086 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1087 ok(ret
, "%u\n", GetLastError());
1089 SetLastError(0xdeadbeef);
1091 size
= sizeof(DWORD
);
1092 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1093 ok(ret
, "%u\n", GetLastError());
1094 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1096 SetLastError(0xdeadbeef);
1098 size
= sizeof(DWORD
);
1099 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1100 ok(ret
, "%u\n", GetLastError());
1101 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1103 SetLastError(0xdeadbeef);
1105 size
= sizeof(DWORD
);
1106 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1107 ok(ret
, "%u\n", GetLastError());
1108 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1110 SetLastError(0xdeadbeef);
1112 size
= sizeof(DWORD
);
1113 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1114 ok(ret
, "%u\n", GetLastError());
1115 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1117 SetLastError(0xdeadbeef);
1119 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1120 ok(ret
, "%u\n", GetLastError());
1122 SetLastError(0xdeadbeef);
1124 size
= sizeof(DWORD
);
1125 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1126 ok(ret
, "%u\n", GetLastError());
1127 ok(value
== 0, "Expected 0, got %u\n", value
);
1129 SetLastError(0xdeadbeef);
1131 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1132 ok(ret
, "%u\n", GetLastError());
1134 SetLastError(0xdeadbeef);
1136 size
= sizeof(DWORD
);
1137 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1138 ok(ret
, "%u\n", GetLastError());
1139 ok(value
== 0, "Expected 0, got %u\n", value
);
1141 SetLastError(0xdeadbeef);
1143 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1144 ok(ret
, "%u\n", GetLastError());
1146 SetLastError(0xdeadbeef);
1148 size
= sizeof(DWORD
);
1149 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1150 ok(ret
, "%u\n", GetLastError());
1151 ok(value
== 0, "Expected 0, got %u\n", value
);
1153 SetLastError(0xdeadbeef);
1155 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1156 ok(ret
, "%u\n", GetLastError());
1158 SetLastError(0xdeadbeef);
1160 size
= sizeof(DWORD
);
1161 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1162 ok(ret
, "%u\n", GetLastError());
1163 ok(value
== 0, "Expected 0, got %u\n", value
);
1165 SetLastError(0xdeadbeef);
1167 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1168 ok(ret
, "%u\n", GetLastError());
1170 SetLastError(0xdeadbeef);
1172 size
= sizeof(DWORD
);
1173 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1174 ok(ret
, "%u\n", GetLastError());
1175 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1177 SetLastError(0xdeadbeef);
1179 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1180 ok(ret
, "%u\n", GetLastError());
1182 SetLastError(0xdeadbeef);
1184 size
= sizeof(DWORD
);
1185 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1186 ok(ret
, "%u\n", GetLastError());
1187 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1189 SetLastError(0xdeadbeef);
1191 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1192 ok(ret
, "%u\n", GetLastError());
1194 SetLastError(0xdeadbeef);
1196 size
= sizeof(DWORD
);
1197 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1198 ok(ret
, "%u\n", GetLastError());
1199 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1201 SetLastError(0xdeadbeef);
1203 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1204 ok(ret
, "%u\n", GetLastError());
1206 SetLastError(0xdeadbeef);
1208 size
= sizeof(DWORD
);
1209 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1210 ok(ret
, "%u\n", GetLastError());
1211 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1213 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1214 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1216 /* Timeout values should match the last one set for session */
1217 SetLastError(0xdeadbeef);
1219 size
= sizeof(DWORD
);
1220 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1221 ok(ret
, "%u\n", GetLastError());
1222 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1224 SetLastError(0xdeadbeef);
1226 size
= sizeof(DWORD
);
1227 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1228 ok(ret
, "%u\n", GetLastError());
1229 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1231 SetLastError(0xdeadbeef);
1233 size
= sizeof(DWORD
);
1234 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1235 ok(ret
, "%u\n", GetLastError());
1236 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1238 SetLastError(0xdeadbeef);
1240 size
= sizeof(DWORD
);
1241 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1242 ok(ret
, "%u\n", GetLastError());
1243 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1245 SetLastError(0xdeadbeef);
1246 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 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, -2, 0, 0);
1252 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1253 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1255 SetLastError(0xdeadbeef);
1256 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1257 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1258 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1260 SetLastError(0xdeadbeef);
1261 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1262 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1263 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1265 SetLastError(0xdeadbeef);
1266 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1267 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1268 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1270 SetLastError(0xdeadbeef);
1271 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1272 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1273 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1275 SetLastError(0xdeadbeef);
1277 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1278 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1279 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1281 SetLastError(0xdeadbeef);
1283 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1284 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1285 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1287 SetLastError(0xdeadbeef);
1289 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1290 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1291 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1293 SetLastError(0xdeadbeef);
1295 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1296 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1297 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1299 /* Changing timeout values for session should affect the values for connection */
1300 SetLastError(0xdeadbeef);
1302 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1303 ok(ret
, "%u\n", GetLastError());
1305 SetLastError(0xdeadbeef);
1307 size
= sizeof(DWORD
);
1308 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1309 ok(ret
, "%u\n", GetLastError());
1310 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1312 SetLastError(0xdeadbeef);
1314 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1315 ok(ret
, "%u\n", GetLastError());
1317 SetLastError(0xdeadbeef);
1319 size
= sizeof(DWORD
);
1320 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1321 ok(ret
, "%u\n", GetLastError());
1322 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1324 SetLastError(0xdeadbeef);
1326 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1327 ok(ret
, "%u\n", GetLastError());
1329 SetLastError(0xdeadbeef);
1331 size
= sizeof(DWORD
);
1332 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1333 ok(ret
, "%u\n", GetLastError());
1334 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1336 SetLastError(0xdeadbeef);
1338 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1339 ok(ret
, "%u\n", GetLastError());
1341 SetLastError(0xdeadbeef);
1343 size
= sizeof(DWORD
);
1344 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1345 ok(ret
, "%u\n", GetLastError());
1346 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1348 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1349 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1351 /* Timeout values should match the last one set for session */
1352 SetLastError(0xdeadbeef);
1354 size
= sizeof(DWORD
);
1355 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1356 ok(ret
, "%u\n", GetLastError());
1357 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1359 SetLastError(0xdeadbeef);
1361 size
= sizeof(DWORD
);
1362 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1363 ok(ret
, "%u\n", GetLastError());
1364 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1366 SetLastError(0xdeadbeef);
1368 size
= sizeof(DWORD
);
1369 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1370 ok(ret
, "%u\n", GetLastError());
1371 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1373 SetLastError(0xdeadbeef);
1375 size
= sizeof(DWORD
);
1376 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1377 ok(ret
, "%u\n", GetLastError());
1378 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1380 SetLastError(0xdeadbeef);
1381 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 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, -2, 0, 0);
1387 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1388 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1390 SetLastError(0xdeadbeef);
1391 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1392 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1393 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1395 SetLastError(0xdeadbeef);
1396 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1397 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1398 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1400 SetLastError(0xdeadbeef);
1401 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1402 ok(ret
, "%u\n", GetLastError());
1404 SetLastError(0xdeadbeef);
1405 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1406 ok(ret
, "%u\n", GetLastError());
1408 SetLastError(0xdeadbeef);
1409 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1410 ok(ret
, "%u\n", GetLastError());
1412 SetLastError(0xdeadbeef);
1414 size
= sizeof(DWORD
);
1415 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1416 ok(ret
, "%u\n", GetLastError());
1417 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1419 SetLastError(0xdeadbeef);
1421 size
= sizeof(DWORD
);
1422 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1423 ok(ret
, "%u\n", GetLastError());
1424 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1426 SetLastError(0xdeadbeef);
1428 size
= sizeof(DWORD
);
1429 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1430 ok(ret
, "%u\n", GetLastError());
1431 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1433 SetLastError(0xdeadbeef);
1435 size
= sizeof(DWORD
);
1436 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1437 ok(ret
, "%u\n", GetLastError());
1438 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1440 SetLastError(0xdeadbeef);
1442 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1443 ok(ret
, "%u\n", GetLastError());
1445 SetLastError(0xdeadbeef);
1447 size
= sizeof(DWORD
);
1448 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1449 ok(ret
, "%u\n", GetLastError());
1450 ok(value
== 0, "Expected 0, got %u\n", value
);
1452 SetLastError(0xdeadbeef);
1454 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1455 ok(ret
, "%u\n", GetLastError());
1457 SetLastError(0xdeadbeef);
1459 size
= sizeof(DWORD
);
1460 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1461 ok(ret
, "%u\n", GetLastError());
1462 ok(value
== 0, "Expected 0, got %u\n", value
);
1464 SetLastError(0xdeadbeef);
1466 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1467 ok(ret
, "%u\n", GetLastError());
1469 SetLastError(0xdeadbeef);
1471 size
= sizeof(DWORD
);
1472 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1473 ok(ret
, "%u\n", GetLastError());
1474 ok(value
== 0, "Expected 0, got %u\n", value
);
1476 SetLastError(0xdeadbeef);
1478 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1479 ok(ret
, "%u\n", GetLastError());
1481 SetLastError(0xdeadbeef);
1483 size
= sizeof(DWORD
);
1484 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1485 ok(ret
, "%u\n", GetLastError());
1486 ok(value
== 0, "Expected 0, got %u\n", value
);
1488 SetLastError(0xdeadbeef);
1490 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1491 ok(ret
, "%u\n", GetLastError());
1493 SetLastError(0xdeadbeef);
1495 size
= sizeof(DWORD
);
1496 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1497 ok(ret
, "%u\n", GetLastError());
1498 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1500 SetLastError(0xdeadbeef);
1502 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1503 ok(ret
, "%u\n", GetLastError());
1505 SetLastError(0xdeadbeef);
1507 size
= sizeof(DWORD
);
1508 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1509 ok(ret
, "%u\n", GetLastError());
1510 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1512 SetLastError(0xdeadbeef);
1514 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1515 ok(ret
, "%u\n", GetLastError());
1517 SetLastError(0xdeadbeef);
1519 size
= sizeof(DWORD
);
1520 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1521 ok(ret
, "%u\n", GetLastError());
1522 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1524 SetLastError(0xdeadbeef);
1526 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1527 ok(ret
, "%u\n", GetLastError());
1529 SetLastError(0xdeadbeef);
1531 size
= sizeof(DWORD
);
1532 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1533 ok(ret
, "%u\n", GetLastError());
1534 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1536 /* Changing timeout values for session should not affect the values for a request,
1537 * neither should the other way around.
1539 SetLastError(0xdeadbeef);
1541 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1542 ok(ret
, "%u\n", GetLastError());
1544 SetLastError(0xdeadbeef);
1546 size
= sizeof(DWORD
);
1547 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1548 ok(ret
, "%u\n", GetLastError());
1549 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1551 SetLastError(0xdeadbeef);
1553 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1554 ok(ret
, "%u\n", GetLastError());
1556 SetLastError(0xdeadbeef);
1558 size
= sizeof(DWORD
);
1559 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1560 ok(ret
, "%u\n", GetLastError());
1561 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1563 SetLastError(0xdeadbeef);
1565 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1566 ok(ret
, "%u\n", GetLastError());
1568 SetLastError(0xdeadbeef);
1570 size
= sizeof(DWORD
);
1571 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1572 ok(ret
, "%u\n", GetLastError());
1573 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1575 SetLastError(0xdeadbeef);
1577 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1578 ok(ret
, "%u\n", GetLastError());
1580 SetLastError(0xdeadbeef);
1582 size
= sizeof(DWORD
);
1583 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1584 ok(ret
, "%u\n", GetLastError());
1585 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1587 SetLastError(0xdeadbeef);
1589 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1590 ok(ret
, "%u\n", GetLastError());
1592 SetLastError(0xdeadbeef);
1594 size
= sizeof(DWORD
);
1595 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1596 ok(ret
, "%u\n", GetLastError());
1597 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1599 SetLastError(0xdeadbeef);
1601 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1602 ok(ret
, "%u\n", GetLastError());
1604 SetLastError(0xdeadbeef);
1606 size
= sizeof(DWORD
);
1607 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1608 ok(ret
, "%u\n", GetLastError());
1609 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1611 SetLastError(0xdeadbeef);
1613 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1614 ok(ret
, "%u\n", GetLastError());
1616 SetLastError(0xdeadbeef);
1618 size
= sizeof(DWORD
);
1619 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1620 ok(ret
, "%u\n", GetLastError());
1621 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1623 SetLastError(0xdeadbeef);
1625 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1626 ok(ret
, "%u\n", GetLastError());
1628 SetLastError(0xdeadbeef);
1630 size
= sizeof(DWORD
);
1631 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1632 ok(ret
, "%u\n", GetLastError());
1633 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1635 WinHttpCloseHandle(req
);
1636 WinHttpCloseHandle(con
);
1637 WinHttpCloseHandle(ses
);
1640 static void test_resolve_timeout(void)
1642 static const WCHAR codeweavers
[] =
1643 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1644 static const WCHAR nxdomain
[] =
1645 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1647 HINTERNET ses
, con
, req
;
1651 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1652 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1655 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1656 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1658 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1659 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1661 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1662 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1664 SetLastError(0xdeadbeef);
1665 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1666 ok(!ret
, "sent request\n");
1667 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1668 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1670 WinHttpCloseHandle(req
);
1671 WinHttpCloseHandle(con
);
1672 WinHttpCloseHandle(ses
);
1674 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1675 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1678 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1679 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1681 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1682 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1684 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1685 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1687 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1688 ok(ret
, "failed to send request\n");
1690 WinHttpCloseHandle(req
);
1691 WinHttpCloseHandle(con
);
1692 WinHttpCloseHandle(ses
);
1695 static const char page1
[] =
1697 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1698 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1701 static const char okmsg
[] =
1702 "HTTP/1.1 200 OK\r\n"
1703 "Server: winetest\r\n"
1706 static const char notokmsg
[] =
1707 "HTTP/1.1 400 Bad Request\r\n"
1708 "Server: winetest\r\n"
1711 static const char noauthmsg
[] =
1712 "HTTP/1.1 401 Unauthorized\r\n"
1713 "Server: winetest\r\n"
1714 "Connection: close\r\n"
1715 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1718 static const char proxymsg
[] =
1719 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1720 "Server: winetest\r\n"
1721 "Proxy-Connection: close\r\n"
1722 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1731 static DWORD CALLBACK
server_thread(LPVOID param
)
1733 struct server_info
*si
= param
;
1736 struct sockaddr_in sa
;
1739 int last_request
= 0;
1741 WSAStartup(MAKEWORD(1,1), &wsaData
);
1743 s
= socket(AF_INET
, SOCK_STREAM
, 0);
1744 if (s
== INVALID_SOCKET
)
1748 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
1750 memset(&sa
, 0, sizeof sa
);
1751 sa
.sin_family
= AF_INET
;
1752 sa
.sin_port
= htons(si
->port
);
1753 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
1755 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
1760 SetEvent(si
->event
);
1763 c
= accept(s
, NULL
, NULL
);
1765 memset(buffer
, 0, sizeof buffer
);
1766 for(i
= 0; i
< sizeof buffer
- 1; i
++)
1768 r
= recv(c
, &buffer
[i
], 1, 0);
1771 if (i
< 4) continue;
1772 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
1773 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
1776 if (strstr(buffer
, "GET /basic"))
1778 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1779 send(c
, page1
, sizeof page1
- 1, 0);
1781 if (strstr(buffer
, "/auth"))
1783 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
1784 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1786 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
1788 if (strstr(buffer
, "/no_headers"))
1790 send(c
, page1
, sizeof page1
- 1, 0);
1792 if (strstr(buffer
, "GET /quit"))
1794 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1795 send(c
, page1
, sizeof page1
- 1, 0);
1801 } while (!last_request
);
1807 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
1809 HINTERNET ses
, con
, req
;
1811 DWORD count
, status
, size
;
1814 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1815 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1817 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1818 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1820 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
1821 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1823 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1824 ok(ret
, "failed to send request %u\n", GetLastError());
1826 ret
= WinHttpReceiveResponse(req
, NULL
);
1827 ok(ret
, "failed to receive response %u\n", GetLastError());
1829 size
= sizeof(status
);
1830 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1831 ok(ret
, "failed to query status code %u\n", GetLastError());
1832 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1835 memset(buffer
, 0, sizeof(buffer
));
1836 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
1837 ok(ret
, "failed to read data %u\n", GetLastError());
1838 ok(count
== sizeof page1
- 1, "count was wrong\n");
1839 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
1841 WinHttpCloseHandle(req
);
1842 WinHttpCloseHandle(con
);
1843 WinHttpCloseHandle(ses
);
1846 static void test_basic_authentication(int port
)
1848 static const WCHAR authW
[] = {'/','a','u','t','h',0};
1849 static const WCHAR userW
[] = {'u','s','e','r',0};
1850 static const WCHAR passW
[] = {'p','w','d',0};
1851 HINTERNET ses
, con
, req
;
1852 DWORD status
, size
, error
;
1855 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1856 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1858 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1859 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1861 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
1862 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1864 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1865 ok(ret
, "failed to send request %u\n", GetLastError());
1867 ret
= WinHttpReceiveResponse(req
, NULL
);
1868 ok(ret
, "failed to receive response %u\n", GetLastError());
1870 size
= sizeof(status
);
1871 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1872 ok(ret
, "failed to query status code %u\n", GetLastError());
1873 ok(status
== 401, "request failed unexpectedly %u\n", status
);
1875 SetLastError(0xdeadbeef);
1876 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
1877 error
= GetLastError();
1878 ok(!ret
, "expected failure\n");
1879 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
1881 SetLastError(0xdeadbeef);
1882 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
1883 error
= GetLastError();
1884 ok(!ret
, "expected failure\n");
1885 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
1887 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
1888 ok(ret
, "failed to set credentials %u\n", GetLastError());
1890 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1891 ok(ret
, "failed to send request %u\n", GetLastError());
1893 ret
= WinHttpReceiveResponse(req
, NULL
);
1894 ok(ret
, "failed to receive response %u\n", GetLastError());
1896 size
= sizeof(status
);
1897 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1898 ok(ret
, "failed to query status code %u\n", GetLastError());
1899 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1901 WinHttpCloseHandle(req
);
1902 WinHttpCloseHandle(con
);
1903 WinHttpCloseHandle(ses
);
1906 static void test_no_headers(int port
)
1908 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1909 HINTERNET ses
, con
, req
;
1912 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1913 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1915 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1916 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1918 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
1919 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1921 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1922 ok(ret
, "failed to send request %u\n", GetLastError());
1924 ret
= WinHttpReceiveResponse(req
, NULL
);
1925 ok(!ret
, "expected failure\n");
1927 WinHttpCloseHandle(req
);
1928 WinHttpCloseHandle(con
);
1929 WinHttpCloseHandle(ses
);
1932 static void test_credentials(void)
1934 static WCHAR userW
[] = {'u','s','e','r',0};
1935 static WCHAR passW
[] = {'p','a','s','s',0};
1936 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
1937 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
1938 HINTERNET ses
, con
, req
;
1943 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
1944 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1946 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
1947 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1949 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1950 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1952 size
= sizeof(buffer
)/sizeof(WCHAR
);
1953 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
1954 ok(ret
, "failed to query proxy username %u\n", GetLastError());
1955 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1956 ok(!size
, "expected 0, got %u\n", size
);
1958 size
= sizeof(buffer
)/sizeof(WCHAR
);
1959 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
1960 ok(ret
, "failed to query proxy password %u\n", GetLastError());
1961 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1962 ok(!size
, "expected 0, got %u\n", size
);
1964 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
1965 ok(ret
, "failed to set username %u\n", GetLastError());
1967 size
= sizeof(buffer
)/sizeof(WCHAR
);
1968 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
1969 ok(ret
, "failed to query proxy username %u\n", GetLastError());
1970 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
1971 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
1973 size
= sizeof(buffer
)/sizeof(WCHAR
);
1974 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
1975 ok(ret
, "failed to query username %u\n", GetLastError());
1976 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1977 ok(!size
, "expected 0, got %u\n", size
);
1979 size
= sizeof(buffer
)/sizeof(WCHAR
);
1980 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
1981 ok(ret
, "failed to query password %u\n", GetLastError());
1982 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
1983 ok(!size
, "expected 0, got %u\n", size
);
1985 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
1986 ok(ret
, "failed to set proxy password %u\n", GetLastError());
1988 size
= sizeof(buffer
)/sizeof(WCHAR
);
1989 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
1990 ok(ret
, "failed to query proxy password %u\n", GetLastError());
1991 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
1992 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
1994 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
1995 ok(ret
, "failed to set username %u\n", GetLastError());
1997 size
= sizeof(buffer
)/sizeof(WCHAR
);
1998 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
1999 ok(ret
, "failed to query username %u\n", GetLastError());
2000 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2001 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2003 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2004 ok(ret
, "failed to set password %u\n", GetLastError());
2006 size
= sizeof(buffer
)/sizeof(WCHAR
);
2007 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2008 ok(ret
, "failed to query password %u\n", GetLastError());
2009 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2010 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2012 WinHttpCloseHandle(req
);
2014 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2015 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2017 SetLastError(0xdeadbeef);
2018 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2019 error
= GetLastError();
2020 ok(!ret
, "expected failure\n");
2021 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2023 SetLastError(0xdeadbeef);
2024 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2025 error
= GetLastError();
2026 ok(!ret
, "expected failure\n");
2027 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2029 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2030 ok(ret
, "failed to set credentials %u\n", GetLastError());
2032 size
= sizeof(buffer
)/sizeof(WCHAR
);
2033 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2034 ok(ret
, "failed to query username %u\n", GetLastError());
2036 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2037 ok(!size
, "expected 0, got %u\n", size
);
2040 size
= sizeof(buffer
)/sizeof(WCHAR
);
2041 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2042 ok(ret
, "failed to query password %u\n", GetLastError());
2044 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2045 ok(!size
, "expected 0, got %u\n", size
);
2048 WinHttpCloseHandle(req
);
2049 WinHttpCloseHandle(con
);
2050 WinHttpCloseHandle(ses
);
2053 START_TEST (winhttp
)
2055 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2056 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
2057 struct server_info si
;
2063 test_WinHttpTimeFromSystemTime();
2064 test_WinHttpTimeToSystemTime();
2065 test_WinHttpAddHeaders();
2066 test_secure_connection();
2067 test_request_parameter_defaults();
2069 test_set_default_proxy_config();
2070 test_empty_headers_param();
2072 test_resolve_timeout();
2075 si
.event
= CreateEvent(NULL
, 0, 0, NULL
);
2078 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
2079 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
2081 ret
= WaitForSingleObject(si
.event
, 10000);
2082 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
2083 if (ret
!= WAIT_OBJECT_0
)
2086 test_basic_request(si
.port
, NULL
, basicW
);
2087 test_no_headers(si
.port
);
2088 test_basic_authentication(si
.port
);
2090 /* send the basic request again to shutdown the server thread */
2091 test_basic_request(si
.port
, NULL
, quitW
);
2093 WaitForSingleObject(thread
, 3000);