winhttp: Fix a couple of corner cases in header processing.
This commit is contained in:
parent
49b6b60e23
commit
2516fb7807
|
@ -327,12 +327,8 @@ static header_t *parse_header( LPCWSTR string )
|
|||
|
||||
q++; /* skip past colon */
|
||||
while (*q == ' ') q++;
|
||||
if (!*q)
|
||||
{
|
||||
WARN("no value in line %s\n", debugstr_w(string));
|
||||
return header;
|
||||
}
|
||||
len = strlenW( q );
|
||||
|
||||
if (!(header->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
free_header( header );
|
||||
|
@ -404,76 +400,65 @@ static BOOL delete_header( request_t *request, DWORD index )
|
|||
static BOOL process_header( request_t *request, LPCWSTR field, LPCWSTR value, DWORD flags, BOOL request_only )
|
||||
{
|
||||
int index;
|
||||
header_t *header;
|
||||
header_t hdr;
|
||||
|
||||
TRACE("%s: %s 0x%08x\n", debugstr_w(field), debugstr_w(value), flags);
|
||||
|
||||
/* replace wins out over add */
|
||||
if (flags & WINHTTP_ADDREQ_FLAG_REPLACE) flags &= ~WINHTTP_ADDREQ_FLAG_ADD;
|
||||
|
||||
if (flags & WINHTTP_ADDREQ_FLAG_ADD) index = -1;
|
||||
else
|
||||
index = get_header_index( request, field, 0, request_only );
|
||||
|
||||
if (index >= 0)
|
||||
if ((index = get_header_index( request, field, 0, request_only )) >= 0)
|
||||
{
|
||||
if (flags & WINHTTP_ADDREQ_FLAG_ADD_IF_NEW) return FALSE;
|
||||
header = &request->headers[index];
|
||||
}
|
||||
else if (value)
|
||||
|
||||
if (flags & WINHTTP_ADDREQ_FLAG_REPLACE)
|
||||
{
|
||||
header_t hdr;
|
||||
if (index >= 0)
|
||||
{
|
||||
delete_header( request, index );
|
||||
if (!value || !value[0]) return TRUE;
|
||||
}
|
||||
else if (!(flags & WINHTTP_ADDREQ_FLAG_ADD))
|
||||
{
|
||||
set_last_error( ERROR_WINHTTP_HEADER_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hdr.field = (LPWSTR)field;
|
||||
hdr.value = (LPWSTR)value;
|
||||
hdr.is_request = request_only;
|
||||
|
||||
return insert_header( request, &hdr );
|
||||
}
|
||||
/* no value to delete */
|
||||
else return TRUE;
|
||||
|
||||
if (flags & WINHTTP_ADDREQ_FLAG_REPLACE)
|
||||
else if (value)
|
||||
{
|
||||
delete_header( request, index );
|
||||
if (value)
|
||||
|
||||
if ((flags & (WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA | WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON)) &&
|
||||
index >= 0)
|
||||
{
|
||||
header_t hdr;
|
||||
WCHAR *tmp;
|
||||
int len, len_orig, len_value;
|
||||
header_t *header = &request->headers[index];
|
||||
|
||||
hdr.field = (LPWSTR)field;
|
||||
hdr.value = (LPWSTR)value;
|
||||
hdr.is_request = request_only;
|
||||
len_orig = strlenW( header->value );
|
||||
len_value = strlenW( value );
|
||||
|
||||
return insert_header( request, &hdr );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else if (flags & (WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA | WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
|
||||
{
|
||||
WCHAR sep, *tmp;
|
||||
int len, orig_len, value_len;
|
||||
|
||||
orig_len = strlenW( header->value );
|
||||
value_len = strlenW( value );
|
||||
|
||||
if (flags & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) sep = ',';
|
||||
else sep = ';';
|
||||
|
||||
len = orig_len + value_len + 2;
|
||||
if ((tmp = heap_realloc( header->value, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
len = len_orig + len_value + 2;
|
||||
if (!(tmp = heap_realloc( header->value, (len + 1) * sizeof(WCHAR) ))) return FALSE;
|
||||
header->value = tmp;
|
||||
header->value[len_orig++] = (flags & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) ? ',' : ';';
|
||||
header->value[len_orig++] = ' ';
|
||||
|
||||
header->value[orig_len] = sep;
|
||||
orig_len++;
|
||||
header->value[orig_len] = ' ';
|
||||
orig_len++;
|
||||
|
||||
memcpy( &header->value[orig_len], value, value_len * sizeof(WCHAR) );
|
||||
memcpy( &header->value[len_orig], value, len_value * sizeof(WCHAR) );
|
||||
header->value[len] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdr.field = (LPWSTR)field;
|
||||
hdr.value = (LPWSTR)value;
|
||||
hdr.is_request = request_only;
|
||||
return insert_header( request, &hdr );
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2128,7 +2113,9 @@ static BOOL read_reply( request_t *request )
|
|||
/* we rely on the fact that the protocol is ascii */
|
||||
MultiByteToWideChar( CP_ACP, 0, status_code, len, status_codeW, len );
|
||||
status_codeW[len] = 0;
|
||||
if (!(process_header( request, attr_status, status_codeW, WINHTTP_ADDREQ_FLAG_REPLACE, FALSE ))) return FALSE;
|
||||
if (!(process_header( request, attr_status, status_codeW,
|
||||
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE, FALSE )))
|
||||
return FALSE;
|
||||
|
||||
len = status_code - buffer;
|
||||
if (!(versionW = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
|
||||
|
@ -2358,7 +2345,7 @@ static BOOL handle_redirect( request_t *request, DWORD status )
|
|||
}
|
||||
else heap_free( hostname );
|
||||
|
||||
if (!(ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_REPLACE ))) goto end;
|
||||
if (!(ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE ))) goto end;
|
||||
if (!(ret = open_connection( request ))) goto end;
|
||||
|
||||
heap_free( request->path );
|
||||
|
@ -3227,7 +3214,8 @@ static HRESULT WINAPI winhttp_request_SetRequestHeader(
|
|||
goto done;
|
||||
}
|
||||
sprintfW( str, fmtW, header, value ? value : emptyW );
|
||||
if (!WinHttpAddRequestHeaders( request->hrequest, str, len, WINHTTP_ADDREQ_FLAG_REPLACE ))
|
||||
if (!WinHttpAddRequestHeaders( request->hrequest, str, len,
|
||||
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE ))
|
||||
{
|
||||
err = get_last_error();
|
||||
}
|
||||
|
|
|
@ -420,6 +420,8 @@ static void test_WinHttpAddHeaders(void)
|
|||
{'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0','/','p','o','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
|
||||
static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
|
||||
static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
|
||||
static const WCHAR test_header_name2[] = {'n','a','m','e',0};
|
||||
static const WCHAR test_header_name3[] = {'a',0};
|
||||
static const WCHAR test_header_range[] = {'R','a','n','g','e',0};
|
||||
static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
|
||||
static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
|
||||
|
@ -438,6 +440,7 @@ static void test_WinHttpAddHeaders(void)
|
|||
static const WCHAR field[] = {'f','i','e','l','d',0};
|
||||
static const WCHAR value[] = {'v','a','l','u','e',' ',0};
|
||||
static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
|
||||
static const WCHAR empty[] = {0};
|
||||
|
||||
static const WCHAR test_headers[][14] =
|
||||
{
|
||||
|
@ -454,7 +457,9 @@ static void test_WinHttpAddHeaders(void)
|
|||
{':','b',0},
|
||||
{'c','d',0},
|
||||
{' ','e',' ',':','f',0},
|
||||
{'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
|
||||
{'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
|
||||
{'n','a','m','e',':',' ','v','a','l','u','e',0},
|
||||
{'n','a','m','e',':',0}
|
||||
};
|
||||
static const WCHAR test_indices[][6] =
|
||||
{
|
||||
|
@ -763,6 +768,14 @@ static void test_WinHttpAddHeaders(void)
|
|||
ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
|
||||
ok(ret, "WinHttpAddRequestHeaders failed\n");
|
||||
|
||||
index = 0;
|
||||
memset(buffer, 0xff, sizeof(buffer));
|
||||
len = sizeof(buffer);
|
||||
ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
|
||||
test_header_name3, buffer, &len, &index);
|
||||
ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
|
||||
ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n");
|
||||
|
||||
ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
|
||||
ok(!ret, "WinHttpAddRequestHeaders failed\n");
|
||||
|
||||
|
@ -803,6 +816,52 @@ static void test_WinHttpAddHeaders(void)
|
|||
ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len);
|
||||
ok(index == 1, "wrong index %u\n", index);
|
||||
|
||||
index = 0;
|
||||
len = sizeof(buffer);
|
||||
ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
|
||||
test_header_name2, buffer, &len, &index);
|
||||
ok(!ret, "unexpected success\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
|
||||
err = GetLastError();
|
||||
ok(!ret, "unexpected success\n");
|
||||
ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
|
||||
|
||||
ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
|
||||
ok(ret, "got %u\n", GetLastError());
|
||||
|
||||
index = 0;
|
||||
len = sizeof(buffer);
|
||||
ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
|
||||
test_header_name2, buffer, &len, &index);
|
||||
ok(ret, "got %u\n", GetLastError());
|
||||
ok(index == 1, "wrong index %u\n", index);
|
||||
ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
|
||||
|
||||
ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
|
||||
ok(ret, "got %u\n", GetLastError());
|
||||
|
||||
index = 0;
|
||||
len = sizeof(buffer);
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
|
||||
test_header_name2, buffer, &len, &index);
|
||||
err = GetLastError();
|
||||
ok(!ret, "unexpected success\n");
|
||||
ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
|
||||
|
||||
ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0);
|
||||
ok(ret, "got %u\n", GetLastError());
|
||||
|
||||
index = 0;
|
||||
len = sizeof(buffer);
|
||||
ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
|
||||
test_header_name2, buffer, &len, &index);
|
||||
ok(ret, "got %u\n", GetLastError());
|
||||
ok(index == 1, "wrong index %u\n", index);
|
||||
ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
|
||||
|
||||
ret = WinHttpCloseHandle(request);
|
||||
ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
|
||||
done:
|
||||
|
|
Loading…
Reference in New Issue