Commit e24ce4c1 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

wininet: Added new cookie_set_t type and use it in get_cookie.

parent 75c02048
......@@ -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;
}
/***********************************************************************
......
......@@ -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);
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment