Changeset 198665 in webkit


Ignore:
Timestamp:
Mar 25, 2016 7:19:31 AM (8 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

[Fetch API] Add basic loading of resources
https://bugs.webkit.org/show_bug.cgi?id=155637

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebasing test expectations.
Updating scheme-blob.js to ensure generated test names are stable run after run.

  • web-platform-tests/fetch/api/basic/accept-header-expected.txt:
  • web-platform-tests/fetch/api/basic/integrity-expected.txt:
  • web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
  • web-platform-tests/fetch/api/basic/mode-same-origin-expected.txt:
  • web-platform-tests/fetch/api/basic/request-forbidden-headers-expected.txt:
  • web-platform-tests/fetch/api/basic/request-headers-expected.txt:
  • web-platform-tests/fetch/api/basic/scheme-about-expected.txt:
  • 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:

(checkFetchResponse): Deleted.
(checkKoUrl): Deleted.

  • web-platform-tests/fetch/api/basic/scheme-data-expected.txt:
  • web-platform-tests/fetch/api/basic/scheme-others-expected.txt:
  • web-platform-tests/fetch/api/basic/stream-response-expected.txt:

Source/WebCore:

Adding support for basic fetch for Window (no support for Worker yet).
A FetchResponse object is created for every fetch task.
But it will only be exposed to JS at promise fulfillment time, i.e. once initial response headers are retrieved.

Updating Blob resource handle to add Content-Type and Content-Length header and notifying of error in case of erroneous HTTP method.

Fetch is limited to same origin requests currently due to some WPT tests that would timeout otherwise.

Tests: http/tests/fetch/closing-while-fetching.html

http/tests/fetch/get-response-body-while-loading.html

Also covered by rebased tests.

  • Modules/fetch/DOMWindowFetch.cpp: Creating a FetchResponse to start fetching.

(WebCore::DOMWindowFetch::fetch):

  • Modules/fetch/DOMWindowFetch.h:
  • Modules/fetch/FetchBody.cpp:

(WebCore::FetchBody::consume):
(WebCore::FetchBody::consumeArrayBuffer): Handling of body promises in case of data stored as a buffer.
(WebCore::FetchBody::consumeText): Passing the promise as a reference.
(WebCore::blobFromArrayBuffer): Helper routine.
(WebCore::FetchBody::fulfillTextPromise): Helper routine.
(WebCore::FetchBody::loadedAsArrayBuffer): Updated to handle storing of data as a buffer.
(WebCore::FetchBody::loadedAsText):
(WebCore::FetchBody::bodyForInternalRequest): Helper routine to generate the request body data to be sent as part of the fetch request.
(WebCore::FetchBody::extractFromText):

  • Modules/fetch/FetchBody.h:

(WebCore::FetchBody::loadingBody):
(WebCore::FetchBody::FetchBody):

  • Modules/fetch/FetchBodyOwner.cpp:

(WebCore::FetchBodyOwner::loadBlob): Updated to cope with the change that FetchLoader::start does not return a boolean anymore
but will directly call failure callbacks.
(WebCore::FetchBodyOwner::loadedBlobAsText): Moving it closer to other blob loading routines.
(WebCore::FetchBodyOwner::finishBlobLoading):

  • Modules/fetch/FetchBodyOwner.h:

(WebCore::FetchBodyOwner::body):
(WebCore::FetchBodyOwner::loadedBlobAsArrayBuffer):

  • Modules/fetch/FetchHeaders.cpp:

(WebCore::FetchHeaders::fill):
(WebCore::FetchHeaders::filterAndFill): Helper routine to fill headers from a HTTPHeaderMap after being filtered.

  • Modules/fetch/FetchHeaders.h:

(WebCore::FetchHeaders::internalHeaders):

  • Modules/fetch/FetchLoader.cpp:

(WebCore::FetchLoader::start):
(WebCore::FetchLoader::didFailRedirectCheck):

  • Modules/fetch/FetchLoader.h:
  • Modules/fetch/FetchRequest.cpp:

(WebCore::FetchRequest::internalRequest): Routine used to create the ResourceRequest transmitted to ThreadableLoader.

  • Modules/fetch/FetchRequest.h:
  • Modules/fetch/FetchResponse.cpp:

(WebCore::FetchResponse::fetch): Start fetching by creating a FetchLoader based on passed request.
(WebCore::FetchResponse::BodyLoader::didSucceed): FetchLoader callback.
(WebCore::FetchResponse::BodyLoader::didFail): Ditto.
(WebCore::FetchResponse::BodyLoader::BodyLoader): Ditto.
(WebCore::FetchResponse::BodyLoader::didReceiveResponse): Ditto.
(WebCore::FetchResponse::BodyLoader::didFinishLoadingAsArrayBuffer): Ditto.
(WebCore::FetchResponse::BodyLoader::start): Starting fetch loader.
(WebCore::FetchResponse::BodyLoader::stop): Stopping fetch loader.
(WebCore::FetchResponse::stop): Stop loader if any.

  • Modules/fetch/FetchResponse.h:
  • platform/network/BlobResourceHandle.cpp:

(WebCore::BlobResourceHandle::doStart: Notifying the loader with an error if verb is not GET.
(WebCore::BlobResourceHandle::notifyResponseOnSuccess): Adding support for Content-Type and Content-Lenth headers.
(WebCore::BlobResourceHandle::createAsync): Removing GET verb check.

LayoutTests:

  • TestExpectations: Removed flaky test expectations.
  • http/tests/fetch/closing-while-fetching-expected.txt: Added.
  • http/tests/fetch/closing-while-fetching.html: Added.
  • http/tests/fetch/get-response-body-while-loading-expected.txt: Added.
  • http/tests/fetch/get-response-body-while-loading.html: Added.
  • http/tests/resources/download-json-with-delay.php: Added.
  • platform/gtk/imported/w3c/web-platform-tests/fetch/api/basic/request-headers-expected.txt: Added.
Location:
trunk
Files:
12 added
32 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r198663 r198665  
     12016-03-25  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Fetch API] Add basic loading of resources
     4        https://bugs.webkit.org/show_bug.cgi?id=155637
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestExpectations: Removed flaky test expectations.
     9        * http/tests/fetch/closing-while-fetching-expected.txt: Added.
     10        * http/tests/fetch/closing-while-fetching.html: Added.
     11        * http/tests/fetch/get-response-body-while-loading-expected.txt: Added.
     12        * http/tests/fetch/get-response-body-while-loading.html: Added.
     13        * http/tests/resources/download-json-with-delay.php: Added.
     14        * platform/gtk/imported/w3c/web-platform-tests/fetch/api/basic/request-headers-expected.txt: Added.
     15
    1162016-03-25  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
    217
  • trunk/LayoutTests/TestExpectations

    r198649 r198665  
    317317imported/w3c/web-platform-tests/XMLHttpRequest/send-redirect-to-cors.htm [ Skip ]
    318318imported/w3c/web-platform-tests/XMLHttpRequest/send-redirect-to-non-cors.htm [ Skip ]
    319 
    320 # Tests that are flaky as failing assertions print a new token generated for each test run.
    321 imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob.html [ Failure ]
    322 imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob-worker.html [ Failure ]
    323319
    324320# New W3C ref tests that are failing.
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r198649 r198665  
     12016-03-25  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Fetch API] Add basic loading of resources
     4        https://bugs.webkit.org/show_bug.cgi?id=155637
     5
     6        Reviewed by Darin Adler.
     7
     8        Rebasing test expectations.
     9        Updating scheme-blob.js to ensure generated test names are stable run after run.
     10
     11        * web-platform-tests/fetch/api/basic/accept-header-expected.txt:
     12        * web-platform-tests/fetch/api/basic/integrity-expected.txt:
     13        * web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
     14        * web-platform-tests/fetch/api/basic/mode-same-origin-expected.txt:
     15        * web-platform-tests/fetch/api/basic/request-forbidden-headers-expected.txt:
     16        * web-platform-tests/fetch/api/basic/request-headers-expected.txt:
     17        * web-platform-tests/fetch/api/basic/scheme-about-expected.txt:
     18        * web-platform-tests/fetch/api/basic/scheme-blob-expected.txt:
     19        * web-platform-tests/fetch/api/basic/scheme-blob-worker-expected.txt:
     20        * web-platform-tests/fetch/api/basic/scheme-blob.js:
     21        (checkFetchResponse): Deleted.
     22        (checkKoUrl): Deleted.
     23        * web-platform-tests/fetch/api/basic/scheme-data-expected.txt:
     24        * web-platform-tests/fetch/api/basic/scheme-others-expected.txt:
     25        * web-platform-tests/fetch/api/basic/stream-response-expected.txt:
     26
    1272016-03-24  Commit Queue  <commit-queue@webkit.org>
    228
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/accept-header-expected.txt

    r198649 r198665  
    11
    2 FAIL Request through fetch should have 'accept' header with value '*/*' promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
     2PASS Request through fetch should have 'accept' header with value '*/*'
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/integrity-expected.txt

    r198649 r198665  
    11
    2 FAIL Empty string integrity promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL SHA-256 integrity promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL SHA-384 integrity promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    5 FAIL SHA-512 integrity promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    6 FAIL Invalid integrity assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    7 FAIL Multiple integrities: valid stronger than invalid promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    8 FAIL Multiple integrities: invalid stronger than valid assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    9 FAIL Multiple integrities: invalid as strong as valid promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    10 FAIL Multiple integrities: both are valid promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    11 FAIL Multiple integrities: both are invalid assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    12 FAIL CORS empty integrity promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    13 FAIL CORS SHA-512 integrity promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    14 FAIL CORS invalid integrity assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2PASS Empty string integrity
     3PASS SHA-256 integrity
     4PASS SHA-384 integrity
     5PASS SHA-512 integrity
     6FAIL Invalid integrity assert_unreached: Should have rejected. Reached unreachable code
     7PASS Multiple integrities: valid stronger than invalid
     8FAIL Multiple integrities: invalid stronger than valid assert_unreached: Should have rejected. Reached unreachable code
     9PASS Multiple integrities: invalid as strong as valid
     10PASS Multiple integrities: both are valid
     11FAIL Multiple integrities: both are invalid assert_unreached: Should have rejected. Reached unreachable code
     12FAIL CORS empty integrity promise_test: Unhandled rejection with value: object "TypeError: Type error"
     13FAIL CORS SHA-512 integrity promise_test: Unhandled rejection with value: object "TypeError: Type error"
     14PASS CORS invalid integrity
    1515
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetch ../resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    5 FAIL Fetch http://www.localhost:8800/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
     2PASS Fetch ../resources/top.txt with no-cors mode
     3PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
     4FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object "TypeError: Type error"
     5FAIL Fetch http://www.localhost:8800/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object "TypeError: Type error"
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-same-origin-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetch ../resources/top.txt with same-origin mode promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetch http://localhost:8800/fetch/api/resources/top.txt with same-origin mode promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with same-origin mode assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    5 FAIL Fetch http://www.localhost:8800/fetch/api/resources/top.txt with same-origin mode assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2PASS Fetch ../resources/top.txt with same-origin mode
     3PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with same-origin mode
     4PASS Fetch https://localhost:9443/fetch/api/resources/top.txt with same-origin mode
     5PASS Fetch http://www.localhost:8800/fetch/api/resources/top.txt with same-origin mode
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-forbidden-headers-expected.txt

    r198649 r198665  
    11
    2 FAIL Accept-Charset is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Accept-Encoding is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL Access-Control-Request-Headers is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    5 FAIL Access-Control-Request-Method is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    6 FAIL Connection is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    7 FAIL Content-Length is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    8 FAIL Cookie is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    9 FAIL Cookie2 is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    10 FAIL Date is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    11 FAIL DNT is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    12 FAIL Expect is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    13 FAIL Host is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    14 FAIL Keep-Alive is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    15 FAIL Origin is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    16 FAIL Referer is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    17 FAIL TE is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    18 FAIL Trailer is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    19 FAIL Transfer-Encoding is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    20 FAIL Upgrade is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    21 FAIL Via is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    22 FAIL Proxy- is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    23 FAIL Proxy-Test is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    24 FAIL Sec- is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    25 FAIL Sec-Test is a forbidden request header promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
     2PASS Accept-Charset is a forbidden request header
     3PASS Accept-Encoding is a forbidden request header
     4PASS Access-Control-Request-Headers is a forbidden request header
     5PASS Access-Control-Request-Method is a forbidden request header
     6PASS Connection is a forbidden request header
     7PASS Content-Length is a forbidden request header
     8PASS Cookie is a forbidden request header
     9PASS Cookie2 is a forbidden request header
     10PASS Date is a forbidden request header
     11PASS DNT is a forbidden request header
     12PASS Expect is a forbidden request header
     13PASS Host is a forbidden request header
     14PASS Keep-Alive is a forbidden request header
     15PASS Origin is a forbidden request header
     16PASS Referer is a forbidden request header
     17PASS TE is a forbidden request header
     18PASS Trailer is a forbidden request header
     19PASS Transfer-Encoding is a forbidden request header
     20PASS Upgrade is a forbidden request header
     21PASS Via is a forbidden request header
     22PASS Proxy- is a forbidden request header
     23PASS Proxy-Test is a forbidden request header
     24PASS Sec- is a forbidden request header
     25PASS Sec-Test is a forbidden request header
    2626
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-headers-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetch with GET promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetch with HEAD promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL Fetch with HEAD with body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    5 FAIL Fetch with PUT without body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    6 FAIL Fetch with PUT with body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    7 FAIL Fetch with POST without body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    8 FAIL Fetch with POST with body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    9 FAIL Fetch with Chicken promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    10 FAIL Fetch with Chicken with body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
     2FAIL Fetch with GET assert_equals: Request has header origin: http://localhost:8800 expected (string) "http://localhost:8800" but got (object) null
     3FAIL Fetch with HEAD assert_equals: Request has header origin: http://localhost:8800 expected (string) "http://localhost:8800" but got (object) null
     4FAIL Fetch with HEAD with body promise_test: Unhandled rejection with value: object "TypeError: Type error"
     5PASS Fetch with PUT without body
     6PASS Fetch with PUT with body
     7PASS Fetch with POST without body
     8PASS Fetch with POST with body
     9FAIL Fetch with Chicken assert_equals: Request has header content-length: null expected (object) null but got (string) "0"
     10PASS Fetch with Chicken with body
    1111
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetching about:blank is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetching about:unicorn is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL Fetching about:invalid.com is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    5 FAIL Fetching about:config is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2FAIL Fetching about:blank is OK promise_test: Unhandled rejection with value: object "TypeError: Type error"
     3FAIL Fetching about:unicorn is OK promise_test: Unhandled rejection with value: object "TypeError: Type error"
     4PASS Fetching about:invalid.com is KO
     5PASS Fetching about:config is KO
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetching blob:http://localhost:8800/4580501e-3c0f-4b03[...] is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetching [GET] blob:http://www.localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    4 FAIL Fetching [POST] blob:http://localhost:8800/ad829fe3-9045-4b29[...] is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2PASS Regular Blob loading
     3PASS Loading an erroneous blob scheme URL
     4FAIL Loading a blob URL using POST assert_unreached: Should have rejected. Reached unreachable code
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob-worker-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetching blob:http://localhost:8800/8807dca8-91bf-4414[...] is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetching [GET] blob:http://www.localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    4 FAIL Fetching [POST] blob:http://localhost:8800/41805be3-d8cc-490f[...] is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2FAIL Regular Blob loading promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
     3FAIL Loading an erroneous blob scheme URL assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     4FAIL Loading a blob URL using POST assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-blob.js

    r198649 r198665  
    55
    66function checkFetchResponse(url, data, mime, size, desc) {
    7   if (!desc)
    8     var cut = (url.length >= 45) ? "[...]" : "";
    9     desc = "Fetching " + url.substring(0, 45) + cut + " is OK"
    107  promise_test(function(test) {
    118    size = size.toString();
     
    2320
    2421var blob = new Blob(["Blob's data"], { "type" : "text/plain" });
    25 checkFetchResponse(URL.createObjectURL(blob), "Blob's data", "text/plain",  blob.size);
     22checkFetchResponse(URL.createObjectURL(blob), "Blob's data", "text/plain",  blob.size, "Regular Blob loading");
    2623
    2724function checkKoUrl(url, method, desc) {
    28   if (!desc)
    29     var cut = (url.length >= 45) ? "[...]" : "";
    30     desc = "Fetching [" + method + "] " + url.substring(0, 45) + cut +  " is KO"
    3125  promise_test(function(test) {
    3226    var promise = fetch(url, {"method": method});
     
    3630
    3731var blob2 = new Blob(["Blob's data"], { "type" : "text/plain" });
    38 checkKoUrl("blob:http://{{domains[www]}}:{{ports[http][0]}}/", "GET");
    39 checkKoUrl(URL.createObjectURL(blob2), "POST");
     32checkKoUrl("blob:http://{{domains[www]}}:{{ports[http][0]}}/", "GET", "Loading an erroneous blob scheme URL");
     33checkKoUrl(URL.createObjectURL(blob2), "POST", "Loading a blob URL using POST");
    4034
    4135done();
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-data-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetching data:,response%27s%20body is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    3 FAIL Fetching data:text/plain;base64,cmVzcG9uc2UncyBib[...] is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    4 FAIL Fetching data:image/png;base64,cmVzcG9uc2UncyBib2[...] is OK promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
    5 FAIL Fetching [GET] data:notAdataUrl.com is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    6 FAIL Fetching [POST] data:,response%27s%20body is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    7 FAIL Fetching [HEAD] data:,response%27s%20body is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2FAIL Fetching data:,response%27s%20body is OK promise_test: Unhandled rejection with value: object "TypeError: Type error"
     3FAIL Fetching data:text/plain;base64,cmVzcG9uc2UncyBib[...] is OK promise_test: Unhandled rejection with value: object "TypeError: Type error"
     4FAIL Fetching data:image/png;base64,cmVzcG9uc2UncyBib2[...] is OK promise_test: Unhandled rejection with value: object "TypeError: Type error"
     5PASS Fetching [GET] data:notAdataUrl.com is KO
     6PASS Fetching [POST] data:,response%27s%20body is KO
     7PASS Fetching [HEAD] data:,response%27s%20body is KO
    88
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-others-expected.txt

    r198649 r198665  
    11
    2 FAIL Fetching aaa://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    3 FAIL Fetching cap://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    4 FAIL Fetching cid://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    5 FAIL Fetching dav://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    6 FAIL Fetching dict://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    7 FAIL Fetching dns://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    8 FAIL Fetching geo://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    9 FAIL Fetching im://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    10 FAIL Fetching imap://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    11 FAIL Fetching ipp://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    12 FAIL Fetching ldap://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    13 FAIL Fetching mailto://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    14 FAIL Fetching nfs://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    15 FAIL Fetching pop://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    16 FAIL Fetching rtsp://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
    17 FAIL Fetching snmp://localhost:8800/ is KO assert_throws: function "function () { throw e }" threw "Fetch is not yet implemented" (undefined) expected object "TypeError" ("TypeError")
     2PASS Fetching aaa://localhost:8800/ is KO
     3PASS Fetching cap://localhost:8800/ is KO
     4PASS Fetching cid://localhost:8800/ is KO
     5PASS Fetching dav://localhost:8800/ is KO
     6PASS Fetching dict://localhost:8800/ is KO
     7PASS Fetching dns://localhost:8800/ is KO
     8PASS Fetching geo://localhost:8800/ is KO
     9PASS Fetching im://localhost:8800/ is KO
     10PASS Fetching imap://localhost:8800/ is KO
     11PASS Fetching ipp://localhost:8800/ is KO
     12PASS Fetching ldap://localhost:8800/ is KO
     13PASS Fetching mailto://localhost:8800/ is KO
     14PASS Fetching nfs://localhost:8800/ is KO
     15PASS Fetching pop://localhost:8800/ is KO
     16PASS Fetching rtsp://localhost:8800/ is KO
     17PASS Fetching snmp://localhost:8800/ is KO
    1818
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/stream-response-expected.txt

    r198649 r198665  
    11
    2 FAIL Stream response's body promise_test: Unhandled rejection with value: "Fetch is not yet implemented"
     2FAIL Stream response's body assert_unreached: Body does not exist in response Reached unreachable code
    33
  • trunk/Source/WebCore/ChangeLog

    r198664 r198665  
     12016-03-25  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Fetch API] Add basic loading of resources
     4        https://bugs.webkit.org/show_bug.cgi?id=155637
     5
     6        Reviewed by Darin Adler.
     7
     8        Adding support for basic fetch for Window (no support for Worker yet).
     9        A FetchResponse object is created for every fetch task.
     10        But it will only be exposed to JS at promise fulfillment time, i.e. once initial response headers are retrieved.
     11
     12        Updating Blob resource handle to add Content-Type and Content-Length header and notifying of error in case of erroneous HTTP method.
     13
     14        Fetch is limited to same origin requests currently due to some WPT tests that would timeout otherwise.
     15
     16        Tests: http/tests/fetch/closing-while-fetching.html
     17               http/tests/fetch/get-response-body-while-loading.html
     18        Also covered by rebased tests.
     19
     20        * Modules/fetch/DOMWindowFetch.cpp: Creating a FetchResponse to start fetching.
     21        (WebCore::DOMWindowFetch::fetch):
     22        * Modules/fetch/DOMWindowFetch.h:
     23        * Modules/fetch/FetchBody.cpp:
     24        (WebCore::FetchBody::consume):
     25        (WebCore::FetchBody::consumeArrayBuffer): Handling of body promises in case of data stored as a buffer.
     26        (WebCore::FetchBody::consumeText): Passing the promise as a reference.
     27        (WebCore::blobFromArrayBuffer): Helper routine.
     28        (WebCore::FetchBody::fulfillTextPromise): Helper routine.
     29        (WebCore::FetchBody::loadedAsArrayBuffer): Updated to handle storing of data as a buffer.
     30        (WebCore::FetchBody::loadedAsText):
     31        (WebCore::FetchBody::bodyForInternalRequest): Helper routine to generate the request body data to be sent as part of the fetch request.
     32        (WebCore::FetchBody::extractFromText):
     33        * Modules/fetch/FetchBody.h:
     34        (WebCore::FetchBody::loadingBody):
     35        (WebCore::FetchBody::FetchBody):
     36        * Modules/fetch/FetchBodyOwner.cpp:
     37        (WebCore::FetchBodyOwner::loadBlob): Updated to cope with the change that FetchLoader::start does not return a boolean anymore
     38        but will directly call failure callbacks.
     39        (WebCore::FetchBodyOwner::loadedBlobAsText): Moving it closer to other blob loading routines.
     40        (WebCore::FetchBodyOwner::finishBlobLoading):
     41        * Modules/fetch/FetchBodyOwner.h:
     42        (WebCore::FetchBodyOwner::body):
     43        (WebCore::FetchBodyOwner::loadedBlobAsArrayBuffer):
     44        * Modules/fetch/FetchHeaders.cpp:
     45        (WebCore::FetchHeaders::fill):
     46        (WebCore::FetchHeaders::filterAndFill): Helper routine to fill headers from a HTTPHeaderMap after being filtered.
     47        * Modules/fetch/FetchHeaders.h:
     48        (WebCore::FetchHeaders::internalHeaders):
     49        * Modules/fetch/FetchLoader.cpp:
     50        (WebCore::FetchLoader::start):
     51        (WebCore::FetchLoader::didFailRedirectCheck):
     52        * Modules/fetch/FetchLoader.h:
     53        * Modules/fetch/FetchRequest.cpp:
     54        (WebCore::FetchRequest::internalRequest): Routine used to create the ResourceRequest transmitted to ThreadableLoader.
     55       * Modules/fetch/FetchRequest.h:
     56        * Modules/fetch/FetchResponse.cpp:
     57        (WebCore::FetchResponse::fetch): Start fetching by creating a FetchLoader based on passed request.
     58        (WebCore::FetchResponse::BodyLoader::didSucceed): FetchLoader callback.
     59        (WebCore::FetchResponse::BodyLoader::didFail): Ditto.
     60        (WebCore::FetchResponse::BodyLoader::BodyLoader): Ditto.
     61        (WebCore::FetchResponse::BodyLoader::didReceiveResponse): Ditto.
     62        (WebCore::FetchResponse::BodyLoader::didFinishLoadingAsArrayBuffer): Ditto.
     63        (WebCore::FetchResponse::BodyLoader::start): Starting fetch loader.
     64        (WebCore::FetchResponse::BodyLoader::stop): Stopping fetch loader.
     65        (WebCore::FetchResponse::stop): Stop loader if any.
     66        * Modules/fetch/FetchResponse.h:
     67        * platform/network/BlobResourceHandle.cpp:
     68        (WebCore::BlobResourceHandle::doStart: Notifying the loader with an error if verb is not GET.
     69        (WebCore::BlobResourceHandle::notifyResponseOnSuccess): Adding support for Content-Type and Content-Lenth headers.
     70        (WebCore::BlobResourceHandle::createAsync): Removing GET verb check.
     71
    1722016-03-25  Konstantin Tokarev  <annulen@yandex.ru>
    273
  • trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.cpp

    r198649 r198665  
    3232#if ENABLE(FETCH_API)
    3333
     34#include "DOMWindow.h"
     35#include "FetchRequest.h"
     36#include "FetchResponse.h"
     37
    3438namespace WebCore {
    3539
    36 void DOMWindowFetch::fetch(DOMWindow&, FetchRequest*, const Dictionary&, FetchPromise&& promise)
     40void DOMWindowFetch::fetch(DOMWindow& window, FetchRequest* input, const Dictionary& dictionary, DeferredWrapper&& promise)
    3741{
    38     promise.reject(ASCIILiteral("Fetch is not yet implemented"));
     42    if (!window.scriptExecutionContext())
     43        return;
     44    ScriptExecutionContext& context = *window.scriptExecutionContext();
     45
     46    ExceptionCode ec = 0;
     47    RefPtr<FetchRequest> fetchRequest = FetchRequest::create(context, input, dictionary, ec);
     48    if (ec) {
     49        promise.reject(ec);
     50        return;
     51    }
     52    ASSERT(fetchRequest);
     53    FetchResponse::fetch(context, *fetchRequest, WTFMove(promise));
    3954}
    4055
    41 void DOMWindowFetch::fetch(DOMWindow&, const String&, const Dictionary&, FetchPromise&& promise)
     56void DOMWindowFetch::fetch(DOMWindow& window, const String& url, const Dictionary& dictionary, DeferredWrapper&& promise)
    4257{
    43     promise.reject(ASCIILiteral("Fetch is not yet implemented"));
     58    if (!window.scriptExecutionContext())
     59        return;
     60    ScriptExecutionContext& context = *window.scriptExecutionContext();
     61   
     62    ExceptionCode ec = 0;
     63    RefPtr<FetchRequest> fetchRequest = FetchRequest::create(context, url, dictionary, ec);
     64    if (ec) {
     65        promise.reject(ec);
     66        return;
     67    }
     68    ASSERT(fetchRequest);
     69    FetchResponse::fetch(context, *fetchRequest, WTFMove(promise));
    4470}
    4571
  • trunk/Source/WebCore/Modules/fetch/DOMWindowFetch.h

    r198649 r198665  
    3131#if ENABLE(FETCH_API)
    3232
    33 #include "JSDOMPromise.h"
     33#include <wtf/Forward.h>
    3434
    3535namespace WebCore {
    3636
     37class DOMWindow;
     38class DeferredWrapper;
    3739class Dictionary;
    3840class FetchRequest;
    39 class FetchResponse;
    4041
    4142class DOMWindowFetch {
    4243public:
    43     using FetchPromise = DOMPromise<RefPtr<FetchResponse>, String>;
    44     static void fetch(DOMWindow&, FetchRequest*, const Dictionary&, FetchPromise&&);
    45     static void fetch(DOMWindow&, const String&, const Dictionary&, FetchPromise&&);
     44    static void fetch(DOMWindow&, FetchRequest*, const Dictionary&, DeferredWrapper&&);
     45    static void fetch(DOMWindow&, const String&, const Dictionary&, DeferredWrapper&&);
    4646};
    4747
  • trunk/Source/WebCore/Modules/fetch/FetchBody.cpp

    r198649 r198665  
    3636#include "ExceptionCode.h"
    3737#include "FetchBodyOwner.h"
     38#include "FormData.h"
    3839#include "HTTPParsers.h"
    3940#include "JSBlob.h"
     
    4142
    4243namespace WebCore {
     44
     45static RefPtr<Blob> blobFromArrayBuffer(ArrayBuffer*, const String&);
    4346
    4447FetchBody::FetchBody(Ref<Blob>&& blob)
     
    156159void FetchBody::consume(FetchBodyOwner& owner, Consumer::Type type, DeferredWrapper&& promise)
    157160{
     161    if (m_type == Type::ArrayBuffer) {
     162        consumeArrayBuffer(type, promise);
     163        return;
     164    }
    158165    if (m_type == Type::Text) {
    159         consumeText(type, WTFMove(promise));
     166        consumeText(type, promise);
    160167        return;
    161168    }
     
    164171        return;
    165172    }
     173    if (m_type == Type::Loading) {
     174        // FIXME: We should be able to change the loading type to text if consumer type is JSON or Text.
     175        m_consumer = Consumer({type, WTFMove(promise)});
     176        return;
     177    }
    166178
    167179    // FIXME: Support other types.
     
    169181}
    170182
    171 void FetchBody::consumeText(Consumer::Type type, DeferredWrapper&& promise)
     183void FetchBody::consumeArrayBuffer(Consumer::Type type, DeferredWrapper& promise)
     184{
     185    if (type == Consumer::Type::ArrayBuffer) {
     186        fulfillPromiseWithArrayBuffer(promise, m_data.get());
     187        return;
     188    }
     189    if (type == Consumer::Type::Blob) {
     190        promise.resolve(blobFromArrayBuffer(m_data.get(), Blob::normalizedContentType(extractMIMETypeFromMediaType(m_mimeType))));
     191        return;
     192    }
     193
     194    ASSERT(type == Consumer::Type::Text || type == Consumer::Type::JSON);
     195    // FIXME: Do we need TextResourceDecoder to create a String to decode UTF-8 data.
     196    fulfillTextPromise(type, TextResourceDecoder::create(ASCIILiteral("text/plain"), "UTF-8")->decodeAndFlush(static_cast<const char*>(m_data->data()), m_data->byteLength()), promise);
     197}
     198
     199void FetchBody::consumeText(Consumer::Type type, DeferredWrapper& promise)
    172200{
    173201    ASSERT(type == Consumer::Type::ArrayBuffer || type == Consumer::Type::Blob);
     
    215243}
    216244
     245static inline RefPtr<Blob> blobFromArrayBuffer(ArrayBuffer* buffer, const String& contentType)
     246{
     247    if (!buffer)
     248        return Blob::create(Vector<char>(), contentType);
     249
     250    // FIXME: We should try to move buffer to Blob without doing this copy.
     251    Vector<char> value(buffer->byteLength());
     252    memcpy(value.data(), buffer->data(), buffer->byteLength());
     253    return Blob::create(WTFMove(value), contentType);
     254}
     255
     256void FetchBody::fulfillTextPromise(FetchBody::Consumer::Type type, const String& text, DeferredWrapper& promise)
     257{
     258    ASSERT(type == Consumer::Type::Text || type == Consumer::Type::JSON);
     259    if (type == FetchBody::Consumer::Type::Text)
     260        promise.resolve(text);
     261    else
     262        fulfillPromiseWithJSON(promise, text);
     263}
     264
    217265void FetchBody::loadingFailed()
    218266{
     
    224272void FetchBody::loadedAsArrayBuffer(RefPtr<ArrayBuffer>&& buffer)
    225273{
     274    if (m_type == Type::Loading) {
     275        m_type = Type::ArrayBuffer;
     276        m_data = buffer;
     277        if (m_consumer) {
     278            consumeArrayBuffer(m_consumer->type, m_consumer->promise);
     279            m_consumer = Nullopt;
     280        }
     281        return;
     282    }
     283
    226284    ASSERT(m_consumer);
    227285    ASSERT(m_consumer->type == Consumer::Type::Blob || m_consumer->type == Consumer::Type::ArrayBuffer);
     
    230288    else {
    231289        ASSERT(m_blob);
    232         Vector<char> data;
    233         data.reserveCapacity(buffer->byteLength());
    234         data.append(static_cast<const char*>(buffer->data()), buffer->byteLength());
    235         m_consumer->promise.resolve<RefPtr<Blob>>(Blob::create(WTFMove(data), m_blob->type()));
     290        m_consumer->promise.resolve(blobFromArrayBuffer(buffer.get(), m_blob->type()));
    236291    }
    237292    m_consumer = Nullopt;
     
    242297    ASSERT(m_consumer);
    243298    ASSERT(m_consumer->type == Consumer::Type::Text || m_consumer->type == Consumer::Type::JSON);
    244     if (m_consumer->type == Consumer::Type::Text)
    245         m_consumer->promise.resolve(text);
    246     else
    247         fulfillPromiseWithJSON(m_consumer->promise, text);
     299
     300    fulfillTextPromise(m_consumer->type, text, m_consumer->promise);
    248301    m_consumer = Nullopt;
    249302}
    250303
     304RefPtr<FormData> FetchBody::bodyForInternalRequest() const
     305{
     306    if (m_type == Type::None)
     307        return nullptr;
     308    if (m_type == Type::Text)
     309        return FormData::create(UTF8Encoding().encode(m_text, EntitiesForUnencodables));
     310    if (m_type == Type::Blob) {
     311        RefPtr<FormData> body = FormData::create();
     312        body->appendBlob(m_blob->url());
     313        return body;
     314    }
     315    ASSERT_NOT_REACHED();
     316    return nullptr;
     317}
     318
    251319}
    252320
  • trunk/Source/WebCore/Modules/fetch/FetchBody.h

    r198649 r198665  
    4545
    4646class FetchBodyOwner;
     47class FormData;
    4748
    4849class FetchBody {
     
    6263    static FetchBody extract(JSC::ExecState&, JSC::JSValue);
    6364    static FetchBody extractFromBody(FetchBody*);
     65    static FetchBody loadingBody() { return { Type::Loading }; }
    6466    FetchBody() = default;
    6567
     
    6870    void loadedAsText(String&&);
    6971
     72    RefPtr<FormData> bodyForInternalRequest() const;
     73
    7074private:
    71     enum class Type { None, Text, Blob, FormData };
     75    enum class Type { None, ArrayBuffer, Loading, Text, Blob, FormData };
    7276
    7377    FetchBody(Ref<Blob>&&);
    7478    FetchBody(Ref<DOMFormData>&&);
    7579    FetchBody(String&&);
     80    FetchBody(Type type) : m_type(type) { }
    7681
    7782    struct Consumer {
     
    8590    Vector<char> extractFromText() const;
    8691    bool processIfEmptyOrDisturbed(Consumer::Type, DeferredWrapper&);
    87     void consumeText(Consumer::Type, DeferredWrapper&&);
     92    void consumeArrayBuffer(Consumer::Type, DeferredWrapper&);
     93    void consumeText(Consumer::Type, DeferredWrapper&);
    8894    void consumeBlob(FetchBodyOwner&, Consumer::Type, DeferredWrapper&&);
    8995    static FetchLoader::Type loadingType(Consumer::Type);
     96    static void fulfillTextPromise(FetchBody::Consumer::Type, const String&, DeferredWrapper&);
     97    static void fulfillArrayBufferPromise(FetchBody::Consumer::Type, const String&, DeferredWrapper&);
    9098
    91     Type m_type = Type::None;
     99    Type m_type { Type::None };
    92100    String m_mimeType;
    93     bool m_isDisturbed = false;
     101    bool m_isDisturbed { false };
    94102
    95103    // FIXME: Add support for BufferSource and URLSearchParams.
    96104    RefPtr<Blob> m_blob;
    97105    RefPtr<DOMFormData> m_formData;
     106    RefPtr<ArrayBuffer> m_data;
    98107    String m_text;
    99108
  • trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp

    r198649 r198665  
    6060    ASSERT(!m_blobLoader);
    6161
     62    if (!scriptExecutionContext()) {
     63        m_body.loadingFailed();
     64        return;
     65    }
     66
    6267    m_blobLoader = { *this };
    6368    m_blobLoader->loader = std::make_unique<FetchLoader>(type, *m_blobLoader);
    6469
     70    m_blobLoader->loader->start(*scriptExecutionContext(), blob);
     71    if (!m_blobLoader->loader->isStarted()) {
     72        m_body.loadingFailed();
     73        m_blobLoader = Nullopt;
     74        return;
     75    }
    6576    setPendingActivity(this);
    66     if (!scriptExecutionContext() || !m_blobLoader->loader->start(*scriptExecutionContext(), blob))
    67         blobLoadingFailed();
    68 }
    69 
    70 void FetchBodyOwner::loadedBlobAsText(String&& text)
    71 {
    72     m_body.loadedAsText(WTFMove(text));
    7377}
    7478
     
    7983    m_blobLoader = Nullopt;
    8084    unsetPendingActivity(this);
     85}
     86
     87void FetchBodyOwner::loadedBlobAsText(String&& text)
     88{
     89    m_body.loadedAsText(WTFMove(text));
    8190}
    8291
     
    98107}
    99108
     109void FetchBodyOwner::BlobLoader::didFail()
     110{
     111    // didFail might be called within FetchLoader::start call.
     112    if (loader->isStarted())
     113        owner.blobLoadingFailed();
     114}
     115
    100116} // namespace WebCore
    101117
  • trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h

    r198649 r198665  
    5555    bool isActive() const { return !!m_blobLoader; }
    5656
     57protected:
     58    const FetchBody& body() const { return m_body; }
     59    FetchBody& body() { return m_body; }
     60
     61    // ActiveDOMObject API
     62    void stop() override;
     63
    5764private:
    5865    // Blob loading routines
     
    6370    void finishBlobLoading();
    6471
    65     // ActiveDOMObject API
    66     void stop() override;
    67 
    6872    struct BlobLoader final : FetchLoaderClient {
    6973        BlobLoader(FetchBodyOwner&);
     
    7377        void didFinishLoadingAsArrayBuffer(RefPtr<ArrayBuffer>&& buffer) final { owner.loadedBlobAsArrayBuffer(WTFMove(buffer)); }
    7478        void didReceiveResponse(const ResourceResponse&) final;
    75         void didFail() final { owner.blobLoadingFailed(); };
     79        void didFail() final;
    7680        void didSucceed() final { owner.blobLoadingSucceeded(); }
    7781
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp

    r198649 r198665  
    157157void FetchHeaders::fill(const FetchHeaders* headers)
    158158{
     159    ASSERT(m_guard != Guard::Immutable);
     160
    159161    if (!headers)
    160162        return;
    161163
    162     ASSERT(m_guard != Guard::Immutable);
    163 
     164    filterAndFill(headers->m_headers, m_guard);
     165}
     166
     167void FetchHeaders::filterAndFill(const HTTPHeaderMap& headers, Guard guard)
     168{
    164169    ExceptionCode ec;
    165     for (auto& header : headers->m_headers) {
    166         if (canWriteHeader(header.key, header.value, m_guard, ec)) {
     170    for (auto& header : headers) {
     171        if (canWriteHeader(header.key, header.value, guard, ec)) {
    167172            if (header.keyAsHTTPHeaderName)
    168173                m_headers.add(header.keyAsHTTPHeaderName.value(), header.value);
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.h

    r198649 r198665  
    6565    void fill(const FetchHeaders*);
    6666
     67    void filterAndFill(const HTTPHeaderMap&, Guard);
     68
    6769    String fastGet(HTTPHeaderName name) const { return m_headers.get(name); }
    6870    void fastSet(HTTPHeaderName name, const String& value) { m_headers.set(name, value); }
     
    8082    Iterator createIterator() { return Iterator(*this); }
    8183
     84    const HTTPHeaderMap& internalHeaders() const { return m_headers; }
     85
    8286private:
    8387    FetchHeaders(Guard guard) : m_guard(guard) { }
  • trunk/Source/WebCore/Modules/fetch/FetchLoader.cpp

    r198649 r198665  
    3535#include "FetchBody.h"
    3636#include "FetchLoaderClient.h"
     37#include "FetchRequest.h"
    3738#include "ResourceRequest.h"
    3839#include "ScriptExecutionContext.h"
     40#include "SecurityOrigin.h"
    3941#include "SharedBuffer.h"
    4042#include "TextResourceDecoder.h"
     
    4446namespace WebCore {
    4547
    46 bool FetchLoader::start(ScriptExecutionContext& context, Blob& blob)
     48void FetchLoader::start(ScriptExecutionContext& context, Blob& blob)
    4749{
    4850    auto urlForReading = BlobURL::createPublicURL(context.securityOrigin());
    49     if (urlForReading.isEmpty())
    50         return false;
     51    if (urlForReading.isEmpty()) {
     52        m_client.didFail();
     53        return;
     54    }
     55
    5156    ThreadableBlobRegistry::registerBlobURL(context.securityOrigin(), urlForReading, blob.url());
    5257
     
    6469
    6570    m_loader = ThreadableLoader::create(&context, this, request, options);
    66     return true;
     71}
     72
     73void FetchLoader::start(ScriptExecutionContext& context, const FetchRequest& request)
     74{
     75    // FIXME: Compute loading options according fetch options.
     76    ThreadableLoaderOptions options;
     77    options.setSendLoadCallbacks(SendCallbacks);
     78    options.setSniffContent(DoNotSniffContent);
     79    options.setDataBufferingPolicy(DoNotBufferData);
     80    options.preflightPolicy = ConsiderPreflight;
     81    options.setAllowCredentials(AllowStoredCredentials);
     82    options.crossOriginRequestPolicy = DenyCrossOriginRequests;
     83    options.contentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement::DoNotEnforce;
     84
     85    m_loader = ThreadableLoader::create(&context, this, request.internalRequest(), options);
    6786}
    6887
     
    114133}
    115134
     135void FetchLoader::didFailRedirectCheck()
     136{
     137    m_client.didFail();
     138}
     139
    116140} // namespace WebCore
    117141
  • trunk/Source/WebCore/Modules/fetch/FetchLoader.h

    r198649 r198665  
    4040class Blob;
    4141class FetchLoaderClient;
     42class FetchRequest;
    4243class ScriptExecutionContext;
    4344
     
    4849    FetchLoader(Type, FetchLoaderClient&);
    4950
    50     bool start(ScriptExecutionContext&, Blob&);
     51    void start(ScriptExecutionContext&, const FetchRequest&);
     52    void start(ScriptExecutionContext&, Blob&);
    5153    void stop();
    5254
     55    bool isStarted() const { return !!m_loader; }
    5356private:
    5457    // ThreadableLoaderClient API.
     
    5760    void didFinishLoading(unsigned long, double) final;
    5861    void didFail(const ResourceError&) final;
     62    void didFailRedirectCheck() final;
    5963
    6064private:
  • trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp

    r198649 r198665  
    436436}
    437437
     438ResourceRequest FetchRequest::internalRequest() const
     439{
     440    ResourceRequest request = m_internalRequest.request;
     441    request.setHTTPHeaderFields(m_headers->internalHeaders());
     442    request.setHTTPBody(body().bodyForInternalRequest());
     443    return request;
     444}
     445
    438446RefPtr<FetchRequest> FetchRequest::clone(ScriptExecutionContext& context, ExceptionCode& ec)
    439447{
  • trunk/Source/WebCore/Modules/fetch/FetchRequest.h

    r198649 r198665  
    7373    };
    7474
     75    const FetchOptions& fetchOptions() const { return m_internalRequest.options; }
     76    ResourceRequest internalRequest() const;
     77
    7578private:
    7679    FetchRequest(ScriptExecutionContext&, FetchBody&&, Ref<FetchHeaders>&&, InternalRequest&&);
  • trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp

    r198649 r198665  
    154154}
    155155
     156void FetchResponse::fetch(ScriptExecutionContext& context, const FetchRequest& request, FetchPromise&& promise)
     157{
     158    Ref<FetchResponse> response = adoptRef(*new FetchResponse(context, Type::Basic, FetchBody::loadingBody(), FetchHeaders::create(FetchHeaders::Guard::Immutable), ResourceResponse()));
     159
     160    // Setting pending activity until BodyLoader didFail or didSucceed callback is called.
     161    response->setPendingActivity(response.ptr());
     162
     163    response->m_bodyLoader = BodyLoader(response.get(), WTFMove(promise));
     164    if (!response->m_bodyLoader->start(context, request))
     165        response->m_bodyLoader = Nullopt;
     166}
     167
     168void FetchResponse::BodyLoader::didSucceed()
     169{
     170    m_response.m_bodyLoader = Nullopt;
     171    m_response.unsetPendingActivity(&m_response);
     172}
     173
     174void FetchResponse::BodyLoader::didFail()
     175{
     176    if (m_promise)
     177        std::exchange(m_promise, Nullopt)->reject(TypeError);
     178
     179    // Check whether didFail is called as part of FetchLoader::start.
     180    if (m_loader->isStarted())
     181        m_response.m_bodyLoader = Nullopt;
     182
     183    // FIXME: Handle the case of failing after didReceiveResponse is called.
     184
     185    m_response.unsetPendingActivity(&m_response);
     186}
     187
     188FetchResponse::BodyLoader::BodyLoader(FetchResponse& response, FetchPromise&& promise)
     189    : m_response(response)
     190    , m_promise(WTFMove(promise))
     191{
     192}
     193
     194void FetchResponse::BodyLoader::didReceiveResponse(const ResourceResponse& resourceResponse)
     195{
     196    ASSERT(m_promise);
     197
     198    m_response.m_response = resourceResponse;
     199    m_response.m_headers->filterAndFill(resourceResponse.httpHeaderFields(), FetchHeaders::Guard::Response);
     200
     201    std::exchange(m_promise, Nullopt)->resolve(&m_response);
     202}
     203
     204void FetchResponse::BodyLoader::didFinishLoadingAsArrayBuffer(RefPtr<ArrayBuffer>&& buffer)
     205{
     206    m_response.body().loadedAsArrayBuffer(WTFMove(buffer));
     207}
     208
     209bool FetchResponse::BodyLoader::start(ScriptExecutionContext& context, const FetchRequest& request)
     210{
     211    m_loader = std::make_unique<FetchLoader>(FetchLoader::Type::ArrayBuffer, *this);
     212    m_loader->start(context, request);
     213    return m_loader->isStarted();
     214}
     215
     216void FetchResponse::BodyLoader::stop()
     217{
     218    if (m_loader)
     219        m_loader->stop();
     220}
     221
     222void FetchResponse::stop()
     223{
     224    FetchBodyOwner::stop();
     225    if (m_bodyLoader) {
     226        RefPtr<FetchResponse> protect(this);
     227        m_bodyLoader->stop();
     228        m_bodyLoader = Nullopt;
     229    }
     230}
     231
    156232const char* FetchResponse::activeDOMObjectName() const
    157233{
  • trunk/Source/WebCore/Modules/fetch/FetchResponse.h

    r198649 r198665  
    4343
    4444class Dictionary;
     45class FetchRequest;
    4546
    4647typedef int ExceptionCode;
     
    5354    // FIXME: Binding generator should not require below method to handle optional status parameter.
    5455    static RefPtr<FetchResponse> redirect(ScriptExecutionContext& context, const String& url, ExceptionCode& ec) { return redirect(context, url, 302, ec); }
     56
     57    using FetchPromise = DOMPromise<RefPtr<FetchResponse>, ExceptionCode>;
     58    static void fetch(ScriptExecutionContext&, const FetchRequest&, FetchPromise&&);
    5559
    5660    void initializeWith(const Dictionary&, ExceptionCode&);
     
    7276
    7377    // ActiveDOMObject API
     78    void stop() final;
    7479    const char* activeDOMObjectName() const final;
    7580    bool canSuspendForDocumentSuspension() const final;
     81
     82    class BodyLoader final : public FetchLoaderClient {
     83    public:
     84        BodyLoader(FetchResponse&, FetchPromise&&);
     85
     86        bool start(ScriptExecutionContext&, const FetchRequest&);
     87        void stop();
     88
     89    private:
     90        // FetchLoaderClient API
     91        void didSucceed() final;
     92        void didFail() final;
     93        void didReceiveResponse(const ResourceResponse&);
     94        void didFinishLoadingAsArrayBuffer(RefPtr<ArrayBuffer>&&) final;
     95
     96        FetchResponse& m_response;
     97        Optional<FetchPromise> m_promise;
     98        std::unique_ptr<FetchLoader> m_loader;
     99    };
    76100
    77101    Type m_type;
     
    80104    bool m_isLocked = false;
    81105    bool m_isRedirected = false;
     106    Optional<BodyLoader> m_bodyLoader;
    82107};
    83108
  • trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp

    r198649 r198665  
    137137PassRefPtr<BlobResourceHandle> BlobResourceHandle::createAsync(BlobData* blobData, const ResourceRequest& request, ResourceHandleClient* client)
    138138{
    139     // FIXME: Should probably call didFail() instead of blocking the load without explanation.
    140     if (!equalLettersIgnoringASCIICase(request.httpMethod(), "get"))
    141         return nullptr;
    142 
    143139    return adoptRef(new BlobResourceHandle(blobData, request, client, true));
    144140}
     
    207203    if (m_aborted || m_errorCode)
    208204        return;
     205
     206    if (!equalLettersIgnoringASCIICase(firstRequest().httpMethod(), "get")) {
     207        m_errorCode = methodNotAllowed;
     208        notifyResponse();
     209        return;
     210    }
    209211
    210212    // If the blob data is not found, fail now.
     
    579581    response.setHTTPStatusCode(isRangeRequest ? httpPartialContent : httpOK);
    580582    response.setHTTPStatusText(isRangeRequest ? httpPartialContentText : httpOKText);
     583
     584    response.setHTTPHeaderField(HTTPHeaderName::ContentType, m_blobData->contentType());
     585    response.setHTTPHeaderField(HTTPHeaderName::ContentLength, String::number(m_totalRemainingSize));
     586
    581587    if (isRangeRequest)
    582588        response.setHTTPHeaderField(HTTPHeaderName::ContentRange, ParsedContentRange(m_rangeOffset, m_rangeEnd, m_totalSize).headerValue());
Note: See TracChangeset for help on using the changeset viewer.