diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 5067b668497..d1d0d05010e 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -467,12 +467,14 @@ typedef struct {
UINT url_scheme;
} nsChannel;
-typedef struct ResponseHeader {
+typedef struct {
struct list entry;
WCHAR *header;
WCHAR *data;
} http_header_t;
+HRESULT set_http_header(struct list*,const WCHAR*,int,const WCHAR*,int);
+
typedef struct {
HRESULT (*qi)(HTMLDOMNode*,REFIID,void**);
void (*destructor)(HTMLDOMNode*);
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c
index e4779893246..935a3b992f6 100644
--- a/dlls/mshtml/navigate.c
+++ b/dlls/mshtml/navigate.c
@@ -1104,6 +1104,7 @@ static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code,
LPCWSTR response_headers)
{
nsChannelBSC *This = NSCHANNELBSC_THIS(bsc);
+ HRESULT hres;
This->nschannel->response_status = response_code;
@@ -1112,9 +1113,7 @@ static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code,
hdr_start = strchrW(response_headers, '\r');
while(hdr_start) {
- const WCHAR *colon;
- struct ResponseHeader *new_header;
- int len;
+ const WCHAR *colon, *value;
hdr_start += 2;
hdr_end = strchrW(hdr_start, '\r');
@@ -1132,35 +1131,14 @@ static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code,
continue;
}
- new_header = heap_alloc(sizeof(struct ResponseHeader));
- if(!new_header)
- return E_OUTOFMEMORY;
+ value = colon+1;
+ while(*value == ' ')
+ value++;
- len = colon - hdr_start;
- new_header->header = heap_alloc((len + 1) * sizeof(WCHAR));
- if(!new_header->header) {
- heap_free(new_header);
- return E_OUTOFMEMORY;
- }
- memcpy(new_header->header, hdr_start, len * sizeof(WCHAR));
- new_header->header[len] = 0;
-
- colon++;
- while(*colon == ' ')
- colon++;
-
- len = hdr_end - colon;
- new_header->data = heap_alloc((len + 1) * sizeof(WCHAR));
- if(!new_header->data) {
- heap_free(new_header->header);
- heap_free(new_header);
- return E_OUTOFMEMORY;
- }
- memcpy(new_header->data, colon, len * sizeof(WCHAR));
- new_header->data[len] = 0;
-
- list_add_head(&This->nschannel->response_headers, &new_header->entry);
- TRACE("Adding header to list: (%s):(%s)\n", wine_dbgstr_w(new_header->header), wine_dbgstr_w(new_header->data));
+ hres = set_http_header(&This->nschannel->response_headers, hdr_start, colon-hdr_start,
+ value, hdr_end-value);
+ if(FAILED(hres))
+ return hres;
hdr_start = strchrW(hdr_start, '\r');
}
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c
index fa0aa8d59df..9bef7f0a826 100644
--- a/dlls/mshtml/nsio.c
+++ b/dlls/mshtml/nsio.c
@@ -350,6 +350,43 @@ static nsresult get_channel_http_header(struct list *headers, const nsACString *
return NS_OK;
}
+HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
+ const WCHAR *value, int value_len)
+{
+ http_header_t *header;
+
+ TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
+
+ header = find_http_header(headers, name, name_len);
+ if(header) {
+ WCHAR *new_data;
+
+ new_data = heap_strndupW(value, value_len);
+ if(!new_data)
+ return E_OUTOFMEMORY;
+
+ heap_free(header->data);
+ header->data = new_data;
+ }else {
+ header = heap_alloc(sizeof(http_header_t));
+ if(!header)
+ return E_OUTOFMEMORY;
+
+ header->header = heap_strndupW(name, name_len);
+ header->data = heap_strndupW(value, value_len);
+ if(!header->header || !header->data) {
+ heap_free(header->header);
+ heap_free(header->data);
+ heap_free(header);
+ return E_OUTOFMEMORY;
+ }
+
+ list_add_tail(headers, &header->entry);
+ }
+
+ return S_OK;
+}
+
static void free_http_headers(struct list *list)
{
http_header_t *iter, *iter_next;