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
3 // found in the LICENSE file.
5 #include "content/renderer/render_frame_impl.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "content/child/appcache/appcache_dispatcher.h"
13 #include "content/child/plugin_messages.h"
14 #include "content/child/quota_dispatcher.h"
15 #include "content/child/request_extra_data.h"
16 #include "content/child/service_worker/web_service_worker_provider_impl.h"
17 #include "content/common/frame_messages.h"
18 #include "content/common/socket_stream_handle_data.h"
19 #include "content/common/swapped_out_messages.h"
20 #include "content/common/view_messages.h"
21 #include "content/public/common/content_constants.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/common/url_constants.h"
24 #include "content/public/renderer/content_renderer_client.h"
25 #include "content/public/renderer/document_state.h"
26 #include "content/public/renderer/navigation_state.h"
27 #include "content/renderer/browser_plugin/browser_plugin.h"
28 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
29 #include "content/renderer/internal_document_state_data.h"
30 #include "content/renderer/npapi/plugin_channel_host.h"
31 #include "content/renderer/render_thread_impl.h"
32 #include "content/renderer/render_view_impl.h"
33 #include "content/renderer/renderer_webapplicationcachehost_impl.h"
34 #include "content/renderer/websharedworker_proxy.h"
35 #include "net/base/net_errors.h"
36 #include "net/http/http_util.h"
37 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
38 #include "third_party/WebKit/public/platform/WebString.h"
39 #include "third_party/WebKit/public/platform/WebURL.h"
40 #include "third_party/WebKit/public/platform/WebURLError.h"
41 #include "third_party/WebKit/public/platform/WebURLResponse.h"
42 #include "third_party/WebKit/public/platform/WebVector.h"
43 #include "third_party/WebKit/public/web/WebDocument.h"
44 #include "third_party/WebKit/public/web/WebFrame.h"
45 #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
46 #include "third_party/WebKit/public/web/WebPlugin.h"
47 #include "third_party/WebKit/public/web/WebPluginParams.h"
48 #include "third_party/WebKit/public/web/WebSearchableFormData.h"
49 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
50 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
51 #include "third_party/WebKit/public/web/WebView.h"
52 #include "webkit/child/weburlresponse_extradata_impl.h"
54 #if defined(ENABLE_WEBRTC)
55 #include "content/renderer/media/rtc_peer_connection_handler.h"
58 using blink::WebDataSource
;
59 using blink::WebDocument
;
60 using blink::WebFrame
;
61 using blink::WebNavigationPolicy
;
62 using blink::WebPluginParams
;
63 using blink::WebReferrerPolicy
;
64 using blink::WebSearchableFormData
;
65 using blink::WebSecurityOrigin
;
66 using blink::WebServiceWorkerProvider
;
67 using blink::WebStorageQuotaCallbacks
;
68 using blink::WebString
;
70 using blink::WebURLError
;
71 using blink::WebURLRequest
;
72 using blink::WebURLResponse
;
73 using blink::WebUserGestureIndicator
;
74 using blink::WebVector
;
77 using base::TimeDelta
;
78 using webkit_glue::WebURLResponseExtraDataImpl
;
84 typedef std::map
<blink::WebFrame
*, RenderFrameImpl
*> FrameMap
;
85 base::LazyInstance
<FrameMap
> g_child_frame_map
= LAZY_INSTANCE_INITIALIZER
;
89 static RenderFrameImpl
* (*g_create_render_frame_impl
)(RenderViewImpl
*, int32
) =
93 RenderFrameImpl
* RenderFrameImpl::Create(RenderViewImpl
* render_view
,
95 DCHECK(routing_id
!= MSG_ROUTING_NONE
);
97 if (g_create_render_frame_impl
)
98 return g_create_render_frame_impl(render_view
, routing_id
);
100 return new RenderFrameImpl(render_view
, routing_id
);
104 void RenderFrameImpl::InstallCreateHook(
105 RenderFrameImpl
* (*create_render_frame_impl
)(RenderViewImpl
*, int32
)) {
106 CHECK(!g_create_render_frame_impl
);
107 g_create_render_frame_impl
= create_render_frame_impl
;
110 // RenderFrameImpl ----------------------------------------------------------
111 RenderFrameImpl::RenderFrameImpl(RenderViewImpl
* render_view
, int routing_id
)
112 : render_view_(render_view
),
113 routing_id_(routing_id
),
114 is_swapped_out_(false),
115 is_detaching_(false) {
118 RenderFrameImpl::~RenderFrameImpl() {
121 int RenderFrameImpl::GetRoutingID() const {
125 bool RenderFrameImpl::Send(IPC::Message
* message
) {
127 ((is_swapped_out_
|| render_view_
->is_swapped_out()) &&
128 !SwappedOutMessages::CanSendWhileSwappedOut(message
))) {
133 return RenderThread::Get()->Send(message
);
136 bool RenderFrameImpl::OnMessageReceived(const IPC::Message
& msg
) {
137 // TODO(ajwong): Fill in with message handlers as various components
138 // are migrated over to understand frames.
142 // blink::WebFrameClient implementation -------------------------------------
144 blink::WebPlugin
* RenderFrameImpl::createPlugin(
145 blink::WebFrame
* frame
,
146 const blink::WebPluginParams
& params
) {
147 blink::WebPlugin
* plugin
= NULL
;
148 if (GetContentClient()->renderer()->OverrideCreatePlugin(
149 render_view_
, frame
, params
, &plugin
)) {
153 #if defined(ENABLE_PLUGINS)
154 if (UTF16ToASCII(params
.mimeType
) == kBrowserPluginMimeType
) {
155 return render_view_
->GetBrowserPluginManager()->CreateBrowserPlugin(
156 render_view_
, frame
, params
);
160 std::string mime_type
;
161 bool found
= render_view_
->GetPluginInfo(
162 params
.url
, frame
->top()->document().url(), params
.mimeType
.utf8(),
167 WebPluginParams params_to_use
= params
;
168 params_to_use
.mimeType
= WebString::fromUTF8(mime_type
);
169 return render_view_
->CreatePlugin(frame
, info
, params_to_use
);
172 #endif // defined(ENABLE_PLUGINS)
175 blink::WebMediaPlayer
* RenderFrameImpl::createMediaPlayer(
176 blink::WebFrame
* frame
,
177 const blink::WebURL
& url
,
178 blink::WebMediaPlayerClient
* client
) {
179 // TODO(nasko): Moving the implementation here involves moving a few media
180 // related client objects here or referencing them in the RenderView. Needs
181 // more work to understand where the proper place for those objects is.
182 return render_view_
->createMediaPlayer(frame
, url
, client
);
185 blink::WebApplicationCacheHost
* RenderFrameImpl::createApplicationCacheHost(
186 blink::WebFrame
* frame
,
187 blink::WebApplicationCacheHostClient
* client
) {
188 if (!frame
|| !frame
->view())
190 return new RendererWebApplicationCacheHostImpl(
191 RenderViewImpl::FromWebView(frame
->view()), client
,
192 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy());
195 blink::WebWorkerPermissionClientProxy
*
196 RenderFrameImpl::createWorkerPermissionClientProxy(WebFrame
* frame
) {
197 if (!frame
|| !frame
->view())
199 return GetContentClient()->renderer()->CreateWorkerPermissionClientProxy(
200 RenderViewImpl::FromWebView(frame
->view()), frame
);
203 blink::WebCookieJar
* RenderFrameImpl::cookieJar(blink::WebFrame
* frame
) {
204 return render_view_
->cookieJar(frame
);
207 blink::WebServiceWorkerProvider
* RenderFrameImpl::createServiceWorkerProvider(
208 blink::WebFrame
* frame
,
209 blink::WebServiceWorkerProviderClient
* client
) {
210 return new WebServiceWorkerProviderImpl(
211 ChildThread::current()->thread_safe_sender(),
212 make_scoped_ptr(client
));
215 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame
* frame
) {
216 render_view_
->didAccessInitialDocument(frame
);
219 blink::WebFrame
* RenderFrameImpl::createChildFrame(
220 blink::WebFrame
* parent
,
221 const blink::WebString
& name
) {
222 long long child_frame_identifier
= WebFrame::generateEmbedderIdentifier();
223 // Synchronously notify the browser of a child frame creation to get the
224 // routing_id for the RenderFrame.
225 int routing_id
= MSG_ROUTING_NONE
;
226 Send(new FrameHostMsg_CreateChildFrame(GetRoutingID(),
227 parent
->identifier(),
228 child_frame_identifier
,
231 if (routing_id
== MSG_ROUTING_NONE
)
233 RenderFrameImpl
* child_render_frame
= RenderFrameImpl::Create(render_view_
,
236 blink::WebFrame
* web_frame
= WebFrame::create(child_render_frame
,
237 child_frame_identifier
);
239 g_child_frame_map
.Get().insert(
240 std::make_pair(web_frame
, child_render_frame
));
245 void RenderFrameImpl::didDisownOpener(blink::WebFrame
* frame
) {
246 render_view_
->didDisownOpener(frame
);
249 void RenderFrameImpl::frameDetached(blink::WebFrame
* frame
) {
250 // NOTE: This function is called on the frame that is being detached and not
251 // the parent frame. This is different from createChildFrame() which is
252 // called on the parent frame.
253 CHECK(!is_detaching_
);
255 bool is_subframe
= !!frame
->parent();
256 int64 parent_frame_id
= -1;
258 parent_frame_id
= frame
->parent()->identifier();
260 Send(new FrameHostMsg_Detach(GetRoutingID(), parent_frame_id
,
261 frame
->identifier()));
263 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be
264 // sent before setting |is_detaching_| to true. In contrast, Observers
265 // should only be notified afterwards so they cannot call back into and
266 // have IPCs fired off.
267 is_detaching_
= true;
269 // Call back to RenderViewImpl for observers to be notified.
270 // TODO(nasko): Remove once we have RenderFrameObserver.
271 render_view_
->frameDetached(frame
);
273 // We need to clean up subframes by removing them from the map and deleting
274 // the RenderFrameImpl. In contrast, the main frame is owned by its
275 // containing RenderViewHost (so that they have the same lifetime), so it does
276 // not require any cleanup here.
278 FrameMap::iterator it
= g_child_frame_map
.Get().find(frame
);
279 DCHECK(it
!= g_child_frame_map
.Get().end());
280 DCHECK_EQ(it
->second
, this);
281 g_child_frame_map
.Get().erase(it
);
284 // |frame| is invalid after here.
289 // Object is invalid after this point.
293 void RenderFrameImpl::willClose(blink::WebFrame
* frame
) {
294 // Call back to RenderViewImpl for observers to be notified.
295 // TODO(nasko): Remove once we have RenderFrameObserver.
296 render_view_
->willClose(frame
);
299 void RenderFrameImpl::didChangeName(blink::WebFrame
* frame
,
300 const blink::WebString
& name
) {
301 if (!render_view_
->renderer_preferences_
.report_frame_name_changes
)
305 new ViewHostMsg_UpdateFrameName(render_view_
->GetRoutingID(),
311 void RenderFrameImpl::didMatchCSS(
312 blink::WebFrame
* frame
,
313 const blink::WebVector
<blink::WebString
>& newly_matching_selectors
,
314 const blink::WebVector
<blink::WebString
>& stopped_matching_selectors
) {
315 render_view_
->didMatchCSS(
316 frame
, newly_matching_selectors
, stopped_matching_selectors
);
319 void RenderFrameImpl::loadURLExternally(blink::WebFrame
* frame
,
320 const blink::WebURLRequest
& request
,
321 blink::WebNavigationPolicy policy
) {
322 loadURLExternally(frame
, request
, policy
, WebString());
325 void RenderFrameImpl::loadURLExternally(
326 blink::WebFrame
* frame
,
327 const blink::WebURLRequest
& request
,
328 blink::WebNavigationPolicy policy
,
329 const blink::WebString
& suggested_name
) {
330 Referrer
referrer(RenderViewImpl::GetReferrerFromRequest(frame
, request
));
331 if (policy
== blink::WebNavigationPolicyDownload
) {
332 render_view_
->Send(new ViewHostMsg_DownloadUrl(render_view_
->GetRoutingID(),
333 request
.url(), referrer
,
336 render_view_
->OpenURL(frame
, request
.url(), referrer
, policy
);
340 blink::WebNavigationPolicy
RenderFrameImpl::decidePolicyForNavigation(
341 blink::WebFrame
* frame
,
342 blink::WebDataSource::ExtraData
* extra_data
,
343 const blink::WebURLRequest
& request
,
344 blink::WebNavigationType type
,
345 blink::WebNavigationPolicy default_policy
,
347 return render_view_
->decidePolicyForNavigation(
348 frame
, extra_data
, request
, type
, default_policy
, is_redirect
);
351 blink::WebNavigationPolicy
RenderFrameImpl::decidePolicyForNavigation(
352 blink::WebFrame
* frame
,
353 const blink::WebURLRequest
& request
,
354 blink::WebNavigationType type
,
355 blink::WebNavigationPolicy default_policy
,
357 return render_view_
->decidePolicyForNavigation(
358 frame
, request
, type
, default_policy
, is_redirect
);
361 void RenderFrameImpl::willSendSubmitEvent(blink::WebFrame
* frame
,
362 const blink::WebFormElement
& form
) {
363 // Call back to RenderViewImpl for observers to be notified.
364 // TODO(nasko): Remove once we have RenderFrameObserver.
365 render_view_
->willSendSubmitEvent(frame
, form
);
368 void RenderFrameImpl::willSubmitForm(blink::WebFrame
* frame
,
369 const blink::WebFormElement
& form
) {
370 DocumentState
* document_state
=
371 DocumentState::FromDataSource(frame
->provisionalDataSource());
372 NavigationState
* navigation_state
= document_state
->navigation_state();
373 InternalDocumentStateData
* internal_data
=
374 InternalDocumentStateData::FromDocumentState(document_state
);
376 if (PageTransitionCoreTypeIs(navigation_state
->transition_type(),
377 PAGE_TRANSITION_LINK
)) {
378 navigation_state
->set_transition_type(PAGE_TRANSITION_FORM_SUBMIT
);
381 // Save these to be processed when the ensuing navigation is committed.
382 WebSearchableFormData
web_searchable_form_data(form
);
383 internal_data
->set_searchable_form_url(web_searchable_form_data
.url());
384 internal_data
->set_searchable_form_encoding(
385 web_searchable_form_data
.encoding().utf8());
387 // Call back to RenderViewImpl for observers to be notified.
388 // TODO(nasko): Remove once we have RenderFrameObserver.
389 render_view_
->willSubmitForm(frame
, form
);
392 void RenderFrameImpl::didCreateDataSource(blink::WebFrame
* frame
,
393 blink::WebDataSource
* datasource
) {
394 // TODO(nasko): Move implementation here. Needed state:
395 // * pending_navigation_params_
398 // * PopulateDocumentStateFromPending
399 // * CreateNavigationStateFromPending
400 render_view_
->didCreateDataSource(frame
, datasource
);
403 void RenderFrameImpl::didStartProvisionalLoad(blink::WebFrame
* frame
) {
404 WebDataSource
* ds
= frame
->provisionalDataSource();
406 // In fast/loader/stop-provisional-loads.html, we abort the load before this
407 // callback is invoked.
411 DocumentState
* document_state
= DocumentState::FromDataSource(ds
);
413 // We should only navigate to swappedout:// when is_swapped_out_ is true.
414 CHECK((ds
->request().url() != GURL(kSwappedOutURL
)) ||
415 render_view_
->is_swapped_out()) <<
416 "Heard swappedout:// when not swapped out.";
418 // Update the request time if WebKit has better knowledge of it.
419 if (document_state
->request_time().is_null()) {
420 double event_time
= ds
->triggeringEventTime();
421 if (event_time
!= 0.0)
422 document_state
->set_request_time(Time::FromDoubleT(event_time
));
425 // Start time is only set after request time.
426 document_state
->set_start_load_time(Time::Now());
428 bool is_top_most
= !frame
->parent();
430 render_view_
->set_navigation_gesture(
431 WebUserGestureIndicator::isProcessingUserGesture() ?
432 NavigationGestureUser
: NavigationGestureAuto
);
433 } else if (ds
->replacesCurrentHistoryItem()) {
434 // Subframe navigations that don't add session history items must be
435 // marked with AUTO_SUBFRAME. See also didFailProvisionalLoad for how we
436 // handle loading of error pages.
437 document_state
->navigation_state()->set_transition_type(
438 PAGE_TRANSITION_AUTO_SUBFRAME
);
442 RenderViewObserver
, render_view_
->observers(),
443 DidStartProvisionalLoad(frame
));
445 Send(new FrameHostMsg_DidStartProvisionalLoadForFrame(
446 routing_id_
, frame
->identifier(),
447 frame
->parent() ? frame
->parent()->identifier() : -1,
448 is_top_most
, ds
->request().url()));
451 void RenderFrameImpl::didReceiveServerRedirectForProvisionalLoad(
452 blink::WebFrame
* frame
) {
453 // TODO(nasko): Move implementation here. Needed state:
455 render_view_
->didReceiveServerRedirectForProvisionalLoad(frame
);
458 void RenderFrameImpl::didFailProvisionalLoad(
459 blink::WebFrame
* frame
,
460 const blink::WebURLError
& error
) {
461 // TODO(nasko): Move implementation here. Needed state:
463 // * pending_navigation_params_
465 // * MaybeLoadAlternateErrorPage
466 // * LoadNavigationErrorPage
467 render_view_
->didFailProvisionalLoad(frame
, error
);
470 void RenderFrameImpl::didCommitProvisionalLoad(blink::WebFrame
* frame
,
471 bool is_new_navigation
) {
472 // TODO(nasko): Move implementation here. Needed state:
475 // * history_list_offset_
476 // * history_list_length_
477 // * history_page_ids_
480 // * UpdateSessionHistory
482 render_view_
->didCommitProvisionalLoad(frame
, is_new_navigation
);
485 void RenderFrameImpl::didClearWindowObject(blink::WebFrame
* frame
) {
486 // TODO(nasko): Move implementation here. Needed state:
487 // * enabled_bindings_
488 // * dom_automation_controller_
489 // * stats_collection_controller_
490 render_view_
->didClearWindowObject(frame
);
493 void RenderFrameImpl::didCreateDocumentElement(blink::WebFrame
* frame
) {
494 // Notify the browser about non-blank documents loading in the top frame.
495 GURL url
= frame
->document().url();
496 if (url
.is_valid() && url
.spec() != kAboutBlankURL
) {
497 // TODO(nasko): Check if webview()->mainFrame() is the same as the
498 // frame->tree()->top().
499 if (frame
== render_view_
->webview()->mainFrame()) {
500 render_view_
->Send(new ViewHostMsg_DocumentAvailableInMainFrame(
501 render_view_
->GetRoutingID()));
505 // Call back to RenderViewImpl for observers to be notified.
506 // TODO(nasko): Remove once we have RenderFrameObserver.
507 render_view_
->didCreateDocumentElement(frame
);
510 void RenderFrameImpl::didReceiveTitle(blink::WebFrame
* frame
,
511 const blink::WebString
& title
,
512 blink::WebTextDirection direction
) {
513 // TODO(nasko): Investigate wheather implementation should move here.
514 render_view_
->didReceiveTitle(frame
, title
, direction
);
517 void RenderFrameImpl::didChangeIcon(blink::WebFrame
* frame
,
518 blink::WebIconURL::Type icon_type
) {
519 // TODO(nasko): Investigate wheather implementation should move here.
520 render_view_
->didChangeIcon(frame
, icon_type
);
523 void RenderFrameImpl::didFinishDocumentLoad(blink::WebFrame
* frame
) {
524 // TODO(nasko): Move implementation here. No state needed, just observers
525 // notification in before updating encoding.
526 render_view_
->didFinishDocumentLoad(frame
);
529 void RenderFrameImpl::didHandleOnloadEvents(blink::WebFrame
* frame
) {
530 // TODO(nasko): Move implementation here. Needed state:
532 render_view_
->didHandleOnloadEvents(frame
);
535 void RenderFrameImpl::didFailLoad(blink::WebFrame
* frame
,
536 const blink::WebURLError
& error
) {
537 // TODO(nasko): Move implementation here. No state needed.
538 render_view_
->didFailLoad(frame
, error
);
541 void RenderFrameImpl::didFinishLoad(blink::WebFrame
* frame
) {
542 // TODO(nasko): Move implementation here. No state needed, just observers
543 // notification before sending message to the browser process.
544 render_view_
->didFinishLoad(frame
);
547 void RenderFrameImpl::didNavigateWithinPage(blink::WebFrame
* frame
,
548 bool is_new_navigation
) {
549 // TODO(nasko): Move implementation here. No state needed, just observers
550 // notification before sending message to the browser process.
551 render_view_
->didNavigateWithinPage(frame
, is_new_navigation
);
554 void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebFrame
* frame
) {
555 // TODO(nasko): Move implementation here. Needed methods:
556 // * StartNavStateSyncTimerIfNecessary
557 render_view_
->didUpdateCurrentHistoryItem(frame
);
560 void RenderFrameImpl::willRequestAfterPreconnect(
561 blink::WebFrame
* frame
,
562 blink::WebURLRequest
& request
) {
563 blink::WebReferrerPolicy referrer_policy
= blink::WebReferrerPolicyDefault
;
564 WebString custom_user_agent
;
566 if (request
.extraData()) {
567 // This will only be called before willSendRequest, so only ExtraData
568 // members we have to copy here is on WebURLRequestExtraDataImpl.
569 webkit_glue::WebURLRequestExtraDataImpl
* old_extra_data
=
570 static_cast<webkit_glue::WebURLRequestExtraDataImpl
*>(
571 request
.extraData());
573 referrer_policy
= old_extra_data
->referrer_policy();
574 custom_user_agent
= old_extra_data
->custom_user_agent();
577 bool was_after_preconnect_request
= true;
578 // The args after |was_after_preconnect_request| are not used, and set to
579 // correct values at |willSendRequest|.
580 request
.setExtraData(new webkit_glue::WebURLRequestExtraDataImpl(
581 referrer_policy
, custom_user_agent
, was_after_preconnect_request
));
584 void RenderFrameImpl::willSendRequest(
585 blink::WebFrame
* frame
,
587 blink::WebURLRequest
& request
,
588 const blink::WebURLResponse
& redirect_response
) {
589 // The request my be empty during tests.
590 if (request
.url().isEmpty())
593 WebFrame
* top_frame
= frame
->top();
596 WebDataSource
* provisional_data_source
= top_frame
->provisionalDataSource();
597 WebDataSource
* top_data_source
= top_frame
->dataSource();
598 WebDataSource
* data_source
=
599 provisional_data_source
? provisional_data_source
: top_data_source
;
601 PageTransition transition_type
= PAGE_TRANSITION_LINK
;
602 DocumentState
* document_state
= DocumentState::FromDataSource(data_source
);
603 DCHECK(document_state
);
604 InternalDocumentStateData
* internal_data
=
605 InternalDocumentStateData::FromDocumentState(document_state
);
606 NavigationState
* navigation_state
= document_state
->navigation_state();
607 transition_type
= navigation_state
->transition_type();
609 GURL
request_url(request
.url());
611 if (GetContentClient()->renderer()->WillSendRequest(
615 request
.firstPartyForCookies(),
617 request
.setURL(WebURL(new_url
));
620 if (internal_data
->is_cache_policy_override_set())
621 request
.setCachePolicy(internal_data
->cache_policy_override());
623 blink::WebReferrerPolicy referrer_policy
;
624 if (internal_data
->is_referrer_policy_set()) {
625 referrer_policy
= internal_data
->referrer_policy();
626 internal_data
->clear_referrer_policy();
628 referrer_policy
= frame
->document().referrerPolicy();
631 // The request's extra data may indicate that we should set a custom user
632 // agent. This needs to be done here, after WebKit is through with setting the
633 // user agent on its own.
634 WebString custom_user_agent
;
635 bool was_after_preconnect_request
= false;
636 if (request
.extraData()) {
637 webkit_glue::WebURLRequestExtraDataImpl
* old_extra_data
=
638 static_cast<webkit_glue::WebURLRequestExtraDataImpl
*>(
639 request
.extraData());
640 custom_user_agent
= old_extra_data
->custom_user_agent();
641 was_after_preconnect_request
=
642 old_extra_data
->was_after_preconnect_request();
644 if (!custom_user_agent
.isNull()) {
645 if (custom_user_agent
.isEmpty())
646 request
.clearHTTPHeaderField("User-Agent");
648 request
.setHTTPHeaderField("User-Agent", custom_user_agent
);
652 // Attach |should_replace_current_entry| state to requests so that, should
653 // this navigation later require a request transfer, all state is preserved
654 // when it is re-created in the new process.
655 bool should_replace_current_entry
= false;
656 if (navigation_state
->is_content_initiated()) {
657 should_replace_current_entry
= data_source
->replacesCurrentHistoryItem();
659 // If the navigation is browser-initiated, the NavigationState contains the
660 // correct value instead of the WebDataSource.
662 // TODO(davidben): Avoid this awkward duplication of state. See comment on
663 // NavigationState::should_replace_current_entry().
664 should_replace_current_entry
=
665 navigation_state
->should_replace_current_entry();
667 request
.setExtraData(
668 new RequestExtraData(referrer_policy
,
670 was_after_preconnect_request
,
671 (frame
== top_frame
),
673 GURL(frame
->document().securityOrigin().toString()),
674 frame
->parent() == top_frame
,
675 frame
->parent() ? frame
->parent()->identifier() : -1,
676 navigation_state
->allow_download(),
678 should_replace_current_entry
,
679 navigation_state
->transferred_request_child_id(),
680 navigation_state
->transferred_request_request_id()));
682 DocumentState
* top_document_state
=
683 DocumentState::FromDataSource(top_data_source
);
684 if (top_document_state
) {
685 // TODO(gavinp): separate out prefetching and prerender field trials
686 // if the rel=prerender rel type is sticking around.
687 if (request
.targetType() == WebURLRequest::TargetIsPrefetch
)
688 top_document_state
->set_was_prefetcher(true);
690 if (was_after_preconnect_request
)
691 top_document_state
->set_was_after_preconnect_request(true);
694 // This is an instance where we embed a copy of the routing id
695 // into the data portion of the message. This can cause problems if we
696 // don't register this id on the browser side, since the download manager
697 // expects to find a RenderViewHost based off the id.
698 request
.setRequestorID(render_view_
->GetRoutingID());
699 request
.setHasUserGesture(WebUserGestureIndicator::isProcessingUserGesture());
701 if (!navigation_state
->extra_headers().empty()) {
702 for (net::HttpUtil::HeadersIterator
i(
703 navigation_state
->extra_headers().begin(),
704 navigation_state
->extra_headers().end(), "\n");
706 request
.setHTTPHeaderField(WebString::fromUTF8(i
.name()),
707 WebString::fromUTF8(i
.values()));
711 if (!render_view_
->renderer_preferences_
.enable_referrers
)
712 request
.clearHTTPHeaderField("Referer");
715 void RenderFrameImpl::didReceiveResponse(
716 blink::WebFrame
* frame
,
718 const blink::WebURLResponse
& response
) {
719 // Only do this for responses that correspond to a provisional data source
720 // of the top-most frame. If we have a provisional data source, then we
721 // can't have any sub-resources yet, so we know that this response must
722 // correspond to a frame load.
723 if (!frame
->provisionalDataSource() || frame
->parent())
726 // If we are in view source mode, then just let the user see the source of
727 // the server's error page.
728 if (frame
->isViewSourceModeEnabled())
731 DocumentState
* document_state
=
732 DocumentState::FromDataSource(frame
->provisionalDataSource());
733 int http_status_code
= response
.httpStatusCode();
735 // Record page load flags.
736 WebURLResponseExtraDataImpl
* extra_data
=
737 RenderViewImpl::GetExtraDataFromResponse(response
);
739 document_state
->set_was_fetched_via_spdy(
740 extra_data
->was_fetched_via_spdy());
741 document_state
->set_was_npn_negotiated(
742 extra_data
->was_npn_negotiated());
743 document_state
->set_npn_negotiated_protocol(
744 extra_data
->npn_negotiated_protocol());
745 document_state
->set_was_alternate_protocol_available(
746 extra_data
->was_alternate_protocol_available());
747 document_state
->set_connection_info(
748 extra_data
->connection_info());
749 document_state
->set_was_fetched_via_proxy(
750 extra_data
->was_fetched_via_proxy());
752 InternalDocumentStateData
* internal_data
=
753 InternalDocumentStateData::FromDocumentState(document_state
);
754 internal_data
->set_http_status_code(http_status_code
);
755 // Whether or not the http status code actually corresponds to an error is
756 // only checked when the page is done loading, if |use_error_page| is
758 internal_data
->set_use_error_page(true);
761 void RenderFrameImpl::didFinishResourceLoad(blink::WebFrame
* frame
,
762 unsigned identifier
) {
763 // TODO(nasko): Move implementation here. Needed state:
766 // * LoadNavigationErrorPage
767 render_view_
->didFinishResourceLoad(frame
, identifier
);
770 void RenderFrameImpl::didLoadResourceFromMemoryCache(
771 blink::WebFrame
* frame
,
772 const blink::WebURLRequest
& request
,
773 const blink::WebURLResponse
& response
) {
774 // The recipients of this message have no use for data: URLs: they don't
775 // affect the page's insecure content list and are not in the disk cache. To
776 // prevent large (1M+) data: URLs from crashing in the IPC system, we simply
777 // filter them out here.
778 GURL
url(request
.url());
779 if (url
.SchemeIs("data"))
782 // Let the browser know we loaded a resource from the memory cache. This
783 // message is needed to display the correct SSL indicators.
784 render_view_
->Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
785 render_view_
->GetRoutingID(),
787 response
.securityInfo(),
788 request
.httpMethod().utf8(),
789 response
.mimeType().utf8(),
790 ResourceType::FromTargetType(request
.targetType())));
793 void RenderFrameImpl::didDisplayInsecureContent(blink::WebFrame
* frame
) {
794 render_view_
->Send(new ViewHostMsg_DidDisplayInsecureContent(
795 render_view_
->GetRoutingID()));
798 void RenderFrameImpl::didRunInsecureContent(
799 blink::WebFrame
* frame
,
800 const blink::WebSecurityOrigin
& origin
,
801 const blink::WebURL
& target
) {
802 render_view_
->Send(new ViewHostMsg_DidRunInsecureContent(
803 render_view_
->GetRoutingID(),
804 origin
.toString().utf8(),
808 void RenderFrameImpl::didAbortLoading(blink::WebFrame
* frame
) {
809 #if defined(ENABLE_PLUGINS)
810 if (frame
!= render_view_
->webview()->mainFrame())
812 PluginChannelHost::Broadcast(
813 new PluginHostMsg_DidAbortLoading(render_view_
->GetRoutingID()));
817 void RenderFrameImpl::didExhaustMemoryAvailableForScript(
818 blink::WebFrame
* frame
) {
819 render_view_
->Send(new ViewHostMsg_JSOutOfMemory(
820 render_view_
->GetRoutingID()));
823 void RenderFrameImpl::didCreateScriptContext(blink::WebFrame
* frame
,
824 v8::Handle
<v8::Context
> context
,
827 GetContentClient()->renderer()->DidCreateScriptContext(
828 frame
, context
, extension_group
, world_id
);
831 void RenderFrameImpl::willReleaseScriptContext(blink::WebFrame
* frame
,
832 v8::Handle
<v8::Context
> context
,
834 GetContentClient()->renderer()->WillReleaseScriptContext(
835 frame
, context
, world_id
);
838 void RenderFrameImpl::didFirstVisuallyNonEmptyLayout(blink::WebFrame
* frame
) {
839 render_view_
->didFirstVisuallyNonEmptyLayout(frame
);
842 void RenderFrameImpl::didChangeContentsSize(blink::WebFrame
* frame
,
843 const blink::WebSize
& size
) {
844 // TODO(nasko): Move implementation here. Needed state:
845 // * cached_has_main_frame_horizontal_scrollbar_
846 // * cached_has_main_frame_vertical_scrollbar_
847 render_view_
->didChangeContentsSize(frame
, size
);
850 void RenderFrameImpl::didChangeScrollOffset(blink::WebFrame
* frame
) {
851 // TODO(nasko): Move implementation here. Needed methods:
852 // * StartNavStateSyncTimerIfNecessary
853 render_view_
->didChangeScrollOffset(frame
);
856 void RenderFrameImpl::willInsertBody(blink::WebFrame
* frame
) {
857 if (!frame
->parent()) {
858 render_view_
->Send(new ViewHostMsg_WillInsertBody(
859 render_view_
->GetRoutingID()));
863 void RenderFrameImpl::reportFindInPageMatchCount(int request_id
,
866 int active_match_ordinal
= -1; // -1 = don't update active match ordinal
868 active_match_ordinal
= 0;
870 render_view_
->Send(new ViewHostMsg_Find_Reply(
871 render_view_
->GetRoutingID(), request_id
, count
,
872 gfx::Rect(), active_match_ordinal
, final_update
));
875 void RenderFrameImpl::reportFindInPageSelection(
877 int active_match_ordinal
,
878 const blink::WebRect
& selection_rect
) {
879 render_view_
->Send(new ViewHostMsg_Find_Reply(
880 render_view_
->GetRoutingID(), request_id
, -1, selection_rect
,
881 active_match_ordinal
, false));
884 void RenderFrameImpl::requestStorageQuota(
885 blink::WebFrame
* frame
,
886 blink::WebStorageQuotaType type
,
887 unsigned long long requested_size
,
888 blink::WebStorageQuotaCallbacks
* callbacks
) {
890 WebSecurityOrigin origin
= frame
->document().securityOrigin();
891 if (origin
.isUnique()) {
892 // Unique origins cannot store persistent state.
893 callbacks
->didFail(blink::WebStorageQuotaErrorAbort
);
896 ChildThread::current()->quota_dispatcher()->RequestStorageQuota(
897 render_view_
->GetRoutingID(), GURL(origin
.toString()),
898 static_cast<quota::StorageType
>(type
), requested_size
,
899 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks
));
902 void RenderFrameImpl::willOpenSocketStream(
903 blink::WebSocketStreamHandle
* handle
) {
904 SocketStreamHandleData::AddToHandle(handle
, render_view_
->GetRoutingID());
907 void RenderFrameImpl::willStartUsingPeerConnectionHandler(
908 blink::WebFrame
* frame
,
909 blink::WebRTCPeerConnectionHandler
* handler
) {
910 #if defined(ENABLE_WEBRTC)
911 static_cast<RTCPeerConnectionHandler
*>(handler
)->associateWithFrame(frame
);
915 bool RenderFrameImpl::willCheckAndDispatchMessageEvent(
916 blink::WebFrame
* sourceFrame
,
917 blink::WebFrame
* targetFrame
,
918 blink::WebSecurityOrigin targetOrigin
,
919 blink::WebDOMMessageEvent event
) {
920 // TODO(nasko): Move implementation here. Needed state:
922 return render_view_
->willCheckAndDispatchMessageEvent(
923 sourceFrame
, targetFrame
, targetOrigin
, event
);
926 blink::WebString
RenderFrameImpl::userAgentOverride(
927 blink::WebFrame
* frame
,
928 const blink::WebURL
& url
) {
929 if (!render_view_
->webview() || !render_view_
->webview()->mainFrame() ||
930 render_view_
->renderer_preferences_
.user_agent_override
.empty()) {
931 return blink::WebString();
934 // If we're in the middle of committing a load, the data source we need
935 // will still be provisional.
936 WebFrame
* main_frame
= render_view_
->webview()->mainFrame();
937 WebDataSource
* data_source
= NULL
;
938 if (main_frame
->provisionalDataSource())
939 data_source
= main_frame
->provisionalDataSource();
941 data_source
= main_frame
->dataSource();
943 InternalDocumentStateData
* internal_data
= data_source
?
944 InternalDocumentStateData::FromDataSource(data_source
) : NULL
;
945 if (internal_data
&& internal_data
->is_overriding_user_agent())
946 return WebString::fromUTF8(
947 render_view_
->renderer_preferences_
.user_agent_override
);
948 return blink::WebString();
951 blink::WebString
RenderFrameImpl::doNotTrackValue(blink::WebFrame
* frame
) {
952 if (render_view_
->renderer_preferences_
.enable_do_not_track
)
953 return WebString::fromUTF8("1");
957 bool RenderFrameImpl::allowWebGL(blink::WebFrame
* frame
, bool default_value
) {
962 render_view_
->Send(new ViewHostMsg_Are3DAPIsBlocked(
963 render_view_
->GetRoutingID(),
964 GURL(frame
->top()->document().securityOrigin().toString()),
965 THREE_D_API_TYPE_WEBGL
,
970 void RenderFrameImpl::didLoseWebGLContext(blink::WebFrame
* frame
,
971 int arb_robustness_status_code
) {
972 render_view_
->Send(new ViewHostMsg_DidLose3DContext(
973 GURL(frame
->top()->document().securityOrigin().toString()),
974 THREE_D_API_TYPE_WEBGL
,
975 arb_robustness_status_code
));
978 } // namespace content