On Sun Sep 14 14:40:22 2025 +0000, Jacek Caban wrote:
There is `nsIXMLHttpRequest::GetChannel` and `nsIChannel::GetContentType` that could potentially be useful. And if we really need to do parsing here, there is `nsIXMLHttpRequest::GetResponseBuffer` that would give us raw data instead of converting it back and forth with potentially different code pages. What's the exact Windows behavior? For example "Accept" header from the other patch could probably be tested with our emulated http protocol handler, I'm not sure how practical that is. It should be easy to capture http traffic on Windows to see, does it behave the same?
I can't get the custom pluggable http protocol to work on native, it keeps aborting on send(). To be specific, it's the `IHttpNegotiate_OnResponse` on the sink that aborts. I tried to find out why, even copy pasted the response headers from the test URL that works (http://test.winehq.org/tests/cors.html) and nothing worked.
nsChannel's GetContentType doesn't seem to help, unfortunately. Because it's going to use the content type specified in the response header instead by that time (Gecko will issue SetContentType on it), so the test will fail.
If you want here's the snippet you can test the nsChannel way with: ```diff diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 52608f7..2f1db09 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1745,10 +1745,40 @@ static HRESULT WINAPI HTMLXDomainRequest_get_timeout(IHTMLXDomainRequest *iface, static HRESULT WINAPI HTMLXDomainRequest_get_contentType(IHTMLXDomainRequest *iface, BSTR *p) { HTMLXMLHttpRequest *This = impl_from_IHTMLXDomainRequest(iface); + const char *content_type = "wine/test"; + nsIChannel *nschannel; + HRESULT hres = S_OK; + nsACString nsstr; + nsresult nsres; + int len;
- FIXME("(%p)->(%p)\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- return E_NOTIMPL; + if(!p) + return E_POINTER; + + if(This->ready_state < READYSTATE_LOADED) { + *p = NULL; + return S_OK; + } + + nsACString_Init(&nsstr, NULL); + + nsres = nsIXMLHttpRequest_GetChannel(This->nsxhr, &nschannel); + if(NS_SUCCEEDED(nsres)) { + nsres = nsIChannel_GetContentType(nschannel, &nsstr); + if(NS_SUCCEEDED(nsres)) + nsACString_GetData(&nsstr, &content_type); + } + + len = MultiByteToWideChar(CP_UTF8, 0, content_type, -1, NULL, 0); + if(!(*p = SysAllocStringLen(NULL, len - 1))) + hres = E_OUTOFMEMORY; + else + MultiByteToWideChar(CP_UTF8, 0, content_type, -1, *p, len); + + nsACString_Finish(&nsstr); + return hres; }
static HRESULT WINAPI HTMLXDomainRequest_put_onprogress(IHTMLXDomainRequest *iface, VARIANT v) ```
The last problem is with `GetResponseBuffer`. I'm not sure what's ideal to do here. GetResponseBuffer works with ArrayBuffer response only (it uses gecko's ArrayBuffer methods for it). Sure, I can use `nsIXMLHttpRequest_SetResponseType` after open() to set it to ArrayBuffer, but then GetResponseText isn't gonna work. Should I manually allocate and convert in GetResponseText or is that too ugly?