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