Nikolay Sivov : msxml3: Implement POST support with supplied body data.
Alexandre Julliard
julliard at winehq.org
Wed Oct 13 11:43:06 CDT 2010
Module: wine
Branch: master
Commit: ace3a81d13a9fe30be3fe434e13964a716f8f3d7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ace3a81d13a9fe30be3fe434e13964a716f8f3d7
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Oct 13 02:41:49 2010 +0400
msxml3: Implement POST support with supplied body data.
---
dlls/msxml3/httprequest.c | 46 +++++++++++++++++++++++++++++++++++++------
dlls/msxml3/tests/domdoc.c | 9 +++----
2 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/dlls/msxml3/httprequest.c b/dlls/msxml3/httprequest.c
index 504da92..98372ff 100644
--- a/dlls/msxml3/httprequest.c
+++ b/dlls/msxml3/httprequest.c
@@ -114,6 +114,9 @@ struct BindStatusCallback
/* response data */
IStream *stream;
+
+ /* request body data */
+ HGLOBAL body;
};
static inline BindStatusCallback *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
@@ -194,6 +197,7 @@ static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
{
if (This->binding) IBinding_Release(This->binding);
if (This->stream) IStream_Release(This->stream);
+ if (This->body) GlobalFree(This->body);
heap_free(This);
}
@@ -240,7 +244,7 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
{
BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
- TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
+ TRACE("(%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
debugstr_w(szStatusText));
return S_OK;
@@ -275,10 +279,13 @@ static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
*bind_flags = 0;
if (This->request->async) *bind_flags |= BINDF_ASYNCHRONOUS;
- if (This->request->verb != BINDVERB_GET)
+ if (This->request->verb != BINDVERB_GET && This->body)
{
- FIXME("only GET verb supported. Got %d\n", This->request->verb);
- return E_FAIL;
+ pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
+ pbindinfo->stgmedData.u.hGlobal = This->body;
+ pbindinfo->cbstgmedData = GlobalSize(This->body);
+ /* callback owns passed body pointer */
+ IBindStatusCallback_QueryInterface(iface, &IID_IUnknown, (void**)&pbindinfo->stgmedData.pUnkForRelease);
}
pbindinfo->dwBindVerb = This->request->verb;
@@ -410,7 +417,7 @@ static const IHttpNegotiateVtbl BSCHttpNegotiateVtbl = {
BSCHttpNegotiate_OnResponse
};
-static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback **obj)
+static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback **obj, const VARIANT *body)
{
BindStatusCallback *bsc;
IBindCtx *pbc;
@@ -432,6 +439,31 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback *
bsc->request = This;
bsc->binding = NULL;
bsc->stream = NULL;
+ bsc->body = NULL;
+
+ TRACE("created callback %p\n", bsc);
+
+ if (This->verb != BINDVERB_GET)
+ {
+ if (V_VT(body) == VT_BSTR)
+ {
+ LONG size = SysStringLen(V_BSTR(body)) * sizeof(WCHAR);
+ void *ptr;
+
+ bsc->body = GlobalAlloc(GMEM_FIXED, size);
+ if (!bsc->body)
+ {
+ heap_free(bsc);
+ return E_OUTOFMEMORY;
+ }
+
+ ptr = GlobalLock(bsc->body);
+ memcpy(ptr, V_BSTR(body), size);
+ GlobalUnlock(bsc->body);
+ }
+ else
+ FIXME("unsupported body data type %d\n", V_VT(body));
+ }
hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)bsc, NULL, 0);
if (hr == S_OK)
@@ -710,7 +742,7 @@ static HRESULT WINAPI httprequest_getAllResponseHeaders(IXMLHTTPRequest *iface,
return E_NOTIMPL;
}
-static HRESULT WINAPI httprequest_send(IXMLHTTPRequest *iface, VARIANT varBody)
+static HRESULT WINAPI httprequest_send(IXMLHTTPRequest *iface, VARIANT body)
{
httprequest *This = impl_from_IXMLHTTPRequest( iface );
BindStatusCallback *bsc = NULL;
@@ -720,7 +752,7 @@ static HRESULT WINAPI httprequest_send(IXMLHTTPRequest *iface, VARIANT varBody)
if (This->state != READYSTATE_LOADING) return E_FAIL;
- hr = BindStatusCallback_create(This, &bsc);
+ hr = BindStatusCallback_create(This, &bsc, &body);
if (FAILED(hr)) return hr;
BindStatusCallback_Detach(This->bsc);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index d85bda9..4cb9abe 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -3334,15 +3334,13 @@ if (0)
IXMLHttpRequest_Release(pXMLHttpRequest);
return;
}
- todo_wine ok(hr == S_OK, "IXMLHttpRequest_send should have succeeded instead of failing with 0x%08x\n", hr);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/* status code after ::send() */
status = 0xdeadbeef;
hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
-todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(status == 200, "got %d\n", status);
-}
/* another ::send() after completed request */
hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
@@ -3351,12 +3349,13 @@ todo_wine {
VariantClear(&varbody);
hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
- todo_wine ok(hr == S_OK, "IXMLHttpRequest_get_responseText should have succeeded instead of failing with 0x%08x\n", hr);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
/* the server currently returns "FAILED" because the Content-Type header is
* not what the server expects */
if(hr == S_OK)
{
- ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)), "bstrResponse differs from what was expected\n");
+ todo_wine ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
+ "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
SysFreeString(bstrResponse);
}
More information about the wine-cvs
mailing list