POST request on a blob resource should return a "network error" instead of HTTP 500...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Jun 2016 17:14:09 +0000 (17:14 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Jun 2016 17:14:09 +0000 (17:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=158022

Patch by Nael Ouedraogo <nael.ouedraogo@crf.canon.fr> on 2016-06-01
Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

Make sure request on blob resource is correct.

* web-platform-tests/fetch/api/basic/scheme-blob-expected.txt:
* web-platform-tests/fetch/api/basic/scheme-blob-worker-expected.txt:
* web-platform-tests/fetch/api/basic/scheme-blob.js: Add new tests with several HTTP methods.

Source/WebCore:

Not allowed HTTP method is notified as failed in BlobResourceHandle as per Fetch
specification (5.2 Basic fetch). This behavior is observable in fetch WPT tests.

The behavior of XHR is slightly changed for asynchronous request on a blob resource with not
allowed or invalid HTTP methods. The onError callback is called instead of throwing an
exception as per XHR specification (https://xhr.spec.whatwg.org/#request-error-steps).

WPT tests expected results have been updated for fetch tests on blob resources which are
now correct.

Test: fast/files/xhr-blob-request.html ensures XHR response to requests on a blob resource is
correct.

* platform/network/BlobResourceHandle.cpp:
(WebCore::BlobResourceHandle::doStart):
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::createRequest):

LayoutTests:

Make sure response to XHR request on blob is correct.

* fast/files/xhr-blob-request-expected.txt: Added.
* fast/files/xhr-blob-request.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@201557 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/files/xhr-blob-request-expected.txt [new file with mode: 0644]
LayoutTests/fast/files/xhr-blob-request.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob-expected.txt
LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob-worker-expected.txt
LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob.js
Source/WebCore/ChangeLog
Source/WebCore/platform/network/BlobResourceHandle.cpp
Source/WebCore/xml/XMLHttpRequest.cpp

index 95ea9a3..75c1a7e 100644 (file)
@@ -1,3 +1,15 @@
+2016-06-01  Nael Ouedraogo  <nael.ouedraogo@crf.canon.fr>
+
+        POST request on a blob resource should return a "network error" instead of HTTP 500 response
+        https://bugs.webkit.org/show_bug.cgi?id=158022
+
+        Reviewed by Alex Christensen.
+
+        Make sure response to XHR request on blob is correct.
+
+        * fast/files/xhr-blob-request-expected.txt: Added.
+        * fast/files/xhr-blob-request.html: Added.
+
 2016-06-01  Javier Fernandez  <jfernandez@igalia.com>
 
         Unreviewed GTK+ gardening. Rebaseline several tests after r201397.
diff --git a/LayoutTests/fast/files/xhr-blob-request-expected.txt b/LayoutTests/fast/files/xhr-blob-request-expected.txt
new file mode 100644 (file)
index 0000000..ee317c8
--- /dev/null
@@ -0,0 +1,19 @@
+
+PASS Exception should be thrown for TRACE request 
+PASS Exception should be thrown for TRACK request 
+PASS Exception should be thrown for CONNECT request 
+PASS Synchronous XHR request should succeed with GET 
+PASS Synchronous XHR request should throw exception with OPTIONS 
+PASS Synchronous XHR request should throw exception with HEAD 
+PASS Synchronous XHR request should throw exception with PUT 
+PASS Synchronous XHR request should throw exception with DELETE 
+PASS Synchronous XHR request should throw exception with INVALID 
+PASS Synchronous XHR request should throw exception with POST 
+PASS Asynchronous XHR request should succeed with GET 
+PASS Asynchronous XHR request should calls onError callback with OPTIONS 
+PASS Asynchronous XHR request should calls onError callback with HEAD 
+PASS Asynchronous XHR request should calls onError callback with PUT 
+PASS Asynchronous XHR request should calls onError callback with DELETE 
+PASS Asynchronous XHR request should calls onError callback with INVALID 
+PASS Asynchronous XHR request should calls onError callback with POST 
+
diff --git a/LayoutTests/fast/files/xhr-blob-request.html b/LayoutTests/fast/files/xhr-blob-request.html
new file mode 100644 (file)
index 0000000..acf3a7d
--- /dev/null
@@ -0,0 +1,129 @@
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Test a XMLHttpRequest request of a Blob URL responds appropriately.</title>
+    <meta name="author" title="Canon Research France" href="https://www.crf.canon.fr">
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <script>
+var array = new Int8Array([0, 1, 2, 3]);
+var blob = new Blob(array);
+var url = URL.createObjectURL(blob);
+
+function test_allowed_method_sync(method) {
+    test (() => {
+        var req = new XMLHttpRequest;
+        var onLoad = false;
+        req.open(method, url, false);
+
+        req.onerror = function(evt) {
+            assert_unreached('Error callback called for synchronous ' + method + ' XHR');
+        }
+
+        req.onload = function() {
+            onLoad = true;
+        }
+
+        try {
+            req.send();
+            assert_true(onLoad);
+        }
+        catch(e) {
+            assert_unreached('Exception thrown for synchronous ' + method + ' XHR');
+        }
+    }, 'Synchronous XHR request should succeed with ' + method);
+}
+
+function test_notAllowed_method_sync(method) {
+    test (() => {
+        var req = new XMLHttpRequest;
+        var onError = false;
+        req.open(method, url, false);
+
+        req.onerror = function(evt) {
+            onError = true;
+        }
+
+        req.onload = function() {
+            assert_unreached('Exception should be thrown for synchronous ' + method + ' XHR');
+        }
+
+        assert_throws('NetworkError', () => { req.send(); }, 'Exception thrown for synchronous ' + method + ' XHR');
+
+        assert_false(onError, 'Error callback is called');
+    }, 'Synchronous XHR request should throw exception with ' + method);
+}
+
+function create_async_xhr_promise(method) {
+    return new Promise(function(resolve) {
+        var req = new XMLHttpRequest;
+        var status = { "onError" : false, "onLoad" : false };
+
+        req.open(method, url, true);
+
+        req.onerror = function(evt) {
+            status.onError = true;
+        }
+
+        req.onload = function() {
+            status.onLoad = true;
+        }
+
+        req.onloadend = function() {
+            resolve(status);
+        }
+
+        try {
+            req.send();
+        }
+        catch(e) {
+            assert_unreached('Exception thrown');
+        }
+    });
+}
+
+function test_method_async(method, shouldLoad) {
+    promise_test(() => {
+        return create_async_xhr_promise(method).then((res) => {
+            assert_equals(res.onError, !shouldLoad, 'XHR request calls onError callback');
+            assert_equals(res.onLoad, shouldLoad, 'XHR request is loaded');
+        })
+    }, 'Asynchronous XHR request should ' + (shouldLoad ? 'succeed' : 'calls onError callback') + ' with ' + method);
+}
+
+
+
+function test_forbidden_method(request) {
+    test(() => {
+        assert_throws('SecurityError', () => {
+            var req = new XMLHttpRequest;
+            req.open(request, url);
+        })
+    }, 'Exception should be thrown for ' + request + ' request');
+}
+test_forbidden_method('TRACE');
+test_forbidden_method('TRACK');
+test_forbidden_method('CONNECT');
+
+test_allowed_method_sync('GET');
+test_notAllowed_method_sync('OPTIONS');
+test_notAllowed_method_sync('HEAD');
+test_notAllowed_method_sync('PUT');
+test_notAllowed_method_sync('DELETE');
+test_notAllowed_method_sync('INVALID');
+test_notAllowed_method_sync('POST');
+
+test_method_async('GET', true);
+test_method_async('OPTIONS',false);
+test_method_async('HEAD',false);
+test_method_async('PUT',false);
+test_method_async('DELETE',false);
+test_method_async('INVALID',false);
+test_method_async('POST',false);
+done()
+
+</script>
+</body>
+</html>
index 72f1a44..fa7db63 100644 (file)
@@ -1,3 +1,16 @@
+2016-06-01  Nael Ouedraogo  <nael.ouedraogo@crf.canon.fr>
+
+        POST request on a blob resource should return a "network error" instead of HTTP 500 response
+        https://bugs.webkit.org/show_bug.cgi?id=158022
+
+        Reviewed by Alex Christensen.
+
+        Make sure request on blob resource is correct.
+
+        * web-platform-tests/fetch/api/basic/scheme-blob-expected.txt:
+        * web-platform-tests/fetch/api/basic/scheme-blob-worker-expected.txt:
+        * web-platform-tests/fetch/api/basic/scheme-blob.js: Add new tests with several HTTP methods.
+
 2016-06-01  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         Close wptserve response file handles explicitly
index 5eed588..a769ec6 100644 (file)
@@ -1,5 +1,10 @@
 
 PASS Fetching [GET] URL.createObjectURL(blob) is OK 
 PASS Fetching [GET] blob:http://www.localhost:8800/ is KO 
-FAIL Fetching [POST] URL.createObjectURL(blob) is KO assert_unreached: Should have rejected. Reached unreachable code
+PASS Fetching [POST] URL.createObjectURL(blob) is KO 
+PASS Fetching [OPTIONS] URL.createObjectURL(blob) is KO 
+PASS Fetching [HEAD] URL.createObjectURL(blob) is KO 
+PASS Fetching [PUT] URL.createObjectURL(blob) is KO 
+PASS Fetching [DELETE] URL.createObjectURL(blob) is KO 
+PASS Fetching [INVALID] URL.createObjectURL(blob) is KO 
 
index 5eed588..a769ec6 100644 (file)
@@ -1,5 +1,10 @@
 
 PASS Fetching [GET] URL.createObjectURL(blob) is OK 
 PASS Fetching [GET] blob:http://www.localhost:8800/ is KO 
-FAIL Fetching [POST] URL.createObjectURL(blob) is KO assert_unreached: Should have rejected. Reached unreachable code
+PASS Fetching [POST] URL.createObjectURL(blob) is KO 
+PASS Fetching [OPTIONS] URL.createObjectURL(blob) is KO 
+PASS Fetching [HEAD] URL.createObjectURL(blob) is KO 
+PASS Fetching [PUT] URL.createObjectURL(blob) is KO 
+PASS Fetching [DELETE] URL.createObjectURL(blob) is KO 
+PASS Fetching [INVALID] URL.createObjectURL(blob) is KO 
 
index d7e5ece..9bf73a6 100644 (file)
@@ -32,7 +32,17 @@ function checkKoUrl(url, method, desc) {
 var blob2 = new Blob(["Blob's data"], { "type" : "text/plain" });
 checkKoUrl("blob:http://{{domains[www]}}:{{ports[http][0]}}/", "GET",
           "Fetching [GET] blob:http://{{domains[www]}}:{{ports[http][0]}}/ is KO");
-checkKoUrl(URL.createObjectURL(blob2), "POST",
-           "Fetching [POST] URL.createObjectURL(blob) is KO");
+
+var invalidRequestMethods = [
+  "POST",
+  "OPTIONS",
+  "HEAD",
+  "PUT",
+  "DELETE",
+  "INVALID",
+];
+invalidRequestMethods.forEach(function(method) {
+  checkKoUrl(URL.createObjectURL(blob2), method, "Fetching [" + method + "] URL.createObjectURL(blob) is KO");
+});
 
 done();
index 4b1ab12..22e4f7e 100644 (file)
@@ -1,3 +1,28 @@
+2016-06-01  Nael Ouedraogo  <nael.ouedraogo@crf.canon.fr>
+
+        POST request on a blob resource should return a "network error" instead of HTTP 500 response
+        https://bugs.webkit.org/show_bug.cgi?id=158022
+
+        Reviewed by Alex Christensen.
+
+        Not allowed HTTP method is notified as failed in BlobResourceHandle as per Fetch
+        specification (5.2 Basic fetch). This behavior is observable in fetch WPT tests.
+
+        The behavior of XHR is slightly changed for asynchronous request on a blob resource with not
+        allowed or invalid HTTP methods. The onError callback is called instead of throwing an
+        exception as per XHR specification (https://xhr.spec.whatwg.org/#request-error-steps).
+
+        WPT tests expected results have been updated for fetch tests on blob resources which are
+        now correct.
+
+        Test: fast/files/xhr-blob-request.html ensures XHR response to requests on a blob resource is
+        correct.
+
+        * platform/network/BlobResourceHandle.cpp:
+        (WebCore::BlobResourceHandle::doStart):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::createRequest):
+
 2016-06-01  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         Remove allocation of SubresourceLoader::m_requestCountTracker
index 484e921..8b28139 100644 (file)
@@ -202,8 +202,7 @@ void BlobResourceHandle::doStart()
         return;
 
     if (!equalLettersIgnoringASCIICase(firstRequest().httpMethod(), "get")) {
-        m_errorCode = methodNotAllowed;
-        notifyResponse();
+        notifyFail(methodNotAllowed);
         return;
     }
 
index c3d4585..f8c7521 100644 (file)
@@ -668,7 +668,7 @@ void XMLHttpRequest::sendBytesData(const void* data, size_t length, ExceptionCod
 void XMLHttpRequest::createRequest(ExceptionCode& ec)
 {
     // Only GET request is supported for blob URL.
-    if (m_url.protocolIsBlob() && m_method != "GET") {
+    if (!m_async && m_url.protocolIsBlob() && m_method != "GET") {
         ec = NETWORK_ERR;
         return;
     }