JDK-8213541 : WebView does not handle HTTP response without ContentType
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 8u192,openjfx12
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2018-11-08
  • Updated: 2020-01-31
  • Resolved: 2018-11-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8u211Fixed openjdk8u212Fixed
Related Reports
Relates :  
Description
If you try to load an URL into the WebView where the response does not specify the content-type, the Loader state switch to "cancelled". 

STEPS TO REPRODUCE (a bit technical because we want to remove headers):

- Download Fiddler here : https://www.telerik.com/download/fiddler
- Launch it, then click on "Rules" -> "Customize rules"
- On the Fiddler script editor, scroll to the function "OnBeforeResponse" and modify it like that :

static function OnBeforeResponse(oSession: Session) {
        if (m_Hide304s && oSession.responseCode == 304) {
            oSession["ui-hide"] = "true";
        }
		if (oSession.uriContains("google") && oSession.responseCode == 200) {
			oSession["ui-color"] = "red";
			oSession.oResponse.headers.Remove("Content-Type");
		}
    }

- Then run the class given in attachment

EXPECTED RESULT:
The WebView should load the google webPage and display it.

ACTUAL RESULT: 
The WebView loader switch to "Cancelled" state.

EXPLANATION:

If we look at the RFC : https://tools.ietf.org/html/rfc7231#section-3.1.1.5 , we can see that the Content-type is not mandatory. Browser do display properly a webPage without Content-Type.

If we debug, we can see that in com.sun.webkit.network.URLLoader, we enter the method "notifyDidReceiveResponse", then call the native method "twkDidReceiveResponse". 
I do not have access to the native code, but after that, the WebView is notified to switch to Cancelled mode because the response is detected as incorrect.

WORK-AROUND:
Currently, it's a bit difficult. A solution consists of providing a custom URLStreamHandlerFactory in URL class. Then we can provide a custom Handler that would override "openConnection" in order to retrieve the URLConnection, wrap it and delegates all methods except from "getContentType" in order to return a default content-type when null.
Comments
Changeset: 908599063479 Author: shadzic Date: 2018-11-15 11:51 +0530 URL: http://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/908599063479 8213541: WebView does not handle HTTP response without ContentType Reviewed-by: mbilla, arajkumar ! modules/javafx.web/src/main/native/Source/WebCore/platform/network/java/URLLoader.cpp
15-11-2018

[~shadzic] please send an RFR to the openjfx-dev list with a pointer to this JBS issue and the Github PR. Then Arun can review it and get it merged / pushed to jfx-dev.
13-11-2018

I just tested fix with following simple test case using nodejs, var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': '', 'Content-Length':5}); res.end("hello"); }).listen(8811); Seems to be working. Fix looks good to me.
12-11-2018

[~arajkumar] can you take a look at this? I think [~shadzic] is suggesting that the "&& contentLength <= 0" be removed from the conditional. What is your opinion of this?
12-11-2018

I checked the bug in question (JDK-8113134) and it can be made public, so I did.
12-11-2018

I was able to find the code of URLLoader.cpp on Mac for JDK 11, and I see that the "setupResponse" method is referring to RT-13802 which should link to https://bugs.openjdk.java.net/browse/JDK-8113134 (but I cannot see this issue). Apparently, there is a piece of code that check if the content-type is empty and sets it to "text/html" if it's empty : // Fix for RT-13802: If the mime type is not specified // and the expected content length is 0 or not specified, // set the mime type to "text/html" as e.g. the CF port // does String contentTypeString(env, contentType); if (contentTypeString.isEmpty() && contentLength <= 0) { contentTypeString = "text/html"; } BUT, in our case, we have a content-type empty but a content-length specified! Therefore we never enter into this piece of code and never set the content-type to a default "text/html"
08-11-2018