mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
[WININET] Sync with Wine Staging 1.9.11. CORE-11368
svn path=/trunk/; revision=71751
This commit is contained in:
parent
91e48f534f
commit
7702f2f814
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include "internet.h"
|
#include "internet.h"
|
||||||
|
|
||||||
|
#include <lmcons.h>
|
||||||
|
|
||||||
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
|
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
|
||||||
|
|
||||||
/* FIXME
|
/* FIXME
|
||||||
|
@ -46,7 +48,8 @@ typedef struct _cookie_t {
|
||||||
typedef struct _cookie_container_t {
|
typedef struct _cookie_container_t {
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
|
||||||
WCHAR *path;
|
WCHAR *cookie_url;
|
||||||
|
substr_t path;
|
||||||
struct _cookie_domain_t *domain;
|
struct _cookie_domain_t *domain;
|
||||||
|
|
||||||
struct list cookie_list;
|
struct list cookie_list;
|
||||||
|
@ -75,19 +78,20 @@ static CRITICAL_SECTION_DEBUG cookie_cs_debug =
|
||||||
static CRITICAL_SECTION cookie_cs = { &cookie_cs_debug, -1, 0, 0, 0, 0 };
|
static CRITICAL_SECTION cookie_cs = { &cookie_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
static struct list domain_list = LIST_INIT(domain_list);
|
static struct list domain_list = LIST_INIT(domain_list);
|
||||||
|
|
||||||
static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
|
static cookie_domain_t *get_cookie_domain(substr_t domain, BOOL create)
|
||||||
{
|
{
|
||||||
const WCHAR *ptr = domain + strlenW(domain), *ptr_end, *subdomain_ptr;
|
const WCHAR *ptr = domain.str + domain.len, *ptr_end, *subdomain_ptr;
|
||||||
cookie_domain_t *iter, *current_domain, *prev_domain = NULL;
|
cookie_domain_t *iter, *current_domain, *prev_domain = NULL;
|
||||||
struct list *current_list = &domain_list;
|
struct list *current_list = &domain_list;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
for(ptr_end = ptr--; ptr > domain && *ptr != '.'; ptr--);
|
for(ptr_end = ptr--; ptr > domain.str && *ptr != '.'; ptr--);
|
||||||
subdomain_ptr = *ptr == '.' ? ptr+1 : ptr;
|
subdomain_ptr = *ptr == '.' ? ptr+1 : ptr;
|
||||||
|
|
||||||
current_domain = NULL;
|
current_domain = NULL;
|
||||||
LIST_FOR_EACH_ENTRY(iter, current_list, cookie_domain_t, entry) {
|
LIST_FOR_EACH_ENTRY(iter, current_list, cookie_domain_t, entry) {
|
||||||
if(ptr_end-subdomain_ptr == iter->subdomain_len && !memcmp(subdomain_ptr, iter->domain, iter->subdomain_len)) {
|
if(ptr_end-subdomain_ptr == iter->subdomain_len
|
||||||
|
&& !memcmp(subdomain_ptr, iter->domain, iter->subdomain_len*sizeof(WCHAR))) {
|
||||||
current_domain = iter;
|
current_domain = iter;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +105,7 @@ static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
|
||||||
if(!current_domain)
|
if(!current_domain)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
current_domain->domain = heap_strdupW(subdomain_ptr);
|
current_domain->domain = heap_strndupW(subdomain_ptr, domain.str + domain.len - subdomain_ptr);
|
||||||
if(!current_domain->domain) {
|
if(!current_domain->domain) {
|
||||||
heap_free(current_domain);
|
heap_free(current_domain);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -116,7 +120,7 @@ static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
|
||||||
list_add_tail(current_list, ¤t_domain->entry);
|
list_add_tail(current_list, ¤t_domain->entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ptr == domain)
|
if(ptr == domain.str)
|
||||||
return current_domain;
|
return current_domain;
|
||||||
|
|
||||||
prev_domain = current_domain;
|
prev_domain = current_domain;
|
||||||
|
@ -124,24 +128,57 @@ static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR *path, BOOL create)
|
static WCHAR *create_cookie_url(substr_t domain, substr_t path, substr_t *ret_path)
|
||||||
|
{
|
||||||
|
WCHAR user[UNLEN], *p, *url;
|
||||||
|
DWORD len, user_len, i;
|
||||||
|
|
||||||
|
static const WCHAR cookie_prefix[] = {'C','o','o','k','i','e',':'};
|
||||||
|
|
||||||
|
user_len = sizeof(user)/sizeof(WCHAR);
|
||||||
|
if(!GetUserNameW(user, &user_len))
|
||||||
|
return FALSE;
|
||||||
|
user_len--;
|
||||||
|
|
||||||
|
len = sizeof(cookie_prefix)/sizeof(WCHAR) + user_len + 1 /* @ */ + domain.len + path.len;
|
||||||
|
url = heap_alloc((len+1) * sizeof(WCHAR));
|
||||||
|
if(!url)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(url, cookie_prefix, sizeof(cookie_prefix));
|
||||||
|
p = url + sizeof(cookie_prefix)/sizeof(WCHAR);
|
||||||
|
|
||||||
|
memcpy(p, user, user_len*sizeof(WCHAR));
|
||||||
|
p += user_len;
|
||||||
|
|
||||||
|
*p++ = '@';
|
||||||
|
|
||||||
|
memcpy(p, domain.str, domain.len*sizeof(WCHAR));
|
||||||
|
p += domain.len;
|
||||||
|
|
||||||
|
for(i=0; i < path.len; i++)
|
||||||
|
p[i] = tolowerW(path.str[i]);
|
||||||
|
p[path.len] = 0;
|
||||||
|
|
||||||
|
ret_path->str = p;
|
||||||
|
ret_path->len = path.len;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cookie_container_t *get_cookie_container(substr_t domain, substr_t path, BOOL create)
|
||||||
{
|
{
|
||||||
cookie_domain_t *cookie_domain;
|
cookie_domain_t *cookie_domain;
|
||||||
cookie_container_t *cookie_container, *iter;
|
cookie_container_t *cookie_container, *iter;
|
||||||
size_t path_len, len;
|
|
||||||
|
|
||||||
cookie_domain = get_cookie_domain(domain, create);
|
cookie_domain = get_cookie_domain(domain, create);
|
||||||
if(!cookie_domain)
|
if(!cookie_domain)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
path_len = strlenW(path);
|
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(cookie_container, &cookie_domain->path_list, cookie_container_t, entry) {
|
LIST_FOR_EACH_ENTRY(cookie_container, &cookie_domain->path_list, cookie_container_t, entry) {
|
||||||
len = strlenW(cookie_container->path);
|
if(cookie_container->path.len < path.len)
|
||||||
if(len < path_len)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!strcmpiW(cookie_container->path, path))
|
if(path.len == cookie_container->path.len && !strncmpiW(cookie_container->path.str, path.str, path.len))
|
||||||
return cookie_container;
|
return cookie_container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +189,8 @@ static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR
|
||||||
if(!cookie_container)
|
if(!cookie_container)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cookie_container->path = heap_strdupW(path);
|
cookie_container->cookie_url = create_cookie_url(substrz(cookie_domain->domain), path, &cookie_container->path);
|
||||||
if(!cookie_container->path) {
|
if(!cookie_container->cookie_url) {
|
||||||
heap_free(cookie_container);
|
heap_free(cookie_container);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -161,9 +198,8 @@ static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR
|
||||||
cookie_container->domain = cookie_domain;
|
cookie_container->domain = cookie_domain;
|
||||||
list_init(&cookie_container->cookie_list);
|
list_init(&cookie_container->cookie_list);
|
||||||
|
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(iter, &cookie_domain->path_list, cookie_container_t, entry) {
|
LIST_FOR_EACH_ENTRY(iter, &cookie_domain->path_list, cookie_container_t, entry) {
|
||||||
if(strlenW(iter->path) <= path_len) {
|
if(iter->path.len <= path.len) {
|
||||||
list_add_before(&iter->entry, &cookie_container->entry);
|
list_add_before(&iter->entry, &cookie_container->entry);
|
||||||
return cookie_container;
|
return cookie_container;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +218,7 @@ static void delete_cookie(cookie_t *cookie)
|
||||||
heap_free(cookie);
|
heap_free(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME expiry, FILETIME create_time, DWORD flags)
|
static cookie_t *alloc_cookie(substr_t name, substr_t data, FILETIME expiry, FILETIME create_time, DWORD flags)
|
||||||
{
|
{
|
||||||
cookie_t *new_cookie;
|
cookie_t *new_cookie;
|
||||||
|
|
||||||
|
@ -195,9 +231,9 @@ static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME exp
|
||||||
new_cookie->flags = flags;
|
new_cookie->flags = flags;
|
||||||
list_init(&new_cookie->entry);
|
list_init(&new_cookie->entry);
|
||||||
|
|
||||||
new_cookie->name = heap_strdupW(name);
|
new_cookie->name = heap_strndupW(name.str, name.len);
|
||||||
new_cookie->data = heap_strdupW(data);
|
new_cookie->data = heap_strndupW(data.str, data.len);
|
||||||
if((name && !new_cookie->name) || (data && !new_cookie->data)) {
|
if(!new_cookie->name || !new_cookie->data) {
|
||||||
delete_cookie(new_cookie);
|
delete_cookie(new_cookie);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -205,12 +241,12 @@ static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME exp
|
||||||
return new_cookie;
|
return new_cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cookie_t *find_cookie(cookie_container_t *container, const WCHAR *name)
|
static cookie_t *find_cookie(cookie_container_t *container, substr_t name)
|
||||||
{
|
{
|
||||||
cookie_t *iter;
|
cookie_t *iter;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(iter, &container->cookie_list, cookie_t, entry) {
|
LIST_FOR_EACH_ENTRY(iter, &container->cookie_list, cookie_t, entry) {
|
||||||
if(!strcmpiW(iter->name, name))
|
if(strlenW(iter->name) == name.len && !strncmpiW(iter->name, name.str, name.len))
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +255,8 @@ static cookie_t *find_cookie(cookie_container_t *container, const WCHAR *name)
|
||||||
|
|
||||||
static void add_cookie(cookie_container_t *container, cookie_t *new_cookie)
|
static void add_cookie(cookie_container_t *container, cookie_t *new_cookie)
|
||||||
{
|
{
|
||||||
TRACE("Adding %s=%s to %s %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
|
TRACE("Adding %s=%s to %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
|
||||||
debugstr_w(container->domain->domain), debugstr_w(container->path));
|
debugstr_w(container->cookie_url));
|
||||||
|
|
||||||
list_add_tail(&container->cookie_list, &new_cookie->entry);
|
list_add_tail(&container->cookie_list, &new_cookie->entry);
|
||||||
new_cookie->container = container;
|
new_cookie->container = container;
|
||||||
|
@ -230,86 +266,41 @@ static void replace_cookie(cookie_container_t *container, cookie_t *new_cookie)
|
||||||
{
|
{
|
||||||
cookie_t *old_cookie;
|
cookie_t *old_cookie;
|
||||||
|
|
||||||
old_cookie = find_cookie(container, new_cookie->name);
|
old_cookie = find_cookie(container, substrz(new_cookie->name));
|
||||||
if(old_cookie)
|
if(old_cookie)
|
||||||
delete_cookie(old_cookie);
|
delete_cookie(old_cookie);
|
||||||
|
|
||||||
add_cookie(container, new_cookie);
|
add_cookie(container, new_cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL cookie_match_path(cookie_container_t *container, const WCHAR *path)
|
static BOOL cookie_match_path(cookie_container_t *container, substr_t path)
|
||||||
{
|
{
|
||||||
return !strncmpiW(container->path, path, strlenW(container->path));
|
return path.len >= container->path.len && !strncmpiW(container->path.str, path.str, container->path.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL create_cookie_url(LPCWSTR domain, LPCWSTR path, WCHAR *buf, DWORD buf_len)
|
static BOOL load_persistent_cookie(substr_t domain, substr_t path)
|
||||||
{
|
|
||||||
static const WCHAR cookie_prefix[] = {'C','o','o','k','i','e',':'};
|
|
||||||
|
|
||||||
WCHAR *p;
|
|
||||||
DWORD len;
|
|
||||||
|
|
||||||
if(buf_len < sizeof(cookie_prefix)/sizeof(WCHAR))
|
|
||||||
return FALSE;
|
|
||||||
memcpy(buf, cookie_prefix, sizeof(cookie_prefix));
|
|
||||||
buf += sizeof(cookie_prefix)/sizeof(WCHAR);
|
|
||||||
buf_len -= sizeof(cookie_prefix)/sizeof(WCHAR);
|
|
||||||
p = buf;
|
|
||||||
|
|
||||||
len = buf_len;
|
|
||||||
if(!GetUserNameW(buf, &len))
|
|
||||||
return FALSE;
|
|
||||||
buf += len-1;
|
|
||||||
buf_len -= len-1;
|
|
||||||
|
|
||||||
if(!buf_len)
|
|
||||||
return FALSE;
|
|
||||||
*(buf++) = '@';
|
|
||||||
buf_len--;
|
|
||||||
|
|
||||||
len = strlenW(domain);
|
|
||||||
if(len >= buf_len)
|
|
||||||
return FALSE;
|
|
||||||
memcpy(buf, domain, len*sizeof(WCHAR));
|
|
||||||
buf += len;
|
|
||||||
buf_len -= len;
|
|
||||||
|
|
||||||
len = strlenW(path);
|
|
||||||
if(len >= buf_len)
|
|
||||||
return FALSE;
|
|
||||||
memcpy(buf, path, len*sizeof(WCHAR));
|
|
||||||
buf += len;
|
|
||||||
|
|
||||||
*buf = 0;
|
|
||||||
|
|
||||||
for(; *p; p++)
|
|
||||||
*p = tolowerW(*p);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
|
|
||||||
{
|
{
|
||||||
INTERNET_CACHE_ENTRY_INFOW *info;
|
INTERNET_CACHE_ENTRY_INFOW *info;
|
||||||
cookie_container_t *cookie_container;
|
cookie_container_t *cookie_container;
|
||||||
cookie_t *new_cookie;
|
cookie_t *new_cookie;
|
||||||
WCHAR cookie_url[MAX_PATH];
|
|
||||||
HANDLE cookie;
|
HANDLE cookie;
|
||||||
char *str = NULL, *pbeg, *pend;
|
char *str = NULL, *pbeg, *pend;
|
||||||
DWORD size, flags;
|
DWORD size, flags;
|
||||||
WCHAR *name, *data;
|
WCHAR *name, *data;
|
||||||
FILETIME expiry, create, time;
|
FILETIME expiry, create, time;
|
||||||
|
|
||||||
if (!create_cookie_url(domain, path, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
|
cookie_container = get_cookie_container(domain, path, TRUE);
|
||||||
|
if(!cookie_container)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
RetrieveUrlCacheEntryStreamW(cookie_url, NULL, &size, FALSE, 0);
|
RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, NULL, &size, FALSE, 0);
|
||||||
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
info = heap_alloc(size);
|
info = heap_alloc(size);
|
||||||
if(!info)
|
if(!info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
cookie = RetrieveUrlCacheEntryStreamW(cookie_url, info, &size, FALSE, 0);
|
cookie = RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, info, &size, FALSE, 0);
|
||||||
size = info->dwSizeLow;
|
size = info->dwSizeLow;
|
||||||
heap_free(info);
|
heap_free(info);
|
||||||
if(!cookie)
|
if(!cookie)
|
||||||
|
@ -323,12 +314,6 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
|
||||||
str[size] = 0;
|
str[size] = 0;
|
||||||
UnlockUrlCacheEntryStream(cookie, 0);
|
UnlockUrlCacheEntryStream(cookie, 0);
|
||||||
|
|
||||||
cookie_container = get_cookie_container(domain, path, TRUE);
|
|
||||||
if(!cookie_container) {
|
|
||||||
heap_free(str);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetSystemTimeAsFileTime(&time);
|
GetSystemTimeAsFileTime(&time);
|
||||||
for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
|
for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
|
||||||
pend = strchr(pbeg, '\n');
|
pend = strchr(pbeg, '\n');
|
||||||
|
@ -362,7 +347,7 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(CompareFileTime(&time, &expiry) <= 0) {
|
if(CompareFileTime(&time, &expiry) <= 0) {
|
||||||
new_cookie = alloc_cookie(NULL, NULL, expiry, create, flags);
|
new_cookie = alloc_cookie(substr(NULL, 0), substr(NULL, 0), expiry, create, flags);
|
||||||
if(!new_cookie)
|
if(!new_cookie)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -386,16 +371,14 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
||||||
{
|
{
|
||||||
static const WCHAR txtW[] = {'t','x','t',0};
|
static const WCHAR txtW[] = {'t','x','t',0};
|
||||||
|
|
||||||
WCHAR cookie_url[MAX_PATH], cookie_file[MAX_PATH];
|
WCHAR cookie_file[MAX_PATH];
|
||||||
HANDLE cookie_handle;
|
HANDLE cookie_handle;
|
||||||
cookie_t *cookie_container = NULL, *cookie_iter;
|
cookie_t *cookie_container = NULL, *cookie_iter;
|
||||||
BOOL do_save = FALSE;
|
BOOL do_save = FALSE;
|
||||||
char buf[64], *dyn_buf;
|
char buf[64], *dyn_buf;
|
||||||
FILETIME time;
|
FILETIME time;
|
||||||
DWORD bytes_written;
|
DWORD bytes_written;
|
||||||
|
size_t len;
|
||||||
if (!create_cookie_url(container->domain->domain, container->path, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* check if there's anything to save */
|
/* check if there's anything to save */
|
||||||
GetSystemTimeAsFileTime(&time);
|
GetSystemTimeAsFileTime(&time);
|
||||||
|
@ -412,13 +395,15 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!do_save) {
|
if(!do_save) {
|
||||||
DeleteUrlCacheEntryW(cookie_url);
|
DeleteUrlCacheEntryW(container->cookie_url);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CreateUrlCacheEntryW(cookie_url, 0, txtW, cookie_file, 0))
|
if(!CreateUrlCacheEntryW(container->cookie_url, 0, txtW, cookie_file, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
cookie_handle = CreateFileW(cookie_file, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
cookie_handle = CreateFileW(cookie_file, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
if(cookie_handle == INVALID_HANDLE_VALUE) {
|
if(cookie_handle == INVALID_HANDLE_VALUE) {
|
||||||
DeleteFileW(cookie_file);
|
DeleteFileW(cookie_file);
|
||||||
|
@ -462,7 +447,12 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
||||||
}
|
}
|
||||||
heap_free(dyn_buf);
|
heap_free(dyn_buf);
|
||||||
|
|
||||||
dyn_buf = heap_strdupWtoA(container->path);
|
len = WideCharToMultiByte(CP_ACP, 0, container->path.str, container->path.len, NULL, 0, NULL, NULL);
|
||||||
|
dyn_buf = heap_alloc(len+1);
|
||||||
|
if(dyn_buf) {
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, container->path.str, container->path.len, dyn_buf, len, NULL, NULL);
|
||||||
|
dyn_buf[len] = 0;
|
||||||
|
}
|
||||||
if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
|
if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
|
||||||
heap_free(dyn_buf);
|
heap_free(dyn_buf);
|
||||||
do_save = FALSE;
|
do_save = FALSE;
|
||||||
|
@ -487,47 +477,26 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&time, 0, sizeof(time));
|
memset(&time, 0, sizeof(time));
|
||||||
return CommitUrlCacheEntryW(cookie_url, cookie_file, time, time, 0, NULL, 0, txtW, 0);
|
return CommitUrlCacheEntryW(container->cookie_url, cookie_file, time, time, 0, NULL, 0, txtW, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostNameLen, LPWSTR path, int pathLen)
|
static BOOL cookie_parse_url(const WCHAR *url, substr_t *host, substr_t *path)
|
||||||
{
|
{
|
||||||
URL_COMPONENTSW UrlComponents;
|
URL_COMPONENTSW comp = { sizeof(comp) };
|
||||||
|
static const WCHAR rootW[] = {'/',0};
|
||||||
|
|
||||||
UrlComponents.lpszExtraInfo = NULL;
|
comp.dwHostNameLength = 1;
|
||||||
UrlComponents.lpszPassword = NULL;
|
comp.dwUrlPathLength = 1;
|
||||||
UrlComponents.lpszScheme = NULL;
|
|
||||||
UrlComponents.lpszUrlPath = path;
|
|
||||||
UrlComponents.lpszUserName = NULL;
|
|
||||||
UrlComponents.lpszHostName = hostName;
|
|
||||||
UrlComponents.dwExtraInfoLength = 0;
|
|
||||||
UrlComponents.dwPasswordLength = 0;
|
|
||||||
UrlComponents.dwSchemeLength = 0;
|
|
||||||
UrlComponents.dwUserNameLength = 0;
|
|
||||||
UrlComponents.dwHostNameLength = hostNameLen;
|
|
||||||
UrlComponents.dwUrlPathLength = pathLen;
|
|
||||||
|
|
||||||
if (!InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents)) return FALSE;
|
if(!InternetCrackUrlW(url, 0, 0, &comp) || !comp.dwHostNameLength)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* discard the webpage off the end of the path */
|
/* discard the webpage off the end of the path */
|
||||||
if (UrlComponents.dwUrlPathLength)
|
while(comp.dwUrlPathLength && comp.lpszUrlPath[comp.dwUrlPathLength-1] != '/')
|
||||||
{
|
comp.dwUrlPathLength--;
|
||||||
if (path[UrlComponents.dwUrlPathLength - 1] != '/')
|
|
||||||
{
|
*host = substr(comp.lpszHostName, comp.dwHostNameLength);
|
||||||
WCHAR *ptr;
|
*path = comp.dwUrlPathLength ? substr(comp.lpszUrlPath, comp.dwUrlPathLength) : substr(rootW, 1);
|
||||||
if ((ptr = strrchrW(path, '/'))) *(++ptr) = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path[0] = '/';
|
|
||||||
path[1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pathLen >= 2)
|
|
||||||
{
|
|
||||||
path[0] = '/';
|
|
||||||
path[1] = 0;
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,45 +508,38 @@ typedef struct {
|
||||||
unsigned string_len;
|
unsigned string_len;
|
||||||
} cookie_set_t;
|
} cookie_set_t;
|
||||||
|
|
||||||
static DWORD get_cookie(const WCHAR *host, const WCHAR *path, DWORD flags, cookie_set_t *res)
|
static DWORD get_cookie(substr_t host, substr_t path, DWORD flags, cookie_set_t *res)
|
||||||
{
|
{
|
||||||
static const WCHAR empty_path[] = { '/',0 };
|
static const WCHAR empty_path[] = { '/',0 };
|
||||||
|
|
||||||
WCHAR *ptr, subpath[INTERNET_MAX_PATH_LENGTH];
|
|
||||||
const WCHAR *p;
|
const WCHAR *p;
|
||||||
cookie_domain_t *domain;
|
cookie_domain_t *domain;
|
||||||
cookie_container_t *container;
|
cookie_container_t *container;
|
||||||
unsigned len;
|
|
||||||
FILETIME tm;
|
FILETIME tm;
|
||||||
|
|
||||||
GetSystemTimeAsFileTime(&tm);
|
GetSystemTimeAsFileTime(&tm);
|
||||||
|
|
||||||
len = strlenW(host);
|
p = host.str + host.len;
|
||||||
p = host+len;
|
while(p > host.str && p[-1] != '.') p--;
|
||||||
while(p>host && p[-1]!='.') p--;
|
while(p != host.str) {
|
||||||
while(p != host) {
|
|
||||||
p--;
|
p--;
|
||||||
while(p>host && p[-1]!='.') p--;
|
while(p > host.str && p[-1] != '.') p--;
|
||||||
if(p == host) break;
|
if(p == host.str) break;
|
||||||
|
|
||||||
load_persistent_cookie(p, empty_path);
|
load_persistent_cookie(substr(p, host.str+host.len-p), substr(empty_path, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlenW(path);
|
p = path.str + path.len;
|
||||||
assert(len+1 < INTERNET_MAX_PATH_LENGTH);
|
|
||||||
memcpy(subpath, path, (len+1)*sizeof(WCHAR));
|
|
||||||
ptr = subpath+len;
|
|
||||||
do {
|
do {
|
||||||
*ptr = 0;
|
load_persistent_cookie(host, substr(path.str, p-path.str));
|
||||||
load_persistent_cookie(host, subpath);
|
|
||||||
|
|
||||||
ptr--;
|
p--;
|
||||||
while(ptr>subpath && ptr[-1]!='/') ptr--;
|
while(p > path.str && p[-1] != '/') p--;
|
||||||
}while(ptr != subpath);
|
}while(p != path.str);
|
||||||
|
|
||||||
domain = get_cookie_domain(host, FALSE);
|
domain = get_cookie_domain(host, FALSE);
|
||||||
if(!domain) {
|
if(!domain) {
|
||||||
TRACE("Unknown host %s\n", debugstr_w(host));
|
TRACE("Unknown host %s\n", debugstr_wn(host.str, host.len));
|
||||||
return ERROR_NO_MORE_ITEMS;
|
return ERROR_NO_MORE_ITEMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,7 +549,7 @@ static DWORD get_cookie(const WCHAR *host, const WCHAR *path, DWORD flags, cooki
|
||||||
LIST_FOR_EACH_ENTRY(container, &domain->path_list, cookie_container_t, entry) {
|
LIST_FOR_EACH_ENTRY(container, &domain->path_list, cookie_container_t, entry) {
|
||||||
struct list *cursor, *cursor2;
|
struct list *cursor, *cursor2;
|
||||||
|
|
||||||
TRACE("path %s\n", debugstr_w(container->path));
|
TRACE("path %s\n", debugstr_wn(container->path.str, container->path.len));
|
||||||
|
|
||||||
if(!cookie_match_path(container, path))
|
if(!cookie_match_path(container, path))
|
||||||
continue;
|
continue;
|
||||||
|
@ -672,7 +634,7 @@ DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
|
||||||
|
|
||||||
EnterCriticalSection(&cookie_cs);
|
EnterCriticalSection(&cookie_cs);
|
||||||
|
|
||||||
res = get_cookie(host, path, INTERNET_COOKIE_HTTPONLY, &cookie_set);
|
res = get_cookie(substrz(host), substrz(path), INTERNET_COOKIE_HTTPONLY, &cookie_set);
|
||||||
if(res != ERROR_SUCCESS) {
|
if(res != ERROR_SUCCESS) {
|
||||||
LeaveCriticalSection(&cookie_cs);
|
LeaveCriticalSection(&cookie_cs);
|
||||||
return res;
|
return res;
|
||||||
|
@ -722,8 +684,8 @@ DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
|
||||||
BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
|
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};
|
cookie_set_t cookie_set = {0};
|
||||||
|
substr_t host, path;
|
||||||
DWORD res;
|
DWORD res;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
|
@ -738,9 +700,8 @@ BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
host[0] = 0;
|
ret = cookie_parse_url(lpszUrl, &host, &path);
|
||||||
ret = COOKIE_crackUrlSimple(lpszUrl, host, sizeof(host)/sizeof(host[0]), path, sizeof(path)/sizeof(path[0]));
|
if (!ret) {
|
||||||
if (!ret || !host[0]) {
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -768,7 +729,7 @@ BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
lpCookieData[cookie_set.string_len] = 0;
|
lpCookieData[cookie_set.string_len] = 0;
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
TRACE("no cookies found for %s\n", debugstr_w(host));
|
TRACE("no cookies found for %s\n", debugstr_wn(host.str, host.len));
|
||||||
SetLastError(ERROR_NO_MORE_ITEMS);
|
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -855,40 +816,25 @@ BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
|
BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
|
||||||
{
|
{
|
||||||
TRACE("(%s, %s, %s, %p)\n", debugstr_a(url), debugstr_a(name), debugstr_a(data), size);
|
TRACE("(%s, %s, %p, %p)\n", debugstr_a(url), debugstr_a(name), data, size);
|
||||||
|
|
||||||
return InternetGetCookieExA(url, name, data, size, 0, NULL);
|
return InternetGetCookieExA(url, name, data, size, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static BOOL is_domain_legal_for_cookie(substr_t domain, substr_t full_domain)
|
||||||
* IsDomainLegalCookieDomainW (WININET.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
|
|
||||||
{
|
{
|
||||||
DWORD s1_len, s2_len;
|
const WCHAR *ptr;
|
||||||
|
|
||||||
FIXME("(%s, %s) semi-stub\n", debugstr_w(s1), debugstr_w(s2));
|
if(!domain.len || *domain.str == '.' || !full_domain.len || *full_domain.str == '.') {
|
||||||
|
|
||||||
if (!s1 || !s2)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0])
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_NAME);
|
SetLastError(ERROR_INVALID_NAME);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!strchrW(s1, '.') || !strchrW(s2, '.'))
|
|
||||||
|
if(domain.len > full_domain.len || !memchrW(domain.str, '.', domain.len) || !memchrW(full_domain.str, '.', full_domain.len))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
s1_len = strlenW(s1);
|
ptr = full_domain.str + full_domain.len - domain.len;
|
||||||
s2_len = strlenW(s2);
|
if (strncmpiW(domain.str, ptr, domain.len) || (full_domain.len > domain.len && ptr[-1] != '.')) {
|
||||||
if (s1_len > s2_len)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (strncmpiW(s1, s2+s2_len-s1_len, s1_len) || (s2_len>s1_len && s2[s2_len-s1_len-1]!='.'))
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -896,129 +842,130 @@ BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_name, const WCHAR *cookie_data, DWORD flags)
|
/***********************************************************************
|
||||||
|
* IsDomainLegalCookieDomainW (WININET.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI IsDomainLegalCookieDomainW(const WCHAR *domain, const WCHAR *full_domain)
|
||||||
|
{
|
||||||
|
FIXME("(%s, %s) semi-stub\n", debugstr_w(domain), debugstr_w(full_domain));
|
||||||
|
|
||||||
|
if (!domain || !full_domain) {
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_domain_legal_for_cookie(substrz(domain), substrz(full_domain));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void substr_skip(substr_t *str, size_t len)
|
||||||
|
{
|
||||||
|
assert(str->len >= len);
|
||||||
|
str->str += len;
|
||||||
|
str->len -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD set_cookie(substr_t domain, substr_t path, substr_t name, substr_t data, DWORD flags)
|
||||||
{
|
{
|
||||||
cookie_container_t *container;
|
cookie_container_t *container;
|
||||||
cookie_t *thisCookie;
|
cookie_t *thisCookie;
|
||||||
LPWSTR data, value;
|
substr_t value;
|
||||||
WCHAR *ptr;
|
const WCHAR *end_ptr;
|
||||||
FILETIME expiry, create;
|
FILETIME expiry, create;
|
||||||
BOOL expired = FALSE, update_persistent = FALSE;
|
BOOL expired = FALSE, update_persistent = FALSE;
|
||||||
DWORD cookie_flags = 0;
|
DWORD cookie_flags = 0, len;
|
||||||
|
|
||||||
TRACE("%s %s %s=%s %x\n", debugstr_w(domain), debugstr_w(path), debugstr_w(cookie_name), debugstr_w(cookie_data), flags);
|
TRACE("%s %s %s=%s %x\n", debugstr_wn(domain.str, domain.len), debugstr_wn(path.str, path.len),
|
||||||
|
debugstr_wn(name.str, name.len), debugstr_wn(data.str, data.len), flags);
|
||||||
value = data = heap_strdupW(cookie_data);
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
ERR("could not allocate the cookie data buffer\n");
|
|
||||||
return COOKIE_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&expiry,0,sizeof(expiry));
|
memset(&expiry,0,sizeof(expiry));
|
||||||
GetSystemTimeAsFileTime(&create);
|
GetSystemTimeAsFileTime(&create);
|
||||||
|
|
||||||
/* lots of information can be parsed out of the cookie value */
|
/* lots of information can be parsed out of the cookie value */
|
||||||
|
|
||||||
ptr = data;
|
if(!(end_ptr = memchrW(data.str, ';', data.len)))
|
||||||
for (;;)
|
end_ptr = data.str + data.len;
|
||||||
{
|
value = substr(data.str, end_ptr-data.str);
|
||||||
static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0};
|
data.str += value.len;
|
||||||
static const WCHAR szPath[] = {'p','a','t','h','=',0};
|
data.len -= value.len;
|
||||||
static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','=',0};
|
|
||||||
static const WCHAR szSecure[] = {'s','e','c','u','r','e',0};
|
|
||||||
static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y',0};
|
|
||||||
static const WCHAR szVersion[] = {'v','e','r','s','i','o','n','=',0};
|
|
||||||
|
|
||||||
if (!(ptr = strchrW(ptr,';'))) break;
|
for(;;) {
|
||||||
*ptr++ = 0;
|
static const WCHAR szDomain[] = {'d','o','m','a','i','n','='};
|
||||||
|
static const WCHAR szPath[] = {'p','a','t','h','='};
|
||||||
|
static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','='};
|
||||||
|
static const WCHAR szSecure[] = {'s','e','c','u','r','e'};
|
||||||
|
static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y'};
|
||||||
|
static const WCHAR szVersion[] = {'v','e','r','s','i','o','n','='};
|
||||||
|
|
||||||
if (value != data) heap_free(value);
|
/* Skip ';' */
|
||||||
value = heap_alloc((ptr - data) * sizeof(WCHAR));
|
if(data.len)
|
||||||
if (value == NULL)
|
substr_skip(&data, 1);
|
||||||
{
|
|
||||||
heap_free(data);
|
|
||||||
ERR("could not allocate the cookie value buffer\n");
|
|
||||||
return COOKIE_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
strcpyW(value, data);
|
|
||||||
|
|
||||||
while (*ptr == ' ') ptr++; /* whitespace */
|
while(data.len && *data.str == ' ')
|
||||||
|
substr_skip(&data, 1);
|
||||||
|
|
||||||
if (strncmpiW(ptr, szDomain, 7) == 0)
|
if(!data.len)
|
||||||
{
|
break;
|
||||||
WCHAR *end_ptr;
|
|
||||||
|
|
||||||
ptr += sizeof(szDomain)/sizeof(szDomain[0])-1;
|
if(!(end_ptr = memchrW(data.str, ';', data.len)))
|
||||||
if(*ptr == '.')
|
end_ptr = data.str + data.len;
|
||||||
ptr++;
|
|
||||||
end_ptr = strchrW(ptr, ';');
|
|
||||||
if(end_ptr)
|
|
||||||
*end_ptr = 0;
|
|
||||||
|
|
||||||
if(!IsDomainLegalCookieDomainW(ptr, domain))
|
if(data.len >= (len = sizeof(szDomain)/sizeof(WCHAR)) && !strncmpiW(data.str, szDomain, len)) {
|
||||||
{
|
substr_skip(&data, len);
|
||||||
if(value != data)
|
|
||||||
heap_free(value);
|
if(data.len && *data.str == '.')
|
||||||
heap_free(data);
|
substr_skip(&data, 1);
|
||||||
|
|
||||||
|
if(!is_domain_legal_for_cookie(substr(data.str, end_ptr-data.str), domain))
|
||||||
return COOKIE_STATE_UNKNOWN;
|
return COOKIE_STATE_UNKNOWN;
|
||||||
}
|
|
||||||
|
|
||||||
if(end_ptr)
|
domain = substr(data.str, end_ptr-data.str);
|
||||||
*end_ptr = ';';
|
TRACE("Parsing new domain %s\n", debugstr_wn(domain.str, domain.len));
|
||||||
|
}else if(data.len >= (len = sizeof(szPath)/sizeof(WCHAR)) && !strncmpiW(data.str, szPath, len)) {
|
||||||
domain = ptr;
|
substr_skip(&data, len);
|
||||||
TRACE("Parsing new domain %s\n",debugstr_w(domain));
|
path = substr(data.str, end_ptr - data.str);
|
||||||
}
|
TRACE("Parsing new path %s\n", debugstr_wn(path.str, path.len));
|
||||||
else if (strncmpiW(ptr, szPath, 5) == 0)
|
}else if(data.len >= (len = sizeof(szExpires)/sizeof(WCHAR)) && !strncmpiW(data.str, szExpires, len)) {
|
||||||
{
|
|
||||||
ptr+=strlenW(szPath);
|
|
||||||
path = ptr;
|
|
||||||
TRACE("Parsing new path %s\n",debugstr_w(path));
|
|
||||||
}
|
|
||||||
else if (strncmpiW(ptr, szExpires, 8) == 0)
|
|
||||||
{
|
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
ptr+=strlenW(szExpires);
|
WCHAR buf[128];
|
||||||
if (InternetTimeToSystemTimeW(ptr, &st, 0))
|
|
||||||
{
|
|
||||||
SystemTimeToFileTime(&st, &expiry);
|
|
||||||
|
|
||||||
if (CompareFileTime(&create,&expiry) > 0)
|
substr_skip(&data, len);
|
||||||
{
|
|
||||||
TRACE("Cookie already expired.\n");
|
if(end_ptr - data.str < sizeof(buf)/sizeof(WCHAR)-1) {
|
||||||
expired = TRUE;
|
memcpy(buf, data.str, data.len*sizeof(WCHAR));
|
||||||
|
buf[data.len] = 0;
|
||||||
|
|
||||||
|
if (InternetTimeToSystemTimeW(data.str, &st, 0)) {
|
||||||
|
SystemTimeToFileTime(&st, &expiry);
|
||||||
|
|
||||||
|
if (CompareFileTime(&create,&expiry) > 0) {
|
||||||
|
TRACE("Cookie already expired.\n");
|
||||||
|
expired = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}else if(data.len >= (len = sizeof(szSecure)/sizeof(WCHAR)) && !strncmpiW(data.str, szSecure, len)) {
|
||||||
else if (strncmpiW(ptr, szSecure, 6) == 0)
|
substr_skip(&data, len);
|
||||||
{
|
FIXME("secure not handled\n");
|
||||||
FIXME("secure not handled (%s)\n",debugstr_w(ptr));
|
}else if(data.len >= (len = sizeof(szHttpOnly)/sizeof(WCHAR)) && !strncmpiW(data.str, szHttpOnly, len)) {
|
||||||
ptr += strlenW(szSecure);
|
substr_skip(&data, len);
|
||||||
}
|
|
||||||
else if (strncmpiW(ptr, szHttpOnly, 8) == 0)
|
|
||||||
{
|
|
||||||
if(!(flags & INTERNET_COOKIE_HTTPONLY)) {
|
if(!(flags & INTERNET_COOKIE_HTTPONLY)) {
|
||||||
WARN("HTTP only cookie added without INTERNET_COOKIE_HTTPONLY flag\n");
|
WARN("HTTP only cookie added without INTERNET_COOKIE_HTTPONLY flag\n");
|
||||||
heap_free(data);
|
|
||||||
if (value != data) heap_free(value);
|
|
||||||
SetLastError(ERROR_INVALID_OPERATION);
|
SetLastError(ERROR_INVALID_OPERATION);
|
||||||
return COOKIE_STATE_REJECT;
|
return COOKIE_STATE_REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie_flags |= INTERNET_COOKIE_HTTPONLY;
|
cookie_flags |= INTERNET_COOKIE_HTTPONLY;
|
||||||
ptr += strlenW(szHttpOnly);
|
}else if(data.len >= (len = sizeof(szVersion)/sizeof(WCHAR)) && !strncmpiW(data.str, szVersion, len)) {
|
||||||
}
|
substr_skip(&data, len);
|
||||||
else if (strncmpiW(ptr, szVersion, 8) == 0)
|
|
||||||
{
|
FIXME("version not handled (%s)\n",debugstr_wn(data.str, data.len));
|
||||||
FIXME("version not handled (%s)\n",debugstr_w(ptr));
|
}else if(data.len) {
|
||||||
ptr += strlenW(szVersion);
|
FIXME("Unknown additional option %s\n", debugstr_wn(data.str, data.len));
|
||||||
}
|
|
||||||
else if (*ptr)
|
|
||||||
{
|
|
||||||
FIXME("Unknown additional option %s\n",debugstr_w(ptr));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
substr_skip(&data, end_ptr - data.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterCriticalSection(&cookie_cs);
|
EnterCriticalSection(&cookie_cs);
|
||||||
|
@ -1027,8 +974,6 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
|
||||||
|
|
||||||
container = get_cookie_container(domain, path, !expired);
|
container = get_cookie_container(domain, path, !expired);
|
||||||
if(!container) {
|
if(!container) {
|
||||||
heap_free(data);
|
|
||||||
if (value != data) heap_free(value);
|
|
||||||
LeaveCriticalSection(&cookie_cs);
|
LeaveCriticalSection(&cookie_cs);
|
||||||
return COOKIE_STATE_ACCEPT;
|
return COOKIE_STATE_ACCEPT;
|
||||||
}
|
}
|
||||||
|
@ -1038,13 +983,10 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
|
||||||
else
|
else
|
||||||
update_persistent = TRUE;
|
update_persistent = TRUE;
|
||||||
|
|
||||||
if ((thisCookie = find_cookie(container, cookie_name)))
|
if ((thisCookie = find_cookie(container, name))) {
|
||||||
{
|
|
||||||
if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
|
if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
|
||||||
WARN("An attempt to override httponly cookie\n");
|
WARN("An attempt to override httponly cookie\n");
|
||||||
SetLastError(ERROR_INVALID_OPERATION);
|
SetLastError(ERROR_INVALID_OPERATION);
|
||||||
heap_free(data);
|
|
||||||
if (value != data) heap_free(value);
|
|
||||||
return COOKIE_STATE_REJECT;
|
return COOKIE_STATE_REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,24 +995,21 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
|
||||||
delete_cookie(thisCookie);
|
delete_cookie(thisCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
|
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_wn(name.str, name.len),
|
||||||
debugstr_w(value), debugstr_w(container->domain->domain),debugstr_w(container->path));
|
debugstr_wn(value.str, value.len), debugstr_w(container->domain->domain),
|
||||||
|
debugstr_wn(container->path.str, container->path.len));
|
||||||
|
|
||||||
if (!expired) {
|
if (!expired) {
|
||||||
cookie_t *new_cookie;
|
cookie_t *new_cookie;
|
||||||
|
|
||||||
new_cookie = alloc_cookie(cookie_name, value, expiry, create, cookie_flags);
|
new_cookie = alloc_cookie(name, value, expiry, create, cookie_flags);
|
||||||
if(!new_cookie) {
|
if(!new_cookie) {
|
||||||
heap_free(data);
|
|
||||||
if (value != data) heap_free(value);
|
|
||||||
LeaveCriticalSection(&cookie_cs);
|
LeaveCriticalSection(&cookie_cs);
|
||||||
return COOKIE_STATE_UNKNOWN;
|
return COOKIE_STATE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_cookie(container, new_cookie);
|
add_cookie(container, new_cookie);
|
||||||
}
|
}
|
||||||
heap_free(data);
|
|
||||||
if (value != data) heap_free(value);
|
|
||||||
|
|
||||||
if (!update_persistent || save_persistent_cookie(container))
|
if (!update_persistent || save_persistent_cookie(container))
|
||||||
{
|
{
|
||||||
|
@ -1089,8 +1028,8 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
|
||||||
DWORD WINAPI InternetSetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
DWORD WINAPI InternetSetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
|
LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
|
||||||
{
|
{
|
||||||
|
substr_t host, path, name, data;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
WCHAR hostName[INTERNET_MAX_HOST_NAME_LENGTH], path[INTERNET_MAX_PATH_LENGTH];
|
|
||||||
|
|
||||||
TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_w(lpszUrl), debugstr_w(lpszCookieName),
|
TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_w(lpszUrl), debugstr_w(lpszCookieName),
|
||||||
debugstr_w(lpCookieData), flags, reserved);
|
debugstr_w(lpCookieData), flags, reserved);
|
||||||
|
@ -1104,34 +1043,26 @@ DWORD WINAPI InternetSetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
||||||
return COOKIE_STATE_UNKNOWN;
|
return COOKIE_STATE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostName[0] = 0;
|
ret = cookie_parse_url(lpszUrl, &host, &path);
|
||||||
ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
|
if (!ret || !host.len) return COOKIE_STATE_UNKNOWN;
|
||||||
if (!ret || !hostName[0]) return COOKIE_STATE_UNKNOWN;
|
|
||||||
|
|
||||||
if (!lpszCookieName)
|
if (!lpszCookieName) {
|
||||||
{
|
const WCHAR *ptr;
|
||||||
WCHAR *cookie, *data;
|
|
||||||
DWORD res;
|
|
||||||
|
|
||||||
cookie = heap_strdupW(lpCookieData);
|
|
||||||
if (!cookie)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
return COOKIE_STATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* some apps (or is it us??) try to add a cookie with no cookie name, but
|
/* some apps (or is it us??) try to add a cookie with no cookie name, but
|
||||||
* the cookie data in the form of name[=data].
|
* the cookie data in the form of name[=data].
|
||||||
*/
|
*/
|
||||||
if (!(data = strchrW(cookie, '='))) data = cookie + strlenW(cookie);
|
if (!(ptr = strchrW(lpCookieData, '=')))
|
||||||
else *data++ = 0;
|
ptr = lpCookieData + strlenW(lpCookieData);
|
||||||
|
|
||||||
res = set_cookie(hostName, path, cookie, data, flags);
|
name = substr(lpCookieData, ptr - lpCookieData);
|
||||||
|
data = substrz(*ptr == '=' ? ptr+1 : ptr);
|
||||||
heap_free(cookie);
|
}else {
|
||||||
return res;
|
name = substrz(lpszCookieName);
|
||||||
|
data = substrz(lpCookieData);
|
||||||
}
|
}
|
||||||
return set_cookie(hostName, path, lpszCookieName, lpCookieData, flags);
|
|
||||||
|
return set_cookie(host, path, name, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -179,7 +179,6 @@ static INT HTTP_GetCustomHeaderIndex(http_request_t *req, LPCWSTR lpszField, INT
|
||||||
static BOOL HTTP_DeleteCustomHeader(http_request_t *req, DWORD index);
|
static BOOL HTTP_DeleteCustomHeader(http_request_t *req, DWORD index);
|
||||||
static LPWSTR HTTP_build_req( LPCWSTR *list, int len );
|
static LPWSTR HTTP_build_req( LPCWSTR *list, int len );
|
||||||
static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD);
|
static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD);
|
||||||
static LPWSTR HTTP_GetRedirectURL(http_request_t *req, LPCWSTR lpszUrl);
|
|
||||||
static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin);
|
static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin);
|
||||||
static BOOL drain_content(http_request_t*,BOOL);
|
static BOOL drain_content(http_request_t*,BOOL);
|
||||||
|
|
||||||
|
@ -247,7 +246,7 @@ static BOOL process_host_port(server_t *server)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_t *get_server(const WCHAR *name, INTERNET_PORT port, BOOL is_https, BOOL do_create)
|
server_t *get_server(substr_t name, INTERNET_PORT port, BOOL is_https, BOOL do_create)
|
||||||
{
|
{
|
||||||
server_t *iter, *server = NULL;
|
server_t *iter, *server = NULL;
|
||||||
|
|
||||||
|
@ -257,7 +256,8 @@ server_t *get_server(const WCHAR *name, INTERNET_PORT port, BOOL is_https, BOOL
|
||||||
EnterCriticalSection(&connection_pool_cs);
|
EnterCriticalSection(&connection_pool_cs);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(iter, &connection_pool, server_t, entry) {
|
LIST_FOR_EACH_ENTRY(iter, &connection_pool, server_t, entry) {
|
||||||
if(iter->port == port && !strcmpW(iter->name, name) && iter->is_https == is_https) {
|
if(iter->port == port && name.len == strlenW(iter->name) && !strncmpW(iter->name, name.str, name.len)
|
||||||
|
&& iter->is_https == is_https) {
|
||||||
server = iter;
|
server = iter;
|
||||||
server_addref(server);
|
server_addref(server);
|
||||||
break;
|
break;
|
||||||
|
@ -271,7 +271,7 @@ server_t *get_server(const WCHAR *name, INTERNET_PORT port, BOOL is_https, BOOL
|
||||||
server->port = port;
|
server->port = port;
|
||||||
server->is_https = is_https;
|
server->is_https = is_https;
|
||||||
list_init(&server->conn_pool);
|
list_init(&server->conn_pool);
|
||||||
server->name = heap_strdupW(name);
|
server->name = heap_strndupW(name.str, name.len);
|
||||||
if(server->name && process_host_port(server)) {
|
if(server->name && process_host_port(server)) {
|
||||||
list_add_head(&connection_pool, &server->entry);
|
list_add_head(&connection_pool, &server->entry);
|
||||||
}else {
|
}else {
|
||||||
|
@ -767,7 +767,7 @@ static void HTTP_ProcessCookies( http_request_t *request )
|
||||||
while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1)
|
while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1)
|
||||||
{
|
{
|
||||||
const WCHAR *data;
|
const WCHAR *data;
|
||||||
WCHAR *name;
|
substr_t name;
|
||||||
|
|
||||||
setCookieHeader = &request->custHeaders[HeaderIndex];
|
setCookieHeader = &request->custHeaders[HeaderIndex];
|
||||||
|
|
||||||
|
@ -778,13 +778,9 @@ static void HTTP_ProcessCookies( http_request_t *request )
|
||||||
if(!data)
|
if(!data)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
name = heap_strndupW(setCookieHeader->lpszValue, data-setCookieHeader->lpszValue);
|
name = substr(setCookieHeader->lpszValue, data - setCookieHeader->lpszValue);
|
||||||
if(!name)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
data++;
|
data++;
|
||||||
set_cookie(request->server->name, path, name, data, INTERNET_COOKIE_HTTPONLY);
|
set_cookie(substrz(request->server->name), substrz(path), name, substrz(data), INTERNET_COOKIE_HTTPONLY);
|
||||||
heap_free(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection( &request->headers_section );
|
LeaveCriticalSection( &request->headers_section );
|
||||||
|
@ -1371,21 +1367,17 @@ BOOL WINAPI HttpAddRequestHeadersW(HINTERNET hHttpRequest,
|
||||||
BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
||||||
LPCSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
|
LPCSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
|
||||||
{
|
{
|
||||||
DWORD len;
|
WCHAR *headers = NULL;
|
||||||
LPWSTR hdr;
|
|
||||||
BOOL r;
|
BOOL r;
|
||||||
|
|
||||||
TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_an(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier);
|
TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_an(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier);
|
||||||
|
|
||||||
len = MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, NULL, 0 );
|
if(lpszHeader)
|
||||||
hdr = heap_alloc(len*sizeof(WCHAR));
|
headers = heap_strndupAtoW(lpszHeader, dwHeaderLength, &dwHeaderLength);
|
||||||
MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, hdr, len );
|
|
||||||
if( dwHeaderLength != ~0U )
|
|
||||||
dwHeaderLength = len;
|
|
||||||
|
|
||||||
r = HttpAddRequestHeadersW( hHttpRequest, hdr, dwHeaderLength, dwModifier );
|
r = HttpAddRequestHeadersW(hHttpRequest, headers, dwHeaderLength, dwModifier);
|
||||||
|
|
||||||
heap_free( hdr );
|
heap_free(headers);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1717,55 +1709,47 @@ static WCHAR *build_proxy_path_url(http_request_t *req)
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL HTTP_DomainMatches(LPCWSTR server, LPCWSTR domain)
|
static BOOL HTTP_DomainMatches(LPCWSTR server, substr_t domain)
|
||||||
{
|
{
|
||||||
static const WCHAR localW[] = { '<','l','o','c','a','l','>',0 };
|
static const WCHAR localW[] = { '<','l','o','c','a','l','>',0 };
|
||||||
BOOL ret = FALSE;
|
const WCHAR *dot, *ptr;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (!strcmpiW( domain, localW ) && !strchrW( server, '.' ))
|
if(domain.len == sizeof(localW)/sizeof(WCHAR)-1 && !strncmpiW(domain.str, localW, domain.len) && !strchrW(server, '.' ))
|
||||||
ret = TRUE;
|
return TRUE;
|
||||||
else if (*domain == '*')
|
|
||||||
{
|
|
||||||
if (domain[1] == '.')
|
|
||||||
{
|
|
||||||
LPCWSTR dot;
|
|
||||||
|
|
||||||
/* For a hostname to match a wildcard, the last domain must match
|
if(domain.len && *domain.str != '*')
|
||||||
* the wildcard exactly. E.g. if the wildcard is *.a.b, and the
|
return domain.len == strlenW(server) && !strncmpiW(server, domain.str, domain.len);
|
||||||
* hostname is www.foo.a.b, it matches, but a.b does not.
|
|
||||||
*/
|
|
||||||
dot = strchrW( server, '.' );
|
|
||||||
if (dot)
|
|
||||||
{
|
|
||||||
int len = strlenW( dot + 1 );
|
|
||||||
|
|
||||||
if (len > strlenW( domain + 2 ))
|
if(domain.len < 2 || domain.str[1] != '.')
|
||||||
{
|
return FALSE;
|
||||||
LPCWSTR ptr;
|
|
||||||
|
|
||||||
/* The server's domain is longer than the wildcard, so it
|
/* For a hostname to match a wildcard, the last domain must match
|
||||||
* could be a subdomain. Compare the last portion of the
|
* the wildcard exactly. E.g. if the wildcard is *.a.b, and the
|
||||||
* server's domain.
|
* hostname is www.foo.a.b, it matches, but a.b does not.
|
||||||
*/
|
*/
|
||||||
ptr = dot + len + 1 - strlenW( domain + 2 );
|
dot = strchrW(server, '.');
|
||||||
if (!strcmpiW( ptr, domain + 2 ))
|
if(!dot)
|
||||||
{
|
return FALSE;
|
||||||
/* This is only a match if the preceding character is
|
|
||||||
* a '.', i.e. that it is a matching domain. E.g.
|
len = strlenW(dot + 1);
|
||||||
* if domain is '*.b.c' and server is 'www.ab.c' they
|
if(len <= domain.len - 2)
|
||||||
* do not match.
|
return FALSE;
|
||||||
*/
|
|
||||||
ret = *(ptr - 1) == '.';
|
/* The server's domain is longer than the wildcard, so it
|
||||||
}
|
* could be a subdomain. Compare the last portion of the
|
||||||
}
|
* server's domain.
|
||||||
else
|
*/
|
||||||
ret = !strcmpiW( dot + 1, domain + 2 );
|
ptr = dot + 1 + len - domain.len + 2;
|
||||||
}
|
if(!strncmpiW(ptr, domain.str+2, domain.len-2))
|
||||||
}
|
/* This is only a match if the preceding character is
|
||||||
}
|
* a '.', i.e. that it is a matching domain. E.g.
|
||||||
else
|
* if domain is '*.b.c' and server is 'www.ab.c' they
|
||||||
ret = !strcmpiW( server, domain );
|
* do not match.
|
||||||
return ret;
|
*/
|
||||||
|
return *(ptr - 1) == '.';
|
||||||
|
|
||||||
|
return len == domain.len-2 && !strncmpiW(dot + 1, domain.str + 2, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
|
static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
|
||||||
|
@ -1775,27 +1759,19 @@ static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
|
||||||
|
|
||||||
if (!lpwai->proxyBypass) return FALSE;
|
if (!lpwai->proxyBypass) return FALSE;
|
||||||
ptr = lpwai->proxyBypass;
|
ptr = lpwai->proxyBypass;
|
||||||
do {
|
while(1) {
|
||||||
LPCWSTR tmp = ptr;
|
LPCWSTR tmp = ptr;
|
||||||
|
|
||||||
ptr = strchrW( ptr, ';' );
|
ptr = strchrW( ptr, ';' );
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
ptr = strchrW( tmp, ' ' );
|
ptr = strchrW( tmp, ' ' );
|
||||||
if (ptr)
|
if (!ptr)
|
||||||
{
|
ptr = tmp + strlenW(ptr);
|
||||||
if (ptr - tmp < INTERNET_MAX_HOST_NAME_LENGTH)
|
ret = HTTP_DomainMatches( server, substr(tmp, ptr-tmp) );
|
||||||
{
|
if (ret || !*ptr)
|
||||||
WCHAR domain[INTERNET_MAX_HOST_NAME_LENGTH];
|
break;
|
||||||
|
ptr++;
|
||||||
memcpy( domain, tmp, (ptr - tmp) * sizeof(WCHAR) );
|
}
|
||||||
domain[ptr - tmp] = 0;
|
|
||||||
ret = HTTP_DomainMatches( server, domain );
|
|
||||||
}
|
|
||||||
ptr += 1;
|
|
||||||
}
|
|
||||||
else if (*tmp)
|
|
||||||
ret = HTTP_DomainMatches( server, tmp );
|
|
||||||
} while (ptr && !ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1806,41 +1782,34 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req
|
||||||
{
|
{
|
||||||
static const WCHAR protoHttp[] = { 'h','t','t','p',0 };
|
static const WCHAR protoHttp[] = { 'h','t','t','p',0 };
|
||||||
static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 };
|
static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 };
|
||||||
static const WCHAR szFormat[] = { 'h','t','t','p',':','/','/','%','s',0 };
|
|
||||||
WCHAR buf[INTERNET_MAX_HOST_NAME_LENGTH];
|
|
||||||
WCHAR protoProxy[INTERNET_MAX_URL_LENGTH];
|
|
||||||
DWORD protoProxyLen = INTERNET_MAX_URL_LENGTH;
|
|
||||||
WCHAR proxy[INTERNET_MAX_URL_LENGTH];
|
|
||||||
static WCHAR szNul[] = { 0 };
|
static WCHAR szNul[] = { 0 };
|
||||||
URL_COMPONENTSW UrlComponents;
|
URL_COMPONENTSW UrlComponents = { sizeof(UrlComponents) };
|
||||||
server_t *new_server;
|
server_t *new_server = NULL;
|
||||||
BOOL is_https;
|
WCHAR *proxy;
|
||||||
|
|
||||||
memset( &UrlComponents, 0, sizeof UrlComponents );
|
proxy = INTERNET_FindProxyForProtocol(hIC->proxy, protoHttp);
|
||||||
UrlComponents.dwStructSize = sizeof UrlComponents;
|
if(!proxy)
|
||||||
UrlComponents.lpszHostName = buf;
|
|
||||||
UrlComponents.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
|
|
||||||
|
|
||||||
if (!INTERNET_FindProxyForProtocol(hIC->proxy, protoHttp, protoProxy, &protoProxyLen))
|
|
||||||
return FALSE;
|
|
||||||
if( CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
|
||||||
protoProxy,strlenW(szHttp),szHttp,strlenW(szHttp)) )
|
|
||||||
sprintfW(proxy, szFormat, protoProxy);
|
|
||||||
else
|
|
||||||
strcpyW(proxy, protoProxy);
|
|
||||||
if( !InternetCrackUrlW(proxy, 0, 0, &UrlComponents) )
|
|
||||||
return FALSE;
|
|
||||||
if( UrlComponents.dwHostNameLength == 0 )
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if(CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
|
||||||
|
proxy, strlenW(szHttp), szHttp, strlenW(szHttp))) {
|
||||||
|
WCHAR *proxy_url = heap_alloc(strlenW(proxy)*sizeof(WCHAR) + sizeof(szHttp));
|
||||||
|
if(!proxy_url)
|
||||||
|
return FALSE;
|
||||||
|
strcpyW(proxy_url, szHttp);
|
||||||
|
strcatW(proxy_url, proxy);
|
||||||
|
heap_free(proxy);
|
||||||
|
proxy = proxy_url;
|
||||||
|
}
|
||||||
|
|
||||||
if( !request->path )
|
UrlComponents.dwHostNameLength = 1;
|
||||||
request->path = szNul;
|
if(InternetCrackUrlW(proxy, 0, 0, &UrlComponents) && UrlComponents.dwHostNameLength) {
|
||||||
|
if( !request->path )
|
||||||
|
request->path = szNul;
|
||||||
|
|
||||||
is_https = (UrlComponents.nScheme == INTERNET_SCHEME_HTTPS);
|
new_server = get_server(substr(UrlComponents.lpszHostName, UrlComponents.dwHostNameLength),
|
||||||
if (is_https && UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
|
UrlComponents.nPort, UrlComponents.nScheme == INTERNET_SCHEME_HTTPS, TRUE);
|
||||||
UrlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
|
}
|
||||||
|
heap_free(proxy);
|
||||||
new_server = get_server(UrlComponents.lpszHostName, UrlComponents.nPort, is_https, TRUE);
|
|
||||||
if(!new_server)
|
if(!new_server)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1876,33 +1845,39 @@ static DWORD HTTP_ResolveName(http_request_t *request)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf)
|
static WCHAR *compose_request_url(http_request_t *req)
|
||||||
{
|
{
|
||||||
static const WCHAR http[] = { 'h','t','t','p',':','/','/',0 };
|
static const WCHAR http[] = { 'h','t','t','p',':','/','/',0 };
|
||||||
static const WCHAR https[] = { 'h','t','t','p','s',':','/','/',0 };
|
static const WCHAR https[] = { 'h','t','t','p','s',':','/','/',0 };
|
||||||
static const WCHAR slash[] = { '/',0 };
|
const WCHAR *host, *scheme;
|
||||||
LPHTTPHEADERW host_header;
|
WCHAR *buf, *ptr;
|
||||||
const WCHAR *host;
|
size_t len;
|
||||||
LPCWSTR scheme;
|
|
||||||
|
|
||||||
EnterCriticalSection( &req->headers_section );
|
host = req->server->canon_host_port;
|
||||||
|
|
||||||
host_header = HTTP_GetHeader(req, hostW);
|
if (req->server->is_https)
|
||||||
if (host_header) host = host_header->lpszValue;
|
|
||||||
else host = req->server->canon_host_port;
|
|
||||||
|
|
||||||
if (req->hdr.dwFlags & INTERNET_FLAG_SECURE)
|
|
||||||
scheme = https;
|
scheme = https;
|
||||||
else
|
else
|
||||||
scheme = http;
|
scheme = http;
|
||||||
strcpyW(buf, scheme);
|
|
||||||
strcatW(buf, host);
|
|
||||||
if (req->path[0] != '/')
|
|
||||||
strcatW(buf, slash);
|
|
||||||
strcatW(buf, req->path);
|
|
||||||
|
|
||||||
LeaveCriticalSection( &req->headers_section );
|
len = strlenW(scheme) + strlenW(host) + (req->path[0] != '/' ? 1 : 0) + strlenW(req->path);
|
||||||
return TRUE;
|
ptr = buf = heap_alloc((len+1) * sizeof(WCHAR));
|
||||||
|
if(buf) {
|
||||||
|
strcpyW(ptr, scheme);
|
||||||
|
ptr += strlenW(ptr);
|
||||||
|
|
||||||
|
strcpyW(ptr, host);
|
||||||
|
ptr += strlenW(ptr);
|
||||||
|
|
||||||
|
if(req->path[0] != '/')
|
||||||
|
*ptr++ = '/';
|
||||||
|
|
||||||
|
strcpyW(ptr, req->path);
|
||||||
|
ptr += strlenW(ptr);
|
||||||
|
*ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2140,17 +2115,18 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
case INTERNET_OPTION_URL: {
|
case INTERNET_OPTION_URL: {
|
||||||
static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0};
|
WCHAR *url;
|
||||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
DWORD res;
|
||||||
|
|
||||||
TRACE("INTERNET_OPTION_URL\n");
|
TRACE("INTERNET_OPTION_URL\n");
|
||||||
|
|
||||||
strcpyW(url, httpW);
|
url = compose_request_url(req);
|
||||||
strcatW(url, req->server->canon_host_port);
|
if(!url)
|
||||||
strcatW(url, req->path);
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url));
|
res = str_to_buffer(url, buffer, size, unicode);
|
||||||
return str_to_buffer(url, buffer, size, unicode);
|
heap_free(url);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
case INTERNET_OPTION_USER_AGENT:
|
case INTERNET_OPTION_USER_AGENT:
|
||||||
return str_to_buffer(req->session->appInfo->agent, buffer, size, unicode);
|
return str_to_buffer(req->session->appInfo->agent, buffer, size, unicode);
|
||||||
|
@ -2166,27 +2142,29 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
|
||||||
case INTERNET_OPTION_CACHE_TIMESTAMPS: {
|
case INTERNET_OPTION_CACHE_TIMESTAMPS: {
|
||||||
INTERNET_CACHE_ENTRY_INFOW *info;
|
INTERNET_CACHE_ENTRY_INFOW *info;
|
||||||
INTERNET_CACHE_TIMESTAMPS *ts = buffer;
|
INTERNET_CACHE_TIMESTAMPS *ts = buffer;
|
||||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
|
||||||
DWORD nbytes, error;
|
DWORD nbytes, error;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
TRACE("INTERNET_OPTION_CACHE_TIMESTAMPS\n");
|
TRACE("INTERNET_OPTION_CACHE_TIMESTAMPS\n");
|
||||||
|
|
||||||
|
if(!req->req_file)
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
|
|
||||||
if (*size < sizeof(*ts))
|
if (*size < sizeof(*ts))
|
||||||
{
|
{
|
||||||
*size = sizeof(*ts);
|
*size = sizeof(*ts);
|
||||||
return ERROR_INSUFFICIENT_BUFFER;
|
return ERROR_INSUFFICIENT_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
nbytes = 0;
|
nbytes = 0;
|
||||||
HTTP_GetRequestURL(req, url);
|
ret = GetUrlCacheEntryInfoW(req->req_file->url, NULL, &nbytes);
|
||||||
ret = GetUrlCacheEntryInfoW(url, NULL, &nbytes);
|
|
||||||
error = GetLastError();
|
error = GetLastError();
|
||||||
if (!ret && error == ERROR_INSUFFICIENT_BUFFER)
|
if (!ret && error == ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
if (!(info = heap_alloc(nbytes)))
|
if (!(info = heap_alloc(nbytes)))
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
GetUrlCacheEntryInfoW(url, info, &nbytes);
|
GetUrlCacheEntryInfoW(req->req_file->url, info, &nbytes);
|
||||||
|
|
||||||
ts->ftExpires = info->ExpireTime;
|
ts->ftExpires = info->ExpireTime;
|
||||||
ts->ftLastModified = info->LastModifiedTime;
|
ts->ftLastModified = info->LastModifiedTime;
|
||||||
|
@ -2375,29 +2353,25 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer,
|
||||||
|
|
||||||
static void commit_cache_entry(http_request_t *req)
|
static void commit_cache_entry(http_request_t *req)
|
||||||
{
|
{
|
||||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
WCHAR *header;
|
||||||
|
DWORD header_len;
|
||||||
|
BOOL res;
|
||||||
|
|
||||||
TRACE("%p\n", req);
|
TRACE("%p\n", req);
|
||||||
|
|
||||||
CloseHandle(req->hCacheFile);
|
CloseHandle(req->hCacheFile);
|
||||||
req->hCacheFile = NULL;
|
req->hCacheFile = NULL;
|
||||||
|
|
||||||
if(HTTP_GetRequestURL(req, url)) {
|
header = build_response_header(req, TRUE);
|
||||||
WCHAR *header;
|
header_len = (header ? strlenW(header) : 0);
|
||||||
DWORD header_len;
|
res = CommitUrlCacheEntryW(req->req_file->url, req->req_file->file_name, req->expires,
|
||||||
BOOL res;
|
req->last_modified, NORMAL_CACHE_ENTRY,
|
||||||
|
header, header_len, NULL, 0);
|
||||||
header = build_response_header(req, TRUE);
|
if(res)
|
||||||
header_len = (header ? strlenW(header) : 0);
|
req->req_file->is_committed = TRUE;
|
||||||
res = CommitUrlCacheEntryW(url, req->req_file->file_name, req->expires,
|
else
|
||||||
req->last_modified, NORMAL_CACHE_ENTRY,
|
WARN("CommitUrlCacheEntry failed: %u\n", GetLastError());
|
||||||
header, header_len, NULL, 0);
|
heap_free(header);
|
||||||
if(res)
|
|
||||||
req->req_file->is_committed = TRUE;
|
|
||||||
else
|
|
||||||
WARN("CommitUrlCacheEntry failed: %u\n", GetLastError());
|
|
||||||
heap_free(header);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_cache_entry(http_request_t *req)
|
static void create_cache_entry(http_request_t *req)
|
||||||
|
@ -2405,8 +2379,8 @@ static void create_cache_entry(http_request_t *req)
|
||||||
static const WCHAR no_cacheW[] = {'n','o','-','c','a','c','h','e',0};
|
static const WCHAR no_cacheW[] = {'n','o','-','c','a','c','h','e',0};
|
||||||
static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};
|
static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};
|
||||||
|
|
||||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
|
||||||
WCHAR file_name[MAX_PATH+1];
|
WCHAR file_name[MAX_PATH+1];
|
||||||
|
WCHAR *url;
|
||||||
BOOL b = TRUE;
|
BOOL b = TRUE;
|
||||||
|
|
||||||
/* FIXME: We should free previous cache file earlier */
|
/* FIXME: We should free previous cache file earlier */
|
||||||
|
@ -2463,8 +2437,8 @@ static void create_cache_entry(http_request_t *req)
|
||||||
FIXME("INTERNET_FLAG_NEED_FILE is not supported correctly\n");
|
FIXME("INTERNET_FLAG_NEED_FILE is not supported correctly\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
b = HTTP_GetRequestURL(req, url);
|
url = compose_request_url(req);
|
||||||
if(!b) {
|
if(!url) {
|
||||||
WARN("Could not get URL\n");
|
WARN("Could not get URL\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2476,6 +2450,7 @@ static void create_cache_entry(http_request_t *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
create_req_file(file_name, &req->req_file);
|
create_req_file(file_name, &req->req_file);
|
||||||
|
req->req_file->url = url;
|
||||||
|
|
||||||
req->hCacheFile = CreateFileW(file_name, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
req->hCacheFile = CreateFileW(file_name, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
@ -3036,7 +3011,7 @@ static void HTTP_ReceiveRequestData(http_request_t *req, BOOL first_notif, DWORD
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read data from the http connection (the read section must be held) */
|
/* read data from the http connection (the read section must be held) */
|
||||||
static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
|
static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read)
|
||||||
{
|
{
|
||||||
DWORD current_read = 0, ret_read = 0;
|
DWORD current_read = 0, ret_read = 0;
|
||||||
blocking_mode_t blocking_mode;
|
blocking_mode_t blocking_mode;
|
||||||
|
@ -3090,7 +3065,7 @@ static BOOL drain_content(http_request_t *req, BOOL blocking)
|
||||||
DWORD bytes_read, res;
|
DWORD bytes_read, res;
|
||||||
BYTE buf[4096];
|
BYTE buf[4096];
|
||||||
|
|
||||||
res = HTTPREQ_Read(req, buf, sizeof(buf), &bytes_read, TRUE);
|
res = HTTPREQ_Read(req, buf, sizeof(buf), &bytes_read);
|
||||||
if(res != ERROR_SUCCESS) {
|
if(res != ERROR_SUCCESS) {
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -3105,23 +3080,6 @@ static BOOL drain_content(http_request_t *req, BOOL blocking)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read)
|
|
||||||
{
|
|
||||||
http_request_t *req = (http_request_t*)hdr;
|
|
||||||
DWORD res;
|
|
||||||
|
|
||||||
EnterCriticalSection( &req->read_section );
|
|
||||||
if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
|
||||||
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
res = HTTPREQ_Read(req, buffer, size, read, TRUE);
|
|
||||||
if(res == ERROR_SUCCESS)
|
|
||||||
res = hdr->dwError;
|
|
||||||
LeaveCriticalSection( &req->read_section );
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
task_header_t hdr;
|
task_header_t hdr;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
@ -3133,11 +3091,23 @@ static void AsyncReadFileExProc(task_header_t *hdr)
|
||||||
{
|
{
|
||||||
read_file_ex_task_t *task = (read_file_ex_task_t*)hdr;
|
read_file_ex_task_t *task = (read_file_ex_task_t*)hdr;
|
||||||
http_request_t *req = (http_request_t*)task->hdr.hdr;
|
http_request_t *req = (http_request_t*)task->hdr.hdr;
|
||||||
DWORD res;
|
DWORD res = ERROR_SUCCESS, read = 0, buffered = 0;
|
||||||
|
|
||||||
TRACE("INTERNETREADFILEEXW %p\n", task->hdr.hdr);
|
TRACE("%p\n", req);
|
||||||
|
|
||||||
|
if(task->ret_read)
|
||||||
|
res = HTTPREQ_Read(req, task->buf, task->size, &read);
|
||||||
|
if(res == ERROR_SUCCESS)
|
||||||
|
res = refill_read_buffer(req, task->ret_read ? BLOCKING_DISALLOW : BLOCKING_ALLOW, &buffered);
|
||||||
|
if (res == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if(task->ret_read)
|
||||||
|
*task->ret_read = read;
|
||||||
|
read += buffered;
|
||||||
|
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
|
||||||
|
&read, sizeof(read));
|
||||||
|
}
|
||||||
|
|
||||||
res = HTTPREQ_Read(req, task->buf, task->size, task->ret_read, TRUE);
|
|
||||||
send_request_complete(req, res == ERROR_SUCCESS, res);
|
send_request_complete(req, res == ERROR_SUCCESS, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3148,20 +3118,22 @@ static DWORD HTTPREQ_ReadFileEx(object_header_t *hdr, void *buf, DWORD size, DWO
|
||||||
http_request_t *req = (http_request_t*)hdr;
|
http_request_t *req = (http_request_t*)hdr;
|
||||||
DWORD res, read, cread, error = ERROR_SUCCESS;
|
DWORD res, read, cread, error = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
TRACE("(%p %p %u %x)\n", req, buf, size, flags);
|
||||||
|
|
||||||
if (flags & ~(IRF_ASYNC|IRF_NO_WAIT))
|
if (flags & ~(IRF_ASYNC|IRF_NO_WAIT))
|
||||||
FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT));
|
FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT));
|
||||||
|
|
||||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
|
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
|
||||||
|
|
||||||
if (hdr->dwFlags & INTERNET_FLAG_ASYNC)
|
if (req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
|
||||||
{
|
{
|
||||||
read_file_ex_task_t *task;
|
read_file_ex_task_t *task;
|
||||||
|
|
||||||
if (TryEnterCriticalSection( &req->read_section ))
|
if (TryEnterCriticalSection( &req->read_section ))
|
||||||
{
|
{
|
||||||
if (get_avail_data(req))
|
if (get_avail_data(req) || end_of_read_data(req))
|
||||||
{
|
{
|
||||||
res = HTTPREQ_Read(req, buf, size, &read, FALSE);
|
res = HTTPREQ_Read(req, buf, size, &read);
|
||||||
LeaveCriticalSection( &req->read_section );
|
LeaveCriticalSection( &req->read_section );
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -3171,7 +3143,7 @@ static DWORD HTTPREQ_ReadFileEx(object_header_t *hdr, void *buf, DWORD size, DWO
|
||||||
task = alloc_async_task(&req->hdr, AsyncReadFileExProc, sizeof(*task));
|
task = alloc_async_task(&req->hdr, AsyncReadFileExProc, sizeof(*task));
|
||||||
task->buf = buf;
|
task->buf = buf;
|
||||||
task->size = size;
|
task->size = size;
|
||||||
task->ret_read = ret_read;
|
task->ret_read = (flags & IRF_NO_WAIT) ? NULL : ret_read;
|
||||||
|
|
||||||
INTERNET_AsyncCall(&task->hdr);
|
INTERNET_AsyncCall(&task->hdr);
|
||||||
|
|
||||||
|
@ -3187,7 +3159,7 @@ static DWORD HTTPREQ_ReadFileEx(object_header_t *hdr, void *buf, DWORD size, DWO
|
||||||
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
res = HTTPREQ_Read(req, (char*)buf+read, size-read, &cread, !(flags & IRF_NO_WAIT));
|
res = HTTPREQ_Read(req, (char*)buf+read, size-read, &cread);
|
||||||
if(res != ERROR_SUCCESS)
|
if(res != ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3238,6 +3210,49 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read)
|
||||||
|
{
|
||||||
|
http_request_t *req = (http_request_t*)hdr;
|
||||||
|
DWORD res;
|
||||||
|
|
||||||
|
if (req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
|
||||||
|
{
|
||||||
|
read_file_ex_task_t *task;
|
||||||
|
|
||||||
|
if (TryEnterCriticalSection( &req->read_section ))
|
||||||
|
{
|
||||||
|
if (get_avail_data(req) || end_of_read_data(req))
|
||||||
|
{
|
||||||
|
res = HTTPREQ_Read(req, buffer, size, read);
|
||||||
|
LeaveCriticalSection( &req->read_section );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection( &req->read_section );
|
||||||
|
}
|
||||||
|
|
||||||
|
task = alloc_async_task(&req->hdr, AsyncReadFileExProc, sizeof(*task));
|
||||||
|
task->buf = buffer;
|
||||||
|
task->size = size;
|
||||||
|
task->ret_read = read;
|
||||||
|
|
||||||
|
*read = 0;
|
||||||
|
INTERNET_AsyncCall(&task->hdr);
|
||||||
|
|
||||||
|
return ERROR_IO_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection( &req->read_section );
|
||||||
|
if(hdr->dwError == INTERNET_HANDLE_IN_USE)
|
||||||
|
hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
res = HTTPREQ_Read(req, buffer, size, read);
|
||||||
|
if(res == ERROR_SUCCESS)
|
||||||
|
res = hdr->dwError;
|
||||||
|
LeaveCriticalSection( &req->read_section );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
task_header_t hdr;
|
task_header_t hdr;
|
||||||
DWORD *ret_size;
|
DWORD *ret_size;
|
||||||
|
@ -3335,7 +3350,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
|
||||||
{
|
{
|
||||||
appinfo_t *hIC = session->appInfo;
|
appinfo_t *hIC = session->appInfo;
|
||||||
http_request_t *request;
|
http_request_t *request;
|
||||||
DWORD len;
|
DWORD port, len;
|
||||||
|
|
||||||
TRACE("-->\n");
|
TRACE("-->\n");
|
||||||
|
|
||||||
|
@ -3364,7 +3379,14 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
|
||||||
request->session = session;
|
request->session = session;
|
||||||
list_add_head( &session->hdr.children, &request->hdr.entry );
|
list_add_head( &session->hdr.children, &request->hdr.entry );
|
||||||
|
|
||||||
request->server = get_server(session->hostName, session->hostPort, (dwFlags & INTERNET_FLAG_SECURE) != 0, TRUE);
|
port = session->hostPort;
|
||||||
|
if (port == INTERNET_INVALID_PORT_NUMBER)
|
||||||
|
{
|
||||||
|
port = (session->hdr.dwFlags & INTERNET_FLAG_SECURE) ?
|
||||||
|
INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->server = get_server(substrz(session->hostName), port, (dwFlags & INTERNET_FLAG_SECURE) != 0, TRUE);
|
||||||
if(!request->server) {
|
if(!request->server) {
|
||||||
WININET_Release(&request->hdr);
|
WININET_Release(&request->hdr);
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
@ -4032,64 +4054,57 @@ BOOL WINAPI HttpQueryInfoA(HINTERNET hHttpRequest, DWORD dwInfoLevel,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static WCHAR *get_redirect_url(http_request_t *request)
|
||||||
* HTTP_GetRedirectURL (internal)
|
|
||||||
*/
|
|
||||||
static LPWSTR HTTP_GetRedirectURL(http_request_t *request, LPCWSTR lpszUrl)
|
|
||||||
{
|
{
|
||||||
static WCHAR szHttp[] = {'h','t','t','p',0};
|
static WCHAR szHttp[] = {'h','t','t','p',0};
|
||||||
static WCHAR szHttps[] = {'h','t','t','p','s',0};
|
static WCHAR szHttps[] = {'h','t','t','p','s',0};
|
||||||
http_session_t *session = request->session;
|
http_session_t *session = request->session;
|
||||||
URL_COMPONENTSW urlComponents;
|
URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
|
||||||
DWORD url_length = 0;
|
WCHAR *orig_url = NULL, *redirect_url = NULL, *combined_url = NULL;
|
||||||
LPWSTR orig_url;
|
DWORD url_length = 0, res;
|
||||||
LPWSTR combined_url;
|
BOOL b;
|
||||||
|
|
||||||
urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
|
|
||||||
urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
|
|
||||||
urlComponents.dwSchemeLength = 0;
|
|
||||||
urlComponents.lpszHostName = request->server->name;
|
|
||||||
urlComponents.dwHostNameLength = 0;
|
|
||||||
urlComponents.nPort = request->server->port;
|
|
||||||
urlComponents.lpszUserName = session->userName;
|
|
||||||
urlComponents.dwUserNameLength = 0;
|
|
||||||
urlComponents.lpszPassword = NULL;
|
|
||||||
urlComponents.dwPasswordLength = 0;
|
|
||||||
urlComponents.lpszUrlPath = request->path;
|
|
||||||
urlComponents.dwUrlPathLength = 0;
|
|
||||||
urlComponents.lpszExtraInfo = NULL;
|
|
||||||
urlComponents.dwExtraInfoLength = 0;
|
|
||||||
|
|
||||||
if (!InternetCreateUrlW(&urlComponents, 0, NULL, &url_length) &&
|
|
||||||
(GetLastError() != ERROR_INSUFFICIENT_BUFFER))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
orig_url = heap_alloc(url_length);
|
|
||||||
|
|
||||||
/* convert from bytes to characters */
|
|
||||||
url_length = url_length / sizeof(WCHAR) - 1;
|
|
||||||
if (!InternetCreateUrlW(&urlComponents, 0, orig_url, &url_length))
|
|
||||||
{
|
|
||||||
heap_free(orig_url);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
url_length = 0;
|
url_length = 0;
|
||||||
if (!InternetCombineUrlW(orig_url, lpszUrl, NULL, &url_length, ICU_ENCODE_SPACES_ONLY) &&
|
res = HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, redirect_url, &url_length, NULL);
|
||||||
(GetLastError() != ERROR_INSUFFICIENT_BUFFER))
|
if(res == ERROR_INSUFFICIENT_BUFFER) {
|
||||||
{
|
redirect_url = heap_alloc(url_length);
|
||||||
heap_free(orig_url);
|
res = HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, redirect_url, &url_length, NULL);
|
||||||
|
}
|
||||||
|
if(res != ERROR_SUCCESS) {
|
||||||
|
heap_free(redirect_url);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
combined_url = heap_alloc(url_length * sizeof(WCHAR));
|
|
||||||
|
|
||||||
if (!InternetCombineUrlW(orig_url, lpszUrl, combined_url, &url_length, ICU_ENCODE_SPACES_ONLY))
|
urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
|
||||||
{
|
urlComponents.lpszHostName = request->server->name;
|
||||||
heap_free(orig_url);
|
urlComponents.nPort = request->server->port;
|
||||||
heap_free(combined_url);
|
urlComponents.lpszUserName = session->userName;
|
||||||
return NULL;
|
urlComponents.lpszUrlPath = request->path;
|
||||||
|
|
||||||
|
b = InternetCreateUrlW(&urlComponents, 0, NULL, &url_length);
|
||||||
|
if(!b && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||||
|
orig_url = heap_alloc(url_length);
|
||||||
|
|
||||||
|
/* convert from bytes to characters */
|
||||||
|
url_length = url_length / sizeof(WCHAR) - 1;
|
||||||
|
b = InternetCreateUrlW(&urlComponents, 0, orig_url, &url_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(b) {
|
||||||
|
url_length = 0;
|
||||||
|
b = InternetCombineUrlW(orig_url, redirect_url, NULL, &url_length, ICU_ENCODE_SPACES_ONLY);
|
||||||
|
if(!b && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||||
|
combined_url = heap_alloc(url_length * sizeof(WCHAR));
|
||||||
|
b = InternetCombineUrlW(orig_url, redirect_url, combined_url, &url_length, ICU_ENCODE_SPACES_ONLY);
|
||||||
|
if(!b) {
|
||||||
|
heap_free(combined_url);
|
||||||
|
combined_url = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
heap_free(orig_url);
|
heap_free(orig_url);
|
||||||
|
heap_free(redirect_url);
|
||||||
return combined_url;
|
return combined_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4100,84 +4115,62 @@ static LPWSTR HTTP_GetRedirectURL(http_request_t *request, LPCWSTR lpszUrl)
|
||||||
static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
|
static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
|
||||||
{
|
{
|
||||||
http_session_t *session = request->session;
|
http_session_t *session = request->session;
|
||||||
WCHAR path[INTERNET_MAX_PATH_LENGTH];
|
WCHAR *path;
|
||||||
|
|
||||||
if(lpszUrl[0]=='/')
|
if(lpszUrl[0]=='/')
|
||||||
{
|
{
|
||||||
/* if it's an absolute path, keep the same session info */
|
/* if it's an absolute path, keep the same session info */
|
||||||
lstrcpynW(path, lpszUrl, INTERNET_MAX_URL_LENGTH);
|
path = heap_strdupW(lpszUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
URL_COMPONENTSW urlComponents;
|
URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
|
||||||
WCHAR protocol[INTERNET_MAX_SCHEME_LENGTH];
|
|
||||||
WCHAR hostName[INTERNET_MAX_HOST_NAME_LENGTH];
|
|
||||||
WCHAR userName[INTERNET_MAX_USER_NAME_LENGTH];
|
|
||||||
BOOL custom_port = FALSE;
|
BOOL custom_port = FALSE;
|
||||||
|
substr_t host;
|
||||||
|
|
||||||
static const WCHAR httpW[] = {'h','t','t','p',0};
|
urlComponents.dwHostNameLength = 1;
|
||||||
static const WCHAR httpsW[] = {'h','t','t','p','s',0};
|
urlComponents.dwUserNameLength = 1;
|
||||||
|
urlComponents.dwUrlPathLength = 1;
|
||||||
userName[0] = 0;
|
|
||||||
hostName[0] = 0;
|
|
||||||
protocol[0] = 0;
|
|
||||||
|
|
||||||
urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
|
|
||||||
urlComponents.lpszScheme = protocol;
|
|
||||||
urlComponents.dwSchemeLength = INTERNET_MAX_SCHEME_LENGTH;
|
|
||||||
urlComponents.lpszHostName = hostName;
|
|
||||||
urlComponents.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
|
|
||||||
urlComponents.lpszUserName = userName;
|
|
||||||
urlComponents.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH;
|
|
||||||
urlComponents.lpszPassword = NULL;
|
|
||||||
urlComponents.dwPasswordLength = 0;
|
|
||||||
urlComponents.lpszUrlPath = path;
|
|
||||||
urlComponents.dwUrlPathLength = INTERNET_MAX_PATH_LENGTH;
|
|
||||||
urlComponents.lpszExtraInfo = NULL;
|
|
||||||
urlComponents.dwExtraInfoLength = 0;
|
|
||||||
if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
|
if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
|
||||||
return INTERNET_GetLastError();
|
return INTERNET_GetLastError();
|
||||||
|
|
||||||
if(!strcmpiW(protocol, httpW)) {
|
if(urlComponents.nScheme == INTERNET_SCHEME_HTTP) {
|
||||||
if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
|
if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
|
||||||
TRACE("redirect from secure page to non-secure page\n");
|
TRACE("redirect from secure page to non-secure page\n");
|
||||||
/* FIXME: warn about from secure redirect to non-secure page */
|
/* FIXME: warn about from secure redirect to non-secure page */
|
||||||
request->hdr.dwFlags &= ~INTERNET_FLAG_SECURE;
|
request->hdr.dwFlags &= ~INTERNET_FLAG_SECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(urlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
|
custom_port = urlComponents.nPort != INTERNET_DEFAULT_HTTP_PORT;
|
||||||
urlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
|
}else if(urlComponents.nScheme == INTERNET_SCHEME_HTTPS) {
|
||||||
else if(urlComponents.nPort != INTERNET_DEFAULT_HTTP_PORT)
|
|
||||||
custom_port = TRUE;
|
|
||||||
}else if(!strcmpiW(protocol, httpsW)) {
|
|
||||||
if(!(request->hdr.dwFlags & INTERNET_FLAG_SECURE)) {
|
if(!(request->hdr.dwFlags & INTERNET_FLAG_SECURE)) {
|
||||||
TRACE("redirect from non-secure page to secure page\n");
|
TRACE("redirect from non-secure page to secure page\n");
|
||||||
/* FIXME: notify about redirect to secure page */
|
/* FIXME: notify about redirect to secure page */
|
||||||
request->hdr.dwFlags |= INTERNET_FLAG_SECURE;
|
request->hdr.dwFlags |= INTERNET_FLAG_SECURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(urlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
|
custom_port = urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT;
|
||||||
urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
|
|
||||||
else if(urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT)
|
|
||||||
custom_port = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_free(session->hostName);
|
heap_free(session->hostName);
|
||||||
|
|
||||||
session->hostName = heap_strdupW(hostName);
|
session->hostName = heap_strndupW(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
|
||||||
session->hostPort = urlComponents.nPort;
|
session->hostPort = urlComponents.nPort;
|
||||||
|
|
||||||
heap_free(session->userName);
|
heap_free(session->userName);
|
||||||
session->userName = NULL;
|
session->userName = NULL;
|
||||||
if (userName[0])
|
if (urlComponents.dwUserNameLength)
|
||||||
session->userName = heap_strdupW(userName);
|
session->userName = heap_strndupW(urlComponents.lpszUserName, urlComponents.dwUserNameLength);
|
||||||
|
|
||||||
reset_data_stream(request);
|
reset_data_stream(request);
|
||||||
|
|
||||||
if(strcmpiW(request->server->name, hostName) || request->server->port != urlComponents.nPort) {
|
host = substr(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
|
||||||
|
|
||||||
|
if(host.len != strlenW(request->server->name) || strncmpiW(request->server->name, host.str, host.len)
|
||||||
|
|| request->server->port != urlComponents.nPort) {
|
||||||
server_t *new_server;
|
server_t *new_server;
|
||||||
|
|
||||||
new_server = get_server(hostName, urlComponents.nPort, urlComponents.nScheme == INTERNET_SCHEME_HTTPS, TRUE);
|
new_server = get_server(host, urlComponents.nPort, urlComponents.nScheme == INTERNET_SCHEME_HTTPS, TRUE);
|
||||||
server_release(request->server);
|
server_release(request->server);
|
||||||
request->server = new_server;
|
request->server = new_server;
|
||||||
}
|
}
|
||||||
|
@ -4186,16 +4179,18 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
|
||||||
HTTP_ProcessHeader(request, hostW, request->server->host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
|
HTTP_ProcessHeader(request, hostW, request->server->host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
|
||||||
else
|
else
|
||||||
HTTP_ProcessHeader(request, hostW, request->server->name, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
|
HTTP_ProcessHeader(request, hostW, request->server->name, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
|
||||||
|
|
||||||
|
path = heap_strndupW(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
|
||||||
}
|
}
|
||||||
heap_free(request->path);
|
heap_free(request->path);
|
||||||
request->path=NULL;
|
request->path = NULL;
|
||||||
if (*path)
|
if (*path)
|
||||||
{
|
{
|
||||||
DWORD needed = 0;
|
DWORD needed = 0;
|
||||||
HRESULT rc;
|
HRESULT rc;
|
||||||
|
|
||||||
rc = UrlEscapeW(path, NULL, &needed, URL_ESCAPE_SPACES_ONLY);
|
rc = UrlEscapeW(path, NULL, &needed, URL_ESCAPE_SPACES_ONLY);
|
||||||
if (rc != E_POINTER)
|
if (rc == E_POINTER)
|
||||||
needed = strlenW(path)+1;
|
needed = strlenW(path)+1;
|
||||||
request->path = heap_alloc(needed*sizeof(WCHAR));
|
request->path = heap_alloc(needed*sizeof(WCHAR));
|
||||||
rc = UrlEscapeW(path, request->path, &needed,
|
rc = UrlEscapeW(path, request->path, &needed,
|
||||||
|
@ -4203,10 +4198,12 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
|
||||||
if (rc != S_OK)
|
if (rc != S_OK)
|
||||||
{
|
{
|
||||||
ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
|
ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
|
||||||
strcpyW(request->path,path);
|
strcpyW(request->path, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
heap_free(path);
|
||||||
|
|
||||||
/* Remove custom content-type/length headers on redirects. */
|
/* Remove custom content-type/length headers on redirects. */
|
||||||
remove_header(request, szContent_Type, TRUE);
|
remove_header(request, szContent_Type, TRUE);
|
||||||
remove_header(request, szContent_Length, TRUE);
|
remove_header(request, szContent_Length, TRUE);
|
||||||
|
@ -5097,14 +5094,15 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
|
||||||
|
|
||||||
if (!(request->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && responseLen)
|
if (!(request->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && responseLen)
|
||||||
{
|
{
|
||||||
WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH];
|
WCHAR *new_url;
|
||||||
dwBufferSize=sizeof(szNewLocation);
|
|
||||||
switch(request->status_code) {
|
switch(request->status_code) {
|
||||||
case HTTP_STATUS_REDIRECT:
|
case HTTP_STATUS_REDIRECT:
|
||||||
case HTTP_STATUS_MOVED:
|
case HTTP_STATUS_MOVED:
|
||||||
case HTTP_STATUS_REDIRECT_KEEP_VERB:
|
case HTTP_STATUS_REDIRECT_KEEP_VERB:
|
||||||
case HTTP_STATUS_REDIRECT_METHOD:
|
case HTTP_STATUS_REDIRECT_METHOD:
|
||||||
if(HTTP_HttpQueryInfoW(request,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL) != ERROR_SUCCESS)
|
new_url = get_redirect_url(request);
|
||||||
|
if(!new_url)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (strcmpW(request->verb, szGET) && strcmpW(request->verb, szHEAD) &&
|
if (strcmpW(request->verb, szGET) && strcmpW(request->verb, szHEAD) &&
|
||||||
|
@ -5114,17 +5112,13 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
|
||||||
request->verb = heap_strdupW(szGET);
|
request->verb = heap_strdupW(szGET);
|
||||||
}
|
}
|
||||||
http_release_netconn(request, drain_content(request, FALSE));
|
http_release_netconn(request, drain_content(request, FALSE));
|
||||||
if ((new_url = HTTP_GetRedirectURL( request, szNewLocation )))
|
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
|
||||||
{
|
new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
|
||||||
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
|
res = HTTP_HandleRedirect(request, new_url);
|
||||||
new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
|
heap_free(new_url);
|
||||||
res = HTTP_HandleRedirect(request, new_url);
|
if (res == ERROR_SUCCESS) {
|
||||||
if (res == ERROR_SUCCESS)
|
heap_free(requestString);
|
||||||
{
|
loop_next = TRUE;
|
||||||
heap_free(requestString);
|
|
||||||
loop_next = TRUE;
|
|
||||||
}
|
|
||||||
heap_free( new_url );
|
|
||||||
}
|
}
|
||||||
redirected = TRUE;
|
redirected = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -5267,7 +5261,6 @@ static void AsyncHttpSendRequestProc(task_header_t *hdr)
|
||||||
|
|
||||||
static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_PTR dwContext)
|
static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_PTR dwContext)
|
||||||
{
|
{
|
||||||
DWORD dwBufferSize;
|
|
||||||
INT responseLen;
|
INT responseLen;
|
||||||
DWORD res = ERROR_SUCCESS;
|
DWORD res = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -5304,9 +5297,10 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
|
||||||
case HTTP_STATUS_MOVED:
|
case HTTP_STATUS_MOVED:
|
||||||
case HTTP_STATUS_REDIRECT_METHOD:
|
case HTTP_STATUS_REDIRECT_METHOD:
|
||||||
case HTTP_STATUS_REDIRECT_KEEP_VERB: {
|
case HTTP_STATUS_REDIRECT_KEEP_VERB: {
|
||||||
WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH];
|
WCHAR *new_url;
|
||||||
dwBufferSize=sizeof(szNewLocation);
|
|
||||||
if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, szNewLocation, &dwBufferSize, NULL) != ERROR_SUCCESS)
|
new_url = get_redirect_url(request);
|
||||||
|
if(!new_url)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (strcmpW(request->verb, szGET) && strcmpW(request->verb, szHEAD) &&
|
if (strcmpW(request->verb, szGET) && strcmpW(request->verb, szHEAD) &&
|
||||||
|
@ -5316,15 +5310,12 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
|
||||||
request->verb = heap_strdupW(szGET);
|
request->verb = heap_strdupW(szGET);
|
||||||
}
|
}
|
||||||
http_release_netconn(request, drain_content(request, FALSE));
|
http_release_netconn(request, drain_content(request, FALSE));
|
||||||
if ((new_url = HTTP_GetRedirectURL( request, szNewLocation )))
|
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
|
||||||
{
|
new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
|
||||||
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
|
res = HTTP_HandleRedirect(request, new_url);
|
||||||
new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
|
heap_free(new_url);
|
||||||
res = HTTP_HandleRedirect(request, new_url);
|
if (res == ERROR_SUCCESS)
|
||||||
if (res == ERROR_SUCCESS)
|
res = HTTP_HttpSendRequestW(request, NULL, 0, NULL, 0, 0, TRUE);
|
||||||
res = HTTP_HttpSendRequestW(request, NULL, 0, NULL, 0, 0, TRUE);
|
|
||||||
heap_free( new_url );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -89,10 +89,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||||
|
|
||||||
extern HMODULE WININET_hModule DECLSPEC_HIDDEN;
|
extern HMODULE WININET_hModule DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#ifndef INET6_ADDRSTRLEN
|
|
||||||
#define INET6_ADDRSTRLEN 46
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
WCHAR *name;
|
WCHAR *name;
|
||||||
INTERNET_PORT port;
|
INTERNET_PORT port;
|
||||||
|
@ -227,6 +223,25 @@ static inline LPWSTR heap_strndupW(LPCWSTR str, UINT max_len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline WCHAR *heap_strndupAtoW(const char *str, int len_a, DWORD *len_w)
|
||||||
|
{
|
||||||
|
WCHAR *ret = NULL;
|
||||||
|
|
||||||
|
if(str) {
|
||||||
|
size_t len;
|
||||||
|
if(len_a < 0) len_a = strlen(str);
|
||||||
|
len = MultiByteToWideChar(CP_ACP, 0, str, len_a, NULL, 0);
|
||||||
|
ret = heap_alloc((len+1)*sizeof(WCHAR));
|
||||||
|
if(ret) {
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, str, len_a, ret, len);
|
||||||
|
ret[len] = 0;
|
||||||
|
*len_w = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static inline WCHAR *heap_strdupAtoW(const char *str)
|
static inline WCHAR *heap_strdupAtoW(const char *str)
|
||||||
{
|
{
|
||||||
LPWSTR ret = NULL;
|
LPWSTR ret = NULL;
|
||||||
|
@ -257,6 +272,22 @@ static inline char *heap_strdupWtoA(LPCWSTR str)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const WCHAR *str;
|
||||||
|
size_t len;
|
||||||
|
} substr_t;
|
||||||
|
|
||||||
|
static inline substr_t substr(const WCHAR *str, size_t len)
|
||||||
|
{
|
||||||
|
substr_t r = {str, len};
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline substr_t substrz(const WCHAR *str)
|
||||||
|
{
|
||||||
|
return substr(str, strlenW(str));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void WININET_find_data_WtoA(LPWIN32_FIND_DATAW dataW, LPWIN32_FIND_DATAA dataA)
|
static inline void WININET_find_data_WtoA(LPWIN32_FIND_DATAW dataW, LPWIN32_FIND_DATAA dataA)
|
||||||
{
|
{
|
||||||
dataA->dwFileAttributes = dataW->dwFileAttributes;
|
dataA->dwFileAttributes = dataW->dwFileAttributes;
|
||||||
|
@ -294,6 +325,7 @@ typedef struct
|
||||||
LONG ref;
|
LONG ref;
|
||||||
HANDLE file_handle;
|
HANDLE file_handle;
|
||||||
WCHAR *file_name;
|
WCHAR *file_name;
|
||||||
|
WCHAR *url;
|
||||||
BOOL is_committed;
|
BOOL is_committed;
|
||||||
} req_file_t;
|
} req_file_t;
|
||||||
|
|
||||||
|
@ -461,7 +493,7 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
|
||||||
BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) DECLSPEC_HIDDEN;
|
BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) 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;
|
DWORD set_cookie(substr_t,substr_t,substr_t,substr_t,DWORD) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
|
void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
|
||||||
DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN;
|
DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN;
|
||||||
|
@ -475,7 +507,7 @@ VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
|
||||||
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
|
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
|
||||||
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
|
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
|
||||||
DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
|
DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
|
||||||
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen) DECLSPEC_HIDDEN;
|
WCHAR *INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN;
|
DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN;
|
||||||
void free_netconn(netconn_t*) DECLSPEC_HIDDEN;
|
void free_netconn(netconn_t*) DECLSPEC_HIDDEN;
|
||||||
|
@ -492,7 +524,7 @@ DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC
|
||||||
int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
|
int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
|
||||||
int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
|
int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL) DECLSPEC_HIDDEN;
|
server_t *get_server(substr_t,INTERNET_PORT,BOOL,BOOL) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
DWORD create_req_file(const WCHAR*,req_file_t**) DECLSPEC_HIDDEN;
|
DWORD create_req_file(const WCHAR*,req_file_t**) DECLSPEC_HIDDEN;
|
||||||
void req_file_release(req_file_t*) DECLSPEC_HIDDEN;
|
void req_file_release(req_file_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -389,6 +389,7 @@ void free_netconn(netconn_t *netconn)
|
||||||
DeleteSecurityContext(&netconn->ssl_ctx);
|
DeleteSecurityContext(&netconn->ssl_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close_netconn(netconn);
|
||||||
heap_free(netconn);
|
heap_free(netconn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2109,7 +2109,7 @@ static BOOL urlcache_entry_get_file(const char *url, void *entry_info, DWORD *si
|
||||||
|
|
||||||
if (!urlcache_find_hash_entry(header, url, &hash_entry)) {
|
if (!urlcache_find_hash_entry(header, url, &hash_entry)) {
|
||||||
cache_container_unlock_index(container, header);
|
cache_container_unlock_index(container, header);
|
||||||
TRACE("entry %s not found!\n", url);
|
TRACE("entry %s not found!\n", debugstr_a(url));
|
||||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
||||||
--- e:\wine\dlls\wininet/http.c 2015-07-14 15:44:36.040192300 +0100
|
--- e:\wine\dlls\wininet/http.c 2016-05-31 18:02:43 +0100
|
||||||
+++ e:\reactos\dll\win32\wininet/http.c 2015-07-20 14:37:24.319646400 +0100
|
+++ e:\reactos\dll\win32\wininet/http.c 2016-07-02 16:18:16 +0100
|
||||||
@@ -143,6 +118,7 @@ static const WCHAR emptyW[] = {0};
|
@@ -118,6 +118,7 @@ static const WCHAR emptyW[] = {0};
|
||||||
|
|
||||||
#define COLLECT_TIME 60000
|
#define COLLECT_TIME 60000
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
||||||
#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
|
#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
|
||||||
|
|
||||||
struct HttpAuthInfo
|
struct HttpAuthInfo
|
||||||
@@ -229,7 +205,13 @@ void server_release(server_t *server)
|
@@ -203,7 +204,13 @@ void server_release(server_t *server)
|
||||||
if(InterlockedDecrement(&server->ref))
|
if(InterlockedDecrement(&server->ref))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
||||||
|
|
||||||
if(server->cert_chain)
|
if(server->cert_chain)
|
||||||
CertFreeCertificateChain(server->cert_chain);
|
CertFreeCertificateChain(server->cert_chain);
|
||||||
@@ -311,7 +293,11 @@ BOOL collect_connections(collect_type_t
|
@@ -286,7 +293,11 @@ BOOL collect_connections(collect_type_t
|
||||||
BOOL remaining = FALSE;
|
BOOL remaining = FALSE;
|
||||||
DWORD64 now;
|
DWORD64 now;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(server, server_safe, &connection_pool, server_t, entry) {
|
LIST_FOR_EACH_ENTRY_SAFE(server, server_safe, &connection_pool, server_t, entry) {
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(netconn, netconn_safe, &server->conn_pool, netconn_t, pool_entry) {
|
LIST_FOR_EACH_ENTRY_SAFE(netconn, netconn_safe, &server->conn_pool, netconn_t, pool_entry) {
|
||||||
@@ -1973,13 +1959,14 @@ static void http_release_netconn(http_re
|
@@ -1923,13 +1934,14 @@ static void http_release_netconn(http_re
|
||||||
if(!is_valid_netconn(req->netconn))
|
if(!is_valid_netconn(req->netconn))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
||||||
req->netconn = NULL;
|
req->netconn = NULL;
|
||||||
|
|
||||||
run_collector = !collector_running;
|
run_collector = !collector_running;
|
||||||
@@ -2007,6 +1994,10 @@ static void http_release_netconn(http_re
|
@@ -1957,6 +1969,10 @@ static void http_release_netconn(http_re
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +63,9 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
||||||
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext,
|
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext,
|
||||||
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
|
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
|
||||||
diff -pudN e:\wine\dlls\wininet/internet.c e:\reactos\dll\win32\wininet/internet.c
|
diff -pudN e:\wine\dlls\wininet/internet.c e:\reactos\dll\win32\wininet/internet.c
|
||||||
--- e:\wine\dlls\wininet/internet.c 2015-04-12 18:21:54.309796800 +0100
|
--- e:\wine\dlls\wininet/internet.c 2016-05-31 18:05:36 +0100
|
||||||
+++ e:\reactos\dll\win32\wininet/internet.c 2015-07-20 14:38:19.188784800 +0100
|
+++ e:\reactos\dll\win32\wininet/internet.c 2016-07-02 16:18:16 +0100
|
||||||
@@ -1033,6 +996,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR l
|
@@ -963,6 +963,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR l
|
||||||
{
|
{
|
||||||
appinfo_t *lpwai = NULL;
|
appinfo_t *lpwai = NULL;
|
||||||
|
|
||||||
|
@ -77,9 +77,9 @@ diff -pudN e:\wine\dlls\wininet/internet.c e:\reactos\dll\win32\wininet/internet
|
||||||
static const wininet_flag_info access_type[] = {
|
static const wininet_flag_info access_type[] = {
|
||||||
|
|
||||||
diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache.c
|
diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache.c
|
||||||
--- e:\wine\dlls\wininet/urlcache.c 2015-07-14 15:44:36.059193400 +0100
|
--- e:\wine\dlls\wininet/urlcache.c 2016-05-31 18:02:43 +0100
|
||||||
+++ e:\reactos\dll\win32\wininet/urlcache.c 2015-07-20 14:40:55.736738800 +0100
|
+++ e:\reactos\dll\win32\wininet/urlcache.c 2016-07-02 16:18:16 +0100
|
||||||
@@ -202,6 +179,8 @@ typedef struct
|
@@ -179,6 +179,8 @@ typedef struct
|
||||||
|
|
||||||
/* List of all containers available */
|
/* List of all containers available */
|
||||||
static struct list UrlContainers = LIST_INIT(UrlContainers);
|
static struct list UrlContainers = LIST_INIT(UrlContainers);
|
||||||
|
@ -88,7 +88,7 @@ diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache
|
||||||
|
|
||||||
static inline char *heap_strdupWtoUTF8(LPCWSTR str)
|
static inline char *heap_strdupWtoUTF8(LPCWSTR str)
|
||||||
{
|
{
|
||||||
@@ -752,6 +731,8 @@ static void cache_containers_init(void)
|
@@ -729,6 +731,8 @@ static void cache_containers_init(void)
|
||||||
static const WCHAR UrlSuffix[] = {'C','o','n','t','e','n','t','.','I','E','5',0};
|
static const WCHAR UrlSuffix[] = {'C','o','n','t','e','n','t','.','I','E','5',0};
|
||||||
static const WCHAR HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',0};
|
static const WCHAR HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',0};
|
||||||
static const WCHAR CookieSuffix[] = {0};
|
static const WCHAR CookieSuffix[] = {0};
|
||||||
|
@ -97,21 +97,21 @@ diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
int nFolder; /* CSIDL_* constant */
|
int nFolder; /* CSIDL_* constant */
|
||||||
@@ -766,6 +747,13 @@ static void cache_containers_init(void)
|
@@ -743,6 +747,13 @@ static void cache_containers_init(void)
|
||||||
};
|
};
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
+ /* ReactOS r50916 */
|
+ /* ReactOS r50916 */
|
||||||
+ if (GetEnvironmentVariableW(UserProfile, NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
+ if (GetEnvironmentVariableW(UserProfile, NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||||
+ {
|
+ {
|
||||||
+ TRACE("Environment variable 'USERPROFILE' does not exist!\n");
|
+ ERR("Environment variable 'USERPROFILE' does not exist!\n");
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
for (i = 0; i < sizeof(DefaultContainerData) / sizeof(DefaultContainerData[0]); i++)
|
for (i = 0; i < sizeof(DefaultContainerData) / sizeof(DefaultContainerData[0]); i++)
|
||||||
{
|
{
|
||||||
WCHAR wszCachePath[MAX_PATH];
|
WCHAR wszCachePath[MAX_PATH];
|
||||||
@@ -816,6 +804,10 @@ static void cache_containers_init(void)
|
@@ -793,6 +804,10 @@ static void cache_containers_init(void)
|
||||||
cache_containers_add(DefaultContainerData[i].cache_prefix, wszCachePath,
|
cache_containers_add(DefaultContainerData[i].cache_prefix, wszCachePath,
|
||||||
DefaultContainerData[i].default_entry_type, wszMutexName);
|
DefaultContainerData[i].default_entry_type, wszMutexName);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_containers_free(void)
|
static void cache_containers_free(void)
|
||||||
@@ -835,6 +827,12 @@ static DWORD cache_containers_find(const
|
@@ -812,6 +827,12 @@ static DWORD cache_containers_find(const
|
||||||
if(!url)
|
if(!url)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache
|
||||||
LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
|
LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
|
||||||
{
|
{
|
||||||
int prefix_len = strlen(container->cache_prefix);
|
int prefix_len = strlen(container->cache_prefix);
|
||||||
@@ -861,6 +859,12 @@ static BOOL cache_containers_enum(char *
|
@@ -838,6 +859,12 @@ static BOOL cache_containers_enum(char *
|
||||||
if (search_pattern && index > 0)
|
if (search_pattern && index > 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache
|
||||||
LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
|
LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
|
||||||
{
|
{
|
||||||
if (search_pattern)
|
if (search_pattern)
|
||||||
@@ -4018,7 +4022,9 @@ BOOL init_urlcache(void)
|
@@ -3995,7 +4022,9 @@ BOOL init_urlcache(void)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.9.4
|
||||||
reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.9.4
|
reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.9.4
|
||||||
reactos/dll/win32/wing32 # Synced to WineStaging-1.9.4
|
reactos/dll/win32/wing32 # Synced to WineStaging-1.9.4
|
||||||
reactos/dll/win32/winhttp # Synced to WineStaging-1.9.4
|
reactos/dll/win32/winhttp # Synced to WineStaging-1.9.4
|
||||||
reactos/dll/win32/wininet # Synced to WineStaging-1.9.4
|
reactos/dll/win32/wininet # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/winmm # Forked at Wine-20050628
|
reactos/dll/win32/winmm # Forked at Wine-20050628
|
||||||
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628
|
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628
|
||||||
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
||||||
|
|
Loading…
Reference in a new issue