Nikolay Sivov : msxml3/httprequest: Implement IXMLHttpRequest:: setRequestHeader().
Alexandre Julliard
julliard at winehq.org
Wed Sep 29 12:00:17 CDT 2010
Module: wine
Branch: master
Commit: 1ac256a5885fcb7a26e5d617f1599b2761f765e2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1ac256a5885fcb7a26e5d617f1599b2761f765e2
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Sep 29 02:50:37 2010 +0400
msxml3/httprequest: Implement IXMLHttpRequest::setRequestHeader().
---
dlls/msxml3/httprequest.c | 80 ++++++++++++++++++++++++++++++++++++++++---
dlls/msxml3/tests/domdoc.c | 36 ++++++++++++++++++++
2 files changed, 110 insertions(+), 6 deletions(-)
diff --git a/dlls/msxml3/httprequest.c b/dlls/msxml3/httprequest.c
index 21bd80c..e0f7701 100644
--- a/dlls/msxml3/httprequest.c
+++ b/dlls/msxml3/httprequest.c
@@ -31,6 +31,7 @@
#include "msxml_private.h"
#include "wine/debug.h"
+#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
@@ -40,14 +41,34 @@ static const WCHAR MethodGetW[] = {'G','E','T',0};
static const WCHAR MethodPutW[] = {'P','U','T',0};
static const WCHAR MethodPostW[] = {'P','O','S','T',0};
+struct reqheader
+{
+ struct list entry;
+ BSTR header;
+ BSTR value;
+};
+
+enum READYSTATE
+{
+ STATE_UNINITIALIZED = 0,
+ STATE_LOADING = 1,
+ STATE_LOADED = 2,
+ STATE_INTERACTIVE = 3,
+ STATE_COMPLETED = 4
+};
+
typedef struct _httprequest
{
const struct IXMLHTTPRequestVtbl *lpVtbl;
LONG ref;
+ READYSTATE state;
+
+ /* request */
BINDVERB verb;
BSTR url;
BOOL async;
+ struct list reqheaders;
/* credentials */
BSTR user;
@@ -59,6 +80,12 @@ static inline httprequest *impl_from_IXMLHTTPRequest( IXMLHTTPRequest *iface )
return (httprequest *)((char*)iface - FIELD_OFFSET(httprequest, lpVtbl));
}
+/* TODO: process OnChange callback */
+static void httprequest_setreadystate(httprequest *This, READYSTATE state)
+{
+ This->state = state;
+}
+
static HRESULT WINAPI httprequest_QueryInterface(IXMLHTTPRequest *iface, REFIID riid, void **ppvObject)
{
httprequest *This = impl_from_IXMLHTTPRequest( iface );
@@ -95,9 +122,20 @@ static ULONG WINAPI httprequest_Release(IXMLHTTPRequest *iface)
ref = InterlockedDecrement( &This->ref );
if ( ref == 0 )
{
+ struct reqheader *header, *header2;
+
SysFreeString(This->url);
SysFreeString(This->user);
SysFreeString(This->password);
+
+ /* request headers */
+ LIST_FOR_EACH_ENTRY_SAFE(header, header2, &This->reqheaders, struct reqheader, entry)
+ {
+ list_remove(&header->entry);
+ SysFreeString(header->header);
+ SysFreeString(header->value);
+ }
+
heap_free( This );
}
@@ -223,16 +261,41 @@ static HRESULT WINAPI httprequest_open(IXMLHTTPRequest *iface, BSTR method, BSTR
if (hr == S_OK)
This->password = V_BSTR(&str);
+ httprequest_setreadystate(This, STATE_LOADING);
+
return S_OK;
}
-static HRESULT WINAPI httprequest_setRequestHeader(IXMLHTTPRequest *iface, BSTR bstrHeader, BSTR bstrValue)
+static HRESULT WINAPI httprequest_setRequestHeader(IXMLHTTPRequest *iface, BSTR header, BSTR value)
{
httprequest *This = impl_from_IXMLHTTPRequest( iface );
+ struct reqheader *entry;
- FIXME("stub (%p) %s %s\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
+ TRACE("(%p)->(%s %s)\n", This, debugstr_w(header), debugstr_w(value));
- return E_NOTIMPL;
+ if (!header || !*header) return E_INVALIDARG;
+ if (This->state != STATE_LOADING) return E_FAIL;
+ if (!value) return E_INVALIDARG;
+
+ /* replace existing header value if already added */
+ LIST_FOR_EACH_ENTRY(entry, &This->reqheaders, struct reqheader, entry)
+ {
+ if (lstrcmpW(entry->header, header) == 0)
+ {
+ return SysReAllocString(&entry->value, value) ? S_OK : E_OUTOFMEMORY;
+ }
+ }
+
+ entry = heap_alloc(sizeof(*entry));
+ if (!entry) return E_OUTOFMEMORY;
+
+ /* new header */
+ entry->header = SysAllocString(header);
+ entry->value = SysAllocString(value);
+
+ list_add_head(&This->reqheaders, &entry->entry);
+
+ return S_OK;
}
static HRESULT WINAPI httprequest_getResponseHeader(IXMLHTTPRequest *iface, BSTR bstrHeader, BSTR *pbstrValue)
@@ -325,13 +388,16 @@ static HRESULT WINAPI httprequest_get_responseStream(IXMLHTTPRequest *iface, VAR
return E_NOTIMPL;
}
-static HRESULT WINAPI httprequest_get_readyState(IXMLHTTPRequest *iface, LONG *plState)
+static HRESULT WINAPI httprequest_get_readyState(IXMLHTTPRequest *iface, LONG *state)
{
httprequest *This = impl_from_IXMLHTTPRequest( iface );
- FIXME("stub %p %p\n", This, plState);
+ TRACE("(%p)->(%p)\n", This, state);
- return E_NOTIMPL;
+ if (!state) return E_INVALIDARG;
+
+ *state = This->state;
+ return S_OK;
}
static HRESULT WINAPI httprequest_put_onreadystatechange(IXMLHTTPRequest *iface, IDispatch *pReadyStateSink)
@@ -385,6 +451,8 @@ HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj)
req->async = FALSE;
req->verb = -1;
req->url = req->user = req->password = NULL;
+ req->state = STATE_UNINITIALIZED;
+ list_init(&req->reqheaders);
*ppObj = &req->lpVtbl;
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 008c6b7..d9587a0 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -2887,6 +2887,7 @@ static void test_XMLHTTP(void)
VARIANT dummy;
VARIANT async;
VARIANT varbody;
+ LONG state;
HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLHttpRequest,
(void **)&pXMLHttpRequest);
@@ -2918,9 +2919,43 @@ static void test_XMLHTTP(void)
hr = IXMLHttpRequest_open(pXMLHttpRequest, NULL, url, async, dummy, dummy);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), NULL);
+ ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win9x, win2k */, "got 0x%08x\n", hr);
+
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, _bstr_("value1"));
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), _bstr_("value1"));
+ ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win9x, win2k */, "got 0x%08x\n", hr);
+
+ hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, NULL);
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ state = -1;
+ hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(state == 0, "got %d, expected 0\n", state);
+
hr = IXMLHttpRequest_open(pXMLHttpRequest, method, url, async, dummy, dummy);
ok(hr == S_OK, "got 0x%08x\n", hr);
+ state = -1;
+ hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(state == 1, "got %d, expected 1\n", state);
+
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), _bstr_("value1"));
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, _bstr_("value1"));
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+ hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_(""), _bstr_("value1"));
+ ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
SysFreeString(method);
SysFreeString(url);
@@ -2945,6 +2980,7 @@ static void test_XMLHTTP(void)
}
IXMLHttpRequest_Release(pXMLHttpRequest);
+ free_bstrs();
}
static void test_IXMLDOMDocument2(void)
More information about the wine-cvs
mailing list