winhttp: Improve parsing of cookie values.

This commit is contained in:
Hans Leidekker 2015-06-15 17:32:25 +02:00 committed by Alexandre Julliard
parent 683ffd7ff1
commit 41cf9a8372
2 changed files with 144 additions and 26 deletions

View File

@ -134,22 +134,14 @@ static cookie_t *parse_cookie( const WCHAR *string )
const WCHAR *p;
int len;
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;
}
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 );
len = p - string;
if (!(cookie->name = heap_alloc( (len + 1) * sizeof(WCHAR) )))
{
heap_free( cookie );
@ -158,18 +150,20 @@ static cookie_t *parse_cookie( const WCHAR *string )
memcpy( cookie->name, string, len * sizeof(WCHAR) );
cookie->name[len] = 0;
p++; /* skip '=' */
while (*p == ' ') p++;
len = strlenW( p );
if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
if (*p++ == '=')
{
free_cookie( cookie );
return NULL;
}
memcpy( cookie->value, p, len * sizeof(WCHAR) );
cookie->value[len] = 0;
while (*p && *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;
}
@ -259,14 +253,21 @@ 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 );

View File

@ -1799,6 +1799,15 @@ static const char okmsg[] =
"Server: winetest\r\n"
"\r\n";
static const char notokmsg[] =
"HTTP/1.1 400 Bad Request\r\n"
"\r\n";
static const char cookiemsg[] =
"HTTP/1.1 200 OK\r\n"
"Set-Cookie: name = value \r\n"
"\r\n";
static const char nocontentmsg[] =
"HTTP/1.1 204 No Content\r\n"
"Server: winetest\r\n"
@ -1917,6 +1926,16 @@ static DWORD CALLBACK server_thread(LPVOID param)
send(c, headmsg, sizeof headmsg - 1, 0);
continue;
}
if (strstr(buffer, "GET /cookie2"))
{
if (strstr(buffer, "Cookie: name=value\r\n")) send(c, okmsg, sizeof(okmsg) - 1, 0);
else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
}
else if (strstr(buffer, "GET /cookie"))
{
if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
}
if (strstr(buffer, "GET /quit"))
{
send(c, okmsg, sizeof okmsg - 1, 0);
@ -2503,6 +2522,103 @@ static void test_multiple_reads(int port)
WinHttpCloseHandle(ses);
}
static void test_cookies( int port )
{
static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0};
static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0};
HINTERNET ses, con, req;
DWORD status, size;
BOOL ret;
ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
ok( ses != NULL, "failed to open session %u\n", GetLastError() );
con = WinHttpConnect( ses, localhostW, port, 0 );
ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 );
ok( req != NULL, "failed to open a request %u\n", GetLastError() );
ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
ok( ret, "failed to send request %u\n", GetLastError() );
ret = WinHttpReceiveResponse( req, NULL );
ok( ret, "failed to receive response %u\n", GetLastError() );
status = 0xdeadbeef;
size = sizeof(status);
ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
ok( ret, "failed to query status code %u\n", GetLastError() );
ok( status == 200, "request failed unexpectedly %u\n", status );
WinHttpCloseHandle( req );
req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
ok( req != NULL, "failed to open a request %u\n", GetLastError() );
ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
ok( ret, "failed to send request %u\n", GetLastError() );
ret = WinHttpReceiveResponse( req, NULL );
ok( ret, "failed to receive response %u\n", GetLastError() );
status = 0xdeadbeef;
size = sizeof(status);
ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
ok( ret, "failed to query status code %u\n", GetLastError() );
ok( status == 200, "request failed unexpectedly %u\n", status );
WinHttpCloseHandle( req );
WinHttpCloseHandle( con );
con = WinHttpConnect( ses, localhostW, port, 0 );
ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
ok( req != NULL, "failed to open a request %u\n", GetLastError() );
ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
ok( ret, "failed to send request %u\n", GetLastError() );
ret = WinHttpReceiveResponse( req, NULL );
ok( ret, "failed to receive response %u\n", GetLastError() );
status = 0xdeadbeef;
size = sizeof(status);
ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
ok( ret, "failed to query status code %u\n", GetLastError() );
ok( status == 200, "request failed unexpectedly %u\n", status );
WinHttpCloseHandle( req );
WinHttpCloseHandle( con );
WinHttpCloseHandle( ses );
ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
ok( ses != NULL, "failed to open session %u\n", GetLastError() );
con = WinHttpConnect( ses, localhostW, port, 0 );
ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
ok( req != NULL, "failed to open a request %u\n", GetLastError() );
ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
ok( ret, "failed to send request %u\n", GetLastError() );
ret = WinHttpReceiveResponse( req, NULL );
ok( ret, "failed to receive response %u\n", GetLastError() );
status = 0xdeadbeef;
size = sizeof(status);
ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
ok( ret, "failed to query status code %u\n", GetLastError() );
ok( status == 400, "request failed unexpectedly %u\n", status );
WinHttpCloseHandle( req );
WinHttpCloseHandle( con );
WinHttpCloseHandle( ses );
}
static void test_connection_info( int port )
{
static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
@ -3478,6 +3594,7 @@ START_TEST (winhttp)
test_basic_authentication(si.port);
test_bad_header(si.port);
test_multiple_reads(si.port);
test_cookies(si.port);
/* send the basic request again to shutdown the server thread */
test_basic_request(si.port, NULL, quitW);