From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/navigate.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index e6f203535b7..5d74cc15e5d 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -708,12 +708,26 @@ HRESULT read_stream(BSCallback *This, IStream *stream, void *buf, DWORD size, DW
static void parse_content_type(nsChannelBSC *This, const WCHAR *value) { - const WCHAR *ptr; - size_t len; + const WCHAR *ptr, *beg, *end; + size_t len = wcslen(value); + char *content_type;
static const WCHAR charsetW[] = {'c','h','a','r','s','e','t','='};
ptr = wcschr(value, ';'); + for(end = ptr ? ptr : value + len; end > value; end--) + if(!iswspace(end[-1])) + break; + for(beg = value; beg < end; beg++) + if(!iswspace(*beg)) + break; + + if((content_type = heap_strndupWtoU(beg, end - beg))) { + heap_free(This->nschannel->content_type); + This->nschannel->content_type = content_type; + strlwr(content_type); + } + if(!ptr) return;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/navigate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 5d74cc15e5d..94ad0ea1988 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1668,10 +1668,9 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW This->nschannel = NULL; }
- if(!This->nschannel) + if(!This->nschannel || This->nschannel->content_type) return S_OK;
- heap_free(This->nschannel->content_type); This->nschannel->content_type = heap_strdupWtoA(status_text); break; case BINDSTATUS_REDIRECTING:
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/script.c | 10 ++++++- dlls/mshtml/tests/xhr.js | 57 ++++++++++++++++++++++++++++++++++-- dlls/mshtml/xmlhttprequest.c | 14 +++++++++ 3 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index e3688242715..efd161db7ec 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -3043,6 +3043,7 @@ typedef struct { IInternetProtocolSink *sink; BINDINFO bind_info;
+ BSTR content_type; IStream *stream; char *data; ULONG size; @@ -3068,6 +3069,7 @@ static void report_data(ProtocolHandler *This) IServiceProvider *service_provider; IHttpNegotiate *http_negotiate; WCHAR *addl_headers = NULL; + WCHAR headers_buf[128]; BSTR headers, url; HRESULT hres;
@@ -3091,7 +3093,10 @@ static void report_data(ProtocolHandler *This)
CoTaskMemFree(addl_headers);
- headers = SysAllocString(L"HTTP/1.1 200 OK\r\n\r\n"); + if(This->content_type) + swprintf(headers_buf, ARRAY_SIZE(headers_buf), L"HTTP/1.1 200 OK\r\nContent-Type: %s\r\n", This->content_type); + + headers = SysAllocString(This->content_type ? headers_buf : L"HTTP/1.1 200 OK\r\n\r\n"); hres = IHttpNegotiate_OnResponse(http_negotiate, 200, headers, NULL, NULL); ok(hres == S_OK, "OnResponse failed: %08lx\n", hres); SysFreeString(headers); @@ -3250,6 +3255,7 @@ static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface) if(This->uri) IUri_Release(This->uri); ReleaseBindInfo(&This->bind_info); + SysFreeString(This->content_type); HeapFree(GetProcessHeap(), 0, This); }
@@ -3424,6 +3430,8 @@ static HRESULT WINAPI ProtocolEx_StartEx(IInternetProtocolEx *iface, IUri *uri, if(SUCCEEDED(hres)) { if(!lstrcmpW(query, L"?delay")) This->delay = 1000; + else if(!wcsncmp(query, L"?content-type=", sizeof("?content-type=")-1)) + This->content_type = SysAllocString(query + sizeof("?content-type=")-1); SysFreeString(query); }
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index c450384e931..303c4add7b4 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<a name="test">wine</a>"; + function test_xhr() { var xhr = new XMLHttpRequest(); var complete_cnt = 0, loadstart = false; @@ -24,7 +26,9 @@ function test_xhr() { if(xhr.readyState != 4) return;
- ok(xhr.responseText === "Testing...", "unexpected responseText " + xhr.responseText); + ok(xhr.responseText === xml, "unexpected responseText " + xhr.responseText); + ok(xhr.responseXML !== null, "unexpected null responseXML"); + if(complete_cnt++ && !("onloadend" in xhr)) next_test(); } @@ -63,7 +67,55 @@ function test_xhr() { ok(xhr.withCredentials === true, "withCredentials = " + xhr.withCredentials); xhr.withCredentials = false; } - xhr.send("Testing..."); + xhr.send(xml); +} + +function test_content_types() { + var xhr = new XMLHttpRequest(), types, i = 0; + var v = document.documentMode; + + var types = [ + "", + "text/plain", + "text/html", + "wine/xml", + "xml" + ]; + var xml_types = [ + "text/xmL", + "apPliCation/xml", + "image/SvG+xml", + "Wine/Test+xml", + "++Xml", + "+xMl" + ]; + + function onload() { + ok(xhr.responseText === xml, "unexpected responseText " + xhr.responseText); + if(v < 10 || types === xml_types) + ok(xhr.responseXML !== null, "unexpected null responseXML for " + types[i]); + else + ok(xhr.responseXML === null, "unexpected non-null responseXML for " + types[i]); + + if(++i >= types.length) { + if(types === xml_types) { + next_test(); + return; + } + types = xml_types; + i = 0; + } + xhr = new XMLHttpRequest(); + xhr.onload = onload; + xhr.open("POST", "echo.php?content-type=" + types[i], true); + xhr.setRequestHeader("X-Test", "True"); + xhr.send(xml); + } + + xhr.onload = onload; + xhr.open("POST", "echo.php?content-type=" + types[i], true); + xhr.setRequestHeader("X-Test", "True"); + xhr.send(xml); }
function test_abort() { @@ -118,6 +170,7 @@ function test_timeout() {
var tests = [ test_xhr, + test_content_types, test_abort, test_timeout ]; diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 8fa91e9960b..c165218bdef 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -374,6 +374,20 @@ static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *if
TRACE("(%p)->(%p)\n", This, p);
+ if(dispex_compat_mode(&This->event_target.dispex) >= COMPAT_MODE_IE10) { + nsIDOMDocument *nsdoc; + nsresult nsres; + + nsres = nsIXMLHttpRequest_GetResponseXML(This->nsxhr, &nsdoc); + if(NS_FAILED(nsres)) + return map_nsresult(nsres); + if(!nsdoc) { + *p = NULL; + return S_OK; + } + nsIDOMDocument_Release(nsdoc); + } + hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc); if(FAILED(hres)) { ERR("CoCreateInstance failed: %08lx\n", hres);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118499
Your paranoid android.
=== w10pro64 (32 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w10pro64_ja (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w7u_adm (32 bit report) ===
mshtml: script.c:644: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1657203719058 expected 1657203719121"
From: Gabriel Ivăncescu gabrielopcode@gmail.com
We have to special case empty string since Gecko special cases them, but IE does not.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/xhr.js | 16 ++++++++++++++-- dlls/mshtml/xmlhttprequest.c | 23 +++++++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 303c4add7b4..8d9af26a943 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -71,7 +71,7 @@ function test_xhr() { }
function test_content_types() { - var xhr = new XMLHttpRequest(), types, i = 0; + var xhr = new XMLHttpRequest(), types, i = 0, override = false; var v = document.documentMode;
var types = [ @@ -95,7 +95,19 @@ function test_content_types() { if(v < 10 || types === xml_types) ok(xhr.responseXML !== null, "unexpected null responseXML for " + types[i]); else - ok(xhr.responseXML === null, "unexpected non-null responseXML for " + types[i]); + ok(xhr.responseXML === null, "unexpected non-null responseXML for " + (override ? "overriden " : "") + types[i]); + + if(("overrideMimeType" in xhr) && !override) { + override = true; + xhr = new XMLHttpRequest(); + xhr.onload = onload; + xhr.open("POST", "echo.php", true); + xhr.setRequestHeader("X-Test", "True"); + xhr.overrideMimeType(types[i]); + xhr.send(xml); + return; + } + override = false;
if(++i >= types.length) { if(types === xml_types) { diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index c165218bdef..f21114abcac 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -978,10 +978,29 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_withCredentials(IWineXMLHtt static HRESULT WINAPI HTMLXMLHttpRequest_private_overrideMimeType(IWineXMLHttpRequestPrivate *iface, BSTR mimeType) { HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); + static const WCHAR generic_type[] = L"application/octet-stream"; + const WCHAR *type = NULL; + WCHAR *lowercase = NULL; + nsAString nsstr; + nsresult nsres;
- FIXME("(%p)->(%s)\n", This, debugstr_w(mimeType)); + TRACE("(%p)->(%s)\n", This, debugstr_w(mimeType));
- return E_NOTIMPL; + if(mimeType) { + if(mimeType[0]) { + if(!(lowercase = heap_strdupW(mimeType))) + return E_OUTOFMEMORY; + _wcslwr(lowercase); + type = lowercase; + }else + type = generic_type; + } + + nsAString_InitDepend(&nsstr, type); + nsres = nsIXMLHttpRequest_SlowOverrideMimeType(This->nsxhr, &nsstr); + nsAString_Finish(&nsstr); + heap_free(lowercase); + return map_nsresult(nsres); }
static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onerror(IWineXMLHttpRequestPrivate *iface, VARIANT v)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118500
Your paranoid android.
=== w10pro64_ja (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w7u_adm (32 bit report) ===
mshtml: script.c:644: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1657205438489 expected 1657205438551"
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Rather than hacking a custom prop.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private_iface.idl | 20 +++++-- dlls/mshtml/xmlhttprequest.c | 86 ++++++++++++---------------- 2 files changed, 51 insertions(+), 55 deletions(-)
diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 972f9b30c90..8e9e3860b13 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -139,6 +139,10 @@ interface IWineDOMTokenList : IDispatch HRESULT toString([retval, out] BSTR *String); }
+const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSE = 1; +const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE = 2; +const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_UPLOAD = 3; +const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_WITHCREDENTIALS = 4; const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE = 5; [ odl, @@ -149,17 +153,17 @@ const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE = 5; ] interface IWineXMLHttpRequestPrivate : IDispatch { - [propget, id(1)] + [propget, id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSE)] HRESULT response([retval, out] VARIANT *p); - [propput, id(2)] + [propput, id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE)] HRESULT responseType([in] BSTR v); - [propget, id(2)] + [propget, id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE)] HRESULT responseType([retval, out] BSTR *p); - [propget, id(3)] + [propget, id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_UPLOAD)] HRESULT upload([retval, out] IDispatch **p); - [propput, id(4)] + [propput, id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_WITHCREDENTIALS)] HRESULT withCredentials([in] VARIANT_BOOL v); - [propget, id(4)] + [propget, id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_WITHCREDENTIALS)] HRESULT withCredentials([retval, out] VARIANT_BOOL *p); [id(DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE)] HRESULT overrideMimeType([in] BSTR mimeType); @@ -183,6 +187,10 @@ interface IWineXMLHttpRequestPrivate : IDispatch HRESULT onloadend([in] VARIANT v); [propget, id(DISPID_EVPROP_LOADEND)] HRESULT onloadend([retval, out] VARIANT *p); + [propput, id(DISPID_EVPROP_ONLOAD)] + HRESULT onload([in] VARIANT v); + [propget, id(DISPID_EVPROP_ONLOAD)] + HRESULT onload([retval, out] VARIANT *p); }
} /* library MSHTML_private */ diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index f21114abcac..b17fa418c6c 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -36,8 +36,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
-#define MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD MSHTML_DISPID_CUSTOM_MIN - static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str) { char *cstr = heap_strdupWtoU(bstr); @@ -1093,6 +1091,24 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onloadend(IWineXMLHttpReque return get_event_handler(&This->event_target, EVENTID_LOADEND, p); }
+static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onload(IWineXMLHttpRequestPrivate *iface, VARIANT v) +{ + HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_event_handler(&This->event_target, EVENTID_LOAD, &v); +} + +static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onload(IWineXMLHttpRequestPrivate *iface, VARIANT *p) +{ + HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_event_handler(&This->event_target, EVENTID_LOAD, p); +} + static const IWineXMLHttpRequestPrivateVtbl WineXMLHttpRequestPrivateVtbl = { HTMLXMLHttpRequest_private_QueryInterface, HTMLXMLHttpRequest_private_AddRef, @@ -1117,7 +1133,9 @@ static const IWineXMLHttpRequestPrivateVtbl WineXMLHttpRequestPrivateVtbl = { HTMLXMLHttpRequest_private_put_onloadstart, HTMLXMLHttpRequest_private_get_onloadstart, HTMLXMLHttpRequest_private_put_onloadend, - HTMLXMLHttpRequest_private_get_onloadend + HTMLXMLHttpRequest_private_get_onloadend, + HTMLXMLHttpRequest_private_put_onload, + HTMLXMLHttpRequest_private_get_onload };
static inline HTMLXMLHttpRequest *impl_from_IProvideClassInfo2(IProvideClassInfo2 *iface) @@ -1170,47 +1188,6 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex); }
-static HRESULT HTMLXMLHttpRequest_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) -{ - /* onload event handler property is supported, but not exposed by any interface. We implement as a custom property. */ - if(!wcscmp(L"onload", name)) { - *dispid = MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD; - return S_OK; - } - - return DISP_E_UNKNOWNNAME; -} - -static HRESULT HTMLXMLHttpRequest_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, - VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) -{ - HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); - - if(id == MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD) { - switch(flags) { - case DISPATCH_PROPERTYGET: - TRACE("(%p) get onload\n", This); - return get_event_handler(&This->event_target, EVENTID_LOAD, res); - - case DISPATCH_PROPERTYPUT: - if(params->cArgs != 1 || (params->cNamedArgs == 1 && *params->rgdispidNamedArgs != DISPID_PROPERTYPUT) - || params->cNamedArgs > 1) { - FIXME("invalid args\n"); - return E_INVALIDARG; - } - - TRACE("(%p)->(%p) set onload\n", This, params->rgvarg); - return set_event_handler(&This->event_target, EVENTID_LOAD, params->rgvarg); - - default: - FIXME("Unimplemented flags %x\n", flags); - return E_NOTIMPL; - } - } - - return DISP_E_UNKNOWNNAME; -} - static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); @@ -1266,22 +1243,33 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode {DISPID_IHTMLXMLHTTPREQUEST_OPEN, HTMLXMLHttpRequest_open_hook}, {DISPID_UNKNOWN} }; - static const dispex_hook_t private_ie10_hooks[] = { + static const dispex_hook_t private_hooks[] = { + {DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSE}, + {DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE}, + {DISPID_IWINEXMLHTTPREQUESTPRIVATE_UPLOAD}, + {DISPID_IWINEXMLHTTPREQUESTPRIVATE_WITHCREDENTIALS}, + {DISPID_EVPROP_ONERROR}, + {DISPID_EVPROP_ONABORT}, + {DISPID_EVPROP_PROGRESS}, + {DISPID_EVPROP_LOADSTART}, + {DISPID_EVPROP_LOADEND}, + + /* IE10 only */ {DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE}, {DISPID_UNKNOWN} }; + const dispex_hook_t *const private_ie10_hooks = private_hooks + ARRAY_SIZE(private_hooks) - 2;
EventTarget_init_dispex_info(info, compat_mode); dispex_info_add_interface(info, IHTMLXMLHttpRequest_tid, compat_mode >= COMPAT_MODE_IE10 ? xhr_hooks : NULL); - if(compat_mode >= COMPAT_MODE_IE10) - dispex_info_add_interface(info, IWineXMLHttpRequestPrivate_tid, compat_mode == COMPAT_MODE_IE10 ? private_ie10_hooks : NULL); + dispex_info_add_interface(info, IWineXMLHttpRequestPrivate_tid, + compat_mode < COMPAT_MODE_IE10 ? private_hooks : + compat_mode < COMPAT_MODE_IE11 ? private_ie10_hooks : NULL); }
static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { { NULL, - HTMLXMLHttpRequest_get_dispid, - HTMLXMLHttpRequest_invoke }, HTMLXMLHttpRequest_get_gecko_target, HTMLXMLHttpRequest_bind_event
Jacek Caban (@jacek) commented about dlls/mshtml/navigate.c:
This->nschannel = NULL; }
if(!This->nschannel)
if(!This->nschannel || This->nschannel->content_type)
That's not how generally MIME types from urlmon are meant to be handled. What's wrong with MIME types from urlmon?
On Thu Jul 7 15:02:35 2022 +0000, Jacek Caban wrote:
That's not how generally MIME types from urlmon are meant to be handled. What's wrong with MIME types from urlmon?
urlmon detects the MIME type from the content (parsing it), but the content type set in the header should take precedence over that. You can see this in the next commit's tests which will simply fail without this.