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