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