Gabriel Ivăncescu : mshtml: Implement timeout for XMLHttpRequest.

Alexandre Julliard julliard at winehq.org
Wed May 25 16:51:47 CDT 2022


Module: wine
Branch: master
Commit: 105e6b83d3ad9d1572ed94c93a8ca62ae0d1f828
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=105e6b83d3ad9d1572ed94c93a8ca62ae0d1f828

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Wed May 25 19:13:13 2022 +0300

mshtml: Implement timeout for XMLHttpRequest.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/mshtml_private.h       |   1 +
 dlls/mshtml/tests/documentmode.js  |   2 +
 dlls/mshtml/tests/xmlhttprequest.c |  36 ++++++++++++
 dlls/mshtml/xmlhttprequest.c       | 116 +++++++++++++++++++++++++++++++++++++
 4 files changed, 155 insertions(+)

diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 930ab3bbe19..55742728923 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -265,6 +265,7 @@ typedef struct EventTarget EventTarget;
     XIID(IHTMLWindow6) \
     XIID(IHTMLWindow7) \
     XIID(IHTMLXMLHttpRequest) \
+    XIID(IHTMLXMLHttpRequest2) \
     XIID(IHTMLXMLHttpRequestFactory) \
     XIID(IOmHistory) \
     XIID(IOmNavigator) \
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 5f104475f0d..8503523f927 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -397,6 +397,8 @@ sync_test("xhr_props", function() {
     test_exposed("addEventListener", v >= 9);
     test_exposed("removeEventListener", v >= 9);
     test_exposed("dispatchEvent", v >= 9);
+    test_exposed("ontimeout", true);
+    test_exposed("timeout", true);
 });
 
 sync_test("stylesheet_props", function() {
diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c
index 868035d0419..6aef9f5a35d 100644
--- a/dlls/mshtml/tests/xmlhttprequest.c
+++ b/dlls/mshtml/tests/xmlhttprequest.c
@@ -1007,6 +1007,41 @@ static void test_xhr_post(IHTMLDocument2 *doc)
     xhr = NULL;
 }
 
+static void test_timeout(IHTMLDocument2 *doc)
+{
+    IHTMLXMLHttpRequest2 *xhr2;
+    LONG timeout;
+    HRESULT hres;
+
+    create_xmlhttprequest(doc);
+    if(!xhr)
+        return;
+
+    hres = IHTMLXMLHttpRequest_QueryInterface(xhr, &IID_IHTMLXMLHttpRequest2, (void**)&xhr2);
+    ok(hres == S_OK, "QueryInterface(IHTMLXMLHttpRequest2) failed: %08lx\n", hres);
+
+    hres = IHTMLXMLHttpRequest2_get_timeout(xhr2, NULL);
+    ok(hres == E_POINTER, "get_timeout returned %08lx\n", hres);
+    hres = IHTMLXMLHttpRequest2_get_timeout(xhr2, &timeout);
+    ok(hres == S_OK, "get_timeout returned %08lx\n", hres);
+    ok(timeout == 0, "timeout = %ld\n", timeout);
+
+    /* Some Windows versions only allow setting timeout after open() */
+    xhr_open(L"http://test.winehq.org/tests/post.php", L"POST", TRUE);
+    IHTMLXMLHttpRequest_Release(xhr);
+    xhr = NULL;
+
+    hres = IHTMLXMLHttpRequest2_put_timeout(xhr2, -1);
+    ok(hres == E_INVALIDARG || broken(hres == E_FAIL), "put_timeout returned %08lx\n", hres);
+    hres = IHTMLXMLHttpRequest2_put_timeout(xhr2, 1337);
+    ok(hres == S_OK, "put_timeout returned %08lx\n", hres);
+    hres = IHTMLXMLHttpRequest2_get_timeout(xhr2, &timeout);
+    ok(hres == S_OK, "get_timeout returned %08lx\n", hres);
+    ok(timeout == 1337, "timeout = %ld\n", timeout);
+
+    IHTMLXMLHttpRequest2_Release(xhr2);
+}
+
 static IHTMLDocument2 *create_doc_from_url(const WCHAR *start_url)
 {
     BSTR url;
@@ -1071,6 +1106,7 @@ START_TEST(xmlhttprequest)
         test_async_xhr(doc, large_page_url, NULL);
         test_async_xhr_abort(doc, large_page_url);
         test_xhr_post(doc);
+        test_timeout(doc);
         IHTMLDocument2_Release(doc);
     }
     SysFreeString(content_type);
diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c
index 17219593026..066b94ba5e7 100644
--- a/dlls/mshtml/xmlhttprequest.c
+++ b/dlls/mshtml/xmlhttprequest.c
@@ -105,6 +105,7 @@ typedef struct {
 struct HTMLXMLHttpRequest {
     EventTarget event_target;
     IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
+    IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface;
     IProvideClassInfo2 IProvideClassInfo2_iface;
     LONG ref;
     nsIXMLHttpRequest *nsxhr;
@@ -236,6 +237,8 @@ static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *ifa
         *ppv = &This->IHTMLXMLHttpRequest_iface;
     }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
         *ppv = &This->IHTMLXMLHttpRequest_iface;
+    }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest2, riid)) {
+        *ppv = &This->IHTMLXMLHttpRequest2_iface;
     }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
         *ppv = &This->IProvideClassInfo2_iface;
     }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
@@ -726,6 +729,117 @@ static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
     HTMLXMLHttpRequest_setRequestHeader
 };
 
+static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest2(IHTMLXMLHttpRequest2 *iface)
+{
+    return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest2_iface);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_QueryInterface(IHTMLXMLHttpRequest2 *iface, REFIID riid, void **ppv)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
+}
+
+static ULONG WINAPI HTMLXMLHttpRequest2_AddRef(IHTMLXMLHttpRequest2 *iface)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
+}
+
+static ULONG WINAPI HTMLXMLHttpRequest2_Release(IHTMLXMLHttpRequest2 *iface)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_GetTypeInfoCount(IHTMLXMLHttpRequest2 *iface, UINT *pctinfo)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_GetTypeInfo(IHTMLXMLHttpRequest2 *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_GetIDsOfNames(IHTMLXMLHttpRequest2 *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
+        LCID lcid, DISPID *rgDispId)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
+            lcid, rgDispId);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_Invoke(IHTMLXMLHttpRequest2 *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
+        WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
+            pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_put_timeout(IHTMLXMLHttpRequest2 *iface, LONG v)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+
+    TRACE("(%p)->(%ld)\n", This, v);
+
+    if(v < 0)
+        return E_INVALIDARG;
+    return map_nsresult(nsIXMLHttpRequest_SetTimeout(This->nsxhr, v));
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_get_timeout(IHTMLXMLHttpRequest2 *iface, LONG *p)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+    nsresult nsres;
+    UINT32 timeout;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    if(!p)
+        return E_POINTER;
+
+    nsres = nsIXMLHttpRequest_GetTimeout(This->nsxhr, &timeout);
+    *p = timeout;
+    return map_nsresult(nsres);
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_put_ontimeout(IHTMLXMLHttpRequest2 *iface, VARIANT v)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+
+    FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLXMLHttpRequest2_get_ontimeout(IHTMLXMLHttpRequest2 *iface, VARIANT *p)
+{
+    HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
+
+    FIXME("(%p)->(%p)\n", This, p);
+
+    return E_NOTIMPL;
+}
+
+static const IHTMLXMLHttpRequest2Vtbl HTMLXMLHttpRequest2Vtbl = {
+    HTMLXMLHttpRequest2_QueryInterface,
+    HTMLXMLHttpRequest2_AddRef,
+    HTMLXMLHttpRequest2_Release,
+    HTMLXMLHttpRequest2_GetTypeInfoCount,
+    HTMLXMLHttpRequest2_GetTypeInfo,
+    HTMLXMLHttpRequest2_GetIDsOfNames,
+    HTMLXMLHttpRequest2_Invoke,
+    HTMLXMLHttpRequest2_put_timeout,
+    HTMLXMLHttpRequest2_get_timeout,
+    HTMLXMLHttpRequest2_put_ontimeout,
+    HTMLXMLHttpRequest2_get_ontimeout
+};
+
 static inline HTMLXMLHttpRequest *impl_from_IProvideClassInfo2(IProvideClassInfo2 *iface)
 {
     return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IProvideClassInfo2_iface);
@@ -895,6 +1009,7 @@ static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = {
 };
 
 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
+    IHTMLXMLHttpRequest2_tid,
     0
 };
 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
@@ -1013,6 +1128,7 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
     ret->nsxhr = nsxhr;
 
     ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
+    ret->IHTMLXMLHttpRequest2_iface.lpVtbl = &HTMLXMLHttpRequest2Vtbl;
     ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl;
     EventTarget_Init(&ret->event_target, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
                      &HTMLXMLHttpRequest_dispex, This->window->doc->document_mode);




More information about the wine-cvs mailing list