X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=dll%2Fwin32%2Fwinhttp%2Fcookie.c;h=b4b25304f7f733fda16fc8697f7072fd61bfc6db;hp=661cc7945c72b9157b95ea12e3bc891f5ffd165e;hb=8317165d650291d2ee8c9fdc79bcbecb12a6266b;hpb=840ea98cba988d0fbe5904305d4783aab57e791f diff --git a/dll/win32/winhttp/cookie.c b/dll/win32/winhttp/cookie.c index 661cc7945c7..b4b25304f7f 100644 --- a/dll/win32/winhttp/cookie.c +++ b/dll/win32/winhttp/cookie.c @@ -16,19 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H +#include "config.h" +#include -#include -//#include +#include "wine/debug.h" +#include "wine/list.h" -#include -//#include "wine/list.h" - -//#include "windef.h" -#include -#include +#include "windef.h" +#include "winbase.h" +#include "winhttp.h" #include "winhttp_private.h" @@ -58,7 +54,7 @@ static cookie_t *find_cookie( domain_t *domain, const WCHAR *path, const WCHAR * LIST_FOR_EACH( item, &domain->cookies ) { cookie = LIST_ENTRY( item, cookie_t, entry ); - if (!strcmpW( cookie->path, path ) && !strcmpiW( cookie->name, name )) + if (!strcmpW( cookie->path, path ) && !strcmpW( cookie->name, name )) { TRACE("found %s=%s\n", debugstr_w(cookie->name), debugstr_w(cookie->value)); return cookie; @@ -125,7 +121,7 @@ static BOOL add_cookie( session_t *session, cookie_t *cookie, WCHAR *domain_name else if ((old_cookie = find_cookie( domain, path, cookie->name ))) delete_cookie( old_cookie ); cookie->path = strdupW( path ); - list_add_tail( &domain->cookies, &cookie->entry ); + list_add_head( &domain->cookies, &cookie->entry ); TRACE("domain %s path %s <- %s=%s\n", debugstr_w(domain_name), debugstr_w(cookie->path), debugstr_w(cookie->name), debugstr_w(cookie->value)); @@ -138,21 +134,14 @@ static cookie_t *parse_cookie( const WCHAR *string ) const WCHAR *p; int len; - if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL; + if (!(p = strchrW( string, '=' ))) p = string + strlenW( string ); + len = p - string; + while (len && string[len - 1] == ' ') len--; + if (!len) return NULL; + if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL; list_init( &cookie->entry ); - if (!(p = strchrW( string, '=' ))) - { - WARN("no '=' in %s\n", debugstr_w(string)); - return NULL; - } - if (p == string) - { - WARN("empty cookie name in %s\n", debugstr_w(string)); - return NULL; - } - len = p - string; if (!(cookie->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) { heap_free( cookie ); @@ -161,32 +150,96 @@ static cookie_t *parse_cookie( const WCHAR *string ) memcpy( cookie->name, string, len * sizeof(WCHAR) ); cookie->name[len] = 0; - p++; /* skip '=' */ + if (*p++ == '=') + { + while (*p == ' ') p++; + len = strlenW( p ); + while (len && p[len - 1] == ' ') len--; + + if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + free_cookie( cookie ); + return NULL; + } + memcpy( cookie->value, p, len * sizeof(WCHAR) ); + cookie->value[len] = 0; + } + return cookie; +} + +struct attr +{ + WCHAR *name; + WCHAR *value; +}; + +static void free_attr( struct attr *attr ) +{ + if (!attr) return; + heap_free( attr->name ); + heap_free( attr->value ); + heap_free( attr ); +} + +static struct attr *parse_attr( const WCHAR *str, int *used ) +{ + const WCHAR *p = str, *q; + struct attr *attr; + int len; + while (*p == ' ') p++; + q = p; + while (*q && *q != ' ' && *q != '=' && *q != ';') q++; + len = q - p; + if (!len) return NULL; - len = strlenW( p ); - if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + if (!(attr = heap_alloc( sizeof(struct attr) ))) return NULL; + if (!(attr->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) { - free_cookie( cookie ); + heap_free( attr ); return NULL; } - memcpy( cookie->value, p, len * sizeof(WCHAR) ); - cookie->value[len] = 0; + memcpy( attr->name, p, len * sizeof(WCHAR) ); + attr->name[len] = 0; + attr->value = NULL; - return cookie; + p = q; + while (*p == ' ') p++; + if (*p++ == '=') + { + while (*p == ' ') p++; + q = p; + while (*q && *q != ';') q++; + len = q - p; + while (len && p[len - 1] == ' ') len--; + + if (!(attr->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + free_attr( attr ); + return NULL; + } + memcpy( attr->value, p, len * sizeof(WCHAR) ); + attr->value[len] = 0; + } + + while (*q == ' ') q++; + if (*q == ';') q++; + *used = q - str; + + return attr; } BOOL set_cookies( request_t *request, const WCHAR *cookies ) { static const WCHAR pathW[] = {'p','a','t','h',0}; static const WCHAR domainW[] = {'d','o','m','a','i','n',0}; - BOOL ret = FALSE; - WCHAR *buffer, *p, *q, *r; + WCHAR *buffer, *p; WCHAR *cookie_domain = NULL, *cookie_path = NULL; + struct attr *attr, *domain = NULL, *path = NULL; session_t *session = request->connect->session; cookie_t *cookie; - int len; + int len, used; len = strlenW( cookies ); if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE; @@ -200,32 +253,26 @@ BOOL set_cookies( request_t *request, const WCHAR *cookies ) heap_free( buffer ); return FALSE; } - if ((q = strstrW( p, domainW ))) /* FIXME: do real attribute parsing */ - { - while (*q && *q != '=') q++; - if (!*q) goto end; - - r = ++q; - while (*r && *r != ';') r++; - len = r - q; - - if (!(cookie_domain = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end; - memcpy( cookie_domain, q, len * sizeof(WCHAR) ); - cookie_domain[len] = 0; - - } - if ((q = strstrW( p, pathW ))) + len = strlenW( p ); + while (len && (attr = parse_attr( p, &used ))) { - while (*q && *q != '=') q++; - if (!*q) goto end; - - r = ++q; - while (*r && *r != ';') r++; - len = r - q; - - if (!(cookie_path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end; - memcpy( cookie_path, q, len * sizeof(WCHAR) ); - cookie_path[len] = 0; + if (!strcmpiW( attr->name, domainW )) + { + domain = attr; + cookie_domain = attr->value; + } + else if (!strcmpiW( attr->name, pathW )) + { + path = attr; + cookie_path = attr->value; + } + else + { + FIXME( "unhandled attribute %s\n", debugstr_w(attr->name) ); + free_attr( attr ); + } + len -= used; + p += used; } if (!cookie_domain && !(cookie_domain = strdupW( request->connect->servername ))) goto end; if (!cookie_path && !(cookie_path = strdupW( request->path ))) goto end; @@ -235,8 +282,10 @@ BOOL set_cookies( request_t *request, const WCHAR *cookies ) end: if (!ret) free_cookie( cookie ); - heap_free( cookie_domain ); - heap_free( cookie_path ); + if (domain) free_attr( domain ); + else heap_free( cookie_domain ); + if (path) free_attr( path ); + else heap_free( cookie_path ); heap_free( buffer ); return ret; } @@ -262,17 +311,25 @@ BOOL add_cookie_headers( request_t *request ) if (strstrW( request->path, cookie->path ) == request->path) { - const WCHAR format[] = {'C','o','o','k','i','e',':',' ','%','s','=','%','s',0}; - int len; + const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '}; + int len, len_cookie = sizeof(cookieW) / sizeof(cookieW[0]), len_name = strlenW( cookie->name ); WCHAR *header; - len = strlenW( cookie->name ) + strlenW( format ) + strlenW( cookie->value ); + len = len_cookie + len_name; + if (cookie->value) len += strlenW( cookie->value ) + 1; if (!(header = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE; - sprintfW( header, format, cookie->name, cookie->value ); + memcpy( header, cookieW, len_cookie * sizeof(WCHAR) ); + strcpyW( header + len_cookie, cookie->name ); + if (cookie->value) + { + header[len_cookie + len_name] = '='; + strcpyW( header + len_cookie + len_name + 1, cookie->value ); + } TRACE("%s\n", debugstr_w(header)); - add_request_headers( request, header, len, WINHTTP_ADDREQ_FLAG_ADD ); + add_request_headers( request, header, len, + WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON ); heap_free( header ); } }