Changeset 239644 in webkit
- Timestamp:
- Jan 4, 2019 4:01:43 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r239642 r239644 1 2019-01-04 Youenn Fablet <youenn@apple.com> 2 3 [Fetch API] Implement abortable fetch 4 https://bugs.webkit.org/show_bug.cgi?id=174980 5 <rdar://problem/46861402> 6 7 Reviewed by Chris Dumez. 8 9 * TestExpectations: Enable abort tests. 10 1 11 2019-01-04 Brent Fulgham <bfulgham@apple.com> 2 12 -
trunk/LayoutTests/TestExpectations
r239574 r239644 212 212 213 213 # Skip service worker tests that are timing out. 214 imported/w3c/web-platform-tests/fetch/api/abort/general-serviceworker.https.html [ Skip ]215 214 imported/w3c/web-platform-tests/service-workers/service-worker/performance-timeline.https.html [ Skip ] 216 215 imported/w3c/web-platform-tests/service-workers/service-worker/respond-with-body-accessed-response.https.html [ Skip ] … … 383 382 webkit.org/b/189910 imported/w3c/web-platform-tests/resource-timing/resource_timing_store_and_clear_during_callback.html [ Pass Failure ] 384 383 webkit.org/b/190523 imported/w3c/web-platform-tests/resource-timing/resource_timing_cross_origin_redirect_chain.html [ Pass Failure ] 385 386 # The follow two tests change their output each run387 imported/w3c/web-platform-tests/fetch/api/abort/general.any.html [ Skip ]388 imported/w3c/web-platform-tests/fetch/api/abort/general.any.worker.html [ Skip ]389 384 390 385 # These tests time out -
trunk/LayoutTests/imported/w3c/ChangeLog
r239574 r239644 1 2019-01-04 Youenn Fablet <youenn@apple.com> 2 3 [Fetch API] Implement abortable fetch 4 https://bugs.webkit.org/show_bug.cgi?id=174980 5 <rdar://problem/46861402> 6 7 Reviewed by Chris Dumez. 8 9 Fixed tests to run in WebKit CI. 10 Also fixed a bug in a test where the fetch response body is not actually empty. 11 12 * web-platform-tests/fetch/api/abort/cache.https-expected.txt: 13 * web-platform-tests/fetch/api/abort/general-serviceworker.https-expected.txt: 14 * web-platform-tests/fetch/api/abort/general.any-expected.txt: 15 * web-platform-tests/fetch/api/abort/general.any.js: 16 * web-platform-tests/fetch/api/abort/general.any.worker-expected.txt: 17 * web-platform-tests/fetch/api/abort/serviceworker-intercepted.https-expected.txt: 18 * web-platform-tests/fetch/api/response/response-consume-stream-expected.txt: 19 1 20 2019-01-02 Simon Fraser <simon.fraser@apple.com> 2 21 -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/abort/cache.https-expected.txt
r222692 r239644 1 1 2 FAIL Signals are not stored in the cache API promise_test: Unhandled rejection with value: object "TypeError: undefined is not an object (evaluating 'cachedRequest.signal.aborted')" 3 FAIL Signals are not stored in the cache API, even if they're already aborted promise_test: Unhandled rejection with value: object "TypeError: undefined is not an object (evaluating 'cachedRequest.signal.aborted')" 2 PASS Signals are not stored in the cache API 3 PASS Signals are not stored in the cache API, even if they're already aborted 4 4 -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/abort/general-serviceworker.https-expected.txt
r224218 r239644 1 1 2 Harness Error (TIMEOUT), message = null 3 4 FAIL Aborting rejects with AbortError assert_unreached: Should have rejected: undefined Reached unreachable code 5 FAIL Aborting rejects with AbortError - no-cors assert_throws: function "function () { throw e }" threw object "TypeError: A server with the specified hostname could not be found." that is not a DOMException AbortError: property "code" is equal to undefined, expected 20 2 PASS Aborting rejects with AbortError 3 PASS Aborting rejects with AbortError - no-cors 6 4 PASS TypeError from request constructor takes priority - RequestInit's window is not null 7 5 PASS TypeError from request constructor takes priority - Input URL is not valid … … 20 18 PASS TypeError from request constructor takes priority - Bad cache init parameter value 21 19 PASS TypeError from request constructor takes priority - Bad redirect init parameter value 22 FAIL Request objects have a signal property assert_true: Signal member is present & truthy expected true got false 23 FAIL Signal on request object assert_true: Signal member is present & truthy expected true got false 24 FAIL Signal on request object created from request object assert_unreached: Should have rejected: undefined Reached unreachable code 25 FAIL Signal on request object created from request object, with signal on second request assert_unreached: Should have rejected: undefined Reached unreachable code 26 FAIL Signal on request object created from request object, with signal on second request overriding another assert_unreached: Should have rejected: undefined Reached unreachable code 27 FAIL Signal retained after unrelated properties are overridden by fetch assert_unreached: Should have rejected: undefined Reached unreachable code 20 PASS Request objects have a signal property 21 PASS Signal on request object 22 PASS Signal on request object created from request object 23 PASS Signal on request object created from request object, with signal on second request 24 PASS Signal on request object created from request object, with signal on second request overriding another 25 PASS Signal retained after unrelated properties are overridden by fetch 28 26 PASS Signal removed by setting to null 29 FAIL Already aborted signal rejects immediately assert_unreached: Fetch must not resolve Reached unreachable code 27 PASS Already aborted signal rejects immediately 30 28 PASS Request is still 'used' if signal is aborted before fetching 31 FAIL response.arrayBuffer() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 32 FAIL response.blob() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 33 FAIL response.formData() rejects if already aborted assert_throws: function "function () { throw e }" threw object "NotSupportedError: The operation is not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20 34 FAIL response.json() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 35 FAIL response.text() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 36 FAIL Already aborted signal does not make request assert_equals: Request hasn't been made to the server expected (object) null but got (string) "open" 37 FAIL Already aborted signal can be used for many fetches assert_unreached: Should have rejected: undefined Reached unreachable code 38 FAIL Signal can be used to abort other fetches, even if another fetch succeeded before aborting assert_unreached: Should have rejected: undefined Reached unreachable code 39 FAIL Underlying connection is closed when aborting after receiving response promise_test: Unhandled rejection with value: object "Error: Timed out" 40 FAIL Underlying connection is closed when aborting after receiving response - no-cors promise_test: Unhandled rejection with value: object "TypeError: A server with the specified hostname could not be found." 41 TIMEOUT Fetch aborted & connection closed when aborted after calling response.arrayBuffer() Test timed out 42 NOTRUNFetch aborted & connection closed when aborted after calling response.blob()43 NOTRUN Fetch aborted & connection closed when aborted after calling response.formData() 44 NOTRUNFetch aborted & connection closed when aborted after calling response.json()45 NOTRUNFetch aborted & connection closed when aborted after calling response.text()46 NOTRUNStream errors once aborted. Underlying connection closed.47 NOTRUNStream errors once aborted, after reading. Underlying connection closed.48 NOTRUNStream will not error if body is empty. It's closed with an empty queue before it errors.49 NOTRUN Readable stream synchronously cancels with AbortError if aborted before reading 50 FAIL Signal state is cloned undefined is not an object (evaluating 'request.signal.aborted') 51 FAIL Clone aborts with original controller undefined is not an object (evaluating 'request.signal.addEventListener') 29 PASS response.arrayBuffer() rejects if already aborted 30 PASS response.blob() rejects if already aborted 31 PASS response.formData() rejects if already aborted 32 PASS response.json() rejects if already aborted 33 PASS response.text() rejects if already aborted 34 PASS Already aborted signal does not make request 35 PASS Already aborted signal can be used for many fetches 36 PASS Signal can be used to abort other fetches, even if another fetch succeeded before aborting 37 PASS Underlying connection is closed when aborting after receiving response 38 PASS Underlying connection is closed when aborting after receiving response - no-cors 39 PASS Fetch aborted & connection closed when aborted after calling response.arrayBuffer() 40 PASS Fetch aborted & connection closed when aborted after calling response.blob() 41 FAIL Fetch aborted & connection closed when aborted after calling response.formData() assert_throws: function "function () { throw e }" threw object "NotSupportedError: The operation is not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20 42 PASS Fetch aborted & connection closed when aborted after calling response.json() 43 PASS Fetch aborted & connection closed when aborted after calling response.text() 44 PASS Stream errors once aborted. Underlying connection closed. 45 PASS Stream errors once aborted, after reading. Underlying connection closed. 46 PASS Stream will not error if body is empty. It's closed with an empty queue before it errors. 47 FAIL Readable stream synchronously cancels with AbortError if aborted before reading assert_true: Cancel called sync expected true got false 48 PASS Signal state is cloned 49 PASS Clone aborts with original controller 52 50 -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/abort/general.any-expected.txt
r222692 r239644 1 Blocked access to external URL http://www1.localhost:8800/fetch/api/resources/data.json 2 CONSOLE MESSAGE: line 36: Fetch API cannot load http://www1.localhost:8800/fetch/api/resources/data.json due to access control checks. 3 Blocked access to external URL http://www1.localhost:8800/fetch/api/resources/infinite-slow-response.py?stateKey=28d5c068-417e-4c81-a0cd-9b8c22aed3c1&abortKey=ef9a1b5a-7afd-4734-b145-f033788c0e6b 4 CONSOLE MESSAGE: line 318: Fetch API cannot load http://www1.localhost:8800/fetch/api/resources/infinite-slow-response.py?stateKey=28d5c068-417e-4c81-a0cd-9b8c22aed3c1&abortKey=ef9a1b5a-7afd-4734-b145-f033788c0e6b due to access control checks. 1 CONSOLE MESSAGE: Unhandled Promise Rejection: AbortError: Request signal is aborted 5 2 6 Harness Error (TIMEOUT), message = null 7 8 FAIL Aborting rejects with AbortError assert_unreached: Should have rejected: undefined Reached unreachable code 9 FAIL Aborting rejects with AbortError - no-cors assert_throws: function "function () { throw e }" threw object "TypeError: Type error" that is not a DOMException AbortError: property "code" is equal to undefined, expected 20 3 PASS Aborting rejects with AbortError 4 PASS Aborting rejects with AbortError - no-cors 10 5 PASS TypeError from request constructor takes priority - RequestInit's window is not null 11 6 PASS TypeError from request constructor takes priority - Input URL is not valid … … 16 11 PASS TypeError from request constructor takes priority - RequestInit's method is forbidden 17 12 PASS TypeError from request constructor takes priority - RequestInit's mode is no-cors and method is not simple 18 PASS TypeError from request constructor takes priority - RequestInit's mode is no-cors and integrity is not empty19 13 PASS TypeError from request constructor takes priority - RequestInit's cache mode is only-if-cached and mode is not same-origin 20 14 PASS TypeError from request constructor takes priority - Request with cache mode: only-if-cached and fetch mode cors … … 25 19 PASS TypeError from request constructor takes priority - Bad cache init parameter value 26 20 PASS TypeError from request constructor takes priority - Bad redirect init parameter value 27 FAIL Request objects have a signal property assert_true: Signal member is present & truthy expected true got false 28 FAIL Signal on request object assert_true: Signal member is present & truthy expected true got false 29 FAIL Signal on request object created from request object assert_unreached: Should have rejected: undefined Reached unreachable code 30 FAIL Signal on request object created from request object, with signal on second request assert_unreached: Should have rejected: undefined Reached unreachable code 31 FAIL Signal on request object created from request object, with signal on second request overriding another assert_unreached: Should have rejected: undefined Reached unreachable code 32 FAIL Signal retained after unrelated properties are overridden by fetch assert_unreached: Should have rejected: undefined Reached unreachable code 21 PASS Request objects have a signal property 22 PASS Signal on request object 23 PASS Signal on request object created from request object 24 PASS Signal on request object created from request object, with signal on second request 25 PASS Signal on request object created from request object, with signal on second request overriding another 26 PASS Signal retained after unrelated properties are overridden by fetch 33 27 PASS Signal removed by setting to null 34 FAIL Already aborted signal rejects immediately assert_unreached: Fetch must not resolve Reached unreachable code 28 PASS Already aborted signal rejects immediately 35 29 PASS Request is still 'used' if signal is aborted before fetching 36 FAIL response.arrayBuffer() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 37 FAIL response.blob() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 38 FAIL response.formData() rejects if already aborted assert_throws: function "function () { throw e }" threw object "NotSupportedError: The operation is not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20 39 FAIL response.json() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 40 FAIL response.text() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 41 FAIL Already aborted signal does not make request assert_equals: Request hasn't been made to the server expected (object) null but got (string) "open" 42 FAIL Already aborted signal can be used for many fetches assert_unreached: Should have rejected: undefined Reached unreachable code 43 FAIL Signal can be used to abort other fetches, even if another fetch succeeded before aborting assert_unreached: Should have rejected: undefined Reached unreachable code 44 FAIL Underlying connection is closed when aborting after receiving response promise_test: Unhandled rejection with value: object "Error: Timed out" 45 FAIL Underlying connection is closed when aborting after receiving response - no-cors promise_test: Unhandled rejection with value: object "TypeError: Type error" 46 TIMEOUT Fetch aborted & connection closed when aborted after calling response.arrayBuffer() Test timed out 47 NOTRUNFetch aborted & connection closed when aborted after calling response.blob()48 NOTRUN Fetch aborted & connection closed when aborted after calling response.formData() 49 NOTRUNFetch aborted & connection closed when aborted after calling response.json()50 NOTRUNFetch aborted & connection closed when aborted after calling response.text()51 NOTRUNStream errors once aborted. Underlying connection closed.52 NOTRUNStream errors once aborted, after reading. Underlying connection closed.53 NOTRUNStream will not error if body is empty. It's closed with an empty queue before it errors.54 NOTRUN Readable stream synchronously cancels with AbortError if aborted before reading 55 FAIL Signal state is cloned undefined is not an object (evaluating 'request.signal.aborted') 56 FAIL Clone aborts with original controller undefined is not an object (evaluating 'request.signal.addEventListener') 30 PASS response.arrayBuffer() rejects if already aborted 31 PASS response.blob() rejects if already aborted 32 PASS response.formData() rejects if already aborted 33 PASS response.json() rejects if already aborted 34 PASS response.text() rejects if already aborted 35 PASS Already aborted signal does not make request 36 PASS Already aborted signal can be used for many fetches 37 PASS Signal can be used to abort other fetches, even if another fetch succeeded before aborting 38 PASS Underlying connection is closed when aborting after receiving response 39 PASS Underlying connection is closed when aborting after receiving response - no-cors 40 PASS Fetch aborted & connection closed when aborted after calling response.arrayBuffer() 41 PASS Fetch aborted & connection closed when aborted after calling response.blob() 42 FAIL Fetch aborted & connection closed when aborted after calling response.formData() assert_throws: function "function () { throw e }" threw object "NotSupportedError: The operation is not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20 43 PASS Fetch aborted & connection closed when aborted after calling response.json() 44 PASS Fetch aborted & connection closed when aborted after calling response.text() 45 PASS Stream errors once aborted. Underlying connection closed. 46 PASS Stream errors once aborted, after reading. Underlying connection closed. 47 PASS Stream will not error if body is empty. It's closed with an empty queue before it errors. 48 FAIL Readable stream synchronously cancels with AbortError if aborted before reading assert_true: Cancel called sync expected true got false 49 PASS Signal state is cloned 50 PASS Clone aborts with original controller 57 51 -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/abort/general.any.js
r230330 r239644 1 1 // META: script=/common/utils.js 2 // META: script=/common/get-host-info.sub.js 2 3 // META: script=../request/request-error.js 3 4 … … 16 17 } 17 18 19 const hostInfo = get_host_info(); 20 const urlHostname = hostInfo.REMOTE_HOST; 21 18 22 promise_test(async t => { 19 23 const controller = new AbortController(); … … 32 36 33 37 const url = new URL('../resources/data.json', location); 34 url.hostname = 'www1.' + url.hostname;38 url.hostname = urlHostname; 35 39 36 40 const fetchPromise = fetch(url, { … … 315 319 316 320 const url = new URL(`../resources/infinite-slow-response.py?stateKey=${stateKey}&abortKey=${abortKey}`, location); 317 url.hostname = 'www1.' + url.hostname;321 url.hostname = urlHostname; 318 322 319 323 await fetch(url, { … … 323 327 324 328 const stashTakeURL = new URL(`../resources/stash-take.py?key=${stateKey}`, location); 325 stashTakeURL.hostname = 'www1.' + stashTakeURL.hostname;329 stashTakeURL.hostname = urlHostname; 326 330 327 331 const beforeAbortResult = await fetch(stashTakeURL).then(r => r.json()); … … 441 445 const signal = controller.signal; 442 446 443 const response = await fetch(`../resources/ empty.txt`, { signal });447 const response = await fetch(`../resources/method.py`, { signal }); 444 448 445 449 // Read whole response to ensure close signal has sent. -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/abort/general.any.worker-expected.txt
r222692 r239644 1 Blocked access to external URL http://www1.localhost:8800/fetch/api/resources/data.json2 Blocked access to external URL http://www1.localhost:8800/fetch/api/resources/infinite-slow-response.py?stateKey=7471d98e-1bdb-4254-a315-9489c98b8f59&abortKey=4c631f17-2786-4b07-84f4-0a5760d28f1e3 1 4 Harness Error (TIMEOUT), message = null 5 6 FAIL Aborting rejects with AbortError assert_unreached: Should have rejected: undefined Reached unreachable code 7 FAIL Aborting rejects with AbortError - no-cors assert_throws: function "function () { throw e }" threw object "TypeError: Type error" that is not a DOMException AbortError: property "code" is equal to undefined, expected 20 2 PASS Aborting rejects with AbortError 3 PASS Aborting rejects with AbortError - no-cors 8 4 PASS TypeError from request constructor takes priority - RequestInit's window is not null 9 5 PASS TypeError from request constructor takes priority - Input URL is not valid … … 14 10 PASS TypeError from request constructor takes priority - RequestInit's method is forbidden 15 11 PASS TypeError from request constructor takes priority - RequestInit's mode is no-cors and method is not simple 16 PASS TypeError from request constructor takes priority - RequestInit's mode is no-cors and integrity is not empty17 12 PASS TypeError from request constructor takes priority - RequestInit's cache mode is only-if-cached and mode is not same-origin 18 13 PASS TypeError from request constructor takes priority - Request with cache mode: only-if-cached and fetch mode cors … … 23 18 PASS TypeError from request constructor takes priority - Bad cache init parameter value 24 19 PASS TypeError from request constructor takes priority - Bad redirect init parameter value 25 FAIL Request objects have a signal property assert_true: Signal member is present & truthy expected true got false 26 FAIL Signal on request object assert_true: Signal member is present & truthy expected true got false 27 FAIL Signal on request object created from request object assert_unreached: Should have rejected: undefined Reached unreachable code 28 FAIL Signal on request object created from request object, with signal on second request assert_unreached: Should have rejected: undefined Reached unreachable code 29 FAIL Signal on request object created from request object, with signal on second request overriding another assert_unreached: Should have rejected: undefined Reached unreachable code 30 FAIL Signal retained after unrelated properties are overridden by fetch assert_unreached: Should have rejected: undefined Reached unreachable code 20 PASS Request objects have a signal property 21 PASS Signal on request object 22 PASS Signal on request object created from request object 23 PASS Signal on request object created from request object, with signal on second request 24 PASS Signal on request object created from request object, with signal on second request overriding another 25 PASS Signal retained after unrelated properties are overridden by fetch 31 26 PASS Signal removed by setting to null 32 FAIL Already aborted signal rejects immediately assert_unreached: Fetch must not resolve Reached unreachable code 27 PASS Already aborted signal rejects immediately 33 28 PASS Request is still 'used' if signal is aborted before fetching 34 FAIL response.arrayBuffer() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 35 FAIL response.blob() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 36 FAIL response.formData() rejects if already aborted assert_throws: function "function () { throw e }" threw object "NotSupportedError: The operation is not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20 37 FAIL response.json() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 38 FAIL response.text() rejects if already aborted assert_unreached: Should have rejected: undefined Reached unreachable code 39 FAIL Already aborted signal does not make request assert_equals: Request hasn't been made to the server expected (object) null but got (string) "open" 40 FAIL Already aborted signal can be used for many fetches assert_unreached: Should have rejected: undefined Reached unreachable code 41 FAIL Signal can be used to abort other fetches, even if another fetch succeeded before aborting assert_unreached: Should have rejected: undefined Reached unreachable code 42 FAIL Underlying connection is closed when aborting after receiving response promise_test: Unhandled rejection with value: object "Error: Timed out" 43 FAIL Underlying connection is closed when aborting after receiving response - no-cors promise_test: Unhandled rejection with value: object "TypeError: Type error" 44 TIMEOUT Fetch aborted & connection closed when aborted after calling response.arrayBuffer() Test timed out 45 NOTRUNFetch aborted & connection closed when aborted after calling response.blob()46 NOTRUN Fetch aborted & connection closed when aborted after calling response.formData() 47 NOTRUNFetch aborted & connection closed when aborted after calling response.json()48 NOTRUNFetch aborted & connection closed when aborted after calling response.text()49 NOTRUNStream errors once aborted. Underlying connection closed.50 NOTRUNStream errors once aborted, after reading. Underlying connection closed.51 NOTRUNStream will not error if body is empty. It's closed with an empty queue before it errors.52 NOTRUN Readable stream synchronously cancels with AbortError if aborted before reading 53 FAIL Signal state is cloned undefined is not an object (evaluating 'request.signal.aborted') 54 FAIL Clone aborts with original controller undefined is not an object (evaluating 'request.signal.addEventListener') 29 PASS response.arrayBuffer() rejects if already aborted 30 PASS response.blob() rejects if already aborted 31 PASS response.formData() rejects if already aborted 32 PASS response.json() rejects if already aborted 33 PASS response.text() rejects if already aborted 34 PASS Already aborted signal does not make request 35 PASS Already aborted signal can be used for many fetches 36 PASS Signal can be used to abort other fetches, even if another fetch succeeded before aborting 37 PASS Underlying connection is closed when aborting after receiving response 38 PASS Underlying connection is closed when aborting after receiving response - no-cors 39 PASS Fetch aborted & connection closed when aborted after calling response.arrayBuffer() 40 PASS Fetch aborted & connection closed when aborted after calling response.blob() 41 FAIL Fetch aborted & connection closed when aborted after calling response.formData() assert_throws: function "function () { throw e }" threw object "NotSupportedError: The operation is not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20 42 PASS Fetch aborted & connection closed when aborted after calling response.json() 43 PASS Fetch aborted & connection closed when aborted after calling response.text() 44 PASS Stream errors once aborted. Underlying connection closed. 45 PASS Stream errors once aborted, after reading. Underlying connection closed. 46 PASS Stream will not error if body is empty. It's closed with an empty queue before it errors. 47 FAIL Readable stream synchronously cancels with AbortError if aborted before reading assert_true: Cancel called sync expected true got false 48 PASS Signal state is cloned 49 PASS Clone aborts with original controller 55 50 -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/abort/serviceworker-intercepted.https-expected.txt
r224947 r239644 1 1 2 FAIL Already aborted request does not land in service worker assert_unreached: Should have rejected: undefined Reached unreachable code3 FAIL response.arrayBuffer() rejects if already aborted promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"4 FAIL response.blob() rejects if already aborted promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"5 FAIL response.formData() rejects if already aborted promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"6 FAIL response.json() rejects if already aborted promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"7 FAIL response.text() rejects if already aborted promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"8 FAIL Stream errors once aborted. promise_test: Unhandled rejection with value: object "Error: wait_for_state must be passed a ServiceWorker"9 2 3 PASS Already aborted request does not land in service worker 4 PASS response.arrayBuffer() rejects if already aborted 5 PASS response.blob() rejects if already aborted 6 PASS response.formData() rejects if already aborted 7 PASS response.json() rejects if already aborted 8 PASS response.text() rejects if already aborted 9 FAIL Stream errors once aborted. assert_unreached: Should have rejected: undefined Reached unreachable code 10 -
trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-stream-expected.txt
r222307 r239644 6 6 PASS Read URLSearchParams response's body as readableStream 7 7 PASS Read array buffer response's body as readableStream 8 FAIL Read form data response's body as readableStream promise_test: Unhandled rejection with value: object " TypeError: not implemented"8 FAIL Read form data response's body as readableStream promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented" 9 9 PASS Getting an error Response stream 10 10 PASS Getting a redirect Response stream -
trunk/LayoutTests/platform/ios-simulator/TestExpectations
r238592 r239644 68 68 webkit.org/b/174079 fast/text/variations/skia-postscript-name.html [ ImageOnlyFailure ] 69 69 70 imported/w3c/web-platform-tests/fetch/api/abort/general-serviceworker.https.html [ Pass Failure ] 70 71 imported/w3c/web-platform-tests/2dcontext/transformations/canvas_transformations_reset_001.html [ ImageOnlyFailure ] 71 72 imported/w3c/web-platform-tests/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-fragment-scrolling-cross-origin.html [ Failure ] -
trunk/Source/WebCore/ChangeLog
r239642 r239644 1 2019-01-04 Youenn Fablet <youenn@apple.com> 2 3 [Fetch API] Implement abortable fetch 4 https://bugs.webkit.org/show_bug.cgi?id=174980 5 <rdar://problem/46861402> 6 7 Reviewed by Chris Dumez. 8 9 Add an AbortSignal to FetchRequest. 10 11 Add support for AbortSignal algorithm. 12 The fetch request signal is added an algorithm to abort the fetch. 13 Update clone algorithm to let signal of the cloned request be following the origin request. 14 15 Update ReadableStream error handling to return an exception instead of a string. 16 This allows passing an AbortError instead of a TypeError as previously done. 17 18 Update FetchBodyOwner to store a loading error either as an exception or as a resource error. 19 The latter is used for passing the error from service worker back to the page. 20 The former is used to pass it to ReadableStream or body accessors. 21 22 Covered by enabled tests. 23 24 * Modules/cache/DOMCache.cpp: 25 (WebCore::DOMCache::put): 26 * Modules/fetch/FetchBody.cpp: 27 (WebCore::FetchBody::consumeAsStream): 28 (WebCore::FetchBody::loadingFailed): 29 * Modules/fetch/FetchBody.h: 30 * Modules/fetch/FetchBodyConsumer.cpp: 31 (WebCore::FetchBodyConsumer::loadingFailed): 32 * Modules/fetch/FetchBodyConsumer.h: 33 * Modules/fetch/FetchBodyOwner.cpp: 34 (WebCore::FetchBodyOwner::arrayBuffer): 35 (WebCore::FetchBodyOwner::blob): 36 (WebCore::FetchBodyOwner::cloneBody): 37 (WebCore::FetchBodyOwner::formData): 38 (WebCore::FetchBodyOwner::json): 39 (WebCore::FetchBodyOwner::text): 40 (WebCore::FetchBodyOwner::loadBlob): 41 (WebCore::FetchBodyOwner::blobLoadingFailed): 42 (WebCore::FetchBodyOwner::consumeBodyAsStream): 43 (WebCore::FetchBodyOwner::setLoadingError): 44 * Modules/fetch/FetchBodyOwner.h: 45 (WebCore::FetchBodyOwner::loadingError const): 46 (WebCore::FetchBodyOwner::loadingException const): 47 * Modules/fetch/FetchBodySource.cpp: 48 (WebCore::FetchBodySource::error): 49 * Modules/fetch/FetchBodySource.h: 50 * Modules/fetch/FetchRequest.cpp: 51 (WebCore::FetchRequest::initializeWith): 52 (WebCore::FetchRequest::clone): 53 * Modules/fetch/FetchRequest.h: 54 (WebCore::FetchRequest::FetchRequest): 55 * Modules/fetch/FetchRequest.idl: 56 * Modules/fetch/FetchRequestInit.h: 57 (WebCore::FetchRequestInit::hasMembers const): 58 * Modules/fetch/FetchRequestInit.idl: 59 * Modules/fetch/FetchResponse.cpp: 60 (WebCore::FetchResponse::clone): 61 (WebCore::FetchResponse::fetch): 62 (WebCore::FetchResponse::BodyLoader::didFail): 63 * Modules/fetch/FetchResponse.h: 64 * bindings/js/ReadableStreamDefaultController.h: 65 (WebCore::ReadableStreamDefaultController::error): 66 * dom/AbortSignal.cpp: 67 (WebCore::AbortSignal::abort): 68 (WebCore::AbortSignal::follow): 69 * dom/AbortSignal.h: 70 1 71 2019-01-04 Brent Fulgham <bfulgham@apple.com> 2 72 -
trunk/Source/WebCore/Modules/cache/DOMCache.cpp
r239427 r239644 322 322 auto request = requestOrException.releaseReturnValue(); 323 323 324 if ( response->loadingError()) {325 promise.reject( Exception { TypeError, response->loadingError()->localizedDescription() });324 if (auto exception = response->loadingException()) { 325 promise.reject(*exception); 326 326 return; 327 327 } -
trunk/Source/WebCore/Modules/fetch/FetchBody.cpp
r239535 r239644 187 187 m_data = nullptr; 188 188 } else if (isFormData()) 189 source.error( "not implemented"_s);189 source.error(Exception { NotSupportedError, "Not implemented"_s }); 190 190 else if (m_consumer.hasData()) 191 191 closeStream = source.enqueue(m_consumer.takeAsArrayBuffer()); … … 225 225 } 226 226 227 void FetchBody::loadingFailed( )228 { 229 m_consumer.loadingFailed( );227 void FetchBody::loadingFailed(const Exception& exception) 228 { 229 m_consumer.loadingFailed(exception); 230 230 } 231 231 -
trunk/Source/WebCore/Modules/fetch/FetchBody.h
r239427 r239644 61 61 WEBCORE_EXPORT static Optional<FetchBody> fromFormData(FormData&); 62 62 63 void loadingFailed( );63 void loadingFailed(const Exception&); 64 64 void loadingSucceeded(); 65 65 -
trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp
r233122 r239644 213 213 } 214 214 215 void FetchBodyConsumer::loadingFailed( )215 void FetchBodyConsumer::loadingFailed(const Exception& exception) 216 216 { 217 217 m_isLoading = false; 218 218 if (m_consumePromise) { 219 m_consumePromise->reject( );219 m_consumePromise->reject(exception); 220 220 m_consumePromise = nullptr; 221 221 } 222 222 if (m_source) { 223 m_source->error( "Loading failed"_s);223 m_source->error(exception); 224 224 m_source = nullptr; 225 225 } -
trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h
r224956 r239644 67 67 void resolveWithData(Ref<DeferredPromise>&&, const unsigned char*, unsigned); 68 68 69 void loadingFailed( );69 void loadingFailed(const Exception&); 70 70 void loadingSucceeded(); 71 71 -
trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp
r239427 r239644 100 100 void FetchBodyOwner::arrayBuffer(Ref<DeferredPromise>&& promise) 101 101 { 102 if (auto exception = loadingException()) { 103 promise->reject(*exception); 104 return; 105 } 106 102 107 if (isBodyNullOrOpaque()) { 103 108 fulfillPromiseWithArrayBuffer(WTFMove(promise), nullptr, 0); … … 114 119 void FetchBodyOwner::blob(Ref<DeferredPromise>&& promise) 115 120 { 121 if (auto exception = loadingException()) { 122 promise->reject(*exception); 123 return; 124 } 125 116 126 if (isBodyNullOrOpaque()) { 117 127 promise->resolve<IDLInterface<Blob>>(Blob::create(Vector<uint8_t> { }, Blob::normalizedContentType(extractMIMETypeFromMediaType(m_contentType)))); … … 128 138 void FetchBodyOwner::cloneBody(FetchBodyOwner& owner) 129 139 { 140 m_loadingError = owner.m_loadingError; 141 130 142 m_contentType = owner.m_contentType; 131 143 if (owner.isBodyNull()) … … 162 174 void FetchBodyOwner::formData(Ref<DeferredPromise>&& promise) 163 175 { 176 if (auto exception = loadingException()) { 177 promise->reject(*exception); 178 return; 179 } 180 164 181 if (isBodyNullOrOpaque()) { 165 182 promise->reject(); … … 176 193 void FetchBodyOwner::json(Ref<DeferredPromise>&& promise) 177 194 { 195 if (auto exception = loadingException()) { 196 promise->reject(*exception); 197 return; 198 } 199 178 200 if (isBodyNullOrOpaque()) { 179 201 promise->reject(SyntaxError); … … 190 212 void FetchBodyOwner::text(Ref<DeferredPromise>&& promise) 191 213 { 214 if (auto exception = loadingException()) { 215 promise->reject(*exception); 216 return; 217 } 218 192 219 if (isBodyNullOrOpaque()) { 193 220 promise->resolve<IDLDOMString>({ }); … … 209 236 210 237 if (!scriptExecutionContext()) { 211 m_body->loadingFailed( );238 m_body->loadingFailed(Exception { TypeError, "Blob loading failed"_s}); 212 239 return; 213 240 } … … 218 245 m_blobLoader->loader->start(*scriptExecutionContext(), blob); 219 246 if (!m_blobLoader->loader->isStarted()) { 220 m_body->loadingFailed( );247 m_body->loadingFailed(Exception { TypeError, "Blob loading failed"_s}); 221 248 m_blobLoader = WTF::nullopt; 222 249 return; … … 252 279 if (m_readableStreamSource) { 253 280 if (!m_readableStreamSource->isCancelling()) 254 m_readableStreamSource->error( "Blob loading failed"_s);281 m_readableStreamSource->error(Exception { TypeError, "Blob loading failed"_s}); 255 282 m_readableStreamSource = nullptr; 256 283 } else 257 284 #endif 258 m_body->loadingFailed( );285 m_body->loadingFailed(Exception { TypeError, "Blob loading failed"_s}); 259 286 260 287 finishBlobLoading(); … … 319 346 ASSERT(m_readableStreamSource); 320 347 321 if (m_loadingError) { 322 auto errorMessage = m_loadingError->localizedDescription(); 323 m_readableStreamSource->error(errorMessage.isEmpty() ? "Loading failed"_s : errorMessage); 348 if (auto exception = loadingException()) { 349 m_readableStreamSource->error(*exception); 324 350 return; 325 351 } … … 330 356 } 331 357 358 ResourceError FetchBodyOwner::loadingError() const 359 { 360 return WTF::switchOn(m_loadingError, [](const ResourceError& error) { 361 return ResourceError { error }; 362 }, [](const Exception& exception) { 363 return ResourceError { errorDomainWebKitInternal, 0, { }, exception.message() }; 364 }, [](auto&&) { 365 return ResourceError { }; 366 }); 367 } 368 369 Optional<Exception> FetchBodyOwner::loadingException() const 370 { 371 return WTF::switchOn(m_loadingError, [](const ResourceError& error) { 372 return Exception { TypeError, error.localizedDescription().isEmpty() ? "Loading failed"_s : error.localizedDescription() }; 373 }, [](const Exception& exception) { 374 return Exception { exception }; 375 }, [](auto&&) -> Optional<Exception> { 376 return WTF::nullopt; 377 }); 378 } 379 380 bool FetchBodyOwner::hasLoadingError() const 381 { 382 return WTF::switchOn(m_loadingError, [](const ResourceError&) { 383 return true; 384 }, [](const Exception&) { 385 return true; 386 }, [](auto&&) { 387 return false; 388 }); 389 } 390 391 void FetchBodyOwner::setLoadingError(Exception&& exception) 392 { 393 if (hasLoadingError()) 394 return; 395 396 m_loadingError = WTFMove(exception); 397 } 398 399 void FetchBodyOwner::setLoadingError(ResourceError&& error) 400 { 401 if (hasLoadingError()) 402 return; 403 404 m_loadingError = WTFMove(error); 405 } 406 332 407 } // namespace WebCore -
trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h
r239427 r239644 67 67 #endif 68 68 69 bool hasLoadingError() const; 70 ResourceError loadingError() const; 71 Optional<Exception> loadingException() const; 72 69 73 protected: 70 74 const FetchBody& body() const { return *m_body; } … … 88 92 void setBodyAsOpaque() { m_isBodyOpaque = true; } 89 93 bool isBodyOpaque() const { return m_isBodyOpaque; } 94 95 void setLoadingError(Exception&&); 96 void setLoadingError(ResourceError&&); 90 97 91 98 private: … … 117 124 #endif 118 125 Ref<FetchHeaders> m_headers; 119 Optional<ResourceError> m_loadingError;120 126 121 127 private: 122 128 Optional<BlobLoader> m_blobLoader; 123 129 bool m_isBodyOpaque { false }; 130 131 Variant<std::nullptr_t, Exception, ResourceError> m_loadingError; 124 132 }; 125 133 -
trunk/Source/WebCore/Modules/fetch/FetchBodySource.cpp
r234045 r239644 89 89 } 90 90 91 void FetchBodySource::error(const String& value)91 void FetchBodySource::error(const Exception& value) 92 92 { 93 93 controller().error(value); -
trunk/Source/WebCore/Modules/fetch/FetchBodySource.h
r234045 r239644 45 45 bool enqueue(RefPtr<JSC::ArrayBuffer>&& chunk) { return controller().enqueue(WTFMove(chunk)); } 46 46 void close(); 47 void error(const String&);47 void error(const Exception&); 48 48 49 49 bool isCancelling() const { return m_isCancelling; } -
trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp
r239427 r239644 160 160 return optionsResult.releaseException(); 161 161 162 if (init.signal && init.signal.value()) 163 m_signal->follow(*init.signal.value()); 164 162 165 if (init.headers) { 163 166 auto fillResult = m_headers->fill(*init.headers); … … 188 191 if (optionsResult.hasException()) 189 192 return optionsResult.releaseException(); 193 194 if (init.signal) { 195 if (init.signal.value()) 196 m_signal->follow(*init.signal.value()); 197 } else 198 m_signal->follow(input.m_signal); 190 199 191 200 if (init.headers) { … … 294 303 auto clone = adoptRef(*new FetchRequest(context, WTF::nullopt, FetchHeaders::create(m_headers.get()), ResourceRequest { m_request }, FetchOptions { m_options}, String { m_referrer })); 295 304 clone->cloneBody(*this); 305 clone->m_signal->follow(m_signal); 296 306 return WTFMove(clone); 297 307 } -
trunk/Source/WebCore/Modules/fetch/FetchRequest.h
r239427 r239644 29 29 #pragma once 30 30 31 #include "AbortSignal.h" 31 32 #include "ExceptionOr.h" 32 33 #include "FetchBodyOwner.h" … … 69 70 Redirect redirect() const { return m_options.redirect; } 70 71 bool keepalive() const { return m_options.keepAlive; }; 72 AbortSignal& signal() { return m_signal.get(); } 71 73 72 74 const String& integrity() const { return m_options.integrity; } … … 97 99 String m_referrer; 98 100 mutable String m_requestURL; 101 Ref<AbortSignal> m_signal; 99 102 }; 100 103 … … 104 107 , m_options(WTFMove(options)) 105 108 , m_referrer(WTFMove(referrer)) 109 , m_signal(AbortSignal::create(context)) 106 110 { 107 111 updateContentType(); -
trunk/Source/WebCore/Modules/fetch/FetchRequest.idl
r227079 r239644 56 56 readonly attribute DOMString integrity; 57 57 [EnabledAtRuntime=FetchAPIKeepAlive] readonly attribute boolean keepalive; 58 readonly attribute AbortSignal signal; 58 59 59 60 [CallWith=ScriptExecutionContext, MayThrowException, NewObject] FetchRequest clone(); -
trunk/Source/WebCore/Modules/fetch/FetchRequestInit.h
r239427 r239644 26 26 #pragma once 27 27 28 #include "AbortSignal.h" 28 29 #include "FetchBody.h" 29 30 #include "FetchHeaders.h" … … 47 48 String integrity; 48 49 Optional<bool> keepalive; 50 Optional<AbortSignal*> signal; 49 51 JSC::JSValue window; 50 52 51 bool hasMembers() const { return !method.isEmpty() || headers || body || !referrer.isEmpty() || referrerPolicy || mode || credentials || cache || redirect || !integrity.isEmpty() || keepalive || !window.isUndefined() ; }53 bool hasMembers() const { return !method.isEmpty() || headers || body || !referrer.isEmpty() || referrerPolicy || mode || credentials || cache || redirect || !integrity.isEmpty() || keepalive || !window.isUndefined() || signal; } 52 54 }; 53 55 -
trunk/Source/WebCore/Modules/fetch/FetchRequestInit.idl
r221201 r239644 40 40 DOMString integrity; 41 41 boolean keepalive; 42 AbortSignal? signal; 42 43 any window; // can only be set to null 43 44 }; -
trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp
r239427 r239644 180 180 181 181 auto clone = FetchResponse::create(context, WTF::nullopt, headers().guard(), ResourceResponse { m_internalResponse }); 182 clone->m_loadingError = m_loadingError;183 182 clone->cloneBody(*this); 184 183 clone->m_opaqueLoadIdentifier = m_opaqueLoadIdentifier; … … 187 186 } 188 187 188 void FetchResponse::addAbortSteps(Ref<AbortSignal>&& signal) 189 { 190 m_abortSignal = WTFMove(signal); 191 m_abortSignal->addAlgorithm([this, weakThis = makeWeakPtr(this)] { 192 // FIXME: Cancel request body if it is a stream. 193 if (!weakThis) 194 return; 195 196 m_abortSignal = nullptr; 197 198 setLoadingError(Exception { AbortError, "Fetch is aborted"_s }); 199 200 if (m_bodyLoader) { 201 if (auto callback = m_bodyLoader->takeNotificationCallback()) 202 callback(Exception { AbortError, "Fetch is aborted"_s }); 203 } 204 205 if (m_readableStreamSource) { 206 if (!m_readableStreamSource->isCancelling()) 207 m_readableStreamSource->error(*loadingException()); 208 m_readableStreamSource = nullptr; 209 } 210 if (m_body) 211 m_body->loadingFailed(*loadingException()); 212 213 if (m_bodyLoader) { 214 m_bodyLoader->stop(); 215 m_bodyLoader = WTF::nullopt; 216 } 217 }); 218 } 219 189 220 void FetchResponse::fetch(ScriptExecutionContext& context, FetchRequest& request, NotificationCallback&& responseCallback) 190 221 { 222 if (request.signal().aborted()) { 223 responseCallback(Exception { AbortError, "Request signal is aborted"_s }); 224 // FIXME: Cancel request body if it is a stream. 225 return; 226 } 227 191 228 if (request.hasReadableStreamBody()) { 192 if (responseCallback) 193 responseCallback(Exception { NotSupportedError, "ReadableStream uploading is not supported" }); 229 responseCallback(Exception { NotSupportedError, "ReadableStream uploading is not supported"_s }); 194 230 return; 195 231 } … … 197 233 198 234 response->body().consumer().setAsLoading(); 235 236 response->addAbortSteps(request.signal()); 199 237 200 238 response->m_bodyLoader.emplace(response.get(), WTFMove(responseCallback)); … … 246 284 ASSERT(m_response.hasPendingActivity()); 247 285 248 m_response. m_loadingError = error;286 m_response.setLoadingError(ResourceError { error }); 249 287 250 288 if (auto responseCallback = WTFMove(m_responseCallback)) … … 257 295 if (m_response.m_readableStreamSource) { 258 296 if (!m_response.m_readableStreamSource->isCancelling()) 259 m_response.m_readableStreamSource->error( makeString("Loading failed: "_s, error.localizedDescription()));297 m_response.m_readableStreamSource->error(*m_response.loadingException()); 260 298 m_response.m_readableStreamSource = nullptr; 261 299 } -
trunk/Source/WebCore/Modules/fetch/FetchResponse.h
r239427 r239644 34 34 #include "ResourceResponse.h" 35 35 #include <JavaScriptCore/TypedArrays.h> 36 #include <wtf/WeakPtr.h> 36 37 37 38 namespace JSC { … … 42 43 namespace WebCore { 43 44 45 class AbortSignal; 44 46 class FetchRequest; 45 47 struct ReadableStreamChunk; 46 48 class ReadableStreamSource; 47 49 48 class FetchResponse final : public FetchBodyOwner {50 class FetchResponse final : public FetchBodyOwner, public CanMakeWeakPtr<FetchResponse> { 49 51 public: 50 52 using Type = ResourceResponse::Type; … … 108 110 void initializeOpaqueLoadIdentifierForTesting() { m_opaqueLoadIdentifier = 1; } 109 111 110 const Optional<ResourceError>& loadingError() const { return m_loadingError; }111 112 112 const HTTPHeaderMap& internalResponseHeaders() const { return m_internalResponse.httpHeaderFields(); } 113 113 … … 125 125 #endif 126 126 127 void addAbortSteps(Ref<AbortSignal>&&); 128 127 129 class BodyLoader final : public FetchLoaderClient { 128 130 public: … … 138 140 RefPtr<SharedBuffer> startStreaming(); 139 141 #endif 142 NotificationCallback takeNotificationCallback() { return WTFMove(m_responseCallback); } 140 143 141 144 private: … … 159 162 uint64_t m_bodySizeWithPadding { 0 }; 160 163 uint64_t m_opaqueLoadIdentifier { 0 }; 164 RefPtr<AbortSignal> m_abortSignal; 161 165 }; 162 166 -
trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.h
r237009 r239644 50 50 bool enqueue(RefPtr<JSC::ArrayBuffer>&&); 51 51 52 template<class ResolveResultType> 53 void error(const ResolveResultType&); 52 void error(const Exception&); 54 53 55 54 void close() { invoke(*globalObject().globalExec(), jsController(), "close", JSC::jsUndefined()); } … … 105 104 } 106 105 107 template<> 108 inline void ReadableStreamDefaultController::error<String>(const String& errorMessage) 106 inline void ReadableStreamDefaultController::error(const Exception& exception) 109 107 { 110 108 JSC::ExecState& state = globalExec(); 111 109 JSC::JSLockHolder locker(&state); 112 error(state, JSC::createTypeError(&state, errorMessage));110 error(state, createDOMException(&state, exception.code(), exception.message())); 113 111 } 114 112 -
trunk/Source/WebCore/dom/AbortSignal.cpp
r234995 r239644 38 38 } 39 39 40 41 40 AbortSignal::AbortSignal(ScriptExecutionContext& context) 42 41 : ContextDestructionObserver(&context) … … 53 52 // 2. Set signal’s aborted flag. 54 53 m_aborted = true; 55 56 // 3. For each algorithm in signal's abort algorithms: run algorithm. 57 // 4. Empty signal's abort algorithms. 58 // FIXME: Add support for 'abort algorithms' - https://dom.spec.whatwg.org/#abortsignal-abort-algorithms 54 55 auto protectedThis = makeRef(*this); 56 auto algorithms = WTFMove(m_algorithms); 57 for (auto& algorithm : algorithms) 58 algorithm(); 59 59 60 60 // 5. Fire an event named abort at signal. … … 62 62 } 63 63 64 // https://dom.spec.whatwg.org/#abortsignal-follow 65 void AbortSignal::follow(AbortSignal& signal) 66 { 67 if (aborted()) 68 return; 69 70 if (signal.aborted()) { 71 abort(); 72 return; 73 } 74 75 signal.addAlgorithm([weakThis = makeWeakPtr(this)] { 76 if (!weakThis) 77 return; 78 weakThis->abort(); 79 }); 64 80 } 81 82 } -
trunk/Source/WebCore/dom/AbortSignal.h
r222692 r239644 28 28 #include "ContextDestructionObserver.h" 29 29 #include "EventTarget.h" 30 #include <wtf/Function.h> 30 31 #include <wtf/Ref.h> 31 32 #include <wtf/RefCounted.h> 33 #include <wtf/WeakPtr.h> 32 34 33 35 namespace WebCore { … … 35 37 class ScriptExecutionContext; 36 38 37 class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWithInlineData, p rivate ContextDestructionObserver {39 class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWithInlineData, public CanMakeWeakPtr<AbortSignal>, private ContextDestructionObserver { 38 40 public: 39 41 static Ref<AbortSignal> create(ScriptExecutionContext&); … … 46 48 using RefCounted::deref; 47 49 50 using Algorithm = WTF::Function<void()>; 51 void addAlgorithm(Algorithm&& algorithm) { m_algorithms.append(WTFMove(algorithm)); } 52 53 void follow(AbortSignal&); 54 48 55 private: 49 56 explicit AbortSignal(ScriptExecutionContext&); … … 55 62 56 63 bool m_aborted { false }; 64 Vector<Algorithm> m_algorithms; 57 65 }; 58 66 -
trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp
r239427 r239644 54 54 client->didReceiveResponse(response->resourceResponse()); 55 55 56 if (response->loadingError()) { 57 client->didFail(*response->loadingError()); 56 auto loadingError = response->loadingError(); 57 if (!loadingError.isNull()) { 58 client->didFail(loadingError); 58 59 return; 59 60 }
Note: See TracChangeset
for help on using the changeset viewer.