Module: wine Branch: master Commit: 1ac256a5885fcb7a26e5d617f1599b2761f765e2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1ac256a5885fcb7a26e5d617f1...
Author: Nikolay Sivov nsivov@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)