From bedf296a27d5689beb693637407829b0bd6d8a1c Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 22 Apr 2013 11:02:50 +0200 Subject: [PATCH] wininet: Add support for INTERNET_OPTION_PROXY_USERNAME and INTERNET_OPTION_PROXY_PASSWORD. --- dlls/wininet/http.c | 81 +++++++++++++---- dlls/wininet/internet.c | 12 +-- dlls/wininet/tests/http.c | 225 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 285 insertions(+), 33 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index dab5dc45010..aa3e46134e2 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1947,6 +1947,34 @@ static void HTTPREQ_CloseConnection(object_header_t *hdr) http_release_netconn(req, drain_content(req, FALSE)); } +static DWORD str_to_buffer(const WCHAR *str, void *buffer, DWORD *size, BOOL unicode) +{ + int len; + if (unicode) + { + len = strlenW(str); + if (*size < (len + 1) * sizeof(WCHAR)) + { + *size = (len + 1) * sizeof(WCHAR); + return ERROR_INSUFFICIENT_BUFFER; + } + strcpyW(buffer, str); + *size = len; + return ERROR_SUCCESS; + } + else + { + len = WideCharToMultiByte(CP_ACP, 0, str, -1, buffer, *size, NULL, NULL); + if (*size < len) + { + *size = len; + return ERROR_INSUFFICIENT_BUFFER; + } + *size = len - 1; + return ERROR_SUCCESS; + } +} + static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { http_request_t *req = (http_request_t*)hdr; @@ -2010,8 +2038,6 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe case INTERNET_OPTION_URL: { WCHAR url[INTERNET_MAX_URL_LENGTH]; HTTPHEADERW *host; - DWORD len; - WCHAR *pch; static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; @@ -2023,24 +2049,18 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe strcatW(url, req->path); TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url)); - - if(unicode) { - len = (strlenW(url)+1) * sizeof(WCHAR); - if(*size < len) - return ERROR_INSUFFICIENT_BUFFER; - - *size = len; - strcpyW(buffer, url); - return ERROR_SUCCESS; - }else { - len = WideCharToMultiByte(CP_ACP, 0, url, -1, buffer, *size, NULL, NULL); - if(len > *size) - return ERROR_INSUFFICIENT_BUFFER; - - *size = len; - return ERROR_SUCCESS; - } + return str_to_buffer(url, buffer, size, unicode); } + case INTERNET_OPTION_USER_AGENT: + return str_to_buffer(req->session->appInfo->agent, buffer, size, unicode); + case INTERNET_OPTION_USERNAME: + return str_to_buffer(req->session->userName, buffer, size, unicode); + case INTERNET_OPTION_PASSWORD: + return str_to_buffer(req->session->password, buffer, size, unicode); + case INTERNET_OPTION_PROXY_USERNAME: + return str_to_buffer(req->session->appInfo->proxyUsername, buffer, size, unicode); + case INTERNET_OPTION_PROXY_PASSWORD: + return str_to_buffer(req->session->appInfo->proxyPassword, buffer, size, unicode); case INTERNET_OPTION_CACHE_TIMESTAMPS: { INTERNET_CACHE_ENTRY_INFOW *info; @@ -2228,6 +2248,17 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, heap_free(req->session->password); if (!(req->session->password = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; return ERROR_SUCCESS; + + case INTERNET_OPTION_PROXY_USERNAME: + heap_free(req->session->appInfo->proxyUsername); + if (!(req->session->appInfo->proxyUsername = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; + return ERROR_SUCCESS; + + case INTERNET_OPTION_PROXY_PASSWORD: + heap_free(req->session->appInfo->proxyPassword); + if (!(req->session->appInfo->proxyPassword = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; + return ERROR_SUCCESS; + case INTERNET_OPTION_HTTP_DECODING: if(size != sizeof(BOOL)) return ERROR_INVALID_PARAMETER; @@ -5514,6 +5545,18 @@ static DWORD HTTPSESSION_SetOption(object_header_t *hdr, DWORD option, void *buf if (!(ses->password = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; return ERROR_SUCCESS; } + case INTERNET_OPTION_PROXY_USERNAME: + { + heap_free(ses->appInfo->proxyUsername); + if (!(ses->appInfo->proxyUsername = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; + return ERROR_SUCCESS; + } + case INTERNET_OPTION_PROXY_PASSWORD: + { + heap_free(ses->appInfo->proxyPassword); + if (!(ses->appInfo->proxyPassword = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; + return ERROR_SUCCESS; + } case INTERNET_OPTION_CONNECT_TIMEOUT: { if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER; diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 82332b1d4fe..dc0c89ca83e 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -788,7 +788,7 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe /* If the buffer is copied, the returned length doesn't include * the NULL terminator. */ - *size = len * sizeof(WCHAR); + *size = len; }else { if (ai->agent) *size = WideCharToMultiByte(CP_ACP, 0, ai->agent, -1, NULL, 0, NULL, NULL); @@ -2943,11 +2943,11 @@ BOOL WINAPI InternetSetOptionA(HINTERNET hInternet, DWORD dwOption, case INTERNET_OPTION_USER_AGENT: case INTERNET_OPTION_USERNAME: case INTERNET_OPTION_PASSWORD: - wlen = MultiByteToWideChar( CP_ACP, 0, lpBuffer, dwBufferLength, - NULL, 0 ); - wbuffer = heap_alloc(wlen*sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, lpBuffer, dwBufferLength, - wbuffer, wlen ); + case INTERNET_OPTION_PROXY_USERNAME: + case INTERNET_OPTION_PROXY_PASSWORD: + wlen = MultiByteToWideChar( CP_ACP, 0, lpBuffer, -1, NULL, 0 ); + if (!(wbuffer = heap_alloc( wlen * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; + MultiByteToWideChar( CP_ACP, 0, lpBuffer, -1, wbuffer, wlen ); break; case INTERNET_OPTION_PER_CONNECTION_OPTION: { unsigned int i; diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 9474d7035f6..fa019175307 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -2159,16 +2159,22 @@ static void test_proxy_direct(int port) { HINTERNET hi, hc, hr; DWORD r, sz; - char buffer[0x40]; + char buffer[0x40], *url; + WCHAR bufferW[0x40]; static CHAR username[] = "mike", - password[] = "1101"; + password[] = "1101", + useragent[] = "winetest", + url_fmt[] = "http://test.winehq.org:%u/test2"; + static WCHAR usernameW[] = {'m','i','k','e',0}, + passwordW[] = {'1','1','0','1',0}, + useragentW[] = {'w','i','n','e','t','e','s','t',0}; sprintf(buffer, "localhost:%d\n", port); hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0); ok(hi != NULL, "open failed\n"); /* try connect without authorization */ - hc = InternetConnect(hi, "test.winehq.org/", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + hc = InternetConnect(hi, "test.winehq.org", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); ok(hc != NULL, "connect failed\n"); hr = HttpOpenRequest(hc, NULL, "/test2", NULL, NULL, NULL, 0, 0); @@ -2180,23 +2186,226 @@ static void test_proxy_direct(int port) test_status_code(hr, 407); /* set the user + password then try again */ - todo_wine { + r = InternetSetOption(hi, INTERNET_OPTION_PROXY_USERNAME, username, 4); + ok(!r, "unexpected success\n"); + + r = InternetSetOption(hc, INTERNET_OPTION_PROXY_USERNAME, username, 4); + ok(r, "failed to set user\n"); + r = InternetSetOption(hr, INTERNET_OPTION_PROXY_USERNAME, username, 4); ok(r, "failed to set user\n"); + buffer[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOption(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == strlen(username) + 1, "got %u\n", sz); + + bufferW[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_USERNAME, bufferW, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == (lstrlenW(usernameW) + 1) * sizeof(WCHAR), "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz); + ok(r, "failed to get username\n"); + ok(!strcmp(buffer, username), "got %s\n", buffer); + ok(sz == strlen(username), "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(bufferW); + r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_USERNAME, bufferW, &sz); + ok(r, "failed to get username\n"); + ok(!lstrcmpW(bufferW, usernameW), "wrong username\n"); + ok(sz == lstrlenW(usernameW), "got %u\n", sz); + + r = InternetSetOption(hr, INTERNET_OPTION_PROXY_USERNAME, username, 1); + ok(r, "failed to set user\n"); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz); + ok(r, "failed to get username\n"); + ok(!strcmp(buffer, username), "got %s\n", buffer); + ok(sz == strlen(username), "got %u\n", sz); + + r = InternetSetOption(hi, INTERNET_OPTION_USER_AGENT, useragent, 1); + ok(r, "failed to set useragent\n"); + + buffer[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOption(hi, INTERNET_OPTION_USER_AGENT, buffer, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == strlen(useragent) + 1, "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hi, INTERNET_OPTION_USER_AGENT, buffer, &sz); + ok(r, "failed to get user agent\n"); + ok(!strcmp(buffer, useragent), "got %s\n", buffer); + ok(sz == strlen(useragent), "got %u\n", sz); + + bufferW[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOptionW(hi, INTERNET_OPTION_USER_AGENT, bufferW, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == (lstrlenW(useragentW) + 1) * sizeof(WCHAR), "got %u\n", sz); + + bufferW[0] = 0; + sz = sizeof(bufferW); + r = InternetQueryOptionW(hi, INTERNET_OPTION_USER_AGENT, bufferW, &sz); + ok(r, "failed to get user agent\n"); + ok(!lstrcmpW(bufferW, useragentW), "wrong user agent\n"); + ok(sz == lstrlenW(useragentW), "got %u\n", sz); + + r = InternetSetOption(hr, INTERNET_OPTION_USERNAME, username, 1); + ok(r, "failed to set user\n"); + + buffer[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOption(hr, INTERNET_OPTION_USERNAME, buffer, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == strlen(username) + 1, "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hr, INTERNET_OPTION_USERNAME, buffer, &sz); + ok(r, "failed to get user\n"); + ok(!strcmp(buffer, username), "got %s\n", buffer); + ok(sz == strlen(username), "got %u\n", sz); + + bufferW[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOptionW(hr, INTERNET_OPTION_USERNAME, bufferW, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == (lstrlenW(usernameW) + 1) * sizeof(WCHAR), "got %u\n", sz); + + bufferW[0] = 0; + sz = sizeof(bufferW); + r = InternetQueryOptionW(hr, INTERNET_OPTION_USERNAME, bufferW, &sz); + ok(r, "failed to get user\n"); + ok(!lstrcmpW(bufferW, usernameW), "wrong user\n"); + ok(sz == lstrlenW(usernameW), "got %u\n", sz); + + r = InternetSetOption(hr, INTERNET_OPTION_PASSWORD, password, 1); + ok(r, "failed to set password\n"); + + buffer[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOption(hr, INTERNET_OPTION_PASSWORD, buffer, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == strlen(password) + 1, "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hr, INTERNET_OPTION_PASSWORD, buffer, &sz); + ok(r, "failed to get password\n"); + ok(!strcmp(buffer, password), "got %s\n", buffer); + ok(sz == strlen(password), "got %u\n", sz); + + bufferW[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOptionW(hr, INTERNET_OPTION_PASSWORD, bufferW, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == (lstrlenW(passwordW) + 1) * sizeof(WCHAR), "got %u\n", sz); + + bufferW[0] = 0; + sz = sizeof(bufferW); + r = InternetQueryOptionW(hr, INTERNET_OPTION_PASSWORD, bufferW, &sz); + ok(r, "failed to get password\n"); + ok(!lstrcmpW(bufferW, passwordW), "wrong password\n"); + ok(sz == lstrlenW(passwordW), "got %u\n", sz); + + url = HeapAlloc(GetProcessHeap(), 0, strlen(url_fmt) + 11); + sprintf(url, url_fmt, port); + buffer[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOption(hr, INTERNET_OPTION_URL, buffer, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == strlen(url) + 1, "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hr, INTERNET_OPTION_URL, buffer, &sz); + ok(r, "failed to get url\n"); + ok(!strcmp(buffer, url), "got %s\n", buffer); + ok(sz == strlen(url), "got %u\n", sz); + + bufferW[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOptionW(hr, INTERNET_OPTION_URL, bufferW, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == (strlen(url) + 1) * sizeof(WCHAR), "got %u\n", sz); + + bufferW[0] = 0; + sz = sizeof(bufferW); + r = InternetQueryOptionW(hr, INTERNET_OPTION_URL, bufferW, &sz); + ok(r, "failed to get url\n"); + ok(!strcmp_wa(bufferW, url), "wrong url\n"); + ok(sz == strlen(url), "got %u\n", sz); + HeapFree(GetProcessHeap(), 0, url); + r = InternetSetOption(hr, INTERNET_OPTION_PROXY_PASSWORD, password, 4); ok(r, "failed to set password\n"); - } + + buffer[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOption(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == strlen(password) + 1, "got %u\n", sz); + + buffer[0] = 0; + sz = sizeof(buffer); + r = InternetQueryOption(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz); + ok(r, "failed to get password\n"); + ok(!strcmp(buffer, password), "got %s\n", buffer); + ok(sz == strlen(password), "got %u\n", sz); + + bufferW[0] = 0; + sz = 0; + SetLastError(0xdeadbeef); + r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_PASSWORD, bufferW, &sz); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!r, "unexpected success\n"); + ok(sz == (lstrlenW(passwordW) + 1) * sizeof(WCHAR), "got %u\n", sz); + + bufferW[0] = 0; + sz = sizeof(bufferW); + r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_PASSWORD, bufferW, &sz); + ok(r, "failed to get password\n"); + ok(!lstrcmpW(bufferW, passwordW), "wrong password\n"); + ok(sz == lstrlenW(passwordW), "got %u\n", sz); r = HttpSendRequest(hr, NULL, 0, NULL, 0); ok(r, "HttpSendRequest failed\n"); sz = sizeof buffer; r = HttpQueryInfo(hr, HTTP_QUERY_STATUS_CODE, buffer, &sz, NULL); ok(r, "HttpQueryInfo failed\n"); - todo_wine { ok(!strcmp(buffer, "200"), "proxy code wrong\n"); - } - InternetCloseHandle(hr); InternetCloseHandle(hc); -- 2.11.4.GIT