Jacek Caban : wininet: Added new cookie_set_t type and use it in get_cookie.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jul 15 15:52:44 CDT 2014
Module: wine
Branch: master
Commit: e24ce4c128d91f7eb0bf727246ec36eb2fbc4092
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e24ce4c128d91f7eb0bf727246ec36eb2fbc4092
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Jul 15 17:13:03 2014 +0200
wininet: Added new cookie_set_t type and use it in get_cookie.
---
dlls/wininet/cookie.c | 158 +++++++++++++++++++++++++++++++++---------------
dlls/wininet/http.c | 17 ++----
dlls/wininet/internet.h | 2 +-
3 files changed, 114 insertions(+), 63 deletions(-)
diff --git a/dlls/wininet/cookie.c b/dlls/wininet/cookie.c
index 2c8dd84..d98a127 100644
--- a/dlls/wininet/cookie.c
+++ b/dlls/wininet/cookie.c
@@ -555,15 +555,23 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName
return TRUE;
}
-DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD *size, DWORD flags)
+typedef struct {
+ cookie_t **cookies;
+ unsigned cnt;
+ unsigned size;
+
+ unsigned string_len;
+} cookie_set_t;
+
+static DWORD get_cookie(const WCHAR *host, const WCHAR *path, DWORD flags, cookie_set_t *res)
{
static const WCHAR empty_path[] = { '/',0 };
- unsigned cnt = 0, len, name_len, domain_count = 0, cookie_count = 0;
WCHAR *ptr, subpath[INTERNET_MAX_PATH_LENGTH];
const WCHAR *p;
cookie_domain_t *domain;
cookie_container_t *container;
+ unsigned len;
FILETIME tm;
GetSystemTimeAsFileTime(&tm);
@@ -600,8 +608,6 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
return ERROR_NO_MORE_ITEMS;
}
- ptr = cookie_data;
-
for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
TRACE("Trying %s domain...\n", debugstr_w(domain->domain));
@@ -613,7 +619,6 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
if(!cookie_match_path(container, path))
continue;
- domain_count++;
TRACE("found domain %p\n", domain->domain);
LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
@@ -630,62 +635,93 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
continue;
- if (cookie_count)
- cnt += 2; /* '; ' */
- cnt += name_len = strlenW(cookie_iter->name);
- if ((len = strlenW(cookie_iter->data))) {
- cnt += 1; /* = */
- cnt += len;
+ if(res->size) {
+ cookie_t **new_cookies = heap_realloc(res->cookies, res->size*2*sizeof(*res->cookies));
+ if(!new_cookies)
+ continue;
+ res->cookies = new_cookies;
+ res->size *= 2;
+ }else {
+ res->cookies = heap_alloc(4*sizeof(*res->cookies));
+ if(!res->cookies)
+ continue;
+ res->size = 4;
}
- if(ptr) {
- if(*size > cnt) {
- if(cookie_count) {
- *ptr++ = ';';
- *ptr++ = ' ';
- }
+ if(res->cnt)
+ res->string_len += 2; /* '; ' */
+ res->cookies[res->cnt++] = cookie_iter;
- memcpy(ptr, cookie_iter->name, name_len*sizeof(WCHAR));
- ptr += name_len;
-
- if(len) {
- *ptr++ = '=';
- memcpy(ptr, cookie_iter->data, len*sizeof(WCHAR));
- ptr += len;
- }
-
- assert(cookie_data+cnt == ptr);
- TRACE("Cookie: %s\n", debugstr_wn(cookie_data, cnt));
- }else {
- /* Stop writing data, just compute the size */
- ptr = NULL;
- }
- }
-
- cookie_count++;
+ res->string_len += strlenW(cookie_iter->name);
+ if(*cookie_iter->data)
+ res->string_len += 1 /* = */ + strlenW(cookie_iter->data);
}
}
}
LeaveCriticalSection(&cookie_cs);
+ return ERROR_SUCCESS;
+}
- if(ptr)
- *ptr = 0;
+static void cookie_set_to_string(const cookie_set_t *cookie_set, WCHAR *str)
+{
+ WCHAR *ptr = str;
+ unsigned i, len;
- if (!cnt) {
- TRACE("no cookies found for %s\n", debugstr_w(host));
- return ERROR_NO_MORE_ITEMS;
+ for(i=0; i<cookie_set->cnt; i++) {
+ if(i) {
+ *ptr++ = ';';
+ *ptr++ = ' ';
+ }
+
+ len = strlenW(cookie_set->cookies[i]->name);
+ memcpy(ptr, cookie_set->cookies[i]->name, len*sizeof(WCHAR));
+ ptr += len;
+
+ if(*cookie_set->cookies[i]->data) {
+ *ptr++ = '=';
+ len = strlenW(cookie_set->cookies[i]->data);
+ memcpy(ptr, cookie_set->cookies[i]->data, len*sizeof(WCHAR));
+ ptr += len;
+ }
}
- if(!cookie_data || !ptr) {
- *size = (cnt + 1) * sizeof(WCHAR);
- TRACE("returning %u\n", *size);
- return cookie_data ? ERROR_INSUFFICIENT_BUFFER : ERROR_SUCCESS;
+ assert(ptr-str == cookie_set->string_len);
+ TRACE("%s\n", debugstr_wn(str, ptr-str));
+}
+
+DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
+{
+ cookie_set_t cookie_set = {0};
+ WCHAR *header, *ptr;
+ DWORD res;
+
+ static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '};
+
+ res = get_cookie(host, path, INTERNET_COOKIE_HTTPONLY, &cookie_set);
+ if(res != ERROR_SUCCESS)
+ return res;
+ if(!cookie_set.cnt) {
+ *ret = NULL;
+ return ERROR_SUCCESS;
}
- *size = cnt + 1;
+ ptr = header = heap_alloc(sizeof(cookieW) + (cookie_set.string_len + 3 /* crlf0 */) * sizeof(WCHAR));
+ if(!header)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ memcpy(ptr, cookieW, sizeof(cookieW));
+ ptr += sizeof(cookieW)/sizeof(*cookieW);
+
+ cookie_set_to_string(&cookie_set, ptr);
+ heap_free(cookie_set.cookies);
+ ptr += cookie_set.string_len;
- TRACE("Returning %u (from %u domains): %s\n", cnt, domain_count, debugstr_w(cookie_data));
+ *ptr++ = '\r';
+ *ptr++ = '\n';
+ *ptr++ = 0;
+
+ *ret = header;
return ERROR_SUCCESS;
}
@@ -706,6 +742,7 @@ BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
{
WCHAR host[INTERNET_MAX_HOST_NAME_LENGTH], path[INTERNET_MAX_PATH_LENGTH];
+ cookie_set_t cookie_set = {0};
DWORD res;
BOOL ret;
@@ -727,10 +764,33 @@ BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
return FALSE;
}
- res = get_cookie(host, path, lpCookieData, lpdwSize, flags);
- if(res != ERROR_SUCCESS)
+ res = get_cookie(host, path, flags, &cookie_set);
+ if(res != ERROR_SUCCESS) {
SetLastError(res);
- return res == ERROR_SUCCESS;
+ return FALSE;
+ }
+
+ if(!cookie_set.cnt) {
+ TRACE("no cookies found for %s\n", debugstr_w(host));
+ SetLastError(ERROR_NO_MORE_ITEMS);
+ return FALSE;
+ }
+
+ if(!lpCookieData || cookie_set.string_len+1 > *lpdwSize) {
+ *lpdwSize = (cookie_set.string_len + 1) * sizeof(WCHAR);
+ TRACE("returning %u\n", *lpdwSize);
+ if(lpCookieData) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ ret = FALSE;
+ }
+ }else {
+ *lpdwSize = cookie_set.string_len + 1;
+ cookie_set_to_string(&cookie_set, lpCookieData);
+ lpCookieData[cookie_set.string_len] = 0;
+ }
+
+ heap_free(cookie_set.cookies);
+ return ret;
}
/***********************************************************************
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 8ff42a2..2486fbf 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -4176,24 +4176,15 @@ static LPWSTR HTTP_build_req( LPCWSTR *list, int len )
static void HTTP_InsertCookies(http_request_t *request)
{
- DWORD cookie_size, size, cnt = 0;
WCHAR *cookies;
+ DWORD res;
- static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' ',0};
-
- if(get_cookie(request->server->name, request->path, NULL, &cookie_size, INTERNET_COOKIE_HTTPONLY) != ERROR_SUCCESS)
- return;
-
- size = sizeof(cookieW) + cookie_size * sizeof(WCHAR) + sizeof(szCrLf);
- if(!(cookies = heap_alloc(size)))
+ res = get_cookie_header(request->server->name, request->path, &cookies);
+ if(res != ERROR_SUCCESS || !cookies)
return;
- cnt += sprintfW(cookies, cookieW);
- get_cookie(request->server->name, request->path, cookies+cnt, &cookie_size, INTERNET_COOKIE_HTTPONLY);
- strcatW(cookies, szCrLf);
-
+ get_cookie_header(request->server->name, request->path, &cookies);
HTTP_HttpAddRequestHeadersW(request, cookies, strlenW(cookies), HTTP_ADDREQ_FLAG_REPLACE);
-
heap_free(cookies);
}
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 2647f98..54f688d 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -420,7 +420,7 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
struct sockaddr *psa, socklen_t *sa_len) DECLSPEC_HIDDEN;
-DWORD get_cookie(const WCHAR*,const WCHAR*,WCHAR*,DWORD*,DWORD) DECLSPEC_HIDDEN;
+DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) DECLSPEC_HIDDEN;
DWORD set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN;
void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list