Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/service_worker/service_worker_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/guid.h" | |
| 11 #include "base/location.h" | 12 #include "base/location.h" |
| 12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 13 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 16 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" |
| 19 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 20 #include "content/browser/bad_message.h" | 21 #include "content/browser/bad_message.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 callback.Run(status, false /* accept_connection */, base::string16(), | 174 callback.Run(status, false /* accept_connection */, base::string16(), |
| 174 base::string16()); | 175 base::string16()); |
| 175 } | 176 } |
| 176 | 177 |
| 177 void RunErrorSendStashedPortsCallback( | 178 void RunErrorSendStashedPortsCallback( |
| 178 const ServiceWorkerVersion::SendStashedPortsCallback& callback, | 179 const ServiceWorkerVersion::SendStashedPortsCallback& callback, |
| 179 ServiceWorkerStatusCode status) { | 180 ServiceWorkerStatusCode status) { |
| 180 callback.Run(status, std::vector<int>()); | 181 callback.Run(status, std::vector<int>()); |
| 181 } | 182 } |
| 182 | 183 |
| 183 using WindowOpenedCallback = base::Callback<void(int, int)>; | 184 using OpenURLCallback = base::Callback<void(int, int)>; |
| 184 | 185 |
| 185 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a | 186 // The OpenURLObserver class is a WebContentsObserver that will wait for a |
| 186 // new Window's WebContents to be initialized, run the |callback| passed to its | 187 // WebContents to be initialized, run the |callback| passed to its constructor |
| 187 // constructor then self destroy. | 188 // then self destroy. |
| 188 // The callback will receive the process and frame ids. If something went wrong | 189 // The callback will receive the process and frame ids. If something went wrong |
| 189 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). | 190 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). |
| 190 // The callback will be called in the IO thread. | 191 // The callback will be called in the IO thread. |
| 191 class WindowOpenedObserver : public WebContentsObserver { | 192 class OpenURLObserver : public WebContentsObserver { |
| 192 public: | 193 public: |
| 193 WindowOpenedObserver(WebContents* web_contents, | 194 OpenURLObserver(WebContents* web_contents, const OpenURLCallback& callback) |
| 194 const WindowOpenedCallback& callback) | 195 : WebContentsObserver(web_contents), callback_(callback) {} |
| 195 : WebContentsObserver(web_contents), | |
| 196 callback_(callback) | |
| 197 {} | |
| 198 | 196 |
| 199 void DidCommitProvisionalLoadForFrame( | 197 void DidCommitProvisionalLoadForFrame( |
| 200 RenderFrameHost* render_frame_host, | 198 RenderFrameHost* render_frame_host, |
| 201 const GURL& validated_url, | 199 const GURL& validated_url, |
| 202 ui::PageTransition transition_type) override { | 200 ui::PageTransition transition_type) override { |
| 203 DCHECK(web_contents()); | 201 DCHECK(web_contents()); |
| 204 | 202 |
| 205 if (render_frame_host != web_contents()->GetMainFrame()) | 203 if (render_frame_host != web_contents()->GetMainFrame()) |
| 206 return; | 204 return; |
| 207 | 205 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 225 DCHECK(web_contents()); | 223 DCHECK(web_contents()); |
| 226 | 224 |
| 227 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 225 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 228 base::Bind(callback_, | 226 base::Bind(callback_, |
| 229 render_process_id, | 227 render_process_id, |
| 230 render_frame_id)); | 228 render_frame_id)); |
| 231 Observe(nullptr); | 229 Observe(nullptr); |
| 232 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 230 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 233 } | 231 } |
| 234 | 232 |
| 235 const WindowOpenedCallback callback_; | 233 const OpenURLCallback callback_; |
| 236 | 234 |
| 237 DISALLOW_COPY_AND_ASSIGN(WindowOpenedObserver); | 235 DISALLOW_COPY_AND_ASSIGN(OpenURLObserver); |
| 238 }; | 236 }; |
| 239 | 237 |
| 240 void DidOpenURL(const WindowOpenedCallback& callback, | 238 void DidOpenURL(const OpenURLCallback& callback, WebContents* web_contents) { |
| 241 WebContents* web_contents) { | |
| 242 DCHECK(web_contents); | 239 DCHECK(web_contents); |
| 243 | 240 |
| 244 new WindowOpenedObserver(web_contents, callback); | 241 new OpenURLObserver(web_contents, callback); |
| 242 } | |
| 243 | |
| 244 void NavigateClientOnUI(const GURL& url, | |
| 245 const GURL& script_url, | |
| 246 int process_id, | |
| 247 int frame_id, | |
| 248 const OpenURLCallback& callback) { | |
| 249 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 250 | |
| 251 RenderFrameHost* render_frame_host = | |
| 252 RenderFrameHost::FromID(process_id, frame_id); | |
| 253 WebContents* web_contents = | |
| 254 WebContents::FromRenderFrameHost(render_frame_host); | |
| 255 | |
| 256 if (!render_frame_host || !web_contents) { | |
| 257 BrowserThread::PostTask( | |
| 258 BrowserThread::IO, FROM_HERE, | |
| 259 base::Bind(callback, ChildProcessHost::kInvalidUniqueID, | |
| 260 MSG_ROUTING_NONE)); | |
| 261 return; | |
| 262 } | |
| 263 | |
| 264 OpenURLParams params( | |
| 265 url, Referrer::SanitizeForRequest( | |
| 266 url, Referrer(script_url, blink::WebReferrerPolicyDefault)), | |
| 267 CURRENT_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
| 268 true /* is_renderer_initiated */); | |
| 269 web_contents->OpenURL(params); | |
| 270 DidOpenURL(callback, web_contents); | |
| 245 } | 271 } |
| 246 | 272 |
| 247 void OpenWindowOnUI( | 273 void OpenWindowOnUI( |
| 248 const GURL& url, | 274 const GURL& url, |
| 249 const GURL& script_url, | 275 const GURL& script_url, |
| 250 int process_id, | 276 int process_id, |
| 251 const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper, | 277 const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper, |
| 252 const WindowOpenedCallback& callback) { | 278 const OpenURLCallback& callback) { |
| 253 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 279 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 254 | 280 |
| 255 BrowserContext* browser_context = context_wrapper->storage_partition() | 281 BrowserContext* browser_context = context_wrapper->storage_partition() |
| 256 ? context_wrapper->storage_partition()->browser_context() | 282 ? context_wrapper->storage_partition()->browser_context() |
| 257 : nullptr; | 283 : nullptr; |
| 258 // We are shutting down. | 284 // We are shutting down. |
| 259 if (!browser_context) | 285 if (!browser_context) |
| 260 return; | 286 return; |
| 261 | 287 |
| 262 RenderProcessHost* render_process_host = | 288 RenderProcessHost* render_process_host = |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, | 1244 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, |
| 1219 OnOpenWindow) | 1245 OnOpenWindow) |
| 1220 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetCachedMetadata, | 1246 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetCachedMetadata, |
| 1221 OnSetCachedMetadata) | 1247 OnSetCachedMetadata) |
| 1222 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClearCachedMetadata, | 1248 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClearCachedMetadata, |
| 1223 OnClearCachedMetadata) | 1249 OnClearCachedMetadata) |
| 1224 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToClient, | 1250 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToClient, |
| 1225 OnPostMessageToClient) | 1251 OnPostMessageToClient) |
| 1226 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, | 1252 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, |
| 1227 OnFocusClient) | 1253 OnFocusClient) |
| 1254 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NavigateClient, OnNavigateClient) | |
| 1228 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, | 1255 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, |
| 1229 OnSkipWaiting) | 1256 OnSkipWaiting) |
| 1230 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, | 1257 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, |
| 1231 OnClaimClients) | 1258 OnClaimClients) |
| 1232 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker) | 1259 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker) |
| 1233 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_StashMessagePort, | 1260 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_StashMessagePort, |
| 1234 OnStashMessagePort) | 1261 OnStashMessagePort) |
| 1235 IPC_MESSAGE_UNHANDLED(handled = false) | 1262 IPC_MESSAGE_UNHANDLED(handled = false) |
| 1236 IPC_END_MESSAGE_MAP() | 1263 IPC_END_MESSAGE_MAP() |
| 1237 return handled; | 1264 return handled; |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1684 if (running_status() != RUNNING) | 1711 if (running_status() != RUNNING) |
| 1685 return; | 1712 return; |
| 1686 | 1713 |
| 1687 ServiceWorkerClientInfo client_info(client); | 1714 ServiceWorkerClientInfo client_info(client); |
| 1688 client_info.client_uuid = client_uuid; | 1715 client_info.client_uuid = client_uuid; |
| 1689 | 1716 |
| 1690 embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( | 1717 embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( |
| 1691 request_id, client_info)); | 1718 request_id, client_info)); |
| 1692 } | 1719 } |
| 1693 | 1720 |
| 1721 void ServiceWorkerVersion::OnNavigateClient(int request_id, | |
| 1722 const std::string& client_uuid, | |
| 1723 const GURL& url) { | |
| 1724 if (!context_) | |
| 1725 return; | |
| 1726 | |
| 1727 TRACE_EVENT2("ServiceWorker", "ServiceWorkerVersion::OnNavigateClient", | |
| 1728 "Request id", request_id, "Client id", client_uuid); | |
| 1729 | |
| 1730 if (!url.is_valid()) { | |
| 1731 DVLOG(1) << "Received unexpected invalid URL from renderer process."; | |
| 1732 BrowserThread::PostTask( | |
| 1733 BrowserThread::UI, FROM_HERE, | |
| 1734 base::Bind(&KillEmbeddedWorkerProcess, embedded_worker_->process_id(), | |
| 1735 RESULT_CODE_KILLED_BAD_MESSAGE)); | |
| 1736 return; | |
| 1737 } | |
| 1738 | |
| 1739 // Reject requests for URLs that the process is not allowed to access. It's | |
| 1740 // possible to receive such requests since the renderer-side checks are | |
| 1741 // slightly different. For example, the view-source scheme will not be | |
| 1742 // filtered out by Blink. | |
| 1743 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( | |
| 1744 embedded_worker_->process_id(), url)) { | |
| 1745 embedded_worker_->SendMessage( | |
| 1746 ServiceWorkerMsg_NavigateClientError(request_id, url)); | |
| 1747 return; | |
| 1748 } | |
| 1749 | |
| 1750 if (!base::IsValidGUID(client_uuid)) { | |
|
palmer
2015/07/27 21:55:58
I almost wonder if it's more appropriate to send N
zino
2015/07/28 01:27:22
Done.
| |
| 1751 embedded_worker_->SendMessage( | |
| 1752 ServiceWorkerMsg_NavigateClientError(request_id, url)); | |
| 1753 return; | |
| 1754 } | |
| 1755 | |
| 1756 ServiceWorkerProviderHost* provider_host = | |
| 1757 context_->GetProviderHostByClientID(client_uuid); | |
| 1758 if (!provider_host || provider_host->active_version() != this) { | |
| 1759 embedded_worker_->SendMessage( | |
| 1760 ServiceWorkerMsg_NavigateClientError(request_id, url)); | |
| 1761 return; | |
| 1762 } | |
| 1763 | |
| 1764 BrowserThread::PostTask( | |
| 1765 BrowserThread::UI, FROM_HERE, | |
| 1766 base::Bind(&NavigateClientOnUI, url, script_url_, | |
| 1767 provider_host->process_id(), provider_host->frame_id(), | |
| 1768 base::Bind(&ServiceWorkerVersion::DidNavigateClient, | |
| 1769 weak_factory_.GetWeakPtr(), request_id))); | |
| 1770 } | |
| 1771 | |
| 1772 void ServiceWorkerVersion::DidNavigateClient(int request_id, | |
| 1773 int render_process_id, | |
| 1774 int render_frame_id) { | |
| 1775 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 1776 | |
| 1777 if (running_status() != RUNNING) | |
| 1778 return; | |
| 1779 | |
| 1780 if (render_process_id == ChildProcessHost::kInvalidUniqueID && | |
| 1781 render_frame_id == MSG_ROUTING_NONE) { | |
| 1782 embedded_worker_->SendMessage( | |
| 1783 ServiceWorkerMsg_NavigateClientError(request_id, GURL())); | |
| 1784 return; | |
| 1785 } | |
| 1786 | |
| 1787 for (auto it = | |
| 1788 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); | |
| 1789 !it->IsAtEnd(); it->Advance()) { | |
| 1790 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); | |
| 1791 if (provider_host->process_id() != render_process_id || | |
| 1792 provider_host->frame_id() != render_frame_id) { | |
| 1793 continue; | |
| 1794 } | |
| 1795 provider_host->GetWindowClientInfo(base::Bind( | |
| 1796 &ServiceWorkerVersion::OnNavigateClientFinished, | |
| 1797 weak_factory_.GetWeakPtr(), request_id, provider_host->client_uuid())); | |
| 1798 return; | |
| 1799 } | |
| 1800 | |
| 1801 OnNavigateClientFinished(request_id, std::string(), | |
| 1802 ServiceWorkerClientInfo()); | |
| 1803 } | |
| 1804 | |
| 1805 void ServiceWorkerVersion::OnNavigateClientFinished( | |
| 1806 int request_id, | |
| 1807 const std::string& client_uuid, | |
| 1808 const ServiceWorkerClientInfo& client_info) { | |
| 1809 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 1810 | |
| 1811 if (running_status() != RUNNING) | |
| 1812 return; | |
| 1813 | |
| 1814 ServiceWorkerClientInfo client(client_info); | |
| 1815 | |
| 1816 // If the |client_info| is empty, it means that the navigated client wasn't | |
| 1817 // controlled but the action still succeeded. The renderer process is | |
| 1818 // expecting an empty client in such case. | |
| 1819 if (!client.IsEmpty()) | |
| 1820 client.client_uuid = client_uuid; | |
| 1821 | |
| 1822 embedded_worker_->SendMessage( | |
| 1823 ServiceWorkerMsg_NavigateClientResponse(request_id, client)); | |
| 1824 } | |
| 1825 | |
| 1694 void ServiceWorkerVersion::OnSkipWaiting(int request_id) { | 1826 void ServiceWorkerVersion::OnSkipWaiting(int request_id) { |
| 1695 skip_waiting_ = true; | 1827 skip_waiting_ = true; |
| 1696 if (status_ != INSTALLED) | 1828 if (status_ != INSTALLED) |
| 1697 return DidSkipWaiting(request_id); | 1829 return DidSkipWaiting(request_id); |
| 1698 | 1830 |
| 1699 if (!context_) | 1831 if (!context_) |
| 1700 return; | 1832 return; |
| 1701 ServiceWorkerRegistration* registration = | 1833 ServiceWorkerRegistration* registration = |
| 1702 context_->GetLiveRegistration(registration_id_); | 1834 context_->GetLiveRegistration(registration_id_); |
| 1703 if (!registration) | 1835 if (!registration) |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2220 } | 2352 } |
| 2221 | 2353 |
| 2222 void ServiceWorkerVersion::OnServicePortDispatcherConnectionError() { | 2354 void ServiceWorkerVersion::OnServicePortDispatcherConnectionError() { |
| 2223 RunIDMapCallbacks(&service_port_connect_requests_, | 2355 RunIDMapCallbacks(&service_port_connect_requests_, |
| 2224 SERVICE_WORKER_ERROR_FAILED, false, base::string16(), | 2356 SERVICE_WORKER_ERROR_FAILED, false, base::string16(), |
| 2225 base::string16()); | 2357 base::string16()); |
| 2226 service_port_dispatcher_.reset(); | 2358 service_port_dispatcher_.reset(); |
| 2227 } | 2359 } |
| 2228 | 2360 |
| 2229 } // namespace content | 2361 } // namespace content |
| OLD | NEW |