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" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 ServiceWorkerStatusCode status) { | 170 ServiceWorkerStatusCode status) { |
171 callback.Run(status, false /* accept_connection */); | 171 callback.Run(status, false /* accept_connection */); |
172 } | 172 } |
173 | 173 |
174 void RunErrorSendStashedPortsCallback( | 174 void RunErrorSendStashedPortsCallback( |
175 const ServiceWorkerVersion::SendStashedPortsCallback& callback, | 175 const ServiceWorkerVersion::SendStashedPortsCallback& callback, |
176 ServiceWorkerStatusCode status) { | 176 ServiceWorkerStatusCode status) { |
177 callback.Run(status, std::vector<int>()); | 177 callback.Run(status, std::vector<int>()); |
178 } | 178 } |
179 | 179 |
180 using WindowOpenedCallback = base::Callback<void(int, int)>; | 180 using OpenURLCallback = base::Callback<void(int, int)>; |
181 | 181 |
182 // The WindowOpenedObserver class is a WebContentsObserver that will wait for a | 182 // The OpenURLObserver class is a WebContentsObserver that will wait for a |
183 // new Window's WebContents to be initialized, run the |callback| passed to its | 183 // WebContents to be initialized, run the |callback| passed to its constructor |
184 // constructor then self destroy. | 184 // then self destroy. |
185 // The callback will receive the process and frame ids. If something went wrong | 185 // The callback will receive the process and frame ids. If something went wrong |
186 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). | 186 // those will be (kInvalidUniqueID, MSG_ROUTING_NONE). |
187 // The callback will be called in the IO thread. | 187 // The callback will be called in the IO thread. |
188 class WindowOpenedObserver : public WebContentsObserver { | 188 class OpenURLObserver : public WebContentsObserver { |
189 public: | 189 public: |
190 WindowOpenedObserver(WebContents* web_contents, | 190 OpenURLObserver(WebContents* web_contents, const OpenURLCallback& callback) |
191 const WindowOpenedCallback& callback) | 191 : WebContentsObserver(web_contents), callback_(callback) {} |
192 : WebContentsObserver(web_contents), | |
193 callback_(callback) | |
194 {} | |
195 | 192 |
196 void DidCommitProvisionalLoadForFrame( | 193 void DidCommitProvisionalLoadForFrame( |
197 RenderFrameHost* render_frame_host, | 194 RenderFrameHost* render_frame_host, |
198 const GURL& validated_url, | 195 const GURL& validated_url, |
199 ui::PageTransition transition_type) override { | 196 ui::PageTransition transition_type) override { |
200 DCHECK(web_contents()); | 197 DCHECK(web_contents()); |
201 | 198 |
202 if (render_frame_host != web_contents()->GetMainFrame()) | 199 if (render_frame_host != web_contents()->GetMainFrame()) |
203 return; | 200 return; |
204 | 201 |
(...skipping 17 matching lines...) Expand all Loading... | |
222 DCHECK(web_contents()); | 219 DCHECK(web_contents()); |
223 | 220 |
224 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 221 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
225 base::Bind(callback_, | 222 base::Bind(callback_, |
226 render_process_id, | 223 render_process_id, |
227 render_frame_id)); | 224 render_frame_id)); |
228 Observe(nullptr); | 225 Observe(nullptr); |
229 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 226 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
230 } | 227 } |
231 | 228 |
232 const WindowOpenedCallback callback_; | 229 const OpenURLCallback callback_; |
233 | 230 |
234 DISALLOW_COPY_AND_ASSIGN(WindowOpenedObserver); | 231 DISALLOW_COPY_AND_ASSIGN(OpenURLObserver); |
235 }; | 232 }; |
236 | 233 |
237 void DidOpenURL(const WindowOpenedCallback& callback, | 234 void DidOpenURL(const OpenURLCallback& callback, WebContents* web_contents) { |
238 WebContents* web_contents) { | |
239 DCHECK(web_contents); | 235 DCHECK(web_contents); |
240 | 236 |
241 new WindowOpenedObserver(web_contents, callback); | 237 new OpenURLObserver(web_contents, callback); |
238 } | |
239 | |
240 void NavigateClientOnUI(const GURL& url, | |
241 const GURL& script_url, | |
242 int process_id, | |
243 int frame_id, | |
244 const OpenURLCallback& callback) { | |
245 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
246 | |
247 RenderFrameHost* render_frame_host = | |
248 RenderFrameHost::FromID(process_id, frame_id); | |
249 WebContents* web_contents = | |
250 WebContents::FromRenderFrameHost(render_frame_host); | |
251 | |
252 if (!render_frame_host || !web_contents) { | |
253 BrowserThread::PostTask( | |
254 BrowserThread::IO, FROM_HERE, | |
255 base::Bind(callback, ChildProcessHost::kInvalidUniqueID, | |
256 MSG_ROUTING_NONE)); | |
257 return; | |
258 } | |
259 | |
260 OpenURLParams params( | |
261 url, Referrer::SanitizeForRequest( | |
262 url, Referrer(script_url, blink::WebReferrerPolicyDefault)), | |
263 CURRENT_TAB, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
264 true /* is_renderer_initiated */); | |
265 web_contents->OpenURL(params); | |
266 DidOpenURL(callback, web_contents); | |
242 } | 267 } |
243 | 268 |
244 void OpenWindowOnUI( | 269 void OpenWindowOnUI( |
245 const GURL& url, | 270 const GURL& url, |
246 const GURL& script_url, | 271 const GURL& script_url, |
247 int process_id, | 272 int process_id, |
248 const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper, | 273 const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper, |
249 const WindowOpenedCallback& callback) { | 274 const OpenURLCallback& callback) { |
250 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 275 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
251 | 276 |
252 BrowserContext* browser_context = context_wrapper->storage_partition() | 277 BrowserContext* browser_context = context_wrapper->storage_partition() |
253 ? context_wrapper->storage_partition()->browser_context() | 278 ? context_wrapper->storage_partition()->browser_context() |
254 : nullptr; | 279 : nullptr; |
255 // We are shutting down. | 280 // We are shutting down. |
256 if (!browser_context) | 281 if (!browser_context) |
257 return; | 282 return; |
258 | 283 |
259 RenderProcessHost* render_process_host = | 284 RenderProcessHost* render_process_host = |
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1208 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, | 1233 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenWindow, |
1209 OnOpenWindow) | 1234 OnOpenWindow) |
1210 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetCachedMetadata, | 1235 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetCachedMetadata, |
1211 OnSetCachedMetadata) | 1236 OnSetCachedMetadata) |
1212 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClearCachedMetadata, | 1237 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClearCachedMetadata, |
1213 OnClearCachedMetadata) | 1238 OnClearCachedMetadata) |
1214 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToClient, | 1239 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToClient, |
1215 OnPostMessageToClient) | 1240 OnPostMessageToClient) |
1216 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, | 1241 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, |
1217 OnFocusClient) | 1242 OnFocusClient) |
1243 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_NavigateClient, OnNavigateClient) | |
1218 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, | 1244 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, |
1219 OnSkipWaiting) | 1245 OnSkipWaiting) |
1220 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, | 1246 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, |
1221 OnClaimClients) | 1247 OnClaimClients) |
1222 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker) | 1248 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker) |
1223 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_StashMessagePort, | 1249 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_StashMessagePort, |
1224 OnStashMessagePort) | 1250 OnStashMessagePort) |
1225 IPC_MESSAGE_UNHANDLED(handled = false) | 1251 IPC_MESSAGE_UNHANDLED(handled = false) |
1226 IPC_END_MESSAGE_MAP() | 1252 IPC_END_MESSAGE_MAP() |
1227 return handled; | 1253 return handled; |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1670 if (running_status() != RUNNING) | 1696 if (running_status() != RUNNING) |
1671 return; | 1697 return; |
1672 | 1698 |
1673 ServiceWorkerClientInfo client_info(client); | 1699 ServiceWorkerClientInfo client_info(client); |
1674 client_info.client_uuid = client_uuid; | 1700 client_info.client_uuid = client_uuid; |
1675 | 1701 |
1676 embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( | 1702 embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( |
1677 request_id, client_info)); | 1703 request_id, client_info)); |
1678 } | 1704 } |
1679 | 1705 |
1706 void ServiceWorkerVersion::OnNavigateClient(int request_id, | |
1707 const std::string& client_uuid, | |
1708 const GURL& url) { | |
1709 if (!context_) | |
1710 return; | |
1711 | |
1712 TRACE_EVENT2("ServiceWorker", "ServiceWorkerVersion::OnNavigateClient", | |
1713 "Request id", request_id, "Client id", client_uuid); | |
1714 | |
1715 if (!url.is_valid()) { | |
1716 DVLOG(1) << "Received unexpected invalid URL from renderer process."; | |
1717 BrowserThread::PostTask( | |
1718 BrowserThread::UI, FROM_HERE, | |
1719 base::Bind(&KillEmbeddedWorkerProcess, embedded_worker_->process_id(), | |
1720 RESULT_CODE_KILLED_BAD_MESSAGE)); | |
1721 return; | |
1722 } | |
1723 | |
1724 // Reject requests for URLs that the process is not allowed to access. It's | |
1725 // possible to receive such requests since the renderer-side checks are | |
1726 // slightly different. For example, the view-source scheme will not be | |
1727 // filtered out by Blink. | |
1728 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( | |
1729 embedded_worker_->process_id(), url)) { | |
1730 embedded_worker_->SendMessage(ServiceWorkerMsg_NavigateClientError( | |
1731 request_id, url.spec() + " cannot navigate.")); | |
1732 return; | |
1733 } | |
1734 | |
1735 ServiceWorkerProviderHost* provider_host = | |
1736 context_->GetProviderHostByClientID(client_uuid); | |
1737 if (!provider_host || provider_host->active_version() != this) { | |
1738 embedded_worker_->SendMessage(ServiceWorkerMsg_NavigateClientError( | |
1739 request_id, url.spec() + " cannot navigate.")); | |
1740 return; | |
1741 } | |
1742 | |
1743 BrowserThread::PostTask( | |
1744 BrowserThread::UI, FROM_HERE, | |
1745 base::Bind(&NavigateClientOnUI, url, script_url_, | |
1746 provider_host->process_id(), provider_host->frame_id(), | |
1747 base::Bind(&ServiceWorkerVersion::DidNavigateClient, | |
1748 weak_factory_.GetWeakPtr(), request_id))); | |
1749 } | |
1750 | |
1751 void ServiceWorkerVersion::DidNavigateClient(int request_id, | |
1752 int render_process_id, | |
1753 int render_frame_id) { | |
1754 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
1755 | |
1756 if (running_status() != RUNNING) | |
1757 return; | |
1758 | |
1759 if (render_process_id == ChildProcessHost::kInvalidUniqueID && | |
1760 render_frame_id == MSG_ROUTING_NONE) { | |
1761 embedded_worker_->SendMessage(ServiceWorkerMsg_NavigateClientError( | |
1762 request_id, "Something went wrong while trying to navigate client.")); | |
1763 return; | |
1764 } | |
1765 | |
1766 for (auto it = | |
1767 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); | |
1768 !it->IsAtEnd(); it->Advance()) { | |
1769 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); | |
1770 if (provider_host->process_id() != render_process_id || | |
1771 provider_host->frame_id() != render_frame_id) { | |
1772 continue; | |
1773 } | |
1774 provider_host->GetWindowClientInfo(base::Bind( | |
1775 &ServiceWorkerVersion::OnNavigateClientFinished, | |
1776 weak_factory_.GetWeakPtr(), request_id, provider_host->client_uuid())); | |
1777 return; | |
1778 } | |
1779 | |
1780 OnNavigateClientFinished(request_id, std::string(), | |
1781 ServiceWorkerClientInfo()); | |
1782 } | |
1783 | |
1784 void ServiceWorkerVersion::OnNavigateClientFinished( | |
1785 int request_id, | |
1786 const std::string& client_uuid, | |
1787 const ServiceWorkerClientInfo& client_info) { | |
1788 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
1789 | |
1790 if (running_status() != RUNNING) | |
1791 return; | |
1792 | |
1793 ServiceWorkerClientInfo client(client_info); | |
1794 | |
1795 // If the |client_info| is empty, it means that the navigated client wasn't | |
1796 // controlled but the action still succeeded. The renderer process is | |
1797 // expecting an empty client in such case. | |
1798 if (!client.IsEmpty()) | |
1799 client.client_uuid = client_uuid; | |
palmer
2015/07/15 17:07:54
I think you should validate that the UUID has the
zino
2015/07/16 14:06:52
Thank you for review.
If you're saying that we ha
palmer
2015/07/16 18:28:05
It looks like the provider host gets the UUID dire
zino
2015/07/17 11:26:11
Yes, the uuid is passed from the renderer but it i
palmer
2015/07/20 23:15:32
Yes, for a few reasons.
1. It's best to fail as s
zino
2015/07/23 05:56:17
Done. I added the validation check to |OnNavigateC
| |
1800 | |
1801 embedded_worker_->SendMessage( | |
1802 ServiceWorkerMsg_NavigateClientResponse(request_id, client)); | |
1803 } | |
1804 | |
1680 void ServiceWorkerVersion::OnSkipWaiting(int request_id) { | 1805 void ServiceWorkerVersion::OnSkipWaiting(int request_id) { |
1681 skip_waiting_ = true; | 1806 skip_waiting_ = true; |
1682 if (status_ != INSTALLED) | 1807 if (status_ != INSTALLED) |
1683 return DidSkipWaiting(request_id); | 1808 return DidSkipWaiting(request_id); |
1684 | 1809 |
1685 if (!context_) | 1810 if (!context_) |
1686 return; | 1811 return; |
1687 ServiceWorkerRegistration* registration = | 1812 ServiceWorkerRegistration* registration = |
1688 context_->GetLiveRegistration(registration_id_); | 1813 context_->GetLiveRegistration(registration_id_); |
1689 if (!registration) | 1814 if (!registration) |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2196 | 2321 |
2197 streaming_url_request_jobs_.clear(); | 2322 streaming_url_request_jobs_.clear(); |
2198 | 2323 |
2199 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); | 2324 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); |
2200 | 2325 |
2201 if (should_restart) | 2326 if (should_restart) |
2202 StartWorkerInternal(); | 2327 StartWorkerInternal(); |
2203 } | 2328 } |
2204 | 2329 |
2205 } // namespace content | 2330 } // namespace content |
OLD | NEW |