1 /* 2 * WinHTTP - tests 3 * 4 * Copyright 2008 Google (Zac Brown) 5 * Copyright 2015 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #define WIN32_NO_STATUS 23 #define _INC_WINDOWS 24 #define COM_NO_WINDOWS_H 25 26 #define COBJMACROS 27 #include <stdarg.h> 28 #include <windef.h> 29 #include <winbase.h> 30 #include <winnls.h> 31 #include <ole2.h> 32 #include <winsock2.h> 33 //#include <ws2tcpip.h> 34 #include <winhttp.h> 35 #include <wincrypt.h> 36 #include <winreg.h> 37 #include <stdio.h> 38 //#include "initguid.h" 39 #include <httprequest.h> 40 #include <httprequestid.h> 41 42 #include <wine/test.h> 43 44 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 45 46 static const WCHAR test_useragent[] = 47 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0}; 48 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; 49 static const WCHAR test_winehq_https[] = {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','4','4','3',0}; 50 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0}; 51 52 static BOOL proxy_active(void) 53 { 54 WINHTTP_PROXY_INFO proxy_info; 55 BOOL active = FALSE; 56 57 SetLastError(0xdeadbeef); 58 if (WinHttpGetDefaultProxyConfiguration(&proxy_info)) 59 { 60 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 61 "got %u\n", GetLastError()); 62 active = (proxy_info.lpszProxy != NULL); 63 if (active) 64 GlobalFree(proxy_info.lpszProxy); 65 if (proxy_info.lpszProxyBypass != NULL) 66 GlobalFree(proxy_info.lpszProxyBypass); 67 } 68 else 69 active = FALSE; 70 71 return active; 72 } 73 74 static void test_QueryOption(void) 75 { 76 BOOL ret; 77 HINTERNET session, request, connection; 78 DWORD feature, size; 79 80 SetLastError(0xdeadbeef); 81 session = WinHttpOpen(test_useragent, 0, 0, 0, 0); 82 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError()); 83 84 SetLastError(0xdeadbeef); 85 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL); 86 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 87 ok(GetLastError() == ERROR_INVALID_PARAMETER, 88 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 89 90 size = 0xdeadbeef; 91 SetLastError(0xdeadbeef); 92 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size); 93 ok(!ret, "should fail to query option\n"); 94 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 95 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 96 ok(size == 4, "expected 4, got %u\n", size); 97 98 feature = 0xdeadbeef; 99 size = sizeof(feature) - 1; 100 SetLastError(0xdeadbeef); 101 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); 102 ok(!ret, "should fail to query option\n"); 103 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 104 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 105 ok(size == 4, "expected 4, got %u\n", size); 106 107 feature = 0xdeadbeef; 108 size = sizeof(feature) + 1; 109 SetLastError(0xdeadbeef); 110 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); 111 ok(ret, "failed to query option %u\n", GetLastError()); 112 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 113 "got %u\n", GetLastError()); 114 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size); 115 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, 116 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature); 117 118 SetLastError(0xdeadbeef); 119 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature)); 120 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 121 ok(GetLastError() == ERROR_INVALID_PARAMETER, 122 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 123 124 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 125 SetLastError(0xdeadbeef); 126 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1); 127 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 128 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 129 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 130 131 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 132 SetLastError(0xdeadbeef); 133 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1); 134 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 135 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 136 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 137 138 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 139 SetLastError(0xdeadbeef); 140 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature)); 141 ok(ret, "failed to set redirect policy %u\n", GetLastError()); 142 143 feature = 0xdeadbeef; 144 size = sizeof(feature); 145 SetLastError(0xdeadbeef); 146 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); 147 ok(ret, "failed to query option %u\n", GetLastError()); 148 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, 149 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature); 150 151 feature = WINHTTP_DISABLE_COOKIES; 152 SetLastError(0xdeadbeef); 153 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 154 ok(!ret, "should fail to set disable feature for a session\n"); 155 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 156 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError()); 157 158 SetLastError(0xdeadbeef); 159 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 160 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError()); 161 162 feature = WINHTTP_DISABLE_COOKIES; 163 SetLastError(0xdeadbeef); 164 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 165 ok(!ret, "should fail to set disable feature for a connection\n"); 166 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 167 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError()); 168 169 SetLastError(0xdeadbeef); 170 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER, 171 WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 172 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) 173 { 174 skip("Network unreachable, skipping the test\n"); 175 goto done; 176 } 177 178 feature = 0xdeadbeef; 179 size = sizeof(feature); 180 SetLastError(0xdeadbeef); 181 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size); 182 ok(!ret, "should fail to query disable feature for a request\n"); 183 ok(GetLastError() == ERROR_INVALID_PARAMETER, 184 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 185 186 feature = 0; 187 size = sizeof(feature); 188 SetLastError(0xdeadbeef); 189 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 190 ok(ret, "failed to set feature %u\n", GetLastError()); 191 192 feature = 0xffffffff; 193 size = sizeof(feature); 194 SetLastError(0xdeadbeef); 195 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 196 ok(ret, "failed to set feature %u\n", GetLastError()); 197 198 feature = WINHTTP_DISABLE_COOKIES; 199 size = sizeof(feature); 200 SetLastError(0xdeadbeef); 201 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 202 ok(ret, "failed to set feature %u\n", GetLastError()); 203 204 size = 0; 205 SetLastError(0xdeadbeef); 206 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size); 207 ok(!ret, "should fail to query disable feature for a request\n"); 208 ok(GetLastError() == ERROR_INVALID_PARAMETER, 209 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 210 211 SetLastError(0xdeadbeef); 212 ret = WinHttpCloseHandle(request); 213 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError()); 214 215 done: 216 SetLastError(0xdeadbeef); 217 ret = WinHttpCloseHandle(connection); 218 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError()); 219 SetLastError(0xdeadbeef); 220 ret = WinHttpCloseHandle(session); 221 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError()); 222 } 223 224 static void test_OpenRequest (void) 225 { 226 BOOL ret; 227 HINTERNET session, request, connection; 228 DWORD err; 229 230 SetLastError(0xdeadbeef); 231 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 232 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 233 err = GetLastError(); 234 ok(session != NULL, "WinHttpOpen failed to open session.\n"); 235 ok(err == ERROR_SUCCESS, "got %u\n", err); 236 237 /* Test with a bad server name */ 238 SetLastError(0xdeadbeef); 239 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0); 240 err = GetLastError(); 241 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n"); 242 ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err); 243 244 /* Test with a valid server name */ 245 SetLastError(0xdeadbeef); 246 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 247 err = GetLastError(); 248 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err); 249 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err); 250 251 SetLastError(0xdeadbeef); 252 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER, 253 WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 254 err = GetLastError(); 255 if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED) 256 { 257 skip("Network unreachable, skipping.\n"); 258 goto done; 259 } 260 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err); 261 ok(err == ERROR_SUCCESS, "got %u\n", err); 262 263 SetLastError(0xdeadbeef); 264 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0); 265 err = GetLastError(); 266 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 267 { 268 skip("Connection failed, skipping.\n"); 269 goto done; 270 } 271 ok(ret, "WinHttpSendRequest failed: %u\n", err); 272 ok(err == ERROR_SUCCESS, "got %u\n", err); 273 274 SetLastError(0xdeadbeef); 275 ret = WinHttpCloseHandle(request); 276 err = GetLastError(); 277 ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err); 278 ok(err == ERROR_SUCCESS, "got %u\n", err); 279 280 done: 281 ret = WinHttpCloseHandle(connection); 282 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret); 283 ret = WinHttpCloseHandle(session); 284 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret); 285 286 } 287 288 static void test_empty_headers_param(void) 289 { 290 static const WCHAR empty[] = {0}; 291 HINTERNET ses, con, req; 292 DWORD err; 293 BOOL ret; 294 295 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 296 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 297 298 con = WinHttpConnect(ses, test_winehq, 80, 0); 299 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 300 301 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 302 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 303 304 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0); 305 err = GetLastError(); 306 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 307 { 308 skip("connection failed, skipping\n"); 309 goto done; 310 } 311 ok(ret, "failed to send request %u\n", GetLastError()); 312 313 done: 314 WinHttpCloseHandle(req); 315 WinHttpCloseHandle(con); 316 WinHttpCloseHandle(ses); 317 } 318 319 static void test_SendRequest (void) 320 { 321 static const WCHAR content_type[] = 322 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n', 323 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0}; 324 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0}; 325 static const WCHAR test_verb[] = {'P','O','S','T',0}; 326 static CHAR post_data[] = "mode=Test"; 327 static const char test_post[] = "mode => Test\0\n"; 328 HINTERNET session, request, connection; 329 DWORD header_len, optional_len, total_len, bytes_rw, size, err, disable; 330 DWORD_PTR context; 331 BOOL ret; 332 CHAR buffer[256]; 333 int i; 334 335 header_len = -1L; 336 total_len = optional_len = sizeof(post_data); 337 memset(buffer, 0xff, sizeof(buffer)); 338 339 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 340 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 341 ok(session != NULL, "WinHttpOpen failed to open session.\n"); 342 343 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 344 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError()); 345 346 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER, 347 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE); 348 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) 349 { 350 skip("Network unreachable, skipping.\n"); 351 goto done; 352 } 353 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError()); 354 if (!request) goto done; 355 356 context = 0xdeadbeef; 357 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context)); 358 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError()); 359 360 /* writing more data than promised by the content-length header causes an error when the connection 361 is resued, so disable keep-alive */ 362 disable = WINHTTP_DISABLE_KEEP_ALIVE; 363 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable)); 364 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError()); 365 366 context++; 367 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context); 368 err = GetLastError(); 369 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 370 { 371 skip("connection failed, skipping\n"); 372 goto done; 373 } 374 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError()); 375 376 context = 0; 377 size = sizeof(context); 378 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size); 379 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError()); 380 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context); 381 382 for (i = 3; post_data[i]; i++) 383 { 384 bytes_rw = -1; 385 SetLastError(0xdeadbeef); 386 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw); 387 if (ret) 388 { 389 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError()); 390 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw); 391 } 392 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */ 393 { 394 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError()); 395 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n"); 396 } 397 } 398 399 SetLastError(0xdeadbeef); 400 ret = WinHttpReceiveResponse(request, NULL); 401 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */, 402 "Expected ERROR_SUCCESS got %u.\n", GetLastError()); 403 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError()); 404 405 bytes_rw = -1; 406 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw); 407 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError()); 408 409 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw); 410 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n"); 411 412 done: 413 ret = WinHttpCloseHandle(request); 414 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret); 415 ret = WinHttpCloseHandle(connection); 416 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret); 417 ret = WinHttpCloseHandle(session); 418 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret); 419 } 420 421 static void test_WinHttpTimeFromSystemTime(void) 422 { 423 BOOL ret; 424 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0}; 425 static const WCHAR expected_string[] = 426 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ', 427 '1','0',':','0','5',':','5','2',' ','G','M','T',0}; 428 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1]; 429 DWORD err; 430 431 SetLastError(0xdeadbeef); 432 ret = WinHttpTimeFromSystemTime(&time, NULL); 433 err = GetLastError(); 434 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n"); 435 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 436 437 SetLastError(0xdeadbeef); 438 ret = WinHttpTimeFromSystemTime(NULL, time_string); 439 err = GetLastError(); 440 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n"); 441 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 442 443 SetLastError(0xdeadbeef); 444 ret = WinHttpTimeFromSystemTime(&time, time_string); 445 err = GetLastError(); 446 ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err); 447 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 448 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0, 449 "Time string returned did not match expected time string.\n"); 450 } 451 452 static void test_WinHttpTimeToSystemTime(void) 453 { 454 BOOL ret; 455 SYSTEMTIME time; 456 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0}; 457 static const WCHAR time_string1[] = 458 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ', 459 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0}; 460 static const WCHAR time_string2[] = 461 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ', 462 '1','0',' ','0','5',' ','5','2','\n',0}; 463 DWORD err; 464 465 SetLastError(0xdeadbeef); 466 ret = WinHttpTimeToSystemTime(time_string1, NULL); 467 err = GetLastError(); 468 ok(!ret, "WinHttpTimeToSystemTime succeeded\n"); 469 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 470 471 SetLastError(0xdeadbeef); 472 ret = WinHttpTimeToSystemTime(NULL, &time); 473 err = GetLastError(); 474 ok(!ret, "WinHttpTimeToSystemTime succeeded\n"); 475 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 476 477 SetLastError(0xdeadbeef); 478 ret = WinHttpTimeToSystemTime(time_string1, &time); 479 err = GetLastError(); 480 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err); 481 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 482 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0, 483 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n"); 484 485 SetLastError(0xdeadbeef); 486 ret = WinHttpTimeToSystemTime(time_string2, &time); 487 err = GetLastError(); 488 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err); 489 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 490 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0, 491 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n"); 492 } 493 494 static void test_WinHttpAddHeaders(void) 495 { 496 HINTERNET session, request, connection; 497 BOOL ret, reverse; 498 WCHAR buffer[MAX_PATH]; 499 WCHAR check_buffer[MAX_PATH]; 500 DWORD err, index, len, oldlen; 501 502 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0}; 503 static const WCHAR test_verb[] = {'P','O','S','T',0}; 504 static const WCHAR test_header_begin[] = 505 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'}; 506 static const WCHAR full_path_test_header_begin[] = 507 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0', 508 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'}; 509 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0}; 510 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0}; 511 static const WCHAR test_header_name2[] = {'n','a','m','e',0}; 512 static const WCHAR test_header_name3[] = {'a',0}; 513 static const WCHAR test_header_range[] = {'R','a','n','g','e',0}; 514 static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0}; 515 static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0}; 516 517 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0}; 518 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0}; 519 static const WCHAR test_flag_coalesce_comma[] = 520 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0}; 521 static const WCHAR test_flag_coalesce_comma_reverse[] = 522 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0}; 523 static const WCHAR test_flag_coalesce_semicolon[] = 524 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0}; 525 static const WCHAR test_flag_coalesce_semicolon_reverse[] = 526 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0}; 527 528 static const WCHAR field[] = {'f','i','e','l','d',0}; 529 static const WCHAR value[] = {'v','a','l','u','e',' ',0}; 530 static const WCHAR value_nospace[] = {'v','a','l','u','e',0}; 531 static const WCHAR empty[] = {0}; 532 533 static const WCHAR test_headers[][14] = 534 { 535 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0}, 536 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0}, 537 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0}, 538 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0}, 539 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0}, 540 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0}, 541 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0}, 542 {0}, 543 {':',0}, 544 {'a',':',0}, 545 {':','b',0}, 546 {'c','d',0}, 547 {' ','e',' ',':','f',0}, 548 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}, 549 {'n','a','m','e',':',' ','v','a','l','u','e',0}, 550 {'n','a','m','e',':',0} 551 }; 552 static const WCHAR test_indices[][6] = 553 { 554 {'t','e','s','t','1',0}, 555 {'t','e','s','t','2',0}, 556 {'t','e','s','t','3',0}, 557 {'t','e','s','t','4',0} 558 }; 559 560 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 561 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 562 ok(session != NULL, "WinHttpOpen failed to open session.\n"); 563 564 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 565 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError()); 566 567 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER, 568 WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 569 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) 570 { 571 skip("Network unreachable, skipping.\n"); 572 goto done; 573 } 574 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError()); 575 576 index = 0; 577 len = sizeof(buffer); 578 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 579 test_header_name, buffer, &len, &index); 580 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n"); 581 SetLastError(0xdeadbeef); 582 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD); 583 err = GetLastError(); 584 ok(ret, "WinHttpAddRequestHeaders failed to add new header, got %d with error %u.\n", ret, err); 585 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 586 587 index = 0; 588 len = sizeof(buffer); 589 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 590 test_header_name, buffer, &len, &index); 591 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 592 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n"); 593 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n"); 594 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len); 595 596 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 597 test_header_name, buffer, &len, &index); 598 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n"); 599 600 /* Try to fetch the header info with a buffer that's big enough to fit the 601 * string but not the NULL terminator. 602 */ 603 index = 0; 604 len = 5*sizeof(WCHAR); 605 memset(check_buffer, 0xab, sizeof(check_buffer)); 606 memcpy(buffer, check_buffer, sizeof(buffer)); 607 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 608 test_header_name, buffer, &len, &index); 609 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n"); 610 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0, 611 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n"); 612 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len); 613 614 /* Try with a NULL buffer */ 615 index = 0; 616 len = sizeof(buffer); 617 SetLastError(0xdeadbeef); 618 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 619 test_header_name, NULL, &len, &index); 620 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 621 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 622 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 623 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n"); 624 625 /* Try with a NULL buffer and a length that's too small */ 626 index = 0; 627 len = 10; 628 SetLastError(0xdeadbeef); 629 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 630 test_header_name, NULL, &len, &index); 631 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 632 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 633 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError()); 634 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 635 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n"); 636 637 index = 0; 638 len = 0; 639 SetLastError(0xdeadbeef); 640 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 641 test_header_name, NULL, &len, &index); 642 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 643 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 644 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 645 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 646 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n"); 647 648 /* valid query */ 649 oldlen = len; 650 index = 0; 651 len = sizeof(buffer); 652 memset(buffer, 0xff, sizeof(buffer)); 653 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 654 test_header_name, buffer, &len, &index); 655 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret); 656 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n"); 657 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n"); 658 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n"); 659 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 || 660 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0, 661 "WinHttpQueryHeaders returned invalid beginning of header string.\n"); 662 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0, 663 "WinHttpQueryHeaders returned invalid end of header string.\n"); 664 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n"); 665 666 index = 0; 667 len = 0; 668 SetLastError(0xdeadbeef); 669 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 670 test_header_name, NULL, &len, &index); 671 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 672 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 673 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 674 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 675 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n"); 676 677 oldlen = len; 678 index = 0; 679 len = sizeof(buffer); 680 memset(buffer, 0xff, sizeof(buffer)); 681 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 682 test_header_name, buffer, &len, &index); 683 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError()); 684 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n"); 685 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1], 686 "no double NULL terminator\n"); 687 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 || 688 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0, 689 "invalid beginning of header string.\n"); 690 ok(index == 0, "header index was incremented\n"); 691 692 /* tests for more indices */ 693 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD); 694 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret); 695 696 index = 0; 697 len = sizeof(buffer); 698 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 699 test_header_name, buffer, &len, &index); 700 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 701 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 702 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 703 704 len = sizeof(buffer); 705 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 706 test_header_name, buffer, &len, &index); 707 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 708 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 709 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 710 711 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE); 712 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n"); 713 714 index = 0; 715 len = sizeof(buffer); 716 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 717 test_header_name, buffer, &len, &index); 718 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 719 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 720 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */ 721 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 722 723 len = sizeof(buffer); 724 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 725 test_header_name, buffer, &len, &index); 726 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 727 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 728 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 729 730 /* add if new flag */ 731 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW); 732 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n"); 733 734 index = 0; 735 len = sizeof(buffer); 736 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 737 test_header_name, buffer, &len, &index); 738 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 739 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 740 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 741 742 len = sizeof(buffer); 743 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 744 test_header_name, buffer, &len, &index); 745 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 746 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 747 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 748 749 len = sizeof(buffer); 750 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 751 test_header_name, buffer, &len, &index); 752 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 753 754 /* coalesce flag */ 755 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE); 756 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n"); 757 758 index = 0; 759 len = sizeof(buffer); 760 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 761 test_header_name, buffer, &len, &index); 762 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 763 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 764 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce, 765 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 766 767 len = sizeof(buffer); 768 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 769 test_header_name, buffer, &len, &index); 770 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 771 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 772 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 773 774 len = sizeof(buffer); 775 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 776 test_header_name, buffer, &len, &index); 777 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 778 779 /* coalesce with comma flag */ 780 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA); 781 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n"); 782 783 index = 0; 784 len = sizeof(buffer); 785 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 786 test_header_name, buffer, &len, &index); 787 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 788 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 789 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma, 790 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0, 791 "WinHttpQueryHeaders returned incorrect string.\n"); 792 793 len = sizeof(buffer); 794 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 795 test_header_name, buffer, &len, &index); 796 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 797 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 798 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 799 800 len = sizeof(buffer); 801 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 802 test_header_name, buffer, &len, &index); 803 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 804 805 806 /* coalesce with semicolon flag */ 807 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON); 808 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n"); 809 810 index = 0; 811 len = sizeof(buffer); 812 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 813 test_header_name, buffer, &len, &index); 814 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 815 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 816 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon, 817 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0, 818 "WinHttpQueryHeaders returned incorrect string.\n"); 819 820 len = sizeof(buffer); 821 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 822 test_header_name, buffer, &len, &index); 823 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 824 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 825 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 826 827 len = sizeof(buffer); 828 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 829 test_header_name, buffer, &len, &index); 830 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 831 832 /* add and replace flags */ 833 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); 834 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n"); 835 836 index = 0; 837 len = sizeof(buffer); 838 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 839 test_header_name, buffer, &len, &index); 840 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 841 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 842 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 843 844 len = sizeof(buffer); 845 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 846 test_header_name, buffer, &len, &index); 847 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 848 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 849 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 850 851 len = sizeof(buffer); 852 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 853 test_header_name, buffer, &len, &index); 854 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 855 856 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 857 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 858 859 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 860 ok(ret, "WinHttpAddRequestHeaders failed\n"); 861 862 index = 0; 863 memset(buffer, 0xff, sizeof(buffer)); 864 len = sizeof(buffer); 865 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 866 test_header_name3, buffer, &len, &index); 867 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 868 ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n"); 869 870 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 871 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 872 873 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 874 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 875 876 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 877 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 878 879 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 880 ok(ret, "WinHttpAddRequestHeaders failed\n"); 881 882 index = 0; 883 buffer[0] = 0; 884 len = sizeof(buffer); 885 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 886 field, buffer, &len, &index); 887 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 888 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n"); 889 890 SetLastError(0xdeadbeef); 891 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, 0, 892 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); 893 err = GetLastError(); 894 ok(!ret, "unexpected success\n"); 895 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 896 897 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, ~0u, 898 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); 899 ok(ret, "failed to add header: %u\n", GetLastError()); 900 901 index = 0; 902 len = sizeof(buffer); 903 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 904 test_header_range, buffer, &len, &index); 905 ok(ret, "failed to get range header %u\n", GetLastError()); 906 ok(!memcmp(buffer, test_header_bytes, sizeof(test_header_bytes)), "incorrect string returned\n"); 907 ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len); 908 ok(index == 1, "wrong index %u\n", index); 909 910 index = 0; 911 len = sizeof(buffer); 912 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 913 test_header_name2, buffer, &len, &index); 914 ok(!ret, "unexpected success\n"); 915 916 SetLastError(0xdeadbeef); 917 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE); 918 err = GetLastError(); 919 ok(!ret, "unexpected success\n"); 920 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err); 921 922 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 923 ok(ret, "got %u\n", GetLastError()); 924 925 index = 0; 926 len = sizeof(buffer); 927 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 928 test_header_name2, buffer, &len, &index); 929 ok(ret, "got %u\n", GetLastError()); 930 ok(index == 1, "wrong index %u\n", index); 931 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n"); 932 933 ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE); 934 ok(ret, "got %u\n", GetLastError()); 935 936 index = 0; 937 len = sizeof(buffer); 938 SetLastError(0xdeadbeef); 939 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 940 test_header_name2, buffer, &len, &index); 941 err = GetLastError(); 942 ok(!ret, "unexpected success\n"); 943 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err); 944 945 ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0); 946 ok(ret, "got %u\n", GetLastError()); 947 948 index = 0; 949 len = sizeof(buffer); 950 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 951 test_header_name2, buffer, &len, &index); 952 ok(ret, "got %u\n", GetLastError()); 953 ok(index == 1, "wrong index %u\n", index); 954 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n"); 955 956 ret = WinHttpCloseHandle(request); 957 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret); 958 done: 959 ret = WinHttpCloseHandle(connection); 960 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret); 961 ret = WinHttpCloseHandle(session); 962 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret); 963 964 } 965 966 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len) 967 { 968 DWORD flags = *(DWORD *)buf; 969 970 if (!flags) 971 { 972 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n"); 973 return; 974 } 975 #define X(x) if (flags & x) trace("%s\n", #x); 976 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED) 977 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT) 978 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED) 979 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA) 980 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID) 981 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID) 982 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE) 983 #undef X 984 } 985 986 static void test_secure_connection(void) 987 { 988 static const char data_start[] = "<!DOCTYPE html PUBLIC"; 989 HINTERNET ses, con, req; 990 DWORD size, status, policy, bitness, read_size, err, available_size, protocols; 991 BOOL ret; 992 CERT_CONTEXT *cert; 993 WINHTTP_CERTIFICATE_INFO info; 994 char buffer[32]; 995 996 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 997 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 998 999 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 1000 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy)); 1001 ok(ret, "failed to set redirect policy %u\n", GetLastError()); 1002 1003 protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; 1004 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols)); 1005 err = GetLastError(); 1006 ok(ret || err == ERROR_INVALID_PARAMETER /* < win7 */, "failed to set protocols %u\n", err); 1007 1008 con = WinHttpConnect(ses, test_winehq, 443, 0); 1009 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1010 1011 /* try without setting WINHTTP_FLAG_SECURE */ 1012 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1013 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1014 1015 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0); 1016 err = GetLastError(); 1017 ok(!ret, "unexpected success\n"); 1018 ok(err == ERROR_WINHTTP_INCORRECT_HANDLE_STATE || broken(err == ERROR_INVALID_PARAMETER) /* winxp */, 1019 "setting client cert context returned %u\n", err); 1020 1021 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1022 err = GetLastError(); 1023 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 1024 { 1025 skip("Connection failed, skipping.\n"); 1026 goto cleanup; 1027 } 1028 ok(ret, "failed to send request %u\n", GetLastError()); 1029 1030 ret = WinHttpReceiveResponse(req, NULL); 1031 ok(ret, "failed to receive response %u\n", GetLastError()); 1032 1033 status = 0xdeadbeef; 1034 size = sizeof(status); 1035 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1036 ok(ret, "header query failed %u\n", GetLastError()); 1037 ok(status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status); 1038 1039 WinHttpCloseHandle(req); 1040 1041 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE); 1042 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1043 1044 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0); 1045 err = GetLastError(); 1046 ok(ret || broken(!ret && err == ERROR_INVALID_PARAMETER) /* winxp */, "failed to set client cert context %u\n", err); 1047 1048 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0); 1049 1050 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1051 err = GetLastError(); 1052 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT || 1053 err == ERROR_WINHTTP_TIMEOUT)) 1054 { 1055 skip("secure connection failed, skipping remaining secure tests\n"); 1056 goto cleanup; 1057 } 1058 ok(ret, "failed to send request %u\n", GetLastError()); 1059 1060 size = sizeof(cert); 1061 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size ); 1062 ok(ret, "failed to retrieve certificate context %u\n", GetLastError()); 1063 if (ret) CertFreeCertificateContext(cert); 1064 1065 size = sizeof(bitness); 1066 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size ); 1067 ok(ret, "failed to retrieve key bitness %u\n", GetLastError()); 1068 1069 size = sizeof(info); 1070 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size ); 1071 ok(ret, "failed to retrieve certificate info %u\n", GetLastError()); 1072 1073 if (ret) 1074 { 1075 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo)); 1076 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo)); 1077 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName)); 1078 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName)); 1079 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName)); 1080 trace("dwKeySize %u\n", info.dwKeySize); 1081 LocalFree( info.lpszSubjectInfo ); 1082 LocalFree( info.lpszIssuerInfo ); 1083 } 1084 1085 ret = WinHttpReceiveResponse(req, NULL); 1086 ok(ret, "failed to receive response %u\n", GetLastError()); 1087 1088 available_size = 0; 1089 ret = WinHttpQueryDataAvailable(req, &available_size); 1090 ok(ret, "failed to query available data %u\n", GetLastError()); 1091 ok(available_size > 2014, "available_size = %u\n", available_size); 1092 1093 status = 0xdeadbeef; 1094 size = sizeof(status); 1095 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1096 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1097 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 1098 1099 size = 0; 1100 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL); 1101 ok(!ret, "succeeded unexpectedly\n"); 1102 1103 read_size = 0; 1104 for (;;) 1105 { 1106 size = 0; 1107 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 1108 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError()); 1109 if (!size) break; 1110 read_size += size; 1111 1112 if (read_size <= 32) 1113 ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer); 1114 } 1115 ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size); 1116 1117 cleanup: 1118 WinHttpCloseHandle(req); 1119 WinHttpCloseHandle(con); 1120 WinHttpCloseHandle(ses); 1121 } 1122 1123 static void test_request_parameter_defaults(void) 1124 { 1125 static const WCHAR empty[] = {0}; 1126 HINTERNET ses, con, req; 1127 DWORD size, status, error; 1128 WCHAR *version; 1129 BOOL ret; 1130 1131 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1132 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1133 1134 con = WinHttpConnect(ses, test_winehq, 0, 0); 1135 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1136 1137 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1138 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1139 1140 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1141 error = GetLastError(); 1142 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT)) 1143 { 1144 skip("connection failed, skipping\n"); 1145 goto done; 1146 } 1147 ok(ret, "failed to send request %u\n", GetLastError()); 1148 1149 ret = WinHttpReceiveResponse(req, NULL); 1150 if (!ret && GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE) /* win2k */ 1151 { 1152 win_skip("invalid response\n"); 1153 goto done; 1154 } 1155 ok(ret, "failed to receive response %u\n", GetLastError()); 1156 1157 status = 0xdeadbeef; 1158 size = sizeof(status); 1159 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1160 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1161 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 1162 1163 WinHttpCloseHandle(req); 1164 1165 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0); 1166 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1167 1168 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1169 error = GetLastError(); 1170 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT)) 1171 { 1172 skip("connection failed, skipping\n"); 1173 goto done; 1174 } 1175 ok(ret, "failed to send request %u\n", GetLastError()); 1176 1177 ret = WinHttpReceiveResponse(req, NULL); 1178 ok(ret, "failed to receive response %u\n", GetLastError()); 1179 1180 size = 0; 1181 SetLastError(0xdeadbeef); 1182 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL); 1183 error = GetLastError(); 1184 ok(!ret, "succeeded unexpectedly\n"); 1185 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error); 1186 1187 version = HeapAlloc(GetProcessHeap(), 0, size); 1188 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL); 1189 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1190 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size); 1191 HeapFree(GetProcessHeap(), 0, version); 1192 1193 status = 0xdeadbeef; 1194 size = sizeof(status); 1195 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1196 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1197 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 1198 1199 done: 1200 WinHttpCloseHandle(req); 1201 WinHttpCloseHandle(con); 1202 WinHttpCloseHandle(ses); 1203 } 1204 1205 static const WCHAR Connections[] = { 1206 'S','o','f','t','w','a','r','e','\\', 1207 'M','i','c','r','o','s','o','f','t','\\', 1208 'W','i','n','d','o','w','s','\\', 1209 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 1210 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 1211 'C','o','n','n','e','c','t','i','o','n','s',0 }; 1212 static const WCHAR WinHttpSettings[] = { 1213 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 }; 1214 1215 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type ) 1216 { 1217 LONG l; 1218 HKEY key; 1219 DWORD ret = 0; 1220 1221 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key ); 1222 if (!l) 1223 { 1224 DWORD size = 0; 1225 1226 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size ); 1227 if (!l) 1228 { 1229 if (size <= len) 1230 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf, 1231 &size ); 1232 if (!l) 1233 ret = size; 1234 } 1235 RegCloseKey( key ); 1236 } 1237 return ret; 1238 } 1239 1240 static void set_proxy( REGSAM access, BYTE *buf, DWORD len, DWORD type ) 1241 { 1242 HKEY hkey; 1243 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0, access, NULL, &hkey, NULL )) 1244 { 1245 if (len) RegSetValueExW( hkey, WinHttpSettings, 0, type, buf, len ); 1246 else RegDeleteValueW( hkey, WinHttpSettings ); 1247 RegCloseKey( hkey ); 1248 } 1249 } 1250 1251 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type ) 1252 { 1253 BOOL wow64; 1254 IsWow64Process( GetCurrentProcess(), &wow64 ); 1255 if (sizeof(void *) > sizeof(int) || wow64) 1256 { 1257 set_proxy( KEY_WRITE|KEY_WOW64_64KEY, buf, len, type ); 1258 set_proxy( KEY_WRITE|KEY_WOW64_32KEY, buf, len, type ); 1259 } 1260 else 1261 set_proxy( KEY_WRITE, buf, len, type ); 1262 } 1263 1264 static void test_set_default_proxy_config(void) 1265 { 1266 static WCHAR wideString[] = { 0x226f, 0x575b, 0 }; 1267 static WCHAR normalString[] = { 'f','o','o',0 }; 1268 DWORD type, len; 1269 BYTE *saved_proxy_settings = NULL; 1270 WINHTTP_PROXY_INFO info; 1271 BOOL ret; 1272 1273 /* FIXME: it would be simpler to read the current settings using 1274 * WinHttpGetDefaultProxyConfiguration and save them using 1275 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug. 1276 * 1277 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"', 1278 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1, 1279 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be 1280 * WINHTTP_ACCESS_TYPE_NAMED_PROXY. 1281 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1, 1282 * the lpszProxy and lpszProxyBypass values are ignored. 1283 * Thus, if a proxy is set with proxycfg, then calling 1284 * WinHttpGetDefaultProxyConfiguration followed by 1285 * WinHttpSetDefaultProxyConfiguration results in the proxy settings 1286 * getting deleted from the registry. 1287 * 1288 * Instead I read the current registry value and restore it directly. 1289 */ 1290 len = get_default_proxy_reg_value( NULL, 0, &type ); 1291 if (len) 1292 { 1293 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len ); 1294 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type ); 1295 } 1296 1297 if (0) 1298 { 1299 /* Crashes on Vista and higher */ 1300 SetLastError(0xdeadbeef); 1301 ret = WinHttpSetDefaultProxyConfiguration(NULL); 1302 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1303 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1304 } 1305 1306 /* test with invalid access type */ 1307 info.dwAccessType = 0xdeadbeef; 1308 info.lpszProxy = info.lpszProxyBypass = NULL; 1309 SetLastError(0xdeadbeef); 1310 ret = WinHttpSetDefaultProxyConfiguration(&info); 1311 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1312 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1313 1314 /* at a minimum, the proxy server must be set */ 1315 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; 1316 info.lpszProxy = info.lpszProxyBypass = NULL; 1317 SetLastError(0xdeadbeef); 1318 ret = WinHttpSetDefaultProxyConfiguration(&info); 1319 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1320 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1321 info.lpszProxyBypass = normalString; 1322 SetLastError(0xdeadbeef); 1323 ret = WinHttpSetDefaultProxyConfiguration(&info); 1324 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1325 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1326 1327 /* the proxy server can't have wide characters */ 1328 info.lpszProxy = wideString; 1329 SetLastError(0xdeadbeef); 1330 ret = WinHttpSetDefaultProxyConfiguration(&info); 1331 if (!ret && GetLastError() == ERROR_ACCESS_DENIED) 1332 skip("couldn't set default proxy configuration: access denied\n"); 1333 else 1334 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) || 1335 broken(ret), /* Earlier winhttp versions on W2K/XP */ 1336 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1337 1338 info.lpszProxy = normalString; 1339 SetLastError(0xdeadbeef); 1340 ret = WinHttpSetDefaultProxyConfiguration(&info); 1341 if (!ret && GetLastError() == ERROR_ACCESS_DENIED) 1342 skip("couldn't set default proxy configuration: access denied\n"); 1343 else 1344 { 1345 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError()); 1346 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 1347 "got %u\n", GetLastError()); 1348 } 1349 set_default_proxy_reg_value( saved_proxy_settings, len, type ); 1350 } 1351 1352 static void test_Timeouts (void) 1353 { 1354 BOOL ret; 1355 DWORD value, size; 1356 HINTERNET ses, req, con; 1357 1358 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1359 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1360 1361 SetLastError(0xdeadbeef); 1362 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0); 1363 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1364 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1365 1366 SetLastError(0xdeadbeef); 1367 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0); 1368 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1369 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1370 1371 SetLastError(0xdeadbeef); 1372 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0); 1373 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1374 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1375 1376 SetLastError(0xdeadbeef); 1377 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2); 1378 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1379 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1380 1381 SetLastError(0xdeadbeef); 1382 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1); 1383 ok(ret, "%u\n", GetLastError()); 1384 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 1385 "expected ERROR_SUCCESS, got %u\n", GetLastError()); 1386 1387 SetLastError(0xdeadbeef); 1388 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0); 1389 ok(ret, "%u\n", GetLastError()); 1390 1391 SetLastError(0xdeadbeef); 1392 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef); 1393 ok(ret, "%u\n", GetLastError()); 1394 1395 SetLastError(0xdeadbeef); 1396 value = 0xdeadbeef; 1397 size = sizeof(DWORD); 1398 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1399 ok(ret, "%u\n", GetLastError()); 1400 ok(value == 0x0123, "Expected 0x0123, got %u\n", value); 1401 1402 SetLastError(0xdeadbeef); 1403 value = 0xdeadbeef; 1404 size = sizeof(DWORD); 1405 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1406 ok(ret, "%u\n", GetLastError()); 1407 ok(value == 0x4567, "Expected 0x4567, got %u\n", value); 1408 1409 SetLastError(0xdeadbeef); 1410 value = 0xdeadbeef; 1411 size = sizeof(DWORD); 1412 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1413 ok(ret, "%u\n", GetLastError()); 1414 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value); 1415 1416 SetLastError(0xdeadbeef); 1417 value = 0xdeadbeef; 1418 size = sizeof(DWORD); 1419 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1420 ok(ret, "%u\n", GetLastError()); 1421 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value); 1422 1423 SetLastError(0xdeadbeef); 1424 value = 0; 1425 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1426 ok(ret, "%u\n", GetLastError()); 1427 1428 SetLastError(0xdeadbeef); 1429 value = 0xdeadbeef; 1430 size = sizeof(DWORD); 1431 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1432 ok(ret, "%u\n", GetLastError()); 1433 ok(value == 0, "Expected 0, got %u\n", value); 1434 1435 SetLastError(0xdeadbeef); 1436 value = 0; 1437 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1438 ok(ret, "%u\n", GetLastError()); 1439 1440 SetLastError(0xdeadbeef); 1441 value = 0xdeadbeef; 1442 size = sizeof(DWORD); 1443 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1444 ok(ret, "%u\n", GetLastError()); 1445 ok(value == 0, "Expected 0, got %u\n", value); 1446 1447 SetLastError(0xdeadbeef); 1448 value = 0; 1449 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1450 ok(ret, "%u\n", GetLastError()); 1451 1452 SetLastError(0xdeadbeef); 1453 value = 0xdeadbeef; 1454 size = sizeof(DWORD); 1455 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1456 ok(ret, "%u\n", GetLastError()); 1457 ok(value == 0, "Expected 0, got %u\n", value); 1458 1459 SetLastError(0xdeadbeef); 1460 value = 0; 1461 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1462 ok(ret, "%u\n", GetLastError()); 1463 1464 SetLastError(0xdeadbeef); 1465 value = 0xdeadbeef; 1466 size = sizeof(DWORD); 1467 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1468 ok(ret, "%u\n", GetLastError()); 1469 ok(value == 0, "Expected 0, got %u\n", value); 1470 1471 SetLastError(0xdeadbeef); 1472 value = 0xbeefdead; 1473 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1474 ok(ret, "%u\n", GetLastError()); 1475 1476 SetLastError(0xdeadbeef); 1477 value = 0xdeadbeef; 1478 size = sizeof(DWORD); 1479 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1480 ok(ret, "%u\n", GetLastError()); 1481 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1482 1483 SetLastError(0xdeadbeef); 1484 value = 0xbeefdead; 1485 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1486 ok(ret, "%u\n", GetLastError()); 1487 1488 SetLastError(0xdeadbeef); 1489 value = 0xdeadbeef; 1490 size = sizeof(DWORD); 1491 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1492 ok(ret, "%u\n", GetLastError()); 1493 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1494 1495 SetLastError(0xdeadbeef); 1496 value = 0xbeefdead; 1497 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1498 ok(ret, "%u\n", GetLastError()); 1499 1500 SetLastError(0xdeadbeef); 1501 value = 0xdeadbeef; 1502 size = sizeof(DWORD); 1503 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1504 ok(ret, "%u\n", GetLastError()); 1505 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1506 1507 SetLastError(0xdeadbeef); 1508 value = 0xbeefdead; 1509 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1510 ok(ret, "%u\n", GetLastError()); 1511 1512 SetLastError(0xdeadbeef); 1513 value = 0xdeadbeef; 1514 size = sizeof(DWORD); 1515 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1516 ok(ret, "%u\n", GetLastError()); 1517 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1518 1519 con = WinHttpConnect(ses, test_winehq, 0, 0); 1520 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1521 1522 /* Timeout values should match the last one set for session */ 1523 SetLastError(0xdeadbeef); 1524 value = 0xdeadbeef; 1525 size = sizeof(DWORD); 1526 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1527 ok(ret, "%u\n", GetLastError()); 1528 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1529 1530 SetLastError(0xdeadbeef); 1531 value = 0xdeadbeef; 1532 size = sizeof(DWORD); 1533 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1534 ok(ret, "%u\n", GetLastError()); 1535 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1536 1537 SetLastError(0xdeadbeef); 1538 value = 0xdeadbeef; 1539 size = sizeof(DWORD); 1540 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1541 ok(ret, "%u\n", GetLastError()); 1542 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1543 1544 SetLastError(0xdeadbeef); 1545 value = 0xdeadbeef; 1546 size = sizeof(DWORD); 1547 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1548 ok(ret, "%u\n", GetLastError()); 1549 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1550 1551 SetLastError(0xdeadbeef); 1552 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0); 1553 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1554 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1555 1556 SetLastError(0xdeadbeef); 1557 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0); 1558 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1559 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1560 1561 SetLastError(0xdeadbeef); 1562 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0); 1563 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1564 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1565 1566 SetLastError(0xdeadbeef); 1567 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2); 1568 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1569 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1570 1571 SetLastError(0xdeadbeef); 1572 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1); 1573 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1574 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1575 1576 SetLastError(0xdeadbeef); 1577 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0); 1578 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1579 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1580 1581 SetLastError(0xdeadbeef); 1582 value = 0; 1583 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1584 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1585 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1586 1587 SetLastError(0xdeadbeef); 1588 value = 0; 1589 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1590 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1591 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1592 1593 SetLastError(0xdeadbeef); 1594 value = 0; 1595 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1596 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1597 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1598 1599 SetLastError(0xdeadbeef); 1600 value = 0; 1601 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1602 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1603 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1604 1605 /* Changing timeout values for session should affect the values for connection */ 1606 SetLastError(0xdeadbeef); 1607 value = 0xdead; 1608 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1609 ok(ret, "%u\n", GetLastError()); 1610 1611 SetLastError(0xdeadbeef); 1612 value = 0xdeadbeef; 1613 size = sizeof(DWORD); 1614 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1615 ok(ret, "%u\n", GetLastError()); 1616 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1617 1618 SetLastError(0xdeadbeef); 1619 value = 0xdead; 1620 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1621 ok(ret, "%u\n", GetLastError()); 1622 1623 SetLastError(0xdeadbeef); 1624 value = 0xdeadbeef; 1625 size = sizeof(DWORD); 1626 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1627 ok(ret, "%u\n", GetLastError()); 1628 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1629 1630 SetLastError(0xdeadbeef); 1631 value = 0xdead; 1632 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1633 ok(ret, "%u\n", GetLastError()); 1634 1635 SetLastError(0xdeadbeef); 1636 value = 0xdeadbeef; 1637 size = sizeof(DWORD); 1638 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1639 ok(ret, "%u\n", GetLastError()); 1640 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1641 1642 SetLastError(0xdeadbeef); 1643 value = 0xdead; 1644 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1645 ok(ret, "%u\n", GetLastError()); 1646 1647 SetLastError(0xdeadbeef); 1648 value = 0xdeadbeef; 1649 size = sizeof(DWORD); 1650 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1651 ok(ret, "%u\n", GetLastError()); 1652 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1653 1654 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1655 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1656 1657 /* Timeout values should match the last one set for session */ 1658 SetLastError(0xdeadbeef); 1659 value = 0xdeadbeef; 1660 size = sizeof(DWORD); 1661 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1662 ok(ret, "%u\n", GetLastError()); 1663 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1664 1665 SetLastError(0xdeadbeef); 1666 value = 0xdeadbeef; 1667 size = sizeof(DWORD); 1668 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1669 ok(ret, "%u\n", GetLastError()); 1670 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1671 1672 SetLastError(0xdeadbeef); 1673 value = 0xdeadbeef; 1674 size = sizeof(DWORD); 1675 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1676 ok(ret, "%u\n", GetLastError()); 1677 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1678 1679 SetLastError(0xdeadbeef); 1680 value = 0xdeadbeef; 1681 size = sizeof(DWORD); 1682 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1683 ok(ret, "%u\n", GetLastError()); 1684 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1685 1686 SetLastError(0xdeadbeef); 1687 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0); 1688 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1689 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1690 1691 SetLastError(0xdeadbeef); 1692 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0); 1693 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1694 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1695 1696 SetLastError(0xdeadbeef); 1697 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0); 1698 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1699 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1700 1701 SetLastError(0xdeadbeef); 1702 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2); 1703 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1704 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1705 1706 SetLastError(0xdeadbeef); 1707 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1); 1708 ok(ret, "%u\n", GetLastError()); 1709 1710 SetLastError(0xdeadbeef); 1711 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0); 1712 ok(ret, "%u\n", GetLastError()); 1713 1714 SetLastError(0xdeadbeef); 1715 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123); 1716 ok(ret, "%u\n", GetLastError()); 1717 1718 SetLastError(0xdeadbeef); 1719 value = 0xdeadbeef; 1720 size = sizeof(DWORD); 1721 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1722 ok(ret, "%u\n", GetLastError()); 1723 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value); 1724 1725 SetLastError(0xdeadbeef); 1726 value = 0xdeadbeef; 1727 size = sizeof(DWORD); 1728 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1729 ok(ret, "%u\n", GetLastError()); 1730 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value); 1731 1732 SetLastError(0xdeadbeef); 1733 value = 0xdeadbeef; 1734 size = sizeof(DWORD); 1735 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1736 ok(ret, "%u\n", GetLastError()); 1737 ok(value == 0x4567, "Expected 0x4567, got %u\n", value); 1738 1739 SetLastError(0xdeadbeef); 1740 value = 0xdeadbeef; 1741 size = sizeof(DWORD); 1742 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1743 ok(ret, "%u\n", GetLastError()); 1744 ok(value == 0x0123, "Expected 0x0123, got %u\n", value); 1745 1746 SetLastError(0xdeadbeef); 1747 value = 0; 1748 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1749 ok(ret, "%u\n", GetLastError()); 1750 1751 SetLastError(0xdeadbeef); 1752 value = 0xdeadbeef; 1753 size = sizeof(DWORD); 1754 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1755 ok(ret, "%u\n", GetLastError()); 1756 ok(value == 0, "Expected 0, got %u\n", value); 1757 1758 SetLastError(0xdeadbeef); 1759 value = 0; 1760 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1761 ok(ret, "%u\n", GetLastError()); 1762 1763 SetLastError(0xdeadbeef); 1764 value = 0xdeadbeef; 1765 size = sizeof(DWORD); 1766 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1767 ok(ret, "%u\n", GetLastError()); 1768 ok(value == 0, "Expected 0, got %u\n", value); 1769 1770 SetLastError(0xdeadbeef); 1771 value = 0; 1772 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1773 ok(ret, "%u\n", GetLastError()); 1774 1775 SetLastError(0xdeadbeef); 1776 value = 0xdeadbeef; 1777 size = sizeof(DWORD); 1778 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1779 ok(ret, "%u\n", GetLastError()); 1780 ok(value == 0, "Expected 0, got %u\n", value); 1781 1782 SetLastError(0xdeadbeef); 1783 value = 0; 1784 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1785 ok(ret, "%u\n", GetLastError()); 1786 1787 SetLastError(0xdeadbeef); 1788 value = 0xdeadbeef; 1789 size = sizeof(DWORD); 1790 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1791 ok(ret, "%u\n", GetLastError()); 1792 ok(value == 0, "Expected 0, got %u\n", value); 1793 1794 SetLastError(0xdeadbeef); 1795 value = 0xbeefdead; 1796 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1797 ok(ret, "%u\n", GetLastError()); 1798 1799 SetLastError(0xdeadbeef); 1800 value = 0xdeadbeef; 1801 size = sizeof(DWORD); 1802 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1803 ok(ret, "%u\n", GetLastError()); 1804 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1805 1806 SetLastError(0xdeadbeef); 1807 value = 0xbeefdead; 1808 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1809 ok(ret, "%u\n", GetLastError()); 1810 1811 SetLastError(0xdeadbeef); 1812 value = 0xdeadbeef; 1813 size = sizeof(DWORD); 1814 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1815 ok(ret, "%u\n", GetLastError()); 1816 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1817 1818 SetLastError(0xdeadbeef); 1819 value = 0xbeefdead; 1820 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1821 ok(ret, "%u\n", GetLastError()); 1822 1823 SetLastError(0xdeadbeef); 1824 value = 0xdeadbeef; 1825 size = sizeof(DWORD); 1826 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1827 ok(ret, "%u\n", GetLastError()); 1828 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1829 1830 SetLastError(0xdeadbeef); 1831 value = 0xbeefdead; 1832 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1833 ok(ret, "%u\n", GetLastError()); 1834 1835 SetLastError(0xdeadbeef); 1836 value = 0xdeadbeef; 1837 size = sizeof(DWORD); 1838 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1839 ok(ret, "%u\n", GetLastError()); 1840 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1841 1842 /* Changing timeout values for session should not affect the values for a request, 1843 * neither should the other way around. 1844 */ 1845 SetLastError(0xdeadbeef); 1846 value = 0xbeefdead; 1847 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1848 ok(ret, "%u\n", GetLastError()); 1849 1850 SetLastError(0xdeadbeef); 1851 value = 0xdeadbeef; 1852 size = sizeof(DWORD); 1853 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1854 ok(ret, "%u\n", GetLastError()); 1855 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1856 1857 SetLastError(0xdeadbeef); 1858 value = 0xbeefdead; 1859 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1860 ok(ret, "%u\n", GetLastError()); 1861 1862 SetLastError(0xdeadbeef); 1863 value = 0xdeadbeef; 1864 size = sizeof(DWORD); 1865 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1866 ok(ret, "%u\n", GetLastError()); 1867 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1868 1869 SetLastError(0xdeadbeef); 1870 value = 0xbeefdead; 1871 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1872 ok(ret, "%u\n", GetLastError()); 1873 1874 SetLastError(0xdeadbeef); 1875 value = 0xdeadbeef; 1876 size = sizeof(DWORD); 1877 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1878 ok(ret, "%u\n", GetLastError()); 1879 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1880 1881 SetLastError(0xdeadbeef); 1882 value = 0xbeefdead; 1883 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1884 ok(ret, "%u\n", GetLastError()); 1885 1886 SetLastError(0xdeadbeef); 1887 value = 0xdeadbeef; 1888 size = sizeof(DWORD); 1889 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1890 ok(ret, "%u\n", GetLastError()); 1891 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1892 1893 SetLastError(0xdeadbeef); 1894 value = 0xbeef; 1895 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1896 ok(ret, "%u\n", GetLastError()); 1897 1898 SetLastError(0xdeadbeef); 1899 value = 0xdeadbeef; 1900 size = sizeof(DWORD); 1901 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1902 ok(ret, "%u\n", GetLastError()); 1903 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1904 1905 SetLastError(0xdeadbeef); 1906 value = 0xbeef; 1907 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1908 ok(ret, "%u\n", GetLastError()); 1909 1910 SetLastError(0xdeadbeef); 1911 value = 0xdeadbeef; 1912 size = sizeof(DWORD); 1913 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1914 ok(ret, "%u\n", GetLastError()); 1915 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1916 1917 SetLastError(0xdeadbeef); 1918 value = 0xbeef; 1919 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1920 ok(ret, "%u\n", GetLastError()); 1921 1922 SetLastError(0xdeadbeef); 1923 value = 0xdeadbeef; 1924 size = sizeof(DWORD); 1925 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1926 ok(ret, "%u\n", GetLastError()); 1927 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1928 1929 SetLastError(0xdeadbeef); 1930 value = 0xbeef; 1931 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1932 ok(ret, "%u\n", GetLastError()); 1933 1934 SetLastError(0xdeadbeef); 1935 value = 0xdeadbeef; 1936 size = sizeof(DWORD); 1937 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1938 ok(ret, "%u\n", GetLastError()); 1939 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1940 1941 WinHttpCloseHandle(req); 1942 WinHttpCloseHandle(con); 1943 WinHttpCloseHandle(ses); 1944 } 1945 1946 static void test_resolve_timeout(void) 1947 { 1948 static const WCHAR nxdomain[] = 1949 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0}; 1950 HINTERNET ses, con, req; 1951 DWORD timeout; 1952 BOOL ret; 1953 1954 if (! proxy_active()) 1955 { 1956 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1957 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1958 1959 timeout = 10000; 1960 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout)); 1961 ok(ret, "failed to set resolve timeout %u\n", GetLastError()); 1962 1963 con = WinHttpConnect(ses, nxdomain, 0, 0); 1964 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1965 1966 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1967 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1968 1969 SetLastError(0xdeadbeef); 1970 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1971 if (ret) 1972 { 1973 skip("nxdomain returned success. Broken ISP redirects?\n"); 1974 goto done; 1975 } 1976 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED, 1977 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError()); 1978 1979 WinHttpCloseHandle(req); 1980 WinHttpCloseHandle(con); 1981 WinHttpCloseHandle(ses); 1982 } 1983 else 1984 skip("Skipping host resolution tests, host resolution preformed by proxy\n"); 1985 1986 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1987 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1988 1989 timeout = 10000; 1990 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout)); 1991 ok(ret, "failed to set resolve timeout %u\n", GetLastError()); 1992 1993 con = WinHttpConnect(ses, test_winehq, 0, 0); 1994 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1995 1996 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1997 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1998 1999 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2000 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT) 2001 { 2002 skip("connection failed, skipping\n"); 2003 goto done; 2004 } 2005 ok(ret, "failed to send request\n"); 2006 2007 done: 2008 WinHttpCloseHandle(req); 2009 WinHttpCloseHandle(con); 2010 WinHttpCloseHandle(ses); 2011 } 2012 2013 static const char page1[] = 2014 "<HTML>\r\n" 2015 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n" 2016 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n" 2017 "</HTML>\r\n\r\n"; 2018 2019 static const char okmsg[] = 2020 "HTTP/1.1 200 OK\r\n" 2021 "Server: winetest\r\n" 2022 "\r\n"; 2023 2024 static const char notokmsg[] = 2025 "HTTP/1.1 400 Bad Request\r\n" 2026 "\r\n"; 2027 2028 static const char cookiemsg[] = 2029 "HTTP/1.1 200 OK\r\n" 2030 "Set-Cookie: name = value \r\n" 2031 "Set-Cookie: NAME = value \r\n" 2032 "\r\n"; 2033 2034 static const char cookiemsg2[] = 2035 "HTTP/1.1 200 OK\r\n" 2036 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n" 2037 "\r\n"; 2038 2039 static const char nocontentmsg[] = 2040 "HTTP/1.1 204 No Content\r\n" 2041 "Server: winetest\r\n" 2042 "\r\n"; 2043 2044 static const char notmodified[] = 2045 "HTTP/1.1 304 Not Modified\r\n" 2046 "\r\n"; 2047 2048 static const char noauthmsg[] = 2049 "HTTP/1.1 401 Unauthorized\r\n" 2050 "Server: winetest\r\n" 2051 "Connection: close\r\n" 2052 "WWW-Authenticate: Basic realm=\"placebo\"\r\n" 2053 "Content-Length: 12\r\n" 2054 "Content-Type: text/plain\r\n" 2055 "\r\n"; 2056 2057 static const char okauthmsg[] = 2058 "HTTP/1.1 200 OK\r\n" 2059 "Server: winetest\r\n" 2060 "Connection: close\r\n" 2061 "Content-Length: 11\r\n" 2062 "Content-Type: text/plain\r\n" 2063 "\r\n"; 2064 2065 static const char headmsg[] = 2066 "HTTP/1.1 200 OK\r\n" 2067 "Content-Length: 100\r\n" 2068 "\r\n"; 2069 2070 static const char multiauth[] = 2071 "HTTP/1.1 401 Unauthorized\r\n" 2072 "Server: winetest\r\n" 2073 "WWW-Authenticate: Bearer\r\n" 2074 "WWW-Authenticate: Basic realm=\"placebo\"\r\n" 2075 "WWW-Authenticate: NTLM\r\n" 2076 "Content-Length: 10\r\n" 2077 "Content-Type: text/plain\r\n" 2078 "\r\n"; 2079 2080 static const char largeauth[] = 2081 "HTTP/1.1 401 Unauthorized\r\n" 2082 "Server: winetest\r\n" 2083 "WWW-Authenticate: Basic realm=\"placebo\"\r\n" 2084 "WWW-Authenticate: NTLM\r\n" 2085 "Content-Length: 10240\r\n" 2086 "Content-Type: text/plain\r\n" 2087 "\r\n"; 2088 2089 static const char unauthorized[] = "Unauthorized"; 2090 static const char hello_world[] = "Hello World"; 2091 static const char auth_unseen[] = "Auth Unseen"; 2092 2093 struct server_info 2094 { 2095 HANDLE event; 2096 int port; 2097 }; 2098 2099 #define BIG_BUFFER_LEN 0x2250 2100 2101 static DWORD CALLBACK server_thread(LPVOID param) 2102 { 2103 struct server_info *si = param; 2104 int r, c = -1, i, on; 2105 SOCKET s; 2106 struct sockaddr_in sa; 2107 char buffer[0x100]; 2108 WSADATA wsaData; 2109 int last_request = 0; 2110 2111 WSAStartup(MAKEWORD(1,1), &wsaData); 2112 2113 s = socket(AF_INET, SOCK_STREAM, 0); 2114 if (s == INVALID_SOCKET) 2115 return 1; 2116 2117 on = 1; 2118 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on); 2119 2120 memset(&sa, 0, sizeof sa); 2121 sa.sin_family = AF_INET; 2122 sa.sin_port = htons(si->port); 2123 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 2124 2125 r = bind(s, (struct sockaddr *)&sa, sizeof(sa)); 2126 if (r < 0) 2127 return 1; 2128 2129 listen(s, 0); 2130 SetEvent(si->event); 2131 do 2132 { 2133 if (c == -1) c = accept(s, NULL, NULL); 2134 2135 memset(buffer, 0, sizeof buffer); 2136 for(i = 0; i < sizeof buffer - 1; i++) 2137 { 2138 r = recv(c, &buffer[i], 1, 0); 2139 if (r != 1) 2140 break; 2141 if (i < 4) continue; 2142 if (buffer[i - 2] == '\n' && buffer[i] == '\n' && 2143 buffer[i - 3] == '\r' && buffer[i - 1] == '\r') 2144 break; 2145 } 2146 if (strstr(buffer, "GET /basic")) 2147 { 2148 send(c, okmsg, sizeof okmsg - 1, 0); 2149 send(c, page1, sizeof page1 - 1, 0); 2150 } 2151 if (strstr(buffer, "/auth_with_creds")) 2152 { 2153 send(c, okauthmsg, sizeof okauthmsg - 1, 0); 2154 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q=")) 2155 send(c, hello_world, sizeof hello_world - 1, 0); 2156 else 2157 send(c, auth_unseen, sizeof auth_unseen - 1, 0); 2158 continue; 2159 } 2160 if (strstr(buffer, "/auth")) 2161 { 2162 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q=")) 2163 { 2164 send(c, okauthmsg, sizeof okauthmsg - 1, 0); 2165 send(c, hello_world, sizeof hello_world - 1, 0); 2166 } 2167 else 2168 { 2169 send(c, noauthmsg, sizeof noauthmsg - 1, 0); 2170 send(c, unauthorized, sizeof unauthorized - 1, 0); 2171 } 2172 continue; 2173 } 2174 if (strstr(buffer, "/big")) 2175 { 2176 char msg[BIG_BUFFER_LEN]; 2177 memset(msg, 'm', sizeof(msg)); 2178 send(c, okmsg, sizeof(okmsg) - 1, 0); 2179 send(c, msg, sizeof(msg), 0); 2180 } 2181 if (strstr(buffer, "/no_headers")) 2182 { 2183 send(c, page1, sizeof page1 - 1, 0); 2184 } 2185 if (strstr(buffer, "GET /no_content")) 2186 { 2187 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0); 2188 continue; 2189 } 2190 if (strstr(buffer, "GET /not_modified")) 2191 { 2192 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0); 2193 else send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2194 continue; 2195 } 2196 if (strstr(buffer, "HEAD /head")) 2197 { 2198 send(c, headmsg, sizeof headmsg - 1, 0); 2199 continue; 2200 } 2201 if (strstr(buffer, "GET /multiauth")) 2202 { 2203 send(c, multiauth, sizeof multiauth - 1, 0); 2204 } 2205 if (strstr(buffer, "GET /largeauth")) 2206 { 2207 if (strstr(buffer, "Authorization: NTLM")) 2208 send(c, okmsg, sizeof(okmsg) - 1, 0); 2209 else 2210 { 2211 send(c, largeauth, sizeof largeauth - 1, 0); 2212 #ifdef __REACTOS__ 2213 memset(buffer, 'A', sizeof(buffer)); 2214 for (i = 0; i < (10240 / sizeof(buffer)); i++) send(c, buffer, sizeof(buffer), 0); 2215 #else 2216 for (i = 0; i < 10240; i++) send(c, "A", 1, 0); 2217 #endif 2218 continue; 2219 } 2220 } 2221 if (strstr(buffer, "GET /cookie5")) 2222 { 2223 if (strstr(buffer, "Cookie: name2=value\r\n")) 2224 send(c, okmsg, sizeof(okmsg) - 1, 0); 2225 else 2226 send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2227 } 2228 if (strstr(buffer, "GET /cookie4")) 2229 { 2230 send(c, cookiemsg2, sizeof(cookiemsg2) - 1, 0); 2231 } 2232 if (strstr(buffer, "GET /cookie3")) 2233 { 2234 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") || 2235 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL)) 2236 send(c, okmsg, sizeof(okmsg) - 1, 0); 2237 else 2238 send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2239 } 2240 if (strstr(buffer, "GET /cookie2")) 2241 { 2242 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") || 2243 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL)) 2244 send(c, okmsg, sizeof(okmsg) - 1, 0); 2245 else 2246 send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2247 } 2248 else if (strstr(buffer, "GET /cookie")) 2249 { 2250 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0); 2251 else send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2252 } 2253 if (strstr(buffer, "GET /quit")) 2254 { 2255 send(c, okmsg, sizeof okmsg - 1, 0); 2256 send(c, page1, sizeof page1 - 1, 0); 2257 last_request = 1; 2258 } 2259 shutdown(c, 2); 2260 closesocket(c); 2261 c = -1; 2262 2263 } while (!last_request); 2264 2265 closesocket(s); 2266 return 0; 2267 } 2268 2269 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path) 2270 { 2271 static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0}; 2272 static const WCHAR test_header_end_raw[] = {0,0}; 2273 HINTERNET ses, con, req; 2274 char buffer[0x100]; 2275 WCHAR buffer2[0x100]; 2276 DWORD count, status, size, error, supported, first, target; 2277 BOOL ret; 2278 2279 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2280 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2281 2282 con = WinHttpConnect(ses, localhostW, port, 0); 2283 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2284 2285 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0); 2286 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2287 2288 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2289 ok(ret, "failed to send request %u\n", GetLastError()); 2290 2291 ret = WinHttpReceiveResponse(req, NULL); 2292 ok(ret, "failed to receive response %u\n", GetLastError()); 2293 2294 status = 0xdeadbeef; 2295 size = sizeof(status); 2296 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2297 ok(ret, "failed to query status code %u\n", GetLastError()); 2298 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2299 2300 supported = first = target = 0xdeadbeef; 2301 SetLastError(0xdeadbeef); 2302 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2303 error = GetLastError(); 2304 ok(!ret, "unexpected success\n"); 2305 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error); 2306 ok(supported == 0xdeadbeef, "got %x\n", supported); 2307 ok(first == 0xdeadbeef, "got %x\n", first); 2308 ok(target == 0xdeadbeef, "got %x\n", target); 2309 2310 size = sizeof(buffer2); 2311 memset(buffer2, 0, sizeof(buffer2)); 2312 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL); 2313 ok(ret, "failed to query for raw headers: %u\n", GetLastError()); 2314 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)), 2315 "WinHttpQueryHeaders returned invalid end of header string\n"); 2316 2317 size = sizeof(buffer2); 2318 memset(buffer2, 0, sizeof(buffer2)); 2319 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL); 2320 ok(ret, "failed to query for raw headers: %u\n", GetLastError()); 2321 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)), 2322 "WinHttpQueryHeaders returned invalid end of header string\n"); 2323 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n"); 2324 2325 count = 0; 2326 memset(buffer, 0, sizeof(buffer)); 2327 ret = WinHttpReadData(req, buffer, sizeof buffer, &count); 2328 ok(ret, "failed to read data %u\n", GetLastError()); 2329 ok(count == sizeof page1 - 1, "count was wrong\n"); 2330 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n"); 2331 2332 WinHttpCloseHandle(req); 2333 WinHttpCloseHandle(con); 2334 WinHttpCloseHandle(ses); 2335 } 2336 2337 static void test_basic_authentication(int port) 2338 { 2339 static const WCHAR authW[] = {'/','a','u','t','h',0}; 2340 static const WCHAR auth_with_credsW[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0}; 2341 static WCHAR userW[] = {'u','s','e','r',0}; 2342 static WCHAR passW[] = {'p','w','d',0}; 2343 static WCHAR pass2W[] = {'p','w','d','2',0}; 2344 HINTERNET ses, con, req; 2345 DWORD status, size, error, supported, first, target; 2346 char buffer[32]; 2347 BOOL ret; 2348 2349 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2350 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2351 2352 con = WinHttpConnect(ses, localhostW, port, 0); 2353 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2354 2355 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0); 2356 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2357 2358 SetLastError(0xdeadbeef); 2359 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL); 2360 error = GetLastError(); 2361 ok(!ret, "expected failure\n"); 2362 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error); 2363 2364 SetLastError(0xdeadbeef); 2365 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL); 2366 error = GetLastError(); 2367 ok(!ret, "expected failure\n"); 2368 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error); 2369 2370 supported = 0xdeadbeef; 2371 SetLastError(0xdeadbeef); 2372 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL); 2373 error = GetLastError(); 2374 ok(!ret, "expected failure\n"); 2375 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error); 2376 ok(supported == 0xdeadbeef, "got %x\n", supported); 2377 2378 supported = first = 0xdeadbeef; 2379 SetLastError(0xdeadbeef); 2380 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL); 2381 error = GetLastError(); 2382 ok(!ret, "expected failure\n"); 2383 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error); 2384 ok(supported == 0xdeadbeef, "got %x\n", supported); 2385 ok(first == 0xdeadbeef, "got %x\n", first); 2386 2387 supported = first = target = 0xdeadbeef; 2388 SetLastError(0xdeadbeef); 2389 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2390 error = GetLastError(); 2391 ok(!ret, "expected failure\n"); 2392 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error); 2393 ok(supported == 0xdeadbeef, "got %x\n", supported); 2394 ok(first == 0xdeadbeef, "got %x\n", first); 2395 ok(target == 0xdeadbeef, "got %x\n", target); 2396 2397 supported = first = target = 0xdeadbeef; 2398 SetLastError(0xdeadbeef); 2399 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target); 2400 error = GetLastError(); 2401 ok(!ret, "expected failure\n"); 2402 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error); 2403 ok(supported == 0xdeadbeef, "got %x\n", supported); 2404 ok(first == 0xdeadbeef, "got %x\n", first); 2405 ok(target == 0xdeadbeef, "got %x\n", target); 2406 2407 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2408 ok(ret, "failed to send request %u\n", GetLastError()); 2409 2410 ret = WinHttpReceiveResponse(req, NULL); 2411 ok(ret, "failed to receive response %u\n", GetLastError()); 2412 2413 status = 0xdeadbeef; 2414 size = sizeof(status); 2415 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2416 ok(ret, "failed to query status code %u\n", GetLastError()); 2417 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status); 2418 2419 size = 0; 2420 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 2421 error = GetLastError(); 2422 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError()); 2423 if (ret) 2424 { 2425 ok(size == 12, "expected 12, got %u\n", size); 2426 ok(!memcmp(buffer, unauthorized, 12), "got %s\n", buffer); 2427 } 2428 2429 supported = first = target = 0xdeadbeef; 2430 SetLastError(0xdeadbeef); 2431 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2432 error = GetLastError(); 2433 ok(ret, "failed to query authentication schemes %u\n", error); 2434 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error); 2435 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported); 2436 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first); 2437 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target); 2438 2439 SetLastError(0xdeadbeef); 2440 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL); 2441 error = GetLastError(); 2442 ok(ret, "failed to set credentials %u\n", error); 2443 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error); 2444 2445 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL); 2446 ok(ret, "failed to set credentials %u\n", GetLastError()); 2447 2448 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL); 2449 ok(ret, "failed to set credentials %u\n", GetLastError()); 2450 2451 SetLastError(0xdeadbeef); 2452 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL); 2453 error = GetLastError(); 2454 ok(!ret, "expected failure\n"); 2455 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2456 2457 SetLastError(0xdeadbeef); 2458 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL); 2459 error = GetLastError(); 2460 ok(!ret, "expected failure\n"); 2461 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2462 2463 SetLastError(0xdeadbeef); 2464 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL); 2465 error = GetLastError(); 2466 ok(!ret, "expected failure\n"); 2467 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2468 2469 SetLastError(0xdeadbeef); 2470 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL); 2471 error = GetLastError(); 2472 ok(!ret, "expected failure\n"); 2473 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2474 2475 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 2476 ok(ret, "failed to set credentials %u\n", GetLastError()); 2477 2478 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2479 ok(ret, "failed to send request %u\n", GetLastError()); 2480 2481 ret = WinHttpReceiveResponse(req, NULL); 2482 ok(ret, "failed to receive response %u\n", GetLastError()); 2483 2484 status = 0xdeadbeef; 2485 size = sizeof(status); 2486 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2487 ok(ret, "failed to query status code %u\n", GetLastError()); 2488 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2489 2490 size = 0; 2491 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 2492 error = GetLastError(); 2493 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError()); 2494 if (ret) 2495 { 2496 ok(size == 11, "expected 11, got %u\n", size); 2497 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer); 2498 } 2499 2500 WinHttpCloseHandle(req); 2501 WinHttpCloseHandle(con); 2502 WinHttpCloseHandle(ses); 2503 2504 /* now set the credentials first to show that they get sent with the first request */ 2505 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2506 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2507 2508 con = WinHttpConnect(ses, localhostW, port, 0); 2509 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2510 2511 req = WinHttpOpenRequest(con, NULL, auth_with_credsW, NULL, NULL, NULL, 0); 2512 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2513 2514 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 2515 ok(ret, "failed to set credentials %u\n", GetLastError()); 2516 2517 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2518 ok(ret, "failed to send request %u\n", GetLastError()); 2519 2520 ret = WinHttpReceiveResponse(req, NULL); 2521 ok(ret, "failed to receive response %u\n", GetLastError()); 2522 2523 status = 0xdeadbeef; 2524 size = sizeof(status); 2525 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2526 ok(ret, "failed to query status code %u\n", GetLastError()); 2527 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2528 2529 size = 0; 2530 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 2531 error = GetLastError(); 2532 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError()); 2533 if (ret) 2534 { 2535 ok(size == 11, "expected 11, got %u\n", size); 2536 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer); 2537 } 2538 2539 WinHttpCloseHandle(req); 2540 WinHttpCloseHandle(con); 2541 WinHttpCloseHandle(ses); 2542 2543 /* credentials set with WinHttpSetCredentials take precedence over those set through options */ 2544 2545 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2546 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2547 2548 con = WinHttpConnect(ses, localhostW, port, 0); 2549 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2550 2551 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0); 2552 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2553 2554 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 2555 ok(ret, "failed to set credentials %u\n", GetLastError()); 2556 2557 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); 2558 ok(ret, "failed to set username %u\n", GetLastError()); 2559 2560 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W)); 2561 ok(ret, "failed to set password %u\n", GetLastError()); 2562 2563 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2564 ok(ret, "failed to send request %u\n", GetLastError()); 2565 2566 ret = WinHttpReceiveResponse(req, NULL); 2567 ok(ret, "failed to receive response %u\n", GetLastError()); 2568 2569 status = 0xdeadbeef; 2570 size = sizeof(status); 2571 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2572 ok(ret, "failed to query status code %u\n", GetLastError()); 2573 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2574 2575 WinHttpCloseHandle(req); 2576 WinHttpCloseHandle(con); 2577 WinHttpCloseHandle(ses); 2578 2579 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2580 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2581 2582 con = WinHttpConnect(ses, localhostW, port, 0); 2583 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2584 2585 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0); 2586 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2587 2588 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); 2589 ok(ret, "failed to set username %u\n", GetLastError()); 2590 2591 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW)); 2592 ok(ret, "failed to set password %u\n", GetLastError()); 2593 2594 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, NULL); 2595 ok(ret, "failed to set credentials %u\n", GetLastError()); 2596 2597 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2598 ok(ret, "failed to send request %u\n", GetLastError()); 2599 2600 ret = WinHttpReceiveResponse(req, NULL); 2601 ok(ret, "failed to receive response %u\n", GetLastError()); 2602 2603 status = 0xdeadbeef; 2604 size = sizeof(status); 2605 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2606 ok(ret, "failed to query status code %u\n", GetLastError()); 2607 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status); 2608 2609 WinHttpCloseHandle(req); 2610 WinHttpCloseHandle(con); 2611 WinHttpCloseHandle(ses); 2612 } 2613 2614 static void test_multi_authentication(int port) 2615 { 2616 static const WCHAR multiauthW[] = {'/','m','u','l','t','i','a','u','t','h',0}; 2617 static const WCHAR getW[] = {'G','E','T',0}; 2618 HINTERNET ses, con, req; 2619 DWORD supported, first, target; 2620 BOOL ret; 2621 2622 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2623 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2624 2625 con = WinHttpConnect(ses, localhostW, port, 0); 2626 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2627 2628 req = WinHttpOpenRequest(con, getW, multiauthW, NULL, NULL, NULL, 0); 2629 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2630 2631 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, 2632 WINHTTP_NO_REQUEST_DATA,0, 0, 0 ); 2633 ok(ret, "expected success\n"); 2634 2635 ret = WinHttpReceiveResponse(req, NULL); 2636 ok(ret, "expected success\n"); 2637 2638 supported = first = target = 0xdeadbeef; 2639 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2640 ok(ret, "expected success\n"); 2641 ok(supported == (WINHTTP_AUTH_SCHEME_BASIC | WINHTTP_AUTH_SCHEME_NTLM), "got %x\n", supported); 2642 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target); 2643 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first); 2644 2645 WinHttpCloseHandle(req); 2646 WinHttpCloseHandle(con); 2647 WinHttpCloseHandle(ses); 2648 } 2649 2650 static void test_large_data_authentication(int port) 2651 { 2652 static const WCHAR largeauthW[] = {'/','l','a','r','g','e','a','u','t','h',0}; 2653 static const WCHAR getW[] = {'G','E','T',0}; 2654 static WCHAR userW[] = {'u','s','e','r',0}; 2655 static WCHAR passW[] = {'p','w','d',0}; 2656 HINTERNET ses, con, req; 2657 DWORD status, size; 2658 BOOL ret; 2659 2660 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2661 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2662 2663 con = WinHttpConnect(ses, localhostW, port, 0); 2664 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2665 2666 req = WinHttpOpenRequest(con, getW, largeauthW, NULL, NULL, NULL, 0); 2667 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2668 2669 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); 2670 ok(ret, "expected success\n"); 2671 2672 ret = WinHttpReceiveResponse(req, NULL); 2673 ok(ret, "expected success\n"); 2674 2675 size = sizeof(status); 2676 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, 2677 &status, &size, NULL); 2678 ok(ret, "expected success\n"); 2679 ok(status == HTTP_STATUS_DENIED, "got %d\n", status); 2680 2681 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, userW, passW, NULL); 2682 ok(ret, "expected success\n"); 2683 2684 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); 2685 ok(ret, "expected success %d\n", GetLastError()); 2686 2687 ret = WinHttpReceiveResponse(req, NULL); 2688 ok(ret, "expected success\n"); 2689 2690 size = sizeof(status); 2691 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, 2692 &status, &size, NULL); 2693 ok(ret, "expected success\n"); 2694 ok(status == HTTP_STATUS_OK, "got %d\n", status); 2695 2696 WinHttpCloseHandle(req); 2697 WinHttpCloseHandle(con); 2698 WinHttpCloseHandle(ses); 2699 } 2700 2701 static void test_no_headers(int port) 2702 { 2703 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0}; 2704 HINTERNET ses, con, req; 2705 DWORD error; 2706 BOOL ret; 2707 2708 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2709 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2710 2711 con = WinHttpConnect(ses, localhostW, port, 0); 2712 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2713 2714 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0); 2715 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2716 2717 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2718 if (!ret) 2719 { 2720 error = GetLastError(); 2721 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error); 2722 } 2723 else 2724 { 2725 SetLastError(0xdeadbeef); 2726 ret = WinHttpReceiveResponse(req, NULL); 2727 error = GetLastError(); 2728 ok(!ret, "expected failure\n"); 2729 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error); 2730 } 2731 2732 WinHttpCloseHandle(req); 2733 WinHttpCloseHandle(con); 2734 WinHttpCloseHandle(ses); 2735 } 2736 2737 static void test_no_content(int port) 2738 { 2739 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0}; 2740 HINTERNET ses, con, req; 2741 char buf[128]; 2742 DWORD size, len = sizeof(buf), bytes_read, status; 2743 BOOL ret; 2744 2745 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2746 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2747 2748 con = WinHttpConnect(ses, localhostW, port, 0); 2749 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2750 2751 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0); 2752 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2753 2754 size = 12345; 2755 SetLastError(0xdeadbeef); 2756 ret = WinHttpQueryDataAvailable(req, &size); 2757 todo_wine { 2758 ok(!ret, "expected error\n"); 2759 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, 2760 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError()); 2761 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */, 2762 "expected 12345, got %u\n", size); 2763 } 2764 2765 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2766 ok(ret, "expected success\n"); 2767 2768 ret = WinHttpReceiveResponse(req, NULL); 2769 ok(ret, "expected success\n"); 2770 2771 status = 0xdeadbeef; 2772 size = sizeof(status); 2773 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, 2774 NULL, &status, &size, NULL); 2775 ok(ret, "expected success\n"); 2776 ok(status == HTTP_STATUS_NO_CONTENT, "expected status 204, got %d\n", status); 2777 2778 SetLastError(0xdeadbeef); 2779 size = sizeof(status); 2780 status = 12345; 2781 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, 2782 NULL, &status, &size, 0); 2783 ok(!ret, "expected no content-length header\n"); 2784 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError()); 2785 ok(status == 12345, "expected 0, got %d\n", status); 2786 2787 SetLastError(0xdeadbeef); 2788 size = 12345; 2789 ret = WinHttpQueryDataAvailable(req, &size); 2790 ok(ret, "expected success\n"); 2791 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 2792 "wrong error %u\n", GetLastError()); 2793 ok(!size, "expected 0, got %u\n", size); 2794 2795 SetLastError(0xdeadbeef); 2796 ret = WinHttpReadData(req, buf, len, &bytes_read); 2797 ok(ret, "expected success\n"); 2798 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 2799 "wrong error %u\n", GetLastError()); 2800 ok(!bytes_read, "expected 0, got %u\n", bytes_read); 2801 2802 size = 12345; 2803 ret = WinHttpQueryDataAvailable(req, &size); 2804 ok(ret, "expected success\n"); 2805 ok(size == 0, "expected 0, got %d\n", size); 2806 2807 WinHttpCloseHandle(req); 2808 2809 size = 12345; 2810 SetLastError(0xdeadbeef); 2811 ret = WinHttpQueryDataAvailable(req, &size); 2812 ok(!ret, "expected error\n"); 2813 ok(GetLastError() == ERROR_INVALID_HANDLE, 2814 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError()); 2815 ok(size == 12345, "expected 12345, got %u\n", size); 2816 2817 WinHttpCloseHandle(con); 2818 WinHttpCloseHandle(ses); 2819 } 2820 2821 static void test_head_request(int port) 2822 { 2823 static const WCHAR verbW[] = {'H','E','A','D',0}; 2824 static const WCHAR headW[] = {'/','h','e','a','d',0}; 2825 HINTERNET ses, con, req; 2826 char buf[128]; 2827 DWORD size, len, count, status; 2828 BOOL ret; 2829 2830 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2831 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2832 2833 con = WinHttpConnect(ses, localhostW, port, 0); 2834 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2835 2836 req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0); 2837 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2838 2839 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2840 ok(ret, "failed to send request %u\n", GetLastError()); 2841 2842 ret = WinHttpReceiveResponse(req, NULL); 2843 ok(ret, "failed to receive response %u\n", GetLastError()); 2844 2845 status = 0xdeadbeef; 2846 size = sizeof(status); 2847 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, 2848 NULL, &status, &size, NULL); 2849 ok(ret, "failed to get status code %u\n", GetLastError()); 2850 ok(status == HTTP_STATUS_OK, "got %u\n", status); 2851 2852 len = 0xdeadbeef; 2853 size = sizeof(len); 2854 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, 2855 NULL, &len, &size, 0); 2856 ok(ret, "failed to get content-length header %u\n", GetLastError()); 2857 ok(len == HTTP_STATUS_CONTINUE, "got %u\n", len); 2858 2859 count = 0xdeadbeef; 2860 ret = WinHttpQueryDataAvailable(req, &count); 2861 ok(ret, "failed to query data available %u\n", GetLastError()); 2862 ok(!count, "got %u\n", count); 2863 2864 len = sizeof(buf); 2865 count = 0xdeadbeef; 2866 ret = WinHttpReadData(req, buf, len, &count); 2867 ok(ret, "failed to read data %u\n", GetLastError()); 2868 ok(!count, "got %u\n", count); 2869 2870 count = 0xdeadbeef; 2871 ret = WinHttpQueryDataAvailable(req, &count); 2872 ok(ret, "failed to query data available %u\n", GetLastError()); 2873 ok(!count, "got %u\n", count); 2874 2875 WinHttpCloseHandle(req); 2876 WinHttpCloseHandle(con); 2877 WinHttpCloseHandle(ses); 2878 } 2879 2880 static void test_not_modified(int port) 2881 { 2882 static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0}; 2883 static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '}; 2884 static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0}; 2885 BOOL ret; 2886 HINTERNET session, request, connection; 2887 DWORD index, len, status, size, start = GetTickCount(); 2888 SYSTEMTIME st; 2889 WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32]; 2890 2891 memcpy(today, ifmodifiedW, sizeof(ifmodifiedW)); 2892 GetSystemTime(&st); 2893 WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]); 2894 2895 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, 2896 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 2897 ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError()); 2898 2899 connection = WinHttpConnect(session, localhostW, port, 0); 2900 ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError()); 2901 2902 request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER, 2903 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE); 2904 ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError()); 2905 2906 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0); 2907 ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError()); 2908 2909 ret = WinHttpReceiveResponse(request, NULL); 2910 ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError()); 2911 2912 index = 0; 2913 len = sizeof(buffer); 2914 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 2915 ifmodified2W, buffer, &len, &index); 2916 ok(ret, "failed to get header %u\n", GetLastError()); 2917 2918 status = 0xdeadbeef; 2919 size = sizeof(status); 2920 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, 2921 NULL, &status, &size, NULL); 2922 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 2923 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status); 2924 2925 size = 0xdeadbeef; 2926 ret = WinHttpQueryDataAvailable(request, &size); 2927 ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError()); 2928 ok(!size, "got %u\n", size); 2929 2930 WinHttpCloseHandle(request); 2931 WinHttpCloseHandle(connection); 2932 WinHttpCloseHandle(session); 2933 start = GetTickCount() - start; 2934 ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start); 2935 } 2936 2937 static void test_bad_header( int port ) 2938 { 2939 static const WCHAR bad_headerW[] = 2940 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ', 2941 't','e','x','t','/','h','t','m','l','\n','\r',0}; 2942 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0}; 2943 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0}; 2944 WCHAR buffer[32]; 2945 HINTERNET ses, con, req; 2946 DWORD index, len; 2947 BOOL ret; 2948 2949 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 2950 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 2951 2952 con = WinHttpConnect( ses, localhostW, port, 0 ); 2953 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 2954 2955 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); 2956 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 2957 2958 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD ); 2959 ok( ret, "failed to add header %u\n", GetLastError() ); 2960 2961 index = 0; 2962 buffer[0] = 0; 2963 len = sizeof(buffer); 2964 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 2965 content_typeW, buffer, &len, &index ); 2966 ok( ret, "failed to query headers %u\n", GetLastError() ); 2967 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) ); 2968 2969 WinHttpCloseHandle( req ); 2970 WinHttpCloseHandle( con ); 2971 WinHttpCloseHandle( ses ); 2972 } 2973 2974 static void test_multiple_reads(int port) 2975 { 2976 static const WCHAR bigW[] = {'b','i','g',0}; 2977 HINTERNET ses, con, req; 2978 DWORD total_len = 0; 2979 BOOL ret; 2980 2981 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2982 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2983 2984 con = WinHttpConnect(ses, localhostW, port, 0); 2985 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2986 2987 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0); 2988 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2989 2990 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2991 ok(ret, "failed to send request %u\n", GetLastError()); 2992 2993 ret = WinHttpReceiveResponse(req, NULL); 2994 ok(ret == TRUE, "expected success\n"); 2995 2996 for (;;) 2997 { 2998 DWORD len = 0xdeadbeef; 2999 ret = WinHttpQueryDataAvailable( req, &len ); 3000 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() ); 3001 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" ); 3002 if (len) 3003 { 3004 DWORD bytes_read; 3005 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 ); 3006 3007 ret = WinHttpReadData( req, buf, len, &bytes_read ); 3008 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len ); 3009 3010 HeapFree( GetProcessHeap(), 0, buf ); 3011 if (!bytes_read) break; 3012 total_len += bytes_read; 3013 } 3014 if (!len) break; 3015 } 3016 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len); 3017 3018 WinHttpCloseHandle(req); 3019 WinHttpCloseHandle(con); 3020 WinHttpCloseHandle(ses); 3021 } 3022 3023 static void test_cookies( int port ) 3024 { 3025 static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0}; 3026 static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0}; 3027 static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0}; 3028 static const WCHAR cookie4W[] = {'/','c','o','o','k','i','e','4',0}; 3029 static const WCHAR cookie5W[] = {'/','c','o','o','k','i','e','5',0}; 3030 static const WCHAR cookieheaderW[] = 3031 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0}; 3032 HINTERNET ses, con, req; 3033 DWORD status, size; 3034 BOOL ret; 3035 3036 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3037 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3038 3039 con = WinHttpConnect( ses, localhostW, port, 0 ); 3040 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3041 3042 req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 ); 3043 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3044 3045 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3046 ok( ret, "failed to send request %u\n", GetLastError() ); 3047 3048 ret = WinHttpReceiveResponse( req, NULL ); 3049 ok( ret, "failed to receive response %u\n", GetLastError() ); 3050 3051 status = 0xdeadbeef; 3052 size = sizeof(status); 3053 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3054 ok( ret, "failed to query status code %u\n", GetLastError() ); 3055 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3056 3057 WinHttpCloseHandle( req ); 3058 3059 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); 3060 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3061 3062 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3063 ok( ret, "failed to send request %u\n", GetLastError() ); 3064 3065 ret = WinHttpReceiveResponse( req, NULL ); 3066 ok( ret, "failed to receive response %u\n", GetLastError() ); 3067 3068 status = 0xdeadbeef; 3069 size = sizeof(status); 3070 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3071 ok( ret, "failed to query status code %u\n", GetLastError() ); 3072 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3073 3074 WinHttpCloseHandle( req ); 3075 WinHttpCloseHandle( con ); 3076 3077 con = WinHttpConnect( ses, localhostW, port, 0 ); 3078 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3079 3080 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); 3081 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3082 3083 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3084 ok( ret, "failed to send request %u\n", GetLastError() ); 3085 3086 ret = WinHttpReceiveResponse( req, NULL ); 3087 ok( ret, "failed to receive response %u\n", GetLastError() ); 3088 3089 status = 0xdeadbeef; 3090 size = sizeof(status); 3091 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3092 ok( ret, "failed to query status code %u\n", GetLastError() ); 3093 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3094 3095 WinHttpCloseHandle( req ); 3096 3097 req = WinHttpOpenRequest( con, NULL, cookie3W, NULL, NULL, NULL, 0 ); 3098 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3099 3100 ret = WinHttpSendRequest( req, cookieheaderW, ~0u, NULL, 0, 0, 0 ); 3101 ok( ret, "failed to send request %u\n", GetLastError() ); 3102 3103 ret = WinHttpReceiveResponse( req, NULL ); 3104 ok( ret, "failed to receive response %u\n", GetLastError() ); 3105 3106 status = 0xdeadbeef; 3107 size = sizeof(status); 3108 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3109 ok( ret, "failed to query status code %u\n", GetLastError() ); 3110 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST), "request failed unexpectedly %u\n", status ); 3111 3112 WinHttpCloseHandle( req ); 3113 WinHttpCloseHandle( con ); 3114 WinHttpCloseHandle( ses ); 3115 3116 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3117 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3118 3119 con = WinHttpConnect( ses, localhostW, port, 0 ); 3120 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3121 3122 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); 3123 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3124 3125 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3126 ok( ret, "failed to send request %u\n", GetLastError() ); 3127 3128 ret = WinHttpReceiveResponse( req, NULL ); 3129 ok( ret, "failed to receive response %u\n", GetLastError() ); 3130 3131 status = 0xdeadbeef; 3132 size = sizeof(status); 3133 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3134 ok( ret, "failed to query status code %u\n", GetLastError() ); 3135 ok( status == HTTP_STATUS_BAD_REQUEST, "request failed unexpectedly %u\n", status ); 3136 3137 WinHttpCloseHandle( req ); 3138 WinHttpCloseHandle( con ); 3139 WinHttpCloseHandle( ses ); 3140 3141 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3142 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3143 3144 con = WinHttpConnect( ses, localhostW, port, 0 ); 3145 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3146 3147 req = WinHttpOpenRequest( con, NULL, cookie4W, NULL, NULL, NULL, 0 ); 3148 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3149 3150 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3151 ok( ret, "failed to send request %u\n", GetLastError() ); 3152 3153 ret = WinHttpReceiveResponse( req, NULL ); 3154 ok( ret, "failed to receive response %u\n", GetLastError() ); 3155 3156 status = 0xdeadbeef; 3157 size = sizeof(status); 3158 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3159 ok( ret, "failed to query status code %u\n", GetLastError() ); 3160 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3161 WinHttpCloseHandle( req ); 3162 3163 req = WinHttpOpenRequest( con, NULL, cookie5W, NULL, NULL, NULL, 0 ); 3164 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3165 3166 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3167 ok( ret, "failed to send request %u\n", GetLastError() ); 3168 3169 ret = WinHttpReceiveResponse( req, NULL ); 3170 ok( ret, "failed to receive response %u\n", GetLastError() ); 3171 3172 status = 0xdeadbeef; 3173 size = sizeof(status); 3174 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3175 ok( ret, "failed to query status code %u\n", GetLastError() ); 3176 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST) /* < win7 */, 3177 "request failed unexpectedly %u\n", status ); 3178 3179 WinHttpCloseHandle( req ); 3180 WinHttpCloseHandle( con ); 3181 WinHttpCloseHandle( ses ); 3182 } 3183 3184 static void test_connection_info( int port ) 3185 { 3186 static const WCHAR basicW[] = {'/','b','a','s','i','c',0}; 3187 HINTERNET ses, con, req; 3188 WINHTTP_CONNECTION_INFO info; 3189 DWORD size, error; 3190 BOOL ret; 3191 3192 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3193 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3194 3195 con = WinHttpConnect( ses, localhostW, port, 0 ); 3196 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3197 3198 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 ); 3199 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3200 3201 size = sizeof(info); 3202 SetLastError( 0xdeadbeef ); 3203 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3204 error = GetLastError(); 3205 if (!ret && error == ERROR_INVALID_PARAMETER) 3206 { 3207 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" ); 3208 return; 3209 } 3210 ok( !ret, "unexpected success\n" ); 3211 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error ); 3212 3213 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3214 ok( ret, "failed to send request %u\n", GetLastError() ); 3215 3216 size = 0; 3217 SetLastError( 0xdeadbeef ); 3218 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3219 error = GetLastError(); 3220 ok( !ret, "unexpected success\n" ); 3221 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error ); 3222 3223 size = sizeof(info); 3224 memset( &info, 0, sizeof(info) ); 3225 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3226 ok( ret, "failed to retrieve connection info %u\n", GetLastError() ); 3227 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize ); 3228 3229 ret = WinHttpReceiveResponse( req, NULL ); 3230 ok( ret, "failed to receive response %u\n", GetLastError() ); 3231 3232 size = sizeof(info); 3233 memset( &info, 0, sizeof(info) ); 3234 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3235 ok( ret, "failed to retrieve connection info %u\n", GetLastError() ); 3236 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize ); 3237 3238 WinHttpCloseHandle( req ); 3239 WinHttpCloseHandle( con ); 3240 WinHttpCloseHandle( ses ); 3241 } 3242 3243 static void test_credentials(void) 3244 { 3245 static WCHAR userW[] = {'u','s','e','r',0}; 3246 static WCHAR passW[] = {'p','a','s','s',0}; 3247 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0}; 3248 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0}; 3249 HINTERNET ses, con, req; 3250 DWORD size, error; 3251 WCHAR buffer[32]; 3252 BOOL ret; 3253 3254 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0); 3255 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 3256 3257 con = WinHttpConnect(ses, localhostW, 0, 0); 3258 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 3259 3260 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 3261 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 3262 3263 size = sizeof(buffer)/sizeof(WCHAR); 3264 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size); 3265 ok(ret, "failed to query proxy username %u\n", GetLastError()); 3266 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3267 ok(!size, "expected 0, got %u\n", size); 3268 3269 size = sizeof(buffer)/sizeof(WCHAR); 3270 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size); 3271 ok(ret, "failed to query proxy password %u\n", GetLastError()); 3272 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3273 ok(!size, "expected 0, got %u\n", size); 3274 3275 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW)); 3276 ok(ret, "failed to set username %u\n", GetLastError()); 3277 3278 size = sizeof(buffer)/sizeof(WCHAR); 3279 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size); 3280 ok(ret, "failed to query proxy username %u\n", GetLastError()); 3281 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3282 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size); 3283 3284 size = sizeof(buffer)/sizeof(WCHAR); 3285 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); 3286 ok(ret, "failed to query username %u\n", GetLastError()); 3287 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3288 ok(!size, "expected 0, got %u\n", size); 3289 3290 size = sizeof(buffer)/sizeof(WCHAR); 3291 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); 3292 ok(ret, "failed to query password %u\n", GetLastError()); 3293 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3294 ok(!size, "expected 0, got %u\n", size); 3295 3296 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW)); 3297 ok(ret, "failed to set proxy password %u\n", GetLastError()); 3298 3299 size = sizeof(buffer)/sizeof(WCHAR); 3300 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size); 3301 ok(ret, "failed to query proxy password %u\n", GetLastError()); 3302 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3303 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size); 3304 3305 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); 3306 ok(ret, "failed to set username %u\n", GetLastError()); 3307 3308 size = sizeof(buffer)/sizeof(WCHAR); 3309 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); 3310 ok(ret, "failed to query username %u\n", GetLastError()); 3311 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3312 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size); 3313 3314 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW)); 3315 ok(ret, "failed to set password %u\n", GetLastError()); 3316 3317 size = sizeof(buffer)/sizeof(WCHAR); 3318 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); 3319 ok(ret, "failed to query password %u\n", GetLastError()); 3320 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3321 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size); 3322 3323 WinHttpCloseHandle(req); 3324 3325 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 3326 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 3327 3328 SetLastError(0xdeadbeef); 3329 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL); 3330 error = GetLastError(); 3331 ok(!ret, "expected failure\n"); 3332 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 3333 3334 SetLastError(0xdeadbeef); 3335 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL); 3336 error = GetLastError(); 3337 ok(!ret, "expected failure\n"); 3338 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 3339 3340 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 3341 ok(ret, "failed to set credentials %u\n", GetLastError()); 3342 3343 size = sizeof(buffer)/sizeof(WCHAR); 3344 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); 3345 ok(ret, "failed to query username %u\n", GetLastError()); 3346 todo_wine { 3347 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3348 ok(!size, "expected 0, got %u\n", size); 3349 } 3350 3351 size = sizeof(buffer)/sizeof(WCHAR); 3352 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); 3353 ok(ret, "failed to query password %u\n", GetLastError()); 3354 todo_wine { 3355 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3356 ok(!size, "expected 0, got %u\n", size); 3357 } 3358 3359 WinHttpCloseHandle(req); 3360 WinHttpCloseHandle(con); 3361 WinHttpCloseHandle(ses); 3362 } 3363 3364 static void test_IWinHttpRequest(int port) 3365 { 3366 static const WCHAR data_start[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'}; 3367 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0}; 3368 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0}; 3369 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; 3370 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; 3371 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.', 3372 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0}; 3373 static const WCHAR method1W[] = {'G','E','T',0}; 3374 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0}; 3375 static const WCHAR method3W[] = {'P','O','S','T',0}; 3376 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0}; 3377 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0}; 3378 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0}; 3379 static const WCHAR dateW[] = {'D','a','t','e',0}; 3380 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0}; 3381 static const WCHAR utf8W[] = {'u','t','f','-','8',0}; 3382 static const WCHAR unauthW[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0}; 3383 HRESULT hr; 3384 IWinHttpRequest *req; 3385 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL; 3386 BSTR date, today, connection, value = NULL; 3387 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp; 3388 VARIANT_BOOL succeeded; 3389 LONG status; 3390 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE]; 3391 SYSTEMTIME st; 3392 IStream *stream, *stream2; 3393 LARGE_INTEGER pos; 3394 char buf[128]; 3395 WCHAR bufW[128]; 3396 DWORD count; 3397 3398 GetSystemTime( &st ); 3399 WinHttpTimeFromSystemTime( &st, todayW ); 3400 3401 CoInitialize( NULL ); 3402 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3403 ok( hr == S_OK, "got %08x\n", hr ); 3404 3405 V_VT( &empty ) = VT_ERROR; 3406 V_ERROR( &empty ) = 0xdeadbeef; 3407 3408 V_VT( &async ) = VT_BOOL; 3409 V_BOOL( &async ) = VARIANT_FALSE; 3410 3411 method = SysAllocString( method3W ); 3412 url = SysAllocString( url3W ); 3413 hr = IWinHttpRequest_Open( req, method, url, async ); 3414 ok( hr == S_OK, "got %08x\n", hr ); 3415 SysFreeString( method ); 3416 SysFreeString( url ); 3417 3418 V_VT( &data ) = VT_BSTR; 3419 V_BSTR( &data ) = SysAllocString( test_dataW ); 3420 hr = IWinHttpRequest_Send( req, data ); 3421 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)), 3422 "got %08x\n", hr ); 3423 SysFreeString( V_BSTR( &data ) ); 3424 3425 hr = IWinHttpRequest_Open( req, NULL, NULL, empty ); 3426 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3427 3428 method = SysAllocString( method1W ); 3429 hr = IWinHttpRequest_Open( req, method, NULL, empty ); 3430 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3431 3432 hr = IWinHttpRequest_Open( req, method, NULL, async ); 3433 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3434 3435 url = SysAllocString( url1W ); 3436 hr = IWinHttpRequest_Open( req, NULL, url, empty ); 3437 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3438 3439 hr = IWinHttpRequest_Abort( req ); 3440 ok( hr == S_OK, "got %08x\n", hr ); 3441 3442 hr = IWinHttpRequest_Open( req, method, url, empty ); 3443 ok( hr == S_OK, "got %08x\n", hr ); 3444 3445 hr = IWinHttpRequest_Abort( req ); 3446 ok( hr == S_OK, "got %08x\n", hr ); 3447 3448 IWinHttpRequest_Release( req ); 3449 3450 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3451 ok( hr == S_OK, "got %08x\n", hr ); 3452 3453 SysFreeString( url ); 3454 url = SysAllocString( url2W ); 3455 hr = IWinHttpRequest_Open( req, method, url, async ); 3456 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr ); 3457 3458 SysFreeString( method ); 3459 method = SysAllocString( method2W ); 3460 hr = IWinHttpRequest_Open( req, method, url, async ); 3461 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr ); 3462 3463 SysFreeString( method ); 3464 method = SysAllocString( method1W ); 3465 SysFreeString( url ); 3466 url = SysAllocString( url1W ); 3467 V_VT( &async ) = VT_ERROR; 3468 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND; 3469 hr = IWinHttpRequest_Open( req, method, url, async ); 3470 ok( hr == S_OK, "got %08x\n", hr ); 3471 3472 V_VT( &cp ) = VT_ERROR; 3473 V_ERROR( &cp ) = 0xdeadbeef; 3474 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp ); 3475 ok( hr == S_OK, "got %08x\n", hr ); 3476 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) ); 3477 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) ); 3478 3479 V_VT( &cp ) = VT_UI4; 3480 V_UI4( &cp ) = CP_ACP; 3481 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp ); 3482 ok( hr == S_OK, "got %08x\n", hr ); 3483 3484 V_VT( &cp ) = VT_ERROR; 3485 V_ERROR( &cp ) = 0xdeadbeef; 3486 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp ); 3487 ok( hr == S_OK, "got %08x\n", hr ); 3488 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) ); 3489 ok( V_I4( &cp ) == CP_ACP, "got %u\n", V_I4( &cp ) ); 3490 3491 value = SysAllocString( utf8W ); 3492 V_VT( &cp ) = VT_BSTR; 3493 V_BSTR( &cp ) = value; 3494 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp ); 3495 ok( hr == S_OK, "got %08x\n", hr ); 3496 SysFreeString( value ); 3497 3498 V_VT( &cp ) = VT_ERROR; 3499 V_ERROR( &cp ) = 0xdeadbeef; 3500 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp ); 3501 ok( hr == S_OK, "got %08x\n", hr ); 3502 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) ); 3503 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) ); 3504 3505 hr = IWinHttpRequest_Abort( req ); 3506 ok( hr == S_OK, "got %08x\n", hr ); 3507 3508 hr = IWinHttpRequest_Send( req, empty ); 3509 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3510 3511 hr = IWinHttpRequest_Abort( req ); 3512 ok( hr == S_OK, "got %08x\n", hr ); 3513 3514 IWinHttpRequest_Release( req ); 3515 3516 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3517 ok( hr == S_OK, "got %08x\n", hr ); 3518 3519 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3520 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3521 3522 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3523 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3524 3525 hr = IWinHttpRequest_get_Status( req, NULL ); 3526 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3527 3528 hr = IWinHttpRequest_get_Status( req, &status ); 3529 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3530 3531 hr = IWinHttpRequest_get_StatusText( req, NULL ); 3532 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3533 3534 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3535 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3536 3537 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3538 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3539 3540 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 ); 3541 ok( hr == S_OK, "got %08x\n", hr ); 3542 3543 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef ); 3544 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3545 3546 VariantInit( &proxy_server ); 3547 V_VT( &proxy_server ) = VT_ERROR; 3548 VariantInit( &bypass_list ); 3549 V_VT( &bypass_list ) = VT_ERROR; 3550 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3551 ok( hr == S_OK, "got %08x\n", hr ); 3552 3553 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3554 ok( hr == S_OK, "got %08x\n", hr ); 3555 3556 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3557 ok( hr == S_OK, "got %08x\n", hr ); 3558 3559 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL ); 3560 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3561 3562 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3563 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3564 3565 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL ); 3566 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3567 3568 connection = SysAllocString( connectionW ); 3569 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL ); 3570 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3571 3572 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3573 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3574 3575 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL ); 3576 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3577 3578 date = SysAllocString( dateW ); 3579 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL ); 3580 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3581 3582 today = SysAllocString( todayW ); 3583 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3584 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3585 3586 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef ); 3587 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3588 3589 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3590 ok( hr == S_OK, "got %08x\n", hr ); 3591 3592 SysFreeString( method ); 3593 method = SysAllocString( method1W ); 3594 SysFreeString( url ); 3595 url = SysAllocString( url1W ); 3596 hr = IWinHttpRequest_Open( req, method, url, async ); 3597 ok( hr == S_OK, "got %08x\n", hr ); 3598 3599 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3600 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3601 3602 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3603 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3604 3605 hr = IWinHttpRequest_get_Status( req, &status ); 3606 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3607 3608 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3609 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3610 3611 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3612 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3613 3614 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 ); 3615 ok( hr == S_OK, "got %08x\n", hr ); 3616 3617 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef ); 3618 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3619 3620 username = SysAllocString( usernameW ); 3621 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef ); 3622 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3623 3624 password = SysAllocString( passwordW ); 3625 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef ); 3626 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3627 3628 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef ); 3629 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3630 3631 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3632 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3633 3634 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3635 ok( hr == S_OK, "got %08x\n", hr ); 3636 3637 V_VT( &proxy_server ) = VT_BSTR; 3638 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW ); 3639 V_VT( &bypass_list ) = VT_BSTR; 3640 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW ); 3641 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3642 ok( hr == S_OK, "got %08x\n", hr ); 3643 3644 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list ); 3645 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3646 3647 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3648 ok( hr == S_OK, "got %08x\n", hr ); 3649 3650 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3651 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3652 3653 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3654 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3655 3656 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3657 ok( hr == S_OK, "got %08x\n", hr ); 3658 3659 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL ); 3660 ok( hr == S_OK, "got %08x\n", hr ); 3661 3662 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3663 ok( hr == S_OK, "got %08x\n", hr ); 3664 3665 hr = IWinHttpRequest_Send( req, empty ); 3666 ok( hr == S_OK, "got %08x\n", hr ); 3667 3668 hr = IWinHttpRequest_Send( req, empty ); 3669 ok( hr == S_OK, "got %08x\n", hr ); 3670 3671 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3672 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3673 3674 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3675 ok( hr == S_OK, "got %08x\n", hr ); 3676 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) ); 3677 SysFreeString( response ); 3678 3679 hr = IWinHttpRequest_get_Status( req, NULL ); 3680 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3681 3682 status = 0; 3683 hr = IWinHttpRequest_get_Status( req, &status ); 3684 ok( hr == S_OK, "got %08x\n", hr ); 3685 trace("Status=%d\n", status); 3686 3687 hr = IWinHttpRequest_get_StatusText( req, NULL ); 3688 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3689 3690 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3691 ok( hr == S_OK, "got %08x\n", hr ); 3692 trace("StatusText=%s\n", wine_dbgstr_w(status_text)); 3693 SysFreeString( status_text ); 3694 3695 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3696 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3697 3698 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3699 ok( hr == S_OK, "got %08x\n", hr ); 3700 3701 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3702 ok( hr == S_OK, "got %08x\n", hr ); 3703 3704 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3705 ok( hr == S_OK, "got %08x\n", hr ); 3706 3707 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL ); 3708 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3709 3710 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3711 ok( hr == S_OK, "got %08x\n", hr ); 3712 SysFreeString( headers ); 3713 3714 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL ); 3715 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3716 3717 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL ); 3718 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3719 3720 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3721 ok( hr == S_OK, "got %08x\n", hr ); 3722 SysFreeString( value ); 3723 3724 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3725 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr ); 3726 3727 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3728 ok( hr == S_OK, "got %08x\n", hr ); 3729 3730 VariantInit( &timeout ); 3731 V_VT( &timeout ) = VT_I4; 3732 V_I4( &timeout ) = 10; 3733 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded ); 3734 ok( hr == S_OK, "got %08x\n", hr ); 3735 3736 hr = IWinHttpRequest_get_Status( req, &status ); 3737 ok( hr == S_OK, "got %08x\n", hr ); 3738 3739 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3740 ok( hr == S_OK, "got %08x\n", hr ); 3741 SysFreeString( status_text ); 3742 3743 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3744 ok( hr == S_OK, "got %08x\n", hr ); 3745 3746 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3747 ok( hr == S_OK, "got %08x\n", hr ); 3748 3749 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3750 ok( hr == S_OK, "got %08x\n", hr ); 3751 3752 hr = IWinHttpRequest_Send( req, empty ); 3753 ok( hr == S_OK, "got %08x\n", hr ); 3754 3755 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3756 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3757 3758 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3759 ok( hr == S_OK, "got %08x\n", hr ); 3760 SysFreeString( response ); 3761 3762 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3763 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3764 3765 VariantInit( &body ); 3766 V_VT( &body ) = VT_ERROR; 3767 hr = IWinHttpRequest_get_ResponseBody( req, &body ); 3768 ok( hr == S_OK, "got %08x\n", hr ); 3769 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) ); 3770 3771 hr = VariantClear( &body ); 3772 ok( hr == S_OK, "got %08x\n", hr ); 3773 3774 VariantInit( &body ); 3775 V_VT( &body ) = VT_ERROR; 3776 hr = IWinHttpRequest_get_ResponseStream( req, &body ); 3777 ok( hr == S_OK, "got %08x\n", hr ); 3778 ok( V_VT( &body ) == VT_UNKNOWN, "got %08x\n", V_VT( &body ) ); 3779 3780 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream ); 3781 ok( hr == S_OK, "got %08x\n", hr ); 3782 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" ); 3783 3784 buf[0] = 0; 3785 count = 0xdeadbeef; 3786 hr = IStream_Read( stream, buf, 128, &count ); 3787 ok( hr == S_OK, "got %08x\n", hr ); 3788 ok( count != 0xdeadbeef, "count not set\n" ); 3789 ok( buf[0], "no data\n" ); 3790 3791 VariantInit( &body2 ); 3792 V_VT( &body2 ) = VT_ERROR; 3793 hr = IWinHttpRequest_get_ResponseStream( req, &body2 ); 3794 ok( hr == S_OK, "got %08x\n", hr ); 3795 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %08x\n", V_VT( &body2 ) ); 3796 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" ); 3797 3798 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 ); 3799 ok( hr == S_OK, "got %08x\n", hr ); 3800 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" ); 3801 IStream_Release( stream2 ); 3802 3803 hr = VariantClear( &body ); 3804 ok( hr == S_OK, "got %08x\n", hr ); 3805 3806 hr = VariantClear( &body2 ); 3807 ok( hr == S_OK, "got %08x\n", hr ); 3808 3809 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3810 ok( hr == S_OK, "got %08x\n", hr ); 3811 3812 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3813 ok( hr == S_OK, "got %08x\n", hr ); 3814 3815 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3816 ok( hr == S_OK, "got %08x\n", hr ); 3817 SysFreeString( headers ); 3818 3819 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3820 ok( hr == S_OK, "got %08x\n", hr ); 3821 SysFreeString( value ); 3822 3823 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3824 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr ); 3825 3826 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3827 ok( hr == S_OK, "got %08x\n", hr ); 3828 3829 hr = IWinHttpRequest_Send( req, empty ); 3830 ok( hr == S_OK, "got %08x\n", hr ); 3831 3832 hr = IWinHttpRequest_Abort( req ); 3833 ok( hr == S_OK, "got %08x\n", hr ); 3834 3835 hr = IWinHttpRequest_Abort( req ); 3836 ok( hr == S_OK, "got %08x\n", hr ); 3837 3838 IWinHttpRequest_Release( req ); 3839 3840 pos.QuadPart = 0; 3841 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL ); 3842 ok( hr == S_OK, "got %08x\n", hr ); 3843 3844 buf[0] = 0; 3845 count = 0xdeadbeef; 3846 hr = IStream_Read( stream, buf, 128, &count ); 3847 ok( hr == S_OK, "got %08x\n", hr ); 3848 ok( count != 0xdeadbeef, "count not set\n" ); 3849 ok( buf[0], "no data\n" ); 3850 IStream_Release( stream ); 3851 3852 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3853 ok( hr == S_OK, "got %08x\n", hr ); 3854 3855 V_VT( &async ) = VT_I4; 3856 V_I4( &async ) = 1; 3857 hr = IWinHttpRequest_Open( req, method, url, async ); 3858 ok( hr == S_OK, "got %08x\n", hr ); 3859 3860 hr = IWinHttpRequest_Send( req, empty ); 3861 ok( hr == S_OK, "got %08x\n", hr ); 3862 3863 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded ); 3864 ok( hr == S_OK, "got %08x\n", hr ); 3865 3866 IWinHttpRequest_Release( req ); 3867 3868 SysFreeString( method ); 3869 SysFreeString( url ); 3870 SysFreeString( username ); 3871 SysFreeString( password ); 3872 SysFreeString( connection ); 3873 SysFreeString( date ); 3874 SysFreeString( today ); 3875 VariantClear( &proxy_server ); 3876 VariantClear( &bypass_list ); 3877 3878 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3879 ok( hr == S_OK, "got %08x\n", hr ); 3880 3881 url = SysAllocString( test_winehq_https ); 3882 method = SysAllocString( method3W ); 3883 V_VT( &async ) = VT_BOOL; 3884 V_BOOL( &async ) = VARIANT_FALSE; 3885 hr = IWinHttpRequest_Open( req, method, url, async ); 3886 ok( hr == S_OK, "got %08x\n", hr ); 3887 SysFreeString( method ); 3888 SysFreeString( url ); 3889 3890 hr = IWinHttpRequest_Send( req, empty ); 3891 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE )), "got %08x\n", hr ); 3892 if (hr == S_OK) 3893 { 3894 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3895 ok( hr == S_OK, "got %08x\n", hr ); 3896 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) ); 3897 SysFreeString( response ); 3898 } 3899 3900 IWinHttpRequest_Release( req ); 3901 3902 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3903 ok( hr == S_OK, "got %08x\n", hr ); 3904 3905 sprintf( buf, "http://localhost:%d/auth", port ); 3906 MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, sizeof(bufW)/sizeof(bufW[0]) ); 3907 url = SysAllocString( bufW ); 3908 method = SysAllocString( method3W ); 3909 V_VT( &async ) = VT_BOOL; 3910 V_BOOL( &async ) = VARIANT_FALSE; 3911 hr = IWinHttpRequest_Open( req, method, url, async ); 3912 ok( hr == S_OK, "got %08x\n", hr ); 3913 SysFreeString( method ); 3914 SysFreeString( url ); 3915 3916 hr = IWinHttpRequest_get_Status( req, &status ); 3917 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3918 3919 V_VT( &data ) = VT_BSTR; 3920 V_BSTR( &data ) = SysAllocString( test_dataW ); 3921 hr = IWinHttpRequest_Send( req, data ); 3922 ok( hr == S_OK, "got %08x\n", hr ); 3923 SysFreeString( V_BSTR( &data ) ); 3924 3925 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3926 ok( hr == S_OK, "got %08x\n", hr ); 3927 ok( !memcmp( response, unauthW, sizeof(unauthW) ), "got %s\n", wine_dbgstr_w(response) ); 3928 SysFreeString( response ); 3929 3930 status = 0xdeadbeef; 3931 hr = IWinHttpRequest_get_Status( req, &status ); 3932 ok( hr == S_OK, "got %08x\n", hr ); 3933 ok( status == HTTP_STATUS_DENIED, "got %d\n", status ); 3934 3935 IWinHttpRequest_Release( req ); 3936 3937 CoUninitialize(); 3938 } 3939 3940 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret) 3941 { 3942 DISPPARAMS params; 3943 VARIANT arg; 3944 HRESULT hr; 3945 3946 memset(¶ms, 0, sizeof(params)); 3947 params.cNamedArgs = 0; 3948 params.rgdispidNamedArgs = NULL; 3949 params.cArgs = 1; 3950 params.rgvarg = &arg; 3951 VariantInit(&arg); 3952 V_VT(&arg) = VT_I4; 3953 V_I4(&arg) = property; 3954 VariantInit(ret); 3955 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 3956 DISPATCH_PROPERTYGET, ¶ms, ret, NULL, NULL); 3957 ok(hr == S_OK, "error %#x\n", hr); 3958 } 3959 3960 static void test_IWinHttpRequest_Invoke(void) 3961 { 3962 static const WCHAR utf8W[] = {'U','T','F','-','8',0}; 3963 static const WCHAR regid[] = {'W','i','n','H','t','t','p','.','W','i','n','H','t','t','p','R','e','q','u','e','s','t','.','5','.','1',0}; 3964 WCHAR openW[] = {'O','p','e','n',0}; 3965 WCHAR optionW[] = {'O','p','t','i','o','n',0}; 3966 OLECHAR *open = openW, *option = optionW; 3967 BSTR utf8; 3968 CLSID clsid; 3969 IWinHttpRequest *request; 3970 IDispatch *dispatch; 3971 DISPID id; 3972 DISPPARAMS params; 3973 VARIANT arg[3], ret; 3974 UINT err; 3975 BOOL bret; 3976 HRESULT hr; 3977 3978 CoInitialize(NULL); 3979 3980 hr = CLSIDFromProgID(regid, &clsid); 3981 ok(hr == S_OK, "CLSIDFromProgID error %#x\n", hr); 3982 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest); 3983 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid)); 3984 3985 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request); 3986 ok(hr == S_OK, "error %#x\n", hr); 3987 3988 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch); 3989 ok(hr == S_OK, "error %#x\n", hr); 3990 IDispatch_Release(dispatch); 3991 3992 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id); 3993 ok(hr == S_OK, "error %#x\n", hr); 3994 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id); 3995 3996 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id); 3997 ok(hr == S_OK, "error %#x\n", hr); 3998 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id); 3999 4000 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4001 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4002 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4003 4004 memset(¶ms, 0, sizeof(params)); 4005 params.cArgs = 2; 4006 params.cNamedArgs = 0; 4007 params.rgvarg = arg; 4008 V_VT(&arg[0]) = VT_I4; 4009 V_I4(&arg[0]) = 1252; 4010 V_VT(&arg[1]) = VT_R8; 4011 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4012 VariantInit(&ret); 4013 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 4014 DISPATCH_METHOD, ¶ms, NULL, NULL, &err); 4015 ok(hr == S_OK, "error %#x\n", hr); 4016 4017 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4018 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4019 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4020 4021 memset(¶ms, 0, sizeof(params)); 4022 params.cArgs = 2; 4023 params.cNamedArgs = 0; 4024 params.rgvarg = arg; 4025 V_VT(&arg[0]) = VT_I4; 4026 V_I4(&arg[0]) = 1252; 4027 V_VT(&arg[1]) = VT_R8; 4028 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4029 VariantInit(&ret); 4030 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 4031 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, &err); 4032 ok(hr == S_OK, "error %#x\n", hr); 4033 4034 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4035 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4036 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4037 4038 memset(¶ms, 0, sizeof(params)); 4039 params.cArgs = 2; 4040 params.cNamedArgs = 0; 4041 params.rgvarg = arg; 4042 V_VT(&arg[0]) = VT_I4; 4043 V_I4(&arg[0]) = 1252; 4044 V_VT(&arg[1]) = VT_R8; 4045 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4046 VariantInit(&ret); 4047 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 4048 DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, &err); 4049 ok(hr == S_OK, "error %#x\n", hr); 4050 4051 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4052 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4053 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret)); 4054 4055 memset(¶ms, 0, sizeof(params)); 4056 params.cArgs = 2; 4057 params.cNamedArgs = 0; 4058 params.rgvarg = arg; 4059 V_VT(&arg[0]) = VT_BSTR; 4060 utf8 = SysAllocString(utf8W); 4061 V_BSTR(&arg[0]) = utf8; 4062 V_VT(&arg[1]) = VT_R8; 4063 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4064 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, &err); 4065 ok(hr == S_OK, "error %#x\n", hr); 4066 4067 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4068 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4069 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret)); 4070 4071 VariantInit(&ret); 4072 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &ret, NULL, &err); 4073 ok(hr == S_OK, "error %#x\n", hr); 4074 4075 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4076 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4077 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret)); 4078 4079 VariantInit(&ret); 4080 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4081 ok(hr == S_OK, "error %#x\n", hr); 4082 4083 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4084 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4085 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4086 4087 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL); 4088 ok(hr == S_OK, "error %#x\n", hr); 4089 4090 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL); 4091 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#x\n", hr); 4092 4093 VariantInit(&ret); 4094 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4095 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr); 4096 4097 VariantInit(&ret); 4098 if (0) /* crashes */ 4099 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err); 4100 4101 params.cArgs = 1; 4102 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4103 ok(hr == DISP_E_TYPEMISMATCH, "error %#x\n", hr); 4104 4105 VariantInit(&arg[2]); 4106 params.cArgs = 3; 4107 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4108 todo_wine 4109 ok(hr == S_OK, "error %#x\n", hr); 4110 4111 VariantInit(&arg[0]); 4112 VariantInit(&arg[1]); 4113 VariantInit(&arg[2]); 4114 4115 params.cArgs = 1; 4116 V_VT(&arg[0]) = VT_I4; 4117 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage; 4118 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4119 ok(hr == S_OK, "error %#x\n", hr); 4120 4121 V_VT(&ret) = 0xdead; 4122 V_I4(&ret) = 0xbeef; 4123 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, ¶ms, &ret, NULL, NULL); 4124 ok(hr == S_OK, "error %#x\n", hr); 4125 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4126 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4127 4128 V_VT(&ret) = 0xdead; 4129 V_I4(&ret) = 0xbeef; 4130 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &ret, NULL, NULL); 4131 ok(hr == S_OK, "error %#x\n", hr); 4132 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4133 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4134 4135 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4136 ok(hr == S_OK, "error %#x\n", hr); 4137 4138 V_VT(&ret) = 0xdead; 4139 V_I4(&ret) = 0xbeef; 4140 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, ¶ms, &ret, NULL, NULL); 4141 ok(hr == S_OK, "error %#x\n", hr); 4142 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %d\n", V_VT(&ret)); 4143 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret)); 4144 4145 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, ¶ms, NULL, NULL, NULL); 4146 ok(hr == S_OK, "error %#x\n", hr); 4147 4148 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4149 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr); 4150 4151 params.cArgs = 2; 4152 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4153 todo_wine 4154 ok(hr == S_OK, "error %#x\n", hr); 4155 4156 params.cArgs = 0; 4157 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4158 ok(hr == DISP_E_PARAMNOTFOUND, "error %#x\n", hr); 4159 4160 SysFreeString(utf8); 4161 4162 params.cArgs = 1; 4163 V_VT(&arg[0]) = VT_I4; 4164 V_I4(&arg[0]) = AutoLogonPolicy_Never; 4165 VariantInit(&ret); 4166 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0, 4167 DISPATCH_METHOD, ¶ms, &ret, NULL, NULL); 4168 ok(hr == S_OK, "error %#x\n", hr); 4169 4170 IWinHttpRequest_Release(request); 4171 4172 CoUninitialize(); 4173 } 4174 4175 static void test_WinHttpDetectAutoProxyConfigUrl(void) 4176 { 4177 BOOL ret; 4178 WCHAR *url; 4179 DWORD error; 4180 4181 if (0) /* crashes on some win2k systems */ 4182 { 4183 SetLastError(0xdeadbeef); 4184 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL ); 4185 error = GetLastError(); 4186 ok( !ret, "expected failure\n" ); 4187 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4188 } 4189 url = NULL; 4190 SetLastError(0xdeadbeef); 4191 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url ); 4192 error = GetLastError(); 4193 ok( !ret, "expected failure\n" ); 4194 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4195 4196 if (0) /* crashes on some win2k systems */ 4197 { 4198 SetLastError(0xdeadbeef); 4199 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL ); 4200 error = GetLastError(); 4201 ok( !ret, "expected failure\n" ); 4202 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4203 } 4204 url = (WCHAR *)0xdeadbeef; 4205 SetLastError(0xdeadbeef); 4206 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url ); 4207 error = GetLastError(); 4208 if (!ret) 4209 { 4210 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error ); 4211 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url ); 4212 } 4213 else 4214 { 4215 trace("%s\n", wine_dbgstr_w(url)); 4216 GlobalFree( url ); 4217 } 4218 4219 url = (WCHAR *)0xdeadbeef; 4220 SetLastError(0xdeadbeef); 4221 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url ); 4222 error = GetLastError(); 4223 if (!ret) 4224 { 4225 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error ); 4226 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url ); 4227 } 4228 else 4229 { 4230 ok( error == ERROR_SUCCESS, "got %u\n", error ); 4231 trace("%s\n", wine_dbgstr_w(url)); 4232 GlobalFree( url ); 4233 } 4234 } 4235 4236 static void test_WinHttpGetIEProxyConfigForCurrentUser(void) 4237 { 4238 BOOL ret; 4239 DWORD error; 4240 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg; 4241 4242 memset( &cfg, 0, sizeof(cfg) ); 4243 4244 SetLastError(0xdeadbeef); 4245 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL ); 4246 error = GetLastError(); 4247 ok( !ret, "expected failure\n" ); 4248 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4249 4250 SetLastError(0xdeadbeef); 4251 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg ); 4252 error = GetLastError(); 4253 ok( ret, "expected success\n" ); 4254 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error ); 4255 4256 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect); 4257 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl)); 4258 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy)); 4259 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass)); 4260 GlobalFree( cfg.lpszAutoConfigUrl ); 4261 GlobalFree( cfg.lpszProxy ); 4262 GlobalFree( cfg.lpszProxyBypass ); 4263 } 4264 4265 static void test_WinHttpGetProxyForUrl(void) 4266 { 4267 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0}; 4268 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0}; 4269 static const WCHAR emptyW[] = {0}; 4270 BOOL ret; 4271 DWORD error; 4272 HINTERNET session; 4273 WINHTTP_AUTOPROXY_OPTIONS options; 4274 WINHTTP_PROXY_INFO info; 4275 4276 memset( &options, 0, sizeof(options) ); 4277 4278 SetLastError(0xdeadbeef); 4279 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL ); 4280 error = GetLastError(); 4281 ok( !ret, "expected failure\n" ); 4282 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error ); 4283 4284 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 ); 4285 ok( session != NULL, "failed to open session %u\n", GetLastError() ); 4286 4287 SetLastError(0xdeadbeef); 4288 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL ); 4289 error = GetLastError(); 4290 ok( !ret, "expected failure\n" ); 4291 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4292 4293 SetLastError(0xdeadbeef); 4294 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL ); 4295 error = GetLastError(); 4296 ok( !ret, "expected failure\n" ); 4297 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4298 4299 SetLastError(0xdeadbeef); 4300 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL ); 4301 error = GetLastError(); 4302 ok( !ret, "expected failure\n" ); 4303 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4304 4305 SetLastError(0xdeadbeef); 4306 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4307 error = GetLastError(); 4308 ok( !ret, "expected failure\n" ); 4309 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4310 4311 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 4312 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; 4313 4314 SetLastError(0xdeadbeef); 4315 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL ); 4316 error = GetLastError(); 4317 ok( !ret, "expected failure\n" ); 4318 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4319 4320 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 4321 options.dwAutoDetectFlags = 0; 4322 4323 SetLastError(0xdeadbeef); 4324 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4325 error = GetLastError(); 4326 ok( !ret, "expected failure\n" ); 4327 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4328 4329 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL; 4330 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; 4331 4332 SetLastError(0xdeadbeef); 4333 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4334 error = GetLastError(); 4335 ok( !ret, "expected failure\n" ); 4336 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4337 4338 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 4339 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; 4340 4341 memset( &info, 0, sizeof(info) ); 4342 SetLastError(0xdeadbeef); 4343 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4344 error = GetLastError(); 4345 if (ret) 4346 { 4347 ok( error == ERROR_SUCCESS, "got %u\n", error ); 4348 trace("Proxy.AccessType=%u\n", info.dwAccessType); 4349 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy)); 4350 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass)); 4351 GlobalFree( info.lpszProxy ); 4352 GlobalFree( info.lpszProxyBypass ); 4353 } 4354 4355 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; 4356 options.dwAutoDetectFlags = 0; 4357 options.lpszAutoConfigUrl = wpadW; 4358 4359 memset( &info, 0, sizeof(info) ); 4360 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4361 if (ret) 4362 { 4363 trace("Proxy.AccessType=%u\n", info.dwAccessType); 4364 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy)); 4365 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass)); 4366 GlobalFree( info.lpszProxy ); 4367 GlobalFree( info.lpszProxyBypass ); 4368 } 4369 WinHttpCloseHandle( session ); 4370 } 4371 4372 static void test_chunked_read(void) 4373 { 4374 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0}; 4375 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0}; 4376 WCHAR header[32]; 4377 DWORD len, err; 4378 HINTERNET ses, con = NULL, req = NULL; 4379 BOOL ret; 4380 4381 trace( "starting chunked read test\n" ); 4382 4383 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 ); 4384 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() ); 4385 if (!ses) goto done; 4386 4387 con = WinHttpConnect( ses, test_winehq, 0, 0 ); 4388 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() ); 4389 if (!con) goto done; 4390 4391 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 ); 4392 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() ); 4393 if (!req) goto done; 4394 4395 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 4396 err = GetLastError(); 4397 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 4398 { 4399 skip("connection failed, skipping\n"); 4400 goto done; 4401 } 4402 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() ); 4403 4404 ret = WinHttpReceiveResponse( req, NULL ); 4405 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() ); 4406 4407 header[0] = 0; 4408 len = sizeof(header); 4409 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 ); 4410 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() ); 4411 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) ); 4412 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) ); 4413 4414 header[0] = 0; 4415 len = sizeof(header); 4416 SetLastError( 0xdeadbeef ); 4417 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 ); 4418 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) ); 4419 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() ); 4420 4421 trace( "entering query loop\n" ); 4422 for (;;) 4423 { 4424 len = 0xdeadbeef; 4425 ret = WinHttpQueryDataAvailable( req, &len ); 4426 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() ); 4427 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" ); 4428 trace( "got %u available\n", len ); 4429 if (len) 4430 { 4431 DWORD bytes_read; 4432 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 ); 4433 4434 ret = WinHttpReadData( req, buf, len, &bytes_read ); 4435 4436 buf[bytes_read] = 0; 4437 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read ); 4438 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len ); 4439 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf ); 4440 4441 HeapFree( GetProcessHeap(), 0, buf ); 4442 if (!bytes_read) break; 4443 } 4444 if (!len) break; 4445 } 4446 trace( "done\n" ); 4447 4448 done: 4449 if (req) WinHttpCloseHandle( req ); 4450 if (con) WinHttpCloseHandle( con ); 4451 if (ses) WinHttpCloseHandle( ses ); 4452 } 4453 4454 START_TEST (winhttp) 4455 { 4456 static const WCHAR basicW[] = {'/','b','a','s','i','c',0}; 4457 static const WCHAR quitW[] = {'/','q','u','i','t',0}; 4458 struct server_info si; 4459 HANDLE thread; 4460 DWORD ret; 4461 4462 test_OpenRequest(); 4463 test_SendRequest(); 4464 test_WinHttpTimeFromSystemTime(); 4465 test_WinHttpTimeToSystemTime(); 4466 test_WinHttpAddHeaders(); 4467 test_secure_connection(); 4468 test_request_parameter_defaults(); 4469 test_QueryOption(); 4470 test_set_default_proxy_config(); 4471 test_empty_headers_param(); 4472 test_Timeouts(); 4473 test_resolve_timeout(); 4474 test_credentials(); 4475 test_IWinHttpRequest_Invoke(); 4476 test_WinHttpDetectAutoProxyConfigUrl(); 4477 test_WinHttpGetIEProxyConfigForCurrentUser(); 4478 test_WinHttpGetProxyForUrl(); 4479 test_chunked_read(); 4480 4481 si.event = CreateEventW(NULL, 0, 0, NULL); 4482 si.port = 7532; 4483 4484 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL); 4485 ok(thread != NULL, "failed to create thread %u\n", GetLastError()); 4486 4487 ret = WaitForSingleObject(si.event, 10000); 4488 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError()); 4489 if (ret != WAIT_OBJECT_0) 4490 { 4491 CloseHandle(thread); 4492 return; 4493 } 4494 4495 test_IWinHttpRequest(si.port); 4496 test_connection_info(si.port); 4497 test_basic_request(si.port, NULL, basicW); 4498 test_no_headers(si.port); 4499 test_no_content(si.port); 4500 test_head_request(si.port); 4501 test_not_modified(si.port); 4502 test_basic_authentication(si.port); 4503 test_multi_authentication(si.port); 4504 test_large_data_authentication(si.port); 4505 test_bad_header(si.port); 4506 test_multiple_reads(si.port); 4507 test_cookies(si.port); 4508 4509 /* send the basic request again to shutdown the server thread */ 4510 test_basic_request(si.port, NULL, quitW); 4511 4512 WaitForSingleObject(thread, 3000); 4513 CloseHandle(thread); 4514 } 4515