mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +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 <lmcons.h>
|
||||
|
||||
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
|
||||
|
||||
/* FIXME
|
||||
|
@ -46,7 +48,8 @@ typedef struct _cookie_t {
|
|||
typedef struct _cookie_container_t {
|
||||
struct list entry;
|
||||
|
||||
WCHAR *path;
|
||||
WCHAR *cookie_url;
|
||||
substr_t path;
|
||||
struct _cookie_domain_t *domain;
|
||||
|
||||
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 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;
|
||||
struct list *current_list = &domain_list;
|
||||
|
||||
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;
|
||||
|
||||
current_domain = NULL;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -101,7 +105,7 @@ static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
|
|||
if(!current_domain)
|
||||
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) {
|
||||
heap_free(current_domain);
|
||||
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);
|
||||
}
|
||||
|
||||
if(ptr == domain)
|
||||
if(ptr == domain.str)
|
||||
return 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_container_t *cookie_container, *iter;
|
||||
size_t path_len, len;
|
||||
|
||||
cookie_domain = get_cookie_domain(domain, create);
|
||||
if(!cookie_domain)
|
||||
return NULL;
|
||||
|
||||
path_len = strlenW(path);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cookie_container, &cookie_domain->path_list, cookie_container_t, entry) {
|
||||
len = strlenW(cookie_container->path);
|
||||
if(len < path_len)
|
||||
if(cookie_container->path.len < path.len)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -152,8 +189,8 @@ static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR
|
|||
if(!cookie_container)
|
||||
return NULL;
|
||||
|
||||
cookie_container->path = heap_strdupW(path);
|
||||
if(!cookie_container->path) {
|
||||
cookie_container->cookie_url = create_cookie_url(substrz(cookie_domain->domain), path, &cookie_container->path);
|
||||
if(!cookie_container->cookie_url) {
|
||||
heap_free(cookie_container);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -161,9 +198,8 @@ static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR
|
|||
cookie_container->domain = cookie_domain;
|
||||
list_init(&cookie_container->cookie_list);
|
||||
|
||||
|
||||
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);
|
||||
return cookie_container;
|
||||
}
|
||||
|
@ -182,7 +218,7 @@ static void delete_cookie(cookie_t *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;
|
||||
|
||||
|
@ -195,9 +231,9 @@ static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME exp
|
|||
new_cookie->flags = flags;
|
||||
list_init(&new_cookie->entry);
|
||||
|
||||
new_cookie->name = heap_strdupW(name);
|
||||
new_cookie->data = heap_strdupW(data);
|
||||
if((name && !new_cookie->name) || (data && !new_cookie->data)) {
|
||||
new_cookie->name = heap_strndupW(name.str, name.len);
|
||||
new_cookie->data = heap_strndupW(data.str, data.len);
|
||||
if(!new_cookie->name || !new_cookie->data) {
|
||||
delete_cookie(new_cookie);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -205,12 +241,12 @@ static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME exp
|
|||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
TRACE("Adding %s=%s to %s %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
|
||||
debugstr_w(container->domain->domain), debugstr_w(container->path));
|
||||
TRACE("Adding %s=%s to %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
|
||||
debugstr_w(container->cookie_url));
|
||||
|
||||
list_add_tail(&container->cookie_list, &new_cookie->entry);
|
||||
new_cookie->container = container;
|
||||
|
@ -230,86 +266,41 @@ static void replace_cookie(cookie_container_t *container, cookie_t *new_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)
|
||||
delete_cookie(old_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 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)
|
||||
static BOOL load_persistent_cookie(substr_t domain, substr_t path)
|
||||
{
|
||||
INTERNET_CACHE_ENTRY_INFOW *info;
|
||||
cookie_container_t *cookie_container;
|
||||
cookie_t *new_cookie;
|
||||
WCHAR cookie_url[MAX_PATH];
|
||||
HANDLE cookie;
|
||||
char *str = NULL, *pbeg, *pend;
|
||||
DWORD size, flags;
|
||||
WCHAR *name, *data;
|
||||
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;
|
||||
|
||||
size = 0;
|
||||
RetrieveUrlCacheEntryStreamW(cookie_url, NULL, &size, FALSE, 0);
|
||||
RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, NULL, &size, FALSE, 0);
|
||||
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||
return TRUE;
|
||||
info = heap_alloc(size);
|
||||
if(!info)
|
||||
return FALSE;
|
||||
cookie = RetrieveUrlCacheEntryStreamW(cookie_url, info, &size, FALSE, 0);
|
||||
cookie = RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, info, &size, FALSE, 0);
|
||||
size = info->dwSizeLow;
|
||||
heap_free(info);
|
||||
if(!cookie)
|
||||
|
@ -323,12 +314,6 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
|
|||
str[size] = 0;
|
||||
UnlockUrlCacheEntryStream(cookie, 0);
|
||||
|
||||
cookie_container = get_cookie_container(domain, path, TRUE);
|
||||
if(!cookie_container) {
|
||||
heap_free(str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GetSystemTimeAsFileTime(&time);
|
||||
for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
|
||||
pend = strchr(pbeg, '\n');
|
||||
|
@ -362,7 +347,7 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
|
|||
break;
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
|
@ -386,16 +371,14 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
|||
{
|
||||
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;
|
||||
cookie_t *cookie_container = NULL, *cookie_iter;
|
||||
BOOL do_save = FALSE;
|
||||
char buf[64], *dyn_buf;
|
||||
FILETIME time;
|
||||
DWORD bytes_written;
|
||||
|
||||
if (!create_cookie_url(container->domain->domain, container->path, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
|
||||
return FALSE;
|
||||
size_t len;
|
||||
|
||||
/* check if there's anything to save */
|
||||
GetSystemTimeAsFileTime(&time);
|
||||
|
@ -412,13 +395,15 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!do_save) {
|
||||
DeleteUrlCacheEntryW(cookie_url);
|
||||
DeleteUrlCacheEntryW(container->cookie_url);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(!CreateUrlCacheEntryW(cookie_url, 0, txtW, cookie_file, 0))
|
||||
if(!CreateUrlCacheEntryW(container->cookie_url, 0, txtW, cookie_file, 0))
|
||||
return FALSE;
|
||||
|
||||
cookie_handle = CreateFileW(cookie_file, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if(cookie_handle == INVALID_HANDLE_VALUE) {
|
||||
DeleteFileW(cookie_file);
|
||||
|
@ -462,7 +447,12 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
|||
}
|
||||
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)) {
|
||||
heap_free(dyn_buf);
|
||||
do_save = FALSE;
|
||||
|
@ -487,47 +477,26 @@ static BOOL save_persistent_cookie(cookie_container_t *container)
|
|||
}
|
||||
|
||||
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;
|
||||
UrlComponents.lpszPassword = NULL;
|
||||
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;
|
||||
comp.dwHostNameLength = 1;
|
||||
comp.dwUrlPathLength = 1;
|
||||
|
||||
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 */
|
||||
if (UrlComponents.dwUrlPathLength)
|
||||
{
|
||||
if (path[UrlComponents.dwUrlPathLength - 1] != '/')
|
||||
{
|
||||
WCHAR *ptr;
|
||||
if ((ptr = strrchrW(path, '/'))) *(++ptr) = 0;
|
||||
else
|
||||
{
|
||||
path[0] = '/';
|
||||
path[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pathLen >= 2)
|
||||
{
|
||||
path[0] = '/';
|
||||
path[1] = 0;
|
||||
}
|
||||
while(comp.dwUrlPathLength && comp.lpszUrlPath[comp.dwUrlPathLength-1] != '/')
|
||||
comp.dwUrlPathLength--;
|
||||
|
||||
*host = substr(comp.lpszHostName, comp.dwHostNameLength);
|
||||
*path = comp.dwUrlPathLength ? substr(comp.lpszUrlPath, comp.dwUrlPathLength) : substr(rootW, 1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -539,45 +508,38 @@ typedef struct {
|
|||
unsigned string_len;
|
||||
} 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 };
|
||||
|
||||
WCHAR *ptr, subpath[INTERNET_MAX_PATH_LENGTH];
|
||||
const WCHAR *p;
|
||||
cookie_domain_t *domain;
|
||||
cookie_container_t *container;
|
||||
unsigned len;
|
||||
FILETIME tm;
|
||||
|
||||
GetSystemTimeAsFileTime(&tm);
|
||||
|
||||
len = strlenW(host);
|
||||
p = host+len;
|
||||
while(p>host && p[-1]!='.') p--;
|
||||
while(p != host) {
|
||||
p = host.str + host.len;
|
||||
while(p > host.str && p[-1] != '.') p--;
|
||||
while(p != host.str) {
|
||||
p--;
|
||||
while(p>host && p[-1]!='.') p--;
|
||||
if(p == host) break;
|
||||
while(p > host.str && p[-1] != '.') p--;
|
||||
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);
|
||||
assert(len+1 < INTERNET_MAX_PATH_LENGTH);
|
||||
memcpy(subpath, path, (len+1)*sizeof(WCHAR));
|
||||
ptr = subpath+len;
|
||||
p = path.str + path.len;
|
||||
do {
|
||||
*ptr = 0;
|
||||
load_persistent_cookie(host, subpath);
|
||||
load_persistent_cookie(host, substr(path.str, p-path.str));
|
||||
|
||||
ptr--;
|
||||
while(ptr>subpath && ptr[-1]!='/') ptr--;
|
||||
}while(ptr != subpath);
|
||||
p--;
|
||||
while(p > path.str && p[-1] != '/') p--;
|
||||
}while(p != path.str);
|
||||
|
||||
domain = get_cookie_domain(host, FALSE);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
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))
|
||||
continue;
|
||||
|
@ -672,7 +634,7 @@ DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
|
|||
|
||||
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) {
|
||||
LeaveCriticalSection(&cookie_cs);
|
||||
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,
|
||||
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};
|
||||
substr_t host, path;
|
||||
DWORD res;
|
||||
BOOL ret;
|
||||
|
||||
|
@ -738,9 +700,8 @@ BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
host[0] = 0;
|
||||
ret = COOKIE_crackUrlSimple(lpszUrl, host, sizeof(host)/sizeof(host[0]), path, sizeof(path)/sizeof(path[0]));
|
||||
if (!ret || !host[0]) {
|
||||
ret = cookie_parse_url(lpszUrl, &host, &path);
|
||||
if (!ret) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -768,7 +729,7 @@ BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
|||
lpCookieData[cookie_set.string_len] = 0;
|
||||
}
|
||||
}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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* IsDomainLegalCookieDomainW (WININET.@)
|
||||
*/
|
||||
BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
|
||||
static BOOL is_domain_legal_for_cookie(substr_t domain, substr_t full_domain)
|
||||
{
|
||||
DWORD s1_len, s2_len;
|
||||
const WCHAR *ptr;
|
||||
|
||||
FIXME("(%s, %s) semi-stub\n", debugstr_w(s1), debugstr_w(s2));
|
||||
|
||||
if (!s1 || !s2)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0])
|
||||
{
|
||||
if(!domain.len || *domain.str == '.' || !full_domain.len || *full_domain.str == '.') {
|
||||
SetLastError(ERROR_INVALID_NAME);
|
||||
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;
|
||||
|
||||
s1_len = strlenW(s1);
|
||||
s2_len = strlenW(s2);
|
||||
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]!='.'))
|
||||
{
|
||||
ptr = full_domain.str + full_domain.len - domain.len;
|
||||
if (strncmpiW(domain.str, ptr, domain.len) || (full_domain.len > domain.len && ptr[-1] != '.')) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -896,129 +842,130 @@ BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
|
|||
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_t *thisCookie;
|
||||
LPWSTR data, value;
|
||||
WCHAR *ptr;
|
||||
substr_t value;
|
||||
const WCHAR *end_ptr;
|
||||
FILETIME expiry, create;
|
||||
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);
|
||||
|
||||
value = data = heap_strdupW(cookie_data);
|
||||
if (!data)
|
||||
{
|
||||
ERR("could not allocate the cookie data buffer\n");
|
||||
return COOKIE_STATE_UNKNOWN;
|
||||
}
|
||||
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);
|
||||
|
||||
memset(&expiry,0,sizeof(expiry));
|
||||
GetSystemTimeAsFileTime(&create);
|
||||
|
||||
/* lots of information can be parsed out of the cookie value */
|
||||
|
||||
ptr = data;
|
||||
for (;;)
|
||||
{
|
||||
static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0};
|
||||
static const WCHAR szPath[] = {'p','a','t','h','=',0};
|
||||
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(!(end_ptr = memchrW(data.str, ';', data.len)))
|
||||
end_ptr = data.str + data.len;
|
||||
value = substr(data.str, end_ptr-data.str);
|
||||
data.str += value.len;
|
||||
data.len -= value.len;
|
||||
|
||||
if (!(ptr = strchrW(ptr,';'))) break;
|
||||
*ptr++ = 0;
|
||||
for(;;) {
|
||||
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);
|
||||
value = heap_alloc((ptr - data) * sizeof(WCHAR));
|
||||
if (value == NULL)
|
||||
{
|
||||
heap_free(data);
|
||||
ERR("could not allocate the cookie value buffer\n");
|
||||
return COOKIE_STATE_UNKNOWN;
|
||||
}
|
||||
strcpyW(value, data);
|
||||
/* Skip ';' */
|
||||
if(data.len)
|
||||
substr_skip(&data, 1);
|
||||
|
||||
while (*ptr == ' ') ptr++; /* whitespace */
|
||||
while(data.len && *data.str == ' ')
|
||||
substr_skip(&data, 1);
|
||||
|
||||
if (strncmpiW(ptr, szDomain, 7) == 0)
|
||||
{
|
||||
WCHAR *end_ptr;
|
||||
if(!data.len)
|
||||
break;
|
||||
|
||||
ptr += sizeof(szDomain)/sizeof(szDomain[0])-1;
|
||||
if(*ptr == '.')
|
||||
ptr++;
|
||||
end_ptr = strchrW(ptr, ';');
|
||||
if(end_ptr)
|
||||
*end_ptr = 0;
|
||||
if(!(end_ptr = memchrW(data.str, ';', data.len)))
|
||||
end_ptr = data.str + data.len;
|
||||
|
||||
if(!IsDomainLegalCookieDomainW(ptr, domain))
|
||||
{
|
||||
if(value != data)
|
||||
heap_free(value);
|
||||
heap_free(data);
|
||||
if(data.len >= (len = sizeof(szDomain)/sizeof(WCHAR)) && !strncmpiW(data.str, szDomain, len)) {
|
||||
substr_skip(&data, len);
|
||||
|
||||
if(data.len && *data.str == '.')
|
||||
substr_skip(&data, 1);
|
||||
|
||||
if(!is_domain_legal_for_cookie(substr(data.str, end_ptr-data.str), domain))
|
||||
return COOKIE_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
if(end_ptr)
|
||||
*end_ptr = ';';
|
||||
|
||||
domain = ptr;
|
||||
TRACE("Parsing new domain %s\n",debugstr_w(domain));
|
||||
}
|
||||
else if (strncmpiW(ptr, szPath, 5) == 0)
|
||||
{
|
||||
ptr+=strlenW(szPath);
|
||||
path = ptr;
|
||||
TRACE("Parsing new path %s\n",debugstr_w(path));
|
||||
}
|
||||
else if (strncmpiW(ptr, szExpires, 8) == 0)
|
||||
{
|
||||
domain = substr(data.str, end_ptr-data.str);
|
||||
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)) {
|
||||
substr_skip(&data, len);
|
||||
path = substr(data.str, end_ptr - data.str);
|
||||
TRACE("Parsing new path %s\n", debugstr_wn(path.str, path.len));
|
||||
}else if(data.len >= (len = sizeof(szExpires)/sizeof(WCHAR)) && !strncmpiW(data.str, szExpires, len)) {
|
||||
SYSTEMTIME st;
|
||||
ptr+=strlenW(szExpires);
|
||||
if (InternetTimeToSystemTimeW(ptr, &st, 0))
|
||||
{
|
||||
SystemTimeToFileTime(&st, &expiry);
|
||||
WCHAR buf[128];
|
||||
|
||||
if (CompareFileTime(&create,&expiry) > 0)
|
||||
{
|
||||
TRACE("Cookie already expired.\n");
|
||||
expired = TRUE;
|
||||
substr_skip(&data, len);
|
||||
|
||||
if(end_ptr - data.str < sizeof(buf)/sizeof(WCHAR)-1) {
|
||||
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 (strncmpiW(ptr, szSecure, 6) == 0)
|
||||
{
|
||||
FIXME("secure not handled (%s)\n",debugstr_w(ptr));
|
||||
ptr += strlenW(szSecure);
|
||||
}
|
||||
else if (strncmpiW(ptr, szHttpOnly, 8) == 0)
|
||||
{
|
||||
}else if(data.len >= (len = sizeof(szSecure)/sizeof(WCHAR)) && !strncmpiW(data.str, szSecure, len)) {
|
||||
substr_skip(&data, len);
|
||||
FIXME("secure not handled\n");
|
||||
}else if(data.len >= (len = sizeof(szHttpOnly)/sizeof(WCHAR)) && !strncmpiW(data.str, szHttpOnly, len)) {
|
||||
substr_skip(&data, len);
|
||||
|
||||
if(!(flags & INTERNET_COOKIE_HTTPONLY)) {
|
||||
WARN("HTTP only cookie added without INTERNET_COOKIE_HTTPONLY flag\n");
|
||||
heap_free(data);
|
||||
if (value != data) heap_free(value);
|
||||
SetLastError(ERROR_INVALID_OPERATION);
|
||||
return COOKIE_STATE_REJECT;
|
||||
}
|
||||
|
||||
cookie_flags |= INTERNET_COOKIE_HTTPONLY;
|
||||
ptr += strlenW(szHttpOnly);
|
||||
}
|
||||
else if (strncmpiW(ptr, szVersion, 8) == 0)
|
||||
{
|
||||
FIXME("version not handled (%s)\n",debugstr_w(ptr));
|
||||
ptr += strlenW(szVersion);
|
||||
}
|
||||
else if (*ptr)
|
||||
{
|
||||
FIXME("Unknown additional option %s\n",debugstr_w(ptr));
|
||||
}else if(data.len >= (len = sizeof(szVersion)/sizeof(WCHAR)) && !strncmpiW(data.str, szVersion, len)) {
|
||||
substr_skip(&data, len);
|
||||
|
||||
FIXME("version not handled (%s)\n",debugstr_wn(data.str, data.len));
|
||||
}else if(data.len) {
|
||||
FIXME("Unknown additional option %s\n", debugstr_wn(data.str, data.len));
|
||||
break;
|
||||
}
|
||||
|
||||
substr_skip(&data, end_ptr - data.str);
|
||||
}
|
||||
|
||||
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);
|
||||
if(!container) {
|
||||
heap_free(data);
|
||||
if (value != data) heap_free(value);
|
||||
LeaveCriticalSection(&cookie_cs);
|
||||
return COOKIE_STATE_ACCEPT;
|
||||
}
|
||||
|
@ -1038,13 +983,10 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
|
|||
else
|
||||
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)) {
|
||||
WARN("An attempt to override httponly cookie\n");
|
||||
SetLastError(ERROR_INVALID_OPERATION);
|
||||
heap_free(data);
|
||||
if (value != data) heap_free(value);
|
||||
return COOKIE_STATE_REJECT;
|
||||
}
|
||||
|
||||
|
@ -1053,24 +995,21 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
|
|||
delete_cookie(thisCookie);
|
||||
}
|
||||
|
||||
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
|
||||
debugstr_w(value), debugstr_w(container->domain->domain),debugstr_w(container->path));
|
||||
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_wn(name.str, name.len),
|
||||
debugstr_wn(value.str, value.len), debugstr_w(container->domain->domain),
|
||||
debugstr_wn(container->path.str, container->path.len));
|
||||
|
||||
if (!expired) {
|
||||
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) {
|
||||
heap_free(data);
|
||||
if (value != data) heap_free(value);
|
||||
LeaveCriticalSection(&cookie_cs);
|
||||
return COOKIE_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
add_cookie(container, new_cookie);
|
||||
}
|
||||
heap_free(data);
|
||||
if (value != data) heap_free(value);
|
||||
|
||||
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,
|
||||
LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
|
||||
{
|
||||
substr_t host, path, name, data;
|
||||
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),
|
||||
debugstr_w(lpCookieData), flags, reserved);
|
||||
|
@ -1104,34 +1043,26 @@ DWORD WINAPI InternetSetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
|
|||
return COOKIE_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
hostName[0] = 0;
|
||||
ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
|
||||
if (!ret || !hostName[0]) return COOKIE_STATE_UNKNOWN;
|
||||
ret = cookie_parse_url(lpszUrl, &host, &path);
|
||||
if (!ret || !host.len) return COOKIE_STATE_UNKNOWN;
|
||||
|
||||
if (!lpszCookieName)
|
||||
{
|
||||
WCHAR *cookie, *data;
|
||||
DWORD res;
|
||||
|
||||
cookie = heap_strdupW(lpCookieData);
|
||||
if (!cookie)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return COOKIE_STATE_UNKNOWN;
|
||||
}
|
||||
if (!lpszCookieName) {
|
||||
const WCHAR *ptr;
|
||||
|
||||
/* 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].
|
||||
*/
|
||||
if (!(data = strchrW(cookie, '='))) data = cookie + strlenW(cookie);
|
||||
else *data++ = 0;
|
||||
if (!(ptr = strchrW(lpCookieData, '=')))
|
||||
ptr = lpCookieData + strlenW(lpCookieData);
|
||||
|
||||
res = set_cookie(hostName, path, cookie, data, flags);
|
||||
|
||||
heap_free(cookie);
|
||||
return res;
|
||||
name = substr(lpCookieData, ptr - lpCookieData);
|
||||
data = substrz(*ptr == '=' ? ptr+1 : ptr);
|
||||
}else {
|
||||
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 LPWSTR HTTP_build_req( LPCWSTR *list, int len );
|
||||
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 BOOL drain_content(http_request_t*,BOOL);
|
||||
|
||||
|
@ -247,7 +246,7 @@ static BOOL process_host_port(server_t *server)
|
|||
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;
|
||||
|
||||
|
@ -257,7 +256,8 @@ server_t *get_server(const WCHAR *name, INTERNET_PORT port, BOOL is_https, BOOL
|
|||
EnterCriticalSection(&connection_pool_cs);
|
||||
|
||||
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_addref(server);
|
||||
break;
|
||||
|
@ -271,7 +271,7 @@ server_t *get_server(const WCHAR *name, INTERNET_PORT port, BOOL is_https, BOOL
|
|||
server->port = port;
|
||||
server->is_https = is_https;
|
||||
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)) {
|
||||
list_add_head(&connection_pool, &server->entry);
|
||||
}else {
|
||||
|
@ -767,7 +767,7 @@ static void HTTP_ProcessCookies( http_request_t *request )
|
|||
while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1)
|
||||
{
|
||||
const WCHAR *data;
|
||||
WCHAR *name;
|
||||
substr_t name;
|
||||
|
||||
setCookieHeader = &request->custHeaders[HeaderIndex];
|
||||
|
||||
|
@ -778,13 +778,9 @@ static void HTTP_ProcessCookies( http_request_t *request )
|
|||
if(!data)
|
||||
continue;
|
||||
|
||||
name = heap_strndupW(setCookieHeader->lpszValue, data-setCookieHeader->lpszValue);
|
||||
if(!name)
|
||||
continue;
|
||||
|
||||
name = substr(setCookieHeader->lpszValue, data - setCookieHeader->lpszValue);
|
||||
data++;
|
||||
set_cookie(request->server->name, path, name, data, INTERNET_COOKIE_HTTPONLY);
|
||||
heap_free(name);
|
||||
set_cookie(substrz(request->server->name), substrz(path), name, substrz(data), INTERNET_COOKIE_HTTPONLY);
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
|
@ -1371,21 +1367,17 @@ BOOL WINAPI HttpAddRequestHeadersW(HINTERNET hHttpRequest,
|
|||
BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
||||
LPCSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
|
||||
{
|
||||
DWORD len;
|
||||
LPWSTR hdr;
|
||||
WCHAR *headers = NULL;
|
||||
BOOL r;
|
||||
|
||||
TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_an(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier);
|
||||
|
||||
len = MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, NULL, 0 );
|
||||
hdr = heap_alloc(len*sizeof(WCHAR));
|
||||
MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, hdr, len );
|
||||
if( dwHeaderLength != ~0U )
|
||||
dwHeaderLength = len;
|
||||
if(lpszHeader)
|
||||
headers = heap_strndupAtoW(lpszHeader, dwHeaderLength, &dwHeaderLength);
|
||||
|
||||
r = HttpAddRequestHeadersW( hHttpRequest, hdr, dwHeaderLength, dwModifier );
|
||||
r = HttpAddRequestHeadersW(hHttpRequest, headers, dwHeaderLength, dwModifier);
|
||||
|
||||
heap_free( hdr );
|
||||
heap_free(headers);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1717,55 +1709,47 @@ static WCHAR *build_proxy_path_url(http_request_t *req)
|
|||
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 };
|
||||
BOOL ret = FALSE;
|
||||
const WCHAR *dot, *ptr;
|
||||
int len;
|
||||
|
||||
if (!strcmpiW( domain, localW ) && !strchrW( server, '.' ))
|
||||
ret = TRUE;
|
||||
else if (*domain == '*')
|
||||
{
|
||||
if (domain[1] == '.')
|
||||
{
|
||||
LPCWSTR dot;
|
||||
if(domain.len == sizeof(localW)/sizeof(WCHAR)-1 && !strncmpiW(domain.str, localW, domain.len) && !strchrW(server, '.' ))
|
||||
return TRUE;
|
||||
|
||||
/* For a hostname to match a wildcard, the last domain must match
|
||||
* the wildcard exactly. E.g. if the wildcard is *.a.b, and the
|
||||
* hostname is www.foo.a.b, it matches, but a.b does not.
|
||||
*/
|
||||
dot = strchrW( server, '.' );
|
||||
if (dot)
|
||||
{
|
||||
int len = strlenW( dot + 1 );
|
||||
if(domain.len && *domain.str != '*')
|
||||
return domain.len == strlenW(server) && !strncmpiW(server, domain.str, domain.len);
|
||||
|
||||
if (len > strlenW( domain + 2 ))
|
||||
{
|
||||
LPCWSTR ptr;
|
||||
if(domain.len < 2 || domain.str[1] != '.')
|
||||
return FALSE;
|
||||
|
||||
/* The server's domain is longer than the wildcard, so it
|
||||
* could be a subdomain. Compare the last portion of the
|
||||
* server's domain.
|
||||
*/
|
||||
ptr = dot + len + 1 - strlenW( domain + 2 );
|
||||
if (!strcmpiW( ptr, domain + 2 ))
|
||||
{
|
||||
/* This is only a match if the preceding character is
|
||||
* a '.', i.e. that it is a matching domain. E.g.
|
||||
* if domain is '*.b.c' and server is 'www.ab.c' they
|
||||
* do not match.
|
||||
*/
|
||||
ret = *(ptr - 1) == '.';
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = !strcmpiW( dot + 1, domain + 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = !strcmpiW( server, domain );
|
||||
return ret;
|
||||
/* For a hostname to match a wildcard, the last domain must match
|
||||
* the wildcard exactly. E.g. if the wildcard is *.a.b, and the
|
||||
* hostname is www.foo.a.b, it matches, but a.b does not.
|
||||
*/
|
||||
dot = strchrW(server, '.');
|
||||
if(!dot)
|
||||
return FALSE;
|
||||
|
||||
len = strlenW(dot + 1);
|
||||
if(len <= domain.len - 2)
|
||||
return FALSE;
|
||||
|
||||
/* The server's domain is longer than the wildcard, so it
|
||||
* could be a subdomain. Compare the last portion of the
|
||||
* server's domain.
|
||||
*/
|
||||
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.
|
||||
* if domain is '*.b.c' and server is 'www.ab.c' they
|
||||
* do not match.
|
||||
*/
|
||||
return *(ptr - 1) == '.';
|
||||
|
||||
return len == domain.len-2 && !strncmpiW(dot + 1, domain.str + 2, len);
|
||||
}
|
||||
|
||||
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;
|
||||
ptr = lpwai->proxyBypass;
|
||||
do {
|
||||
while(1) {
|
||||
LPCWSTR tmp = ptr;
|
||||
|
||||
ptr = strchrW( ptr, ';' );
|
||||
if (!ptr)
|
||||
ptr = strchrW( tmp, ' ' );
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr - tmp < INTERNET_MAX_HOST_NAME_LENGTH)
|
||||
{
|
||||
WCHAR domain[INTERNET_MAX_HOST_NAME_LENGTH];
|
||||
|
||||
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);
|
||||
if (!ptr)
|
||||
ptr = tmp + strlenW(ptr);
|
||||
ret = HTTP_DomainMatches( server, substr(tmp, ptr-tmp) );
|
||||
if (ret || !*ptr)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
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 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 };
|
||||
URL_COMPONENTSW UrlComponents;
|
||||
server_t *new_server;
|
||||
BOOL is_https;
|
||||
URL_COMPONENTSW UrlComponents = { sizeof(UrlComponents) };
|
||||
server_t *new_server = NULL;
|
||||
WCHAR *proxy;
|
||||
|
||||
memset( &UrlComponents, 0, sizeof UrlComponents );
|
||||
UrlComponents.dwStructSize = sizeof UrlComponents;
|
||||
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 )
|
||||
proxy = INTERNET_FindProxyForProtocol(hIC->proxy, protoHttp);
|
||||
if(!proxy)
|
||||
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 )
|
||||
request->path = szNul;
|
||||
UrlComponents.dwHostNameLength = 1;
|
||||
if(InternetCrackUrlW(proxy, 0, 0, &UrlComponents) && UrlComponents.dwHostNameLength) {
|
||||
if( !request->path )
|
||||
request->path = szNul;
|
||||
|
||||
is_https = (UrlComponents.nScheme == INTERNET_SCHEME_HTTPS);
|
||||
if (is_https && UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
|
||||
UrlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
|
||||
|
||||
new_server = get_server(UrlComponents.lpszHostName, UrlComponents.nPort, is_https, TRUE);
|
||||
new_server = get_server(substr(UrlComponents.lpszHostName, UrlComponents.dwHostNameLength),
|
||||
UrlComponents.nPort, UrlComponents.nScheme == INTERNET_SCHEME_HTTPS, TRUE);
|
||||
}
|
||||
heap_free(proxy);
|
||||
if(!new_server)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1876,33 +1845,39 @@ static DWORD HTTP_ResolveName(http_request_t *request)
|
|||
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 https[] = { 'h','t','t','p','s',':','/','/',0 };
|
||||
static const WCHAR slash[] = { '/',0 };
|
||||
LPHTTPHEADERW host_header;
|
||||
const WCHAR *host;
|
||||
LPCWSTR scheme;
|
||||
const WCHAR *host, *scheme;
|
||||
WCHAR *buf, *ptr;
|
||||
size_t len;
|
||||
|
||||
EnterCriticalSection( &req->headers_section );
|
||||
host = req->server->canon_host_port;
|
||||
|
||||
host_header = HTTP_GetHeader(req, hostW);
|
||||
if (host_header) host = host_header->lpszValue;
|
||||
else host = req->server->canon_host_port;
|
||||
|
||||
if (req->hdr.dwFlags & INTERNET_FLAG_SECURE)
|
||||
if (req->server->is_https)
|
||||
scheme = https;
|
||||
else
|
||||
scheme = http;
|
||||
strcpyW(buf, scheme);
|
||||
strcatW(buf, host);
|
||||
if (req->path[0] != '/')
|
||||
strcatW(buf, slash);
|
||||
strcatW(buf, req->path);
|
||||
|
||||
LeaveCriticalSection( &req->headers_section );
|
||||
return TRUE;
|
||||
len = strlenW(scheme) + strlenW(host) + (req->path[0] != '/' ? 1 : 0) + strlenW(req->path);
|
||||
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;
|
||||
|
||||
case INTERNET_OPTION_URL: {
|
||||
static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0};
|
||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR *url;
|
||||
DWORD res;
|
||||
|
||||
TRACE("INTERNET_OPTION_URL\n");
|
||||
|
||||
strcpyW(url, httpW);
|
||||
strcatW(url, req->server->canon_host_port);
|
||||
strcatW(url, req->path);
|
||||
url = compose_request_url(req);
|
||||
if(!url)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url));
|
||||
return str_to_buffer(url, buffer, size, unicode);
|
||||
res = str_to_buffer(url, buffer, size, unicode);
|
||||
heap_free(url);
|
||||
return res;
|
||||
}
|
||||
case INTERNET_OPTION_USER_AGENT:
|
||||
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: {
|
||||
INTERNET_CACHE_ENTRY_INFOW *info;
|
||||
INTERNET_CACHE_TIMESTAMPS *ts = buffer;
|
||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
||||
DWORD nbytes, error;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("INTERNET_OPTION_CACHE_TIMESTAMPS\n");
|
||||
|
||||
if(!req->req_file)
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
|
||||
if (*size < sizeof(*ts))
|
||||
{
|
||||
*size = sizeof(*ts);
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
nbytes = 0;
|
||||
HTTP_GetRequestURL(req, url);
|
||||
ret = GetUrlCacheEntryInfoW(url, NULL, &nbytes);
|
||||
ret = GetUrlCacheEntryInfoW(req->req_file->url, NULL, &nbytes);
|
||||
error = GetLastError();
|
||||
if (!ret && error == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
if (!(info = heap_alloc(nbytes)))
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
GetUrlCacheEntryInfoW(url, info, &nbytes);
|
||||
GetUrlCacheEntryInfoW(req->req_file->url, info, &nbytes);
|
||||
|
||||
ts->ftExpires = info->ExpireTime;
|
||||
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)
|
||||
{
|
||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR *header;
|
||||
DWORD header_len;
|
||||
BOOL res;
|
||||
|
||||
TRACE("%p\n", req);
|
||||
|
||||
CloseHandle(req->hCacheFile);
|
||||
req->hCacheFile = NULL;
|
||||
|
||||
if(HTTP_GetRequestURL(req, url)) {
|
||||
WCHAR *header;
|
||||
DWORD header_len;
|
||||
BOOL res;
|
||||
|
||||
header = build_response_header(req, TRUE);
|
||||
header_len = (header ? strlenW(header) : 0);
|
||||
res = CommitUrlCacheEntryW(url, req->req_file->file_name, req->expires,
|
||||
req->last_modified, NORMAL_CACHE_ENTRY,
|
||||
header, header_len, NULL, 0);
|
||||
if(res)
|
||||
req->req_file->is_committed = TRUE;
|
||||
else
|
||||
WARN("CommitUrlCacheEntry failed: %u\n", GetLastError());
|
||||
heap_free(header);
|
||||
}
|
||||
header = build_response_header(req, TRUE);
|
||||
header_len = (header ? strlenW(header) : 0);
|
||||
res = CommitUrlCacheEntryW(req->req_file->url, req->req_file->file_name, req->expires,
|
||||
req->last_modified, NORMAL_CACHE_ENTRY,
|
||||
header, header_len, NULL, 0);
|
||||
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)
|
||||
|
@ -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_storeW[] = {'n','o','-','s','t','o','r','e',0};
|
||||
|
||||
WCHAR url[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR file_name[MAX_PATH+1];
|
||||
WCHAR *url;
|
||||
BOOL b = TRUE;
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
b = HTTP_GetRequestURL(req, url);
|
||||
if(!b) {
|
||||
url = compose_request_url(req);
|
||||
if(!url) {
|
||||
WARN("Could not get URL\n");
|
||||
return;
|
||||
}
|
||||
|
@ -2476,6 +2450,7 @@ static void create_cache_entry(http_request_t *req)
|
|||
}
|
||||
|
||||
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,
|
||||
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) */
|
||||
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;
|
||||
blocking_mode_t blocking_mode;
|
||||
|
@ -3090,7 +3065,7 @@ static BOOL drain_content(http_request_t *req, BOOL blocking)
|
|||
DWORD bytes_read, res;
|
||||
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) {
|
||||
ret = FALSE;
|
||||
break;
|
||||
|
@ -3105,23 +3080,6 @@ static BOOL drain_content(http_request_t *req, BOOL blocking)
|
|||
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 {
|
||||
task_header_t hdr;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
DWORD res, read, cread, error = ERROR_SUCCESS;
|
||||
|
||||
TRACE("(%p %p %u %x)\n", req, buf, size, flags);
|
||||
|
||||
if (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);
|
||||
|
||||
if (hdr->dwFlags & INTERNET_FLAG_ASYNC)
|
||||
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))
|
||||
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 );
|
||||
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->buf = buf;
|
||||
task->size = size;
|
||||
task->ret_read = ret_read;
|
||||
task->ret_read = (flags & IRF_NO_WAIT) ? NULL : ret_read;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
|
@ -3238,6 +3210,49 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
|
|||
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 {
|
||||
task_header_t hdr;
|
||||
DWORD *ret_size;
|
||||
|
@ -3335,7 +3350,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
|
|||
{
|
||||
appinfo_t *hIC = session->appInfo;
|
||||
http_request_t *request;
|
||||
DWORD len;
|
||||
DWORD port, len;
|
||||
|
||||
TRACE("-->\n");
|
||||
|
||||
|
@ -3364,7 +3379,14 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
|
|||
request->session = session;
|
||||
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) {
|
||||
WININET_Release(&request->hdr);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
@ -4032,64 +4054,57 @@ BOOL WINAPI HttpQueryInfoA(HINTERNET hHttpRequest, DWORD dwInfoLevel,
|
|||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* HTTP_GetRedirectURL (internal)
|
||||
*/
|
||||
static LPWSTR HTTP_GetRedirectURL(http_request_t *request, LPCWSTR lpszUrl)
|
||||
static WCHAR *get_redirect_url(http_request_t *request)
|
||||
{
|
||||
static WCHAR szHttp[] = {'h','t','t','p',0};
|
||||
static WCHAR szHttps[] = {'h','t','t','p','s',0};
|
||||
http_session_t *session = request->session;
|
||||
URL_COMPONENTSW urlComponents;
|
||||
DWORD url_length = 0;
|
||||
LPWSTR orig_url;
|
||||
LPWSTR combined_url;
|
||||
|
||||
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_COMPONENTSW urlComponents = { sizeof(urlComponents) };
|
||||
WCHAR *orig_url = NULL, *redirect_url = NULL, *combined_url = NULL;
|
||||
DWORD url_length = 0, res;
|
||||
BOOL b;
|
||||
|
||||
url_length = 0;
|
||||
if (!InternetCombineUrlW(orig_url, lpszUrl, NULL, &url_length, ICU_ENCODE_SPACES_ONLY) &&
|
||||
(GetLastError() != ERROR_INSUFFICIENT_BUFFER))
|
||||
{
|
||||
heap_free(orig_url);
|
||||
res = HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, redirect_url, &url_length, NULL);
|
||||
if(res == ERROR_INSUFFICIENT_BUFFER) {
|
||||
redirect_url = heap_alloc(url_length);
|
||||
res = HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, redirect_url, &url_length, NULL);
|
||||
}
|
||||
if(res != ERROR_SUCCESS) {
|
||||
heap_free(redirect_url);
|
||||
return NULL;
|
||||
}
|
||||
combined_url = heap_alloc(url_length * sizeof(WCHAR));
|
||||
|
||||
if (!InternetCombineUrlW(orig_url, lpszUrl, combined_url, &url_length, ICU_ENCODE_SPACES_ONLY))
|
||||
{
|
||||
heap_free(orig_url);
|
||||
heap_free(combined_url);
|
||||
return NULL;
|
||||
urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
|
||||
urlComponents.lpszHostName = request->server->name;
|
||||
urlComponents.nPort = request->server->port;
|
||||
urlComponents.lpszUserName = session->userName;
|
||||
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(redirect_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)
|
||||
{
|
||||
http_session_t *session = request->session;
|
||||
WCHAR path[INTERNET_MAX_PATH_LENGTH];
|
||||
WCHAR *path;
|
||||
|
||||
if(lpszUrl[0]=='/')
|
||||
{
|
||||
/* if it's an absolute path, keep the same session info */
|
||||
lstrcpynW(path, lpszUrl, INTERNET_MAX_URL_LENGTH);
|
||||
path = heap_strdupW(lpszUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
URL_COMPONENTSW urlComponents;
|
||||
WCHAR protocol[INTERNET_MAX_SCHEME_LENGTH];
|
||||
WCHAR hostName[INTERNET_MAX_HOST_NAME_LENGTH];
|
||||
WCHAR userName[INTERNET_MAX_USER_NAME_LENGTH];
|
||||
URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
|
||||
BOOL custom_port = FALSE;
|
||||
substr_t host;
|
||||
|
||||
static const WCHAR httpW[] = {'h','t','t','p',0};
|
||||
static const WCHAR httpsW[] = {'h','t','t','p','s',0};
|
||||
|
||||
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;
|
||||
urlComponents.dwHostNameLength = 1;
|
||||
urlComponents.dwUserNameLength = 1;
|
||||
urlComponents.dwUrlPathLength = 1;
|
||||
if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents))
|
||||
return INTERNET_GetLastError();
|
||||
|
||||
if(!strcmpiW(protocol, httpW)) {
|
||||
if(urlComponents.nScheme == INTERNET_SCHEME_HTTP) {
|
||||
if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
|
||||
TRACE("redirect from secure page to non-secure page\n");
|
||||
/* FIXME: warn about from secure redirect to non-secure page */
|
||||
request->hdr.dwFlags &= ~INTERNET_FLAG_SECURE;
|
||||
}
|
||||
|
||||
if(urlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
|
||||
urlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
|
||||
else if(urlComponents.nPort != INTERNET_DEFAULT_HTTP_PORT)
|
||||
custom_port = TRUE;
|
||||
}else if(!strcmpiW(protocol, httpsW)) {
|
||||
custom_port = urlComponents.nPort != INTERNET_DEFAULT_HTTP_PORT;
|
||||
}else if(urlComponents.nScheme == INTERNET_SCHEME_HTTPS) {
|
||||
if(!(request->hdr.dwFlags & INTERNET_FLAG_SECURE)) {
|
||||
TRACE("redirect from non-secure page to secure page\n");
|
||||
/* FIXME: notify about redirect to secure page */
|
||||
request->hdr.dwFlags |= INTERNET_FLAG_SECURE;
|
||||
}
|
||||
|
||||
if(urlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
|
||||
urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
|
||||
else if(urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT)
|
||||
custom_port = TRUE;
|
||||
custom_port = urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT;
|
||||
}
|
||||
|
||||
heap_free(session->hostName);
|
||||
|
||||
session->hostName = heap_strdupW(hostName);
|
||||
session->hostName = heap_strndupW(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
|
||||
session->hostPort = urlComponents.nPort;
|
||||
|
||||
heap_free(session->userName);
|
||||
session->userName = NULL;
|
||||
if (userName[0])
|
||||
session->userName = heap_strdupW(userName);
|
||||
if (urlComponents.dwUserNameLength)
|
||||
session->userName = heap_strndupW(urlComponents.lpszUserName, urlComponents.dwUserNameLength);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
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);
|
||||
else
|
||||
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);
|
||||
request->path=NULL;
|
||||
request->path = NULL;
|
||||
if (*path)
|
||||
{
|
||||
DWORD needed = 0;
|
||||
HRESULT rc;
|
||||
|
||||
rc = UrlEscapeW(path, NULL, &needed, URL_ESCAPE_SPACES_ONLY);
|
||||
if (rc != E_POINTER)
|
||||
if (rc == E_POINTER)
|
||||
needed = strlenW(path)+1;
|
||||
request->path = heap_alloc(needed*sizeof(WCHAR));
|
||||
rc = UrlEscapeW(path, request->path, &needed,
|
||||
|
@ -4203,10 +4198,12 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
|
|||
if (rc != S_OK)
|
||||
{
|
||||
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_header(request, szContent_Type, 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)
|
||||
{
|
||||
WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH];
|
||||
dwBufferSize=sizeof(szNewLocation);
|
||||
WCHAR *new_url;
|
||||
|
||||
switch(request->status_code) {
|
||||
case HTTP_STATUS_REDIRECT:
|
||||
case HTTP_STATUS_MOVED:
|
||||
case HTTP_STATUS_REDIRECT_KEEP_VERB:
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
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));
|
||||
res = HTTP_HandleRedirect(request, new_url);
|
||||
if (res == ERROR_SUCCESS)
|
||||
{
|
||||
heap_free(requestString);
|
||||
loop_next = TRUE;
|
||||
}
|
||||
heap_free( new_url );
|
||||
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
|
||||
new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
|
||||
res = HTTP_HandleRedirect(request, new_url);
|
||||
heap_free(new_url);
|
||||
if (res == ERROR_SUCCESS) {
|
||||
heap_free(requestString);
|
||||
loop_next = 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)
|
||||
{
|
||||
DWORD dwBufferSize;
|
||||
INT responseLen;
|
||||
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_REDIRECT_METHOD:
|
||||
case HTTP_STATUS_REDIRECT_KEEP_VERB: {
|
||||
WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH];
|
||||
dwBufferSize=sizeof(szNewLocation);
|
||||
if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, szNewLocation, &dwBufferSize, NULL) != ERROR_SUCCESS)
|
||||
WCHAR *new_url;
|
||||
|
||||
new_url = get_redirect_url(request);
|
||||
if(!new_url)
|
||||
break;
|
||||
|
||||
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);
|
||||
}
|
||||
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));
|
||||
res = HTTP_HandleRedirect(request, new_url);
|
||||
if (res == ERROR_SUCCESS)
|
||||
res = HTTP_HttpSendRequestW(request, NULL, 0, NULL, 0, 0, TRUE);
|
||||
heap_free( new_url );
|
||||
}
|
||||
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_REDIRECT,
|
||||
new_url, (strlenW(new_url) + 1) * sizeof(WCHAR));
|
||||
res = HTTP_HandleRedirect(request, new_url);
|
||||
heap_free(new_url);
|
||||
if (res == ERROR_SUCCESS)
|
||||
res = HTTP_HttpSendRequestW(request, NULL, 0, NULL, 0, 0, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
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;
|
||||
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
#define INET6_ADDRSTRLEN 46
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
WCHAR *name;
|
||||
INTERNET_PORT port;
|
||||
|
@ -227,6 +223,25 @@ static inline LPWSTR heap_strndupW(LPCWSTR str, UINT max_len)
|
|||
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)
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
|
@ -257,6 +272,22 @@ static inline char *heap_strdupWtoA(LPCWSTR str)
|
|||
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)
|
||||
{
|
||||
dataA->dwFileAttributes = dataW->dwFileAttributes;
|
||||
|
@ -294,6 +325,7 @@ typedef struct
|
|||
LONG ref;
|
||||
HANDLE file_handle;
|
||||
WCHAR *file_name;
|
||||
WCHAR *url;
|
||||
BOOL is_committed;
|
||||
} req_file_t;
|
||||
|
||||
|
@ -461,7 +493,7 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
|
|||
BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) 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;
|
||||
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,
|
||||
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
|
||||
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;
|
||||
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_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;
|
||||
void req_file_release(req_file_t*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -389,6 +389,7 @@ void free_netconn(netconn_t *netconn)
|
|||
DeleteSecurityContext(&netconn->ssl_ctx);
|
||||
}
|
||||
|
||||
close_netconn(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)) {
|
||||
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);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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:\reactos\dll\win32\wininet/http.c 2015-07-20 14:37:24.319646400 +0100
|
||||
@@ -143,6 +118,7 @@ static const WCHAR emptyW[] = {0};
|
||||
--- e:\wine\dlls\wininet/http.c 2016-05-31 18:02:43 +0100
|
||||
+++ e:\reactos\dll\win32\wininet/http.c 2016-07-02 16:18:16 +0100
|
||||
@@ -118,6 +118,7 @@ static const WCHAR emptyW[] = {0};
|
||||
|
||||
#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]))
|
||||
|
||||
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))
|
||||
return;
|
||||
|
||||
|
@ -23,7 +23,7 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
|||
|
||||
if(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;
|
||||
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(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))
|
||||
return;
|
||||
|
||||
|
@ -51,7 +51,7 @@ diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
|
|||
req->netconn = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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_STATUS_CLOSING_CONNECTION, 0, 0);
|
||||
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:\reactos\dll\win32\wininet/internet.c 2015-07-20 14:38:19.188784800 +0100
|
||||
@@ -1033,6 +996,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR l
|
||||
--- e:\wine\dlls\wininet/internet.c 2016-05-31 18:05:36 +0100
|
||||
+++ e:\reactos\dll\win32\wininet/internet.c 2016-07-02 16:18:16 +0100
|
||||
@@ -963,6 +963,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR l
|
||||
{
|
||||
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[] = {
|
||||
|
||||
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:\reactos\dll\win32\wininet/urlcache.c 2015-07-20 14:40:55.736738800 +0100
|
||||
@@ -202,6 +179,8 @@ typedef struct
|
||||
--- e:\wine\dlls\wininet/urlcache.c 2016-05-31 18:02:43 +0100
|
||||
+++ e:\reactos\dll\win32\wininet/urlcache.c 2016-07-02 16:18:16 +0100
|
||||
@@ -179,6 +179,8 @@ typedef struct
|
||||
|
||||
/* List of all containers available */
|
||||
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)
|
||||
{
|
||||
@@ -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 HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',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
|
||||
{
|
||||
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;
|
||||
|
||||
+ /* ReactOS r50916 */
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < sizeof(DefaultContainerData) / sizeof(DefaultContainerData[0]); i++)
|
||||
{
|
||||
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,
|
||||
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)
|
||||
@@ -835,6 +827,12 @@ static DWORD cache_containers_find(const
|
||||
@@ -812,6 +827,12 @@ static DWORD cache_containers_find(const
|
||||
if(!url)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (search_pattern)
|
||||
@@ -4018,7 +4022,9 @@ BOOL init_urlcache(void)
|
||||
@@ -3995,7 +4022,9 @@ BOOL init_urlcache(void)
|
||||
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/wing32 # 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/midimap # Forked at Wine-20050628
|
||||
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
||||
|
|
Loading…
Reference in a new issue