winhttp: Parse cookie attributes.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2017-02-21 09:24:36 +01:00 committed by Alexandre Julliard
parent ef15e09d3d
commit 8595cc5386

View File

@ -167,17 +167,79 @@ static cookie_t *parse_cookie( const WCHAR *string )
return cookie; 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;
if (!(attr = heap_alloc( sizeof(struct attr) ))) return NULL;
if (!(attr->name = heap_alloc( (len + 1) * sizeof(WCHAR) )))
{
heap_free( attr );
return NULL;
}
memcpy( attr->name, p, len * sizeof(WCHAR) );
attr->name[len] = 0;
attr->value = NULL;
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 ) BOOL set_cookies( request_t *request, const WCHAR *cookies )
{ {
static const WCHAR pathW[] = {'p','a','t','h',0}; static const WCHAR pathW[] = {'p','a','t','h',0};
static const WCHAR domainW[] = {'d','o','m','a','i','n',0}; static const WCHAR domainW[] = {'d','o','m','a','i','n',0};
BOOL ret = FALSE; BOOL ret = FALSE;
WCHAR *buffer, *p, *q, *r; WCHAR *buffer, *p;
WCHAR *cookie_domain = NULL, *cookie_path = NULL; WCHAR *cookie_domain = NULL, *cookie_path = NULL;
struct attr *attr, *domain = NULL, *path = NULL;
session_t *session = request->connect->session; session_t *session = request->connect->session;
cookie_t *cookie; cookie_t *cookie;
int len; int len, used;
len = strlenW( cookies ); len = strlenW( cookies );
if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE; if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
@ -191,32 +253,26 @@ BOOL set_cookies( request_t *request, const WCHAR *cookies )
heap_free( buffer ); heap_free( buffer );
return FALSE; return FALSE;
} }
if ((q = strstrW( p, domainW ))) /* FIXME: do real attribute parsing */ len = strlenW( p );
while (len && (attr = parse_attr( p, &used )))
{ {
while (*q && *q != '=') q++; if (!strcmpW( attr->name, domainW ))
if (!*q) goto end; {
domain = attr;
r = ++q; cookie_domain = attr->value;
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 ))) else if (!strcmpW( attr->name, pathW ))
{ {
while (*q && *q != '=') q++; path = attr;
if (!*q) goto end; cookie_path = attr->value;
}
r = ++q; else
while (*r && *r != ';') r++; {
len = r - q; FIXME( "unhandled attribute %s\n", debugstr_w(attr->name) );
free_attr( attr );
if (!(cookie_path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end; }
memcpy( cookie_path, q, len * sizeof(WCHAR) ); len -= used;
cookie_path[len] = 0; p += used;
} }
if (!cookie_domain && !(cookie_domain = strdupW( request->connect->servername ))) goto end; if (!cookie_domain && !(cookie_domain = strdupW( request->connect->servername ))) goto end;
if (!cookie_path && !(cookie_path = strdupW( request->path ))) goto end; if (!cookie_path && !(cookie_path = strdupW( request->path ))) goto end;
@ -226,8 +282,10 @@ BOOL set_cookies( request_t *request, const WCHAR *cookies )
end: end:
if (!ret) free_cookie( cookie ); if (!ret) free_cookie( cookie );
heap_free( cookie_domain ); if (domain) free_attr( domain );
heap_free( cookie_path ); else heap_free( cookie_domain );
if (path) free_attr( path );
else heap_free( cookie_path );
heap_free( buffer ); heap_free( buffer );
return ret; return ret;
} }