From: Zhenbo Li Subject: [PATCH 2/3] mshtml: Implement IHTMLXMLHttpRequest::open() method. Message-Id: <5584D5D6.8050405@gmail.com> Date: Sat, 20 Jun 2015 10:54:14 +0800 --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/nsembed.c | 2 +- dlls/mshtml/tests/xmlhttprequest.c | 26 ++++++++++++++ dlls/mshtml/xmlhttprequest.c | 73 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index ca021ba..87e4154 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -855,6 +855,7 @@ HRESULT call_set_active_object(IOleInPlaceUIWindow*,IOleInPlaceActiveObject*) DE void *nsalloc(size_t) __WINE_ALLOC_SIZE(1) DECLSPEC_HIDDEN; void nsfree(void*) DECLSPEC_HIDDEN; +BOOL nsACString_Init(nsACString *str, const char *data) DECLSPEC_HIDDEN; void nsACString_InitDepend(nsACString*,const char*) DECLSPEC_HIDDEN; void nsACString_SetData(nsACString*,const char*) DECLSPEC_HIDDEN; UINT32 nsACString_GetData(const nsACString*,const char**) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 595a9fd..940cf76 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -795,7 +795,7 @@ void nsfree(void *mem) NS_Free(mem); } -static BOOL nsACString_Init(nsACString *str, const char *data) +BOOL nsACString_Init(nsACString *str, const char *data) { return NS_SUCCEEDED(NS_CStringContainerInit2(str, data, PR_UINT32_MAX, 0)); } diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c index a9c4418..ff2c50a 100644 --- a/dlls/mshtml/tests/xmlhttprequest.c +++ b/dlls/mshtml/tests/xmlhttprequest.c @@ -26,6 +26,18 @@ #include "ole2.h" #include "mshtml.h" +static BSTR a2bstr(const char *str) +{ + BSTR ret; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = SysAllocStringLen(NULL, len); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + #define INTERNET_MAX_URL_LENGTH 1000 static const char StartURL[] = "http://test.winehq.org/tests/hello.html"; @@ -36,6 +48,8 @@ static void test_xhr(IHTMLDocument2 *doc, const char *xml_url) IHTMLWindow2 *window; IHTMLWindow5 *window5; VARIANT xhr_var; + VARIANT vbool, vempty; + BSTR method, url; IHTMLXMLHttpRequest *xhr; IHTMLXMLHttpRequestFactory *factory; HRESULT hres; @@ -73,6 +87,18 @@ static void test_xhr(IHTMLDocument2 *doc, const char *xml_url) ok(hres == S_OK, "create failed: %08x\n", hres); ok(xhr != NULL, "xhr == NULL\n"); + method = a2bstr("GET"); + url = a2bstr(xml_url); + V_VT(&vbool) = VT_BOOL; + V_BOOL(&vbool) = VARIANT_FALSE; + V_VT(&vempty) = VT_EMPTY; + hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty); + todo_wine ok(hres == S_OK, "open failed: %08x\n", hres); /* Gecko 30+ only supports async */ + + VariantClear(&vbool); + SysFreeString(method); + SysFreeString(url); + IHTMLXMLHttpRequest_Release(xhr); } diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index fa6cdc6..8107fe7 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -31,6 +31,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +static void nsACString_InitFromBSTR(nsACString *str, BSTR bstr) +{ + char *cstr = heap_strdupWtoU(bstr); + nsACString_Init(str, cstr); + heap_free(cstr); +} + +static HRESULT variant_to_nsAString(nsAString *ret, VARIANT var) +{ + switch(V_VT(&var)) { + case VT_NULL: + case VT_ERROR: + case VT_EMPTY: + nsAString_Init(ret, NULL); + return S_OK; + case VT_BSTR: + nsAString_InitDepend(ret, V_BSTR(&var)); + return S_OK; + default: + ERR("Unsupported VARIANT: %s\n", debugstr_variant(&var)); + return E_INVALIDARG; + } +} + /* IHTMLXMLHttpRequest */ typedef struct { EventTarget event_target; @@ -191,8 +215,53 @@ static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface) static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword) { HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface); - FIXME("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword)); - return E_NOTIMPL; + nsACString method, url; + nsAString user, password; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword)); + + if(V_VT(&varAsync) != VT_BOOL) { + FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync)); + return E_FAIL; + } + + /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), + * synchronous requests on the main thread have been deprecated due to the negative + * effects to the user experience. + */ + if(!V_BOOL(&varAsync)) { + FIXME("Synchronous request is not supported yet\n"); + return E_FAIL; + } + + hres = variant_to_nsAString(&user, varUser); + if(FAILED(hres)) + return hres; + hres = variant_to_nsAString(&password, varPassword); + if(FAILED(hres)) { + nsAString_Finish(&password); + return hres; + } + + nsACString_InitFromBSTR(&method, bstrMethod); + nsACString_InitFromBSTR(&url, bstrUrl); + + nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE, + &user, &password, 0); + + nsACString_Finish(&method); + nsACString_Finish(&url); + nsAString_Finish(&user); + nsAString_Finish(&password); + + if(NS_FAILED(nsres)) { + ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)