WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 175007
Add initial support for navigator.sendBeacon
https://bugs.webkit.org/show_bug.cgi?id=175007
Summary
Add initial support for navigator.sendBeacon
Chris Dumez
Reported
2017-07-31 19:59:30 PDT
Add initial support for navigator.sendBeacon
Attachments
WIP Patch
(70.35 KB, patch)
2017-07-31 20:13 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
WIP Patch
(70.36 KB, patch)
2017-08-01 09:40 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
WIP Patch
(121.88 KB, patch)
2017-08-01 10:52 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(143.55 KB, patch)
2017-08-01 12:19 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(150.44 KB, patch)
2017-08-01 15:45 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(150.78 KB, patch)
2017-08-01 19:02 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from ews105 for mac-elcapitan-wk2
(1.13 MB, application/zip)
2017-08-01 20:17 PDT
,
Build Bot
no flags
Details
Patch
(150.78 KB, patch)
2017-08-01 20:21 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Show Obsolete
(7)
View All
Add attachment
proposed patch, testcase, etc.
Chris Dumez
Comment 1
2017-07-31 20:07:40 PDT
<
rdar://problem/33547728
>
Chris Dumez
Comment 2
2017-07-31 20:13:05 PDT
Created
attachment 316828
[details]
WIP Patch
Build Bot
Comment 3
2017-08-01 09:28:55 PDT
Attachment 316828
[details]
did not pass style-queue: ERROR: Source/WebCore/CMakeLists.txt:875: Alphabetical sorting problem. "Modules/NavigatorBeacon.cpp" should be before "Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp". [list/order] [5] Total errors found: 1 in 53 files If any of these errors are false positives, please file a bug against check-webkit-style.
Chris Dumez
Comment 4
2017-08-01 09:40:29 PDT
Created
attachment 316864
[details]
WIP Patch
Chris Dumez
Comment 5
2017-08-01 10:52:11 PDT
Created
attachment 316872
[details]
WIP Patch
Chris Dumez
Comment 6
2017-08-01 12:19:35 PDT
Created
attachment 316880
[details]
Patch
Sam Weinig
Comment 7
2017-08-01 14:25:36 PDT
Comment on
attachment 316880
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316880&action=review
> Source/WebCore/Modules/beacon/NavigatorBeacon.idl:30 > + [CallWith=Document, EnabledAtRuntime=BeaconAPI, MayThrowException] boolean sendBeacon(USVString url, optional BodyInit? data = null);
Does sendBeacon not exist for Workers? Can this use CallWith=ScriptExecutionContext?
> Source/WebCore/page/RuntimeEnabledFeatures.h:156 > + void setBeaconAPIEnabled(bool isEnabled) { m_isBeaconAPIEnabled = isEnabled; } > + bool beaconAPIEnabled() const { return m_isBeaconAPIEnabled; }
Can this use Settings instead?
Chris Dumez
Comment 8
2017-08-01 14:32:16 PDT
Comment on
attachment 316880
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316880&action=review
>> Source/WebCore/Modules/beacon/NavigatorBeacon.idl:30 >> + [CallWith=Document, EnabledAtRuntime=BeaconAPI, MayThrowException] boolean sendBeacon(USVString url, optional BodyInit? data = null); > > Does sendBeacon not exist for Workers? Can this use CallWith=ScriptExecutionContext?
As far as I can tell, this is not exposed to workers at the moment:
https://w3c.github.io/beacon/#sec-sendBeacon-method
It extended Navigator, not WorkerNavigator:
https://html.spec.whatwg.org/multipage/workers.html#workernavigator
If we do decide to expose to workers at some point, then using CallWith=ScriptExecutionContext would work. For now though, I do not see an obvious reason not to use CallWith=Document.
>> Source/WebCore/page/RuntimeEnabledFeatures.h:156 >> + bool beaconAPIEnabled() const { return m_isBeaconAPIEnabled; } > > Can this use Settings instead?
It is exposed via the "Experimental Features" menu. This seems to be how those features are implemented at the moment but I'll check if any of them is backed by a setting.
Chris Dumez
Comment 9
2017-08-01 14:35:19 PDT
Comment on
attachment 316880
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316880&action=review
>>> Source/WebCore/page/RuntimeEnabledFeatures.h:156 >>> + bool beaconAPIEnabled() const { return m_isBeaconAPIEnabled; } >> >> Can this use Settings instead? > > It is exposed via the "Experimental Features" menu. This seems to be how those features are implemented at the moment but I'll check if any of them is backed by a setting.
Also, I don't get why we want a setting here. RuntimeEnabled is how we've been doing experimental features so far, no? Did we change our policy?
Sam Weinig
Comment 10
2017-08-01 14:44:45 PDT
(In reply to Chris Dumez from
comment #9
)
> Comment on
attachment 316880
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=316880&action=review
> > >>> Source/WebCore/page/RuntimeEnabledFeatures.h:156 > >>> + bool beaconAPIEnabled() const { return m_isBeaconAPIEnabled; } > >> > >> Can this use Settings instead? > > > > It is exposed via the "Experimental Features" menu. This seems to be how those features are implemented at the moment but I'll check if any of them is backed by a setting. > > Also, I don't get why we want a setting here. RuntimeEnabled is how we've > been doing experimental features so far, no? Did we change our policy?
Subresource Integrity uses Settings and is an Experimental Feature. The reason to use Settings is that I would like us to not have concepts that are so similar, Settings and RuntimeEnabledFeatures. Settings, if implemented via Settings.in also gives you automatic generation of InternalSettingsGenerated so it can be accessed from tests.
Sam Weinig
Comment 11
2017-08-01 14:45:21 PDT
(In reply to Chris Dumez from
comment #9
)
> Comment on
attachment 316880
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=316880&action=review
> > >>> Source/WebCore/page/RuntimeEnabledFeatures.h:156 > >>> + bool beaconAPIEnabled() const { return m_isBeaconAPIEnabled; } > >> > >> Can this use Settings instead? > > > > It is exposed via the "Experimental Features" menu. This seems to be how those features are implemented at the moment but I'll check if any of them is backed by a setting. > > Also, I don't get why we want a setting here. RuntimeEnabled is how we've > been doing experimental features so far, no? Did we change our policy?
We don't have a policy, and I have been heavily encouraging others to use Settings in other bugs.
Chris Dumez
Comment 12
2017-08-01 14:46:44 PDT
(In reply to Sam Weinig from
comment #10
)
> (In reply to Chris Dumez from
comment #9
) > > Comment on
attachment 316880
[details]
> > Patch > > > > View in context: > >
https://bugs.webkit.org/attachment.cgi?id=316880&action=review
> > > > >>> Source/WebCore/page/RuntimeEnabledFeatures.h:156 > > >>> + bool beaconAPIEnabled() const { return m_isBeaconAPIEnabled; } > > >> > > >> Can this use Settings instead? > > > > > > It is exposed via the "Experimental Features" menu. This seems to be how those features are implemented at the moment but I'll check if any of them is backed by a setting. > > > > Also, I don't get why we want a setting here. RuntimeEnabled is how we've > > been doing experimental features so far, no? Did we change our policy? > > Subresource Integrity uses Settings and is an Experimental Feature. > > The reason to use Settings is that I would like us to not have concepts that > are so similar, Settings and RuntimeEnabledFeatures. Settings, if > implemented via Settings.in also gives you automatic generation of > InternalSettingsGenerated so it can be accessed from tests.
Ok, I'll look at SRI and match what is done there.
Chris Dumez
Comment 13
2017-08-01 15:45:16 PDT
Created
attachment 316903
[details]
Patch
Chris Dumez
Comment 14
2017-08-01 15:47:38 PDT
Comment on
attachment 316903
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316903&action=review
> Source/WebCore/bindings/scripts/CodeGeneratorJS.pm:4133 > + push(@implContent, " putDirect(vm, vm.propertyNames->iteratorSymbol, this->globalObject()->arrayPrototype()->getDirect(vm, vm.propertyNames->builtinNames().valuesPrivateName()), DontEnum);\n");
@Sam: Mixing RuntimeEnabled and EnabledBySetting on the first interface did not build without this change. The issue is that the RuntimeEnabled code uses globalObject() getter, while the EnabledBySetting code relies on an extra parameter named globalObject being passed to finishCreation(). Both names conflict. I did the easy fix to using this-> but it is not clear to me why the EnabledBySetting code needs this extra parameter and why it cannot rely on globalObject() getter.
Sam Weinig
Comment 15
2017-08-01 17:13:42 PDT
(In reply to Chris Dumez from
comment #14
)
> Comment on
attachment 316903
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=316903&action=review
> > > Source/WebCore/bindings/scripts/CodeGeneratorJS.pm:4133 > > + push(@implContent, " putDirect(vm, vm.propertyNames->iteratorSymbol, this->globalObject()->arrayPrototype()->getDirect(vm, vm.propertyNames->builtinNames().valuesPrivateName()), DontEnum);\n"); > > @Sam: Mixing RuntimeEnabled and EnabledBySetting on the first interface did > not build without this change. The issue is that the RuntimeEnabled code > uses globalObject() getter, while the EnabledBySetting code relies on an > extra parameter named globalObject being passed to finishCreation(). Both > names conflict. I did the easy fix to using this-> but it is not clear to me > why the EnabledBySetting code needs this extra parameter and why it cannot > rely on globalObject() getter.
I doesn't. I'll fix that.
Sam Weinig
Comment 16
2017-08-01 17:20:28 PDT
Comment on
attachment 316903
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316903&action=review
> Source/WebCore/Modules/beacon/NavigatorBeacon.cpp:44 > + return Exception { TypeError, ASCIILiteral("Beacons can only be sent over HTTP(S)") };
Do we use the "HTTP(S)" in other exception text, or anywhere else?
> Source/WebCore/Modules/beacon/NavigatorBeacon.cpp:47 > + // We do not allow sending beacons from detached documents.
This should either explain why or be removed.
> Source/WebCore/loader/PingLoader.cpp:272 > + startPingLoad(frame, request, ShouldFollowRedirects::Yes);
What happens to a ping load that wants to follow redirects when the page is closed? Does the NetworkProcess handle this without consulting the WebProcess? What does that mean for content extensions that would like to block some of those redirects?
> Source/WebCore/loader/PingLoader.h:62 > +using BodyInit = Variant<RefPtr<Blob>, RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<DOMFormData>, RefPtr<URLSearchParams>, String>;
At some point we should put this in a header. You can use FetchBody::Init, which should be the same.
> Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:349 > + m_testRunner->setBeaconAPIEnabled(true);
Why not enable this in the normal preferences? Why use the weird ones in the bundle?
Chris Dumez
Comment 17
2017-08-01 18:22:43 PDT
Comment on
attachment 316903
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316903&action=review
>> Source/WebCore/Modules/beacon/NavigatorBeacon.cpp:44 >> + return Exception { TypeError, ASCIILiteral("Beacons can only be sent over HTTP(S)") }; > > Do we use the "HTTP(S)" in other exception text, or anywhere else?
I do not think so. Do you have a better proposal? Do you prefer "Beacons can only be sent over HTTP or HTTPS" ?
>> Source/WebCore/Modules/beacon/NavigatorBeacon.cpp:47 >> + // We do not allow sending beacons from detached documents. > > This should either explain why or be removed.
OK.
>>> Source/WebCore/bindings/scripts/CodeGeneratorJS.pm:4133 >>> + push(@implContent, " putDirect(vm, vm.propertyNames->iteratorSymbol, this->globalObject()->arrayPrototype()->getDirect(vm, vm.propertyNames->builtinNames().valuesPrivateName()), DontEnum);\n"); >> >> @Sam: Mixing RuntimeEnabled and EnabledBySetting on the first interface did not build without this change. The issue is that the RuntimeEnabled code uses globalObject() getter, while the EnabledBySetting code relies on an extra parameter named globalObject being passed to finishCreation(). Both names conflict. I did the easy fix to using this-> but it is not clear to me why the EnabledBySetting code needs this extra parameter and why it cannot rely on globalObject() getter. > > I doesn't. I'll fix that.
Thanks.
>> Source/WebCore/loader/PingLoader.cpp:272 >> + startPingLoad(frame, request, ShouldFollowRedirects::Yes); > > What happens to a ping load that wants to follow redirects when the page is closed? Does the NetworkProcess handle this without consulting the WebProcess? What does that mean for content extensions that would like to block some of those redirects?
Yes, PingLoad takes care of following the redirects for us on NetworkProcess side, without involving the WebProcess. I believe this means content extensions would not be able to block those redirects.
>> Source/WebCore/loader/PingLoader.h:62 >> +using BodyInit = Variant<RefPtr<Blob>, RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<DOMFormData>, RefPtr<URLSearchParams>, String>; > > At some point we should put this in a header. You can use FetchBody::Init, which should be the same.
Agreed.
>> Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:349 >> + m_testRunner->setBeaconAPIEnabled(true); > > Why not enable this in the normal preferences? Why use the weird ones in the bundle?
I'll take a look. I merely followed an existing (and apparently bad) pattern.
Chris Dumez
Comment 18
2017-08-01 18:26:57 PDT
Comment on
attachment 316903
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316903&action=review
>>> Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:349 >>> + m_testRunner->setBeaconAPIEnabled(true); >> >> Why not enable this in the normal preferences? Why use the weird ones in the bundle? > > I'll take a look. I merely followed an existing (and apparently bad) pattern.
Do you means a WKPreferencesSetXXXEnabled() call in TestController::resetPreferencesToConsistentValues()?
Chris Dumez
Comment 19
2017-08-01 19:02:32 PDT
Created
attachment 316923
[details]
Patch
Build Bot
Comment 20
2017-08-01 20:17:17 PDT
Comment on
attachment 316923
[details]
Patch
Attachment 316923
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
http://webkit-queues.webkit.org/results/4237439
New failing tests: imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker.html imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors.html
Build Bot
Comment 21
2017-08-01 20:17:19 PDT
Created
attachment 316928
[details]
Archive of layout-test-results from ews105 for mac-elcapitan-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: ews105 Port: mac-elcapitan-wk2 Platform: Mac OS X 10.11.6
Chris Dumez
Comment 22
2017-08-01 20:21:23 PDT
Created
attachment 316929
[details]
Patch
Chris Dumez
Comment 23
2017-08-01 21:44:28 PDT
Comment on
attachment 316929
[details]
Patch Clearing flags on attachment: 316929 Committed
r220121
: <
http://trac.webkit.org/changeset/220121
>
Chris Dumez
Comment 24
2017-08-01 21:44:30 PDT
All reviewed patches have been landed. Closing bug.
youenn fablet
Comment 25
2017-08-02 10:09:48 PDT
Comment on
attachment 316929
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=316929&action=review
> Source/WebCore/loader/PingLoader.cpp:193 > +bool PingLoader::sendBeacon(Frame& frame, Document& document, const URL& url, std::optional<BodyInit>&& data)
I am not sure we should continue improving PingLoader. If we were to go through DocumentThreadableLoader or CachedResourceLoader, we would have the following: - consistent fetch algorithm with headers properly set - worker support (if going through DTL, although I am not sure there is a good reason for that) - beacon interception by service worker - some sort of preflighting (if going through DTL although keepAlive would need some specific treatment) Maybe in the short term we could do: - add a keepAlive flag (specified in fetch spec) at CachedResourceRequest and/or ResourceRequest level - make CachedResource or CachedResourceLoader call createPingHandle in case this flag is true At some point, we might consider implementing the 65ko limit, which would mean that ping handle might need to communicate back that it is finished to some WebCore object. This is close to the behavior of CachedResource or preloads. It seems natural for CachedResourceLoader or related siblings to do this 65ko bookkeeping. I also wonder what happens when the WebProcess is terminated, like a tab is closed. In that case, the network process might abort the network load which is probably not expected to happen for beacon. Maybe the NetworkProcess needs to know that the request should be kept alive.
youenn fablet
Comment 26
2017-08-02 10:16:40 PDT
Support of beacon API in Worker was removed. See
https://github.com/w3c/beacon/issues/37
Sam Weinig
Comment 27
2017-08-02 10:33:04 PDT
(In reply to youenn fablet from
comment #25
)
> Comment on
attachment 316929
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=316929&action=review
> > > Source/WebCore/loader/PingLoader.cpp:193 > > +bool PingLoader::sendBeacon(Frame& frame, Document& document, const URL& url, std::optional<BodyInit>&& data) > > I am not sure we should continue improving PingLoader. > > If we were to go through DocumentThreadableLoader or CachedResourceLoader, > we would have the following: > - consistent fetch algorithm with headers properly set > - worker support (if going through DTL, although I am not sure there is a > good reason for that) > - beacon interception by service worker > - some sort of preflighting (if going through DTL although keepAlive would > need some specific treatment) > > Maybe in the short term we could do: > - add a keepAlive flag (specified in fetch spec) at CachedResourceRequest > and/or ResourceRequest level > - make CachedResource or CachedResourceLoader call createPingHandle in case > this flag is true > > At some point, we might consider implementing the 65ko limit, which would > mean that ping handle might need to communicate back that it is finished to > some WebCore object. > This is close to the behavior of CachedResource or preloads. > It seems natural for CachedResourceLoader or related siblings to do this > 65ko bookkeeping. > > I also wonder what happens when the WebProcess is terminated, like a tab is > closed. > In that case, the network process might abort the network load which is > probably not expected to happen for beacon. > Maybe the NetworkProcess needs to know that the request should be kept alive.
I agree the long term plan should be to have a consistent loader that matches the fetch algorithm. Unfortunately, we are not there. It seems like a great project for someone to take on to design a loading pipeline based on Fetch, but I am not sure adding features like beacon should be predicated on it.
youenn fablet
Comment 28
2017-08-02 12:16:10 PDT
New features should use WebKit fetch primitive when the spec says that fetch is to be used. WebKit fetch is CachedResouceLoader/DTL. If WebKit fetch is not sufficient, we can either make an exception or try to upgrade it. In that particular case, a limited upgrade might not be a lot of work, I would give it a try.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug