winhttp: Improve parsing of cookie values.
This commit is contained in:
parent
683ffd7ff1
commit
41cf9a8372
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue