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