| Index: content/browser/push_messaging/push_messaging_message_filter.cc
|
| diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc
|
| index a3b69ea8399a63188f938e3c0e999a1f2f0b1de6..31ddbb504e839f9b911b5aa2fe063e6634937216 100644
|
| --- a/content/browser/push_messaging/push_messaging_message_filter.cc
|
| +++ b/content/browser/push_messaging/push_messaging_message_filter.cc
|
| @@ -83,11 +83,10 @@ void ForwardEncryptionInfoToIOThreadProxy(
|
| base::Bind(callback, success, p256dh, auth));
|
| }
|
|
|
| -// Concatenates the subscription id with the endpoint base to create a new
|
| -// GURL object containing the endpoint unique to the subscription.
|
| -GURL CreatePushEndpoint(const GURL& push_endpoint_base,
|
| - const std::string& push_subscription_id) {
|
| - return GURL(push_endpoint_base.spec() + "/" + push_subscription_id);
|
| +// Returns whether |sender_info| contains a valid application server key, that
|
| +// is, a NIST P-256 public key in uncompressed format.
|
| +bool IsApplicationServerKey(const std::string& sender_info) {
|
| + return sender_info.size() == 65 && sender_info[0] == 0x04;
|
| }
|
|
|
| } // namespace
|
| @@ -220,9 +219,15 @@ PushMessagingMessageFilter::PushMessagingMessageFilter(
|
| // constructor finishes.
|
| ui_core_.reset(
|
| new Core(weak_factory_io_to_io_.GetWeakPtr(), render_process_id));
|
| - PushMessagingService* push_service = ui_core_->service();
|
| - if (push_service)
|
| - push_endpoint_base_ = push_service->GetPushEndpoint();
|
| +
|
| + PushMessagingService* service = ui_core_->service();
|
| + service_available_ = !!service;
|
| +
|
| + if (service_available_) {
|
| + default_endpoint_ = service->GetEndpoint(false /* standard_protocol */);
|
| + web_push_protocol_endpoint_ =
|
| + service->GetEndpoint(true /* standard_protocol */);
|
| + }
|
| }
|
|
|
| PushMessagingMessageFilter::~PushMessagingMessageFilter() {}
|
| @@ -501,23 +506,23 @@ void PushMessagingMessageFilter::SendSubscriptionSuccess(
|
| const std::vector<uint8_t>& auth) {
|
| // Only called from IO thread, but would be safe to call from UI thread.
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - if (push_endpoint_base_.is_empty()) {
|
| + if (!service_available_) {
|
| // This shouldn't be possible in incognito mode, since we've already checked
|
| // that we have an existing registration. Hence it's ok to throw an error.
|
| DCHECK(!ui_core_->is_incognito());
|
| SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE);
|
| return;
|
| }
|
| +
|
| + const GURL endpoint = CreateEndpoint(
|
| + IsApplicationServerKey(data.options.sender_info), push_subscription_id);
|
| +
|
| if (data.FromDocument()) {
|
| Send(new PushMessagingMsg_SubscribeFromDocumentSuccess(
|
| - data.render_frame_id, data.request_id,
|
| - CreatePushEndpoint(push_endpoint_base_, push_subscription_id), p256dh,
|
| - auth));
|
| + data.render_frame_id, data.request_id, endpoint, p256dh, auth));
|
| } else {
|
| Send(new PushMessagingMsg_SubscribeFromWorkerSuccess(
|
| - data.request_id,
|
| - CreatePushEndpoint(push_endpoint_base_, push_subscription_id), p256dh,
|
| - auth));
|
| + data.request_id, endpoint, p256dh, auth));
|
| }
|
| RecordRegistrationStatus(status);
|
| }
|
| @@ -719,15 +724,38 @@ void PushMessagingMessageFilter::OnGetSubscription(
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| // TODO(johnme): Validate arguments?
|
| service_worker_context_->GetRegistrationUserData(
|
| + service_worker_registration_id, {kPushSenderIdServiceWorkerKey},
|
| + base::Bind(&PushMessagingMessageFilter::DidGetSenderInfo,
|
| + weak_factory_io_to_io_.GetWeakPtr(), request_id,
|
| + service_worker_registration_id));
|
| +}
|
| +
|
| +void PushMessagingMessageFilter::DidGetSenderInfo(
|
| + int request_id,
|
| + int64_t service_worker_registration_id,
|
| + const std::vector<std::string>& sender_info,
|
| + ServiceWorkerStatusCode status) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + if (status != SERVICE_WORKER_OK || sender_info.size() != 1) {
|
| + DidGetSubscription(request_id, service_worker_registration_id,
|
| + false /* uses_standard_protocol */,
|
| + std::vector<std::string>() /* push_subscription_id */,
|
| + status);
|
| + return;
|
| + }
|
| +
|
| + const bool uses_standard_protocol = IsApplicationServerKey(sender_info[0]);
|
| + service_worker_context_->GetRegistrationUserData(
|
| service_worker_registration_id, {kPushRegistrationIdServiceWorkerKey},
|
| base::Bind(&PushMessagingMessageFilter::DidGetSubscription,
|
| weak_factory_io_to_io_.GetWeakPtr(), request_id,
|
| - service_worker_registration_id));
|
| + service_worker_registration_id, uses_standard_protocol));
|
| }
|
|
|
| void PushMessagingMessageFilter::DidGetSubscription(
|
| int request_id,
|
| int64_t service_worker_registration_id,
|
| + bool uses_standard_protocol,
|
| const std::vector<std::string>& push_subscription_id,
|
| ServiceWorkerStatusCode service_worker_status) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| @@ -735,7 +763,7 @@ void PushMessagingMessageFilter::DidGetSubscription(
|
| PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR;
|
| switch (service_worker_status) {
|
| case SERVICE_WORKER_OK: {
|
| - if (push_endpoint_base_.is_empty()) {
|
| + if (!service_available_) {
|
| // Return not found in incognito mode, so websites can't detect it.
|
| get_status =
|
| ui_core_->is_incognito()
|
| @@ -751,7 +779,7 @@ void PushMessagingMessageFilter::DidGetSubscription(
|
| const GURL origin = registration->pattern().GetOrigin();
|
| DCHECK_EQ(1u, push_subscription_id.size());
|
| const GURL endpoint =
|
| - CreatePushEndpoint(push_endpoint_base_, push_subscription_id[0]);
|
| + CreateEndpoint(uses_standard_protocol, push_subscription_id[0]);
|
|
|
| auto callback =
|
| base::Bind(&PushMessagingMessageFilter::DidGetSubscriptionKeys,
|
| @@ -909,6 +937,15 @@ void PushMessagingMessageFilter::SendIPC(
|
| Send(message.release());
|
| }
|
|
|
| +GURL PushMessagingMessageFilter::CreateEndpoint(
|
| + bool standard_protocol,
|
| + const std::string& subscription_id) const {
|
| + const GURL& base =
|
| + standard_protocol ? web_push_protocol_endpoint_ : default_endpoint_;
|
| +
|
| + return GURL(base.spec() + subscription_id);
|
| +}
|
| +
|
| PushMessagingService* PushMessagingMessageFilter::Core::service() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| RenderProcessHost* process_host =
|
|
|