Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: content/renderer/render_view_impl.cc

Issue 11193051: To fix the cross-site post submission bug. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reuse ResourceRequestBody Struct Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer/render_view_impl.h" 5 #include "content/renderer/render_view_impl.h"
6 6
7 #include "webkit/glue/weburlloader_impl.h"
8
7 #include <algorithm> 9 #include <algorithm>
8 #include <cmath> 10 #include <cmath>
9 11
10 #include "base/bind.h" 12 #include "base/bind.h"
11 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
12 #include "base/command_line.h" 14 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
14 #include "base/debug/trace_event.h" 16 #include "base/debug/trace_event.h"
15 #include "base/json/json_reader.h" 17 #include "base/json/json_reader.h"
16 #include "base/json/json_writer.h" 18 #include "base/json/json_writer.h"
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 #include "ui/gfx/point.h" 180 #include "ui/gfx/point.h"
179 #include "ui/gfx/rect.h" 181 #include "ui/gfx/rect.h"
180 #include "ui/gfx/size_conversions.h" 182 #include "ui/gfx/size_conversions.h"
181 #include "v8/include/v8.h" 183 #include "v8/include/v8.h"
182 #include "webkit/appcache/web_application_cache_host_impl.h" 184 #include "webkit/appcache/web_application_cache_host_impl.h"
183 #include "webkit/base/file_path_string_conversions.h" 185 #include "webkit/base/file_path_string_conversions.h"
184 #include "webkit/dom_storage/dom_storage_types.h" 186 #include "webkit/dom_storage/dom_storage_types.h"
185 #include "webkit/glue/alt_error_page_resource_fetcher.h" 187 #include "webkit/glue/alt_error_page_resource_fetcher.h"
186 #include "webkit/glue/dom_operations.h" 188 #include "webkit/glue/dom_operations.h"
187 #include "webkit/glue/glue_serialize.h" 189 #include "webkit/glue/glue_serialize.h"
190 #include "webkit/glue/resource_request_body.h"
188 #include "webkit/glue/web_intent_service_data.h" 191 #include "webkit/glue/web_intent_service_data.h"
189 #include "webkit/glue/webdropdata.h" 192 #include "webkit/glue/webdropdata.h"
190 #include "webkit/glue/webkit_constants.h" 193 #include "webkit/glue/webkit_constants.h"
191 #include "webkit/glue/webkit_glue.h" 194 #include "webkit/glue/webkit_glue.h"
192 #include "webkit/glue/weburlresponse_extradata_impl.h" 195 #include "webkit/glue/weburlresponse_extradata_impl.h"
193 #include "webkit/gpu/webgraphicscontext3d_in_process_impl.h" 196 #include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
194 #include "webkit/media/webmediaplayer_impl.h" 197 #include "webkit/media/webmediaplayer_impl.h"
195 #include "webkit/media/webmediaplayer_ms.h" 198 #include "webkit/media/webmediaplayer_ms.h"
196 #include "webkit/plugins/npapi/plugin_list.h" 199 #include "webkit/plugins/npapi/plugin_list.h"
197 #include "webkit/plugins/npapi/webplugin_delegate.h" 200 #include "webkit/plugins/npapi/webplugin_delegate.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 using WebKit::WebVector; 316 using WebKit::WebVector;
314 using WebKit::WebView; 317 using WebKit::WebView;
315 using WebKit::WebWidget; 318 using WebKit::WebWidget;
316 using WebKit::WebWindowFeatures; 319 using WebKit::WebWindowFeatures;
317 using appcache::WebApplicationCacheHostImpl; 320 using appcache::WebApplicationCacheHostImpl;
318 using base::Time; 321 using base::Time;
319 using base::TimeDelta; 322 using base::TimeDelta;
320 323
321 using webkit_glue::AltErrorPageResourceFetcher; 324 using webkit_glue::AltErrorPageResourceFetcher;
322 using webkit_glue::ResourceFetcher; 325 using webkit_glue::ResourceFetcher;
326 using webkit_glue::ResourceRequestBody;
323 using webkit_glue::WebPreferences; 327 using webkit_glue::WebPreferences;
324 using webkit_glue::WebURLResponseExtraDataImpl; 328 using webkit_glue::WebURLResponseExtraDataImpl;
325 329
326 #if defined(OS_ANDROID) 330 #if defined(OS_ANDROID)
327 using WebKit::WebContentDetectionResult; 331 using WebKit::WebContentDetectionResult;
328 using WebKit::WebFloatPoint; 332 using WebKit::WebFloatPoint;
329 using WebKit::WebFloatRect; 333 using WebKit::WebFloatRect;
330 using WebKit::WebHitTestResult; 334 using WebKit::WebHitTestResult;
331 #endif 335 #endif
336 using content::ViewMsg_Request;
332 337
333 namespace content { 338 namespace content {
334 339
340 // Will find a proper place to move to.
341 ViewMsg_Request::ViewMsg_Request() {
342 }
343
344 ViewMsg_Request::~ViewMsg_Request() {
345 }
346
335 //----------------------------------------------------------------------------- 347 //-----------------------------------------------------------------------------
336 348
337 typedef std::map<WebKit::WebView*, RenderViewImpl*> ViewMap; 349 typedef std::map<WebKit::WebView*, RenderViewImpl*> ViewMap;
338 static base::LazyInstance<ViewMap> g_view_map = LAZY_INSTANCE_INITIALIZER; 350 static base::LazyInstance<ViewMap> g_view_map = LAZY_INSTANCE_INITIALIZER;
339 351
340 // Time, in seconds, we delay before sending content state changes (such as form 352 // Time, in seconds, we delay before sending content state changes (such as form
341 // state and scroll position) to the browser. We delay sending changes to avoid 353 // state and scroll position) to the browser. We delay sending changes to avoid
342 // spamming the browser. 354 // spamming the browser.
343 // To avoid having tab/session restore require sending a message to get the 355 // To avoid having tab/session restore require sending a message to get the
344 // current content state during tab closing we use a shorter timeout for the 356 // current content state during tab closing we use a shorter timeout for the
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 1137
1126 if (!params.extra_headers.empty()) { 1138 if (!params.extra_headers.empty()) {
1127 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(), 1139 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
1128 params.extra_headers.end(), "\n"); 1140 params.extra_headers.end(), "\n");
1129 i.GetNext(); ) { 1141 i.GetNext(); ) {
1130 request.addHTTPHeaderField(WebString::fromUTF8(i.name()), 1142 request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
1131 WebString::fromUTF8(i.values())); 1143 WebString::fromUTF8(i.values()));
1132 } 1144 }
1133 } 1145 }
1134 1146
1135 if (params.is_post) { 1147 // Deal With Cross-Process Post Submission
1136 request.setHTTPMethod(WebString::fromUTF8("POST")); 1148 if(params.is_post) {
1137
1138 // Set post data.
1139 WebHTTPBody http_body; 1149 WebHTTPBody http_body;
1140 http_body.initialize(); 1150 http_body.initialize();
1141 http_body.appendData(WebData( 1151 const std::vector<ResourceRequestBody::Element>* uploads =
1142 reinterpret_cast<const char*>( 1152 params.request.request_body->elements();
1143 &params.browser_initiated_post_data.front()), 1153 std::vector<ResourceRequestBody::Element>::const_iterator iter;
1144 params.browser_initiated_post_data.size())); 1154 for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
1155 switch (iter->type()) {
1156 case ResourceRequestBody::Element::TYPE_BYTES: {
1157 http_body.appendData(WebData(iter->bytes(),
1158 static_cast<int>(iter->length())));
1159 break;
1160 }
1161 case ResourceRequestBody::Element::TYPE_FILE: {
1162 http_body.appendFileRange(
1163 WebString::fromUTF8(iter->path().value()),
1164 static_cast<long long>(iter->offset()),
1165 static_cast<long long>(iter->length()),
1166 iter->expected_modification_time().ToDoubleT());
1167 break;
1168 }
1169 case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM: {
1170 // Since I cannot found a cross-site post submission
1171 // in this type which does not use XHR,
1172 // this part have't been testes.
michaeln 2012/11/02 00:08:23 Q: do cross-site posts ever cross storage partitio
irobert 2012/11/02 17:22:55 I need to chat with Albert about it. On 2012/11/0
1173 http_body.appendURLRange(
1174 iter->url(),
1175 static_cast<long long>(iter->offset()),
1176 static_cast<long long>(iter->length()),
1177 iter->expected_modification_time().ToDoubleT());
1178 break;
1179 }
1180 case ResourceRequestBody::Element:: TYPE_BLOB: {
1181 // Since I cannot found a cross-site post submission
1182 // in this type which does not use XHR,
1183 // this part have't been testes.
1184 http_body.appendBlob(iter->url());
1185 break;
1186 }
1187 default:
1188 NOTREACHED();
1189 }
1190 }
1145 request.setHTTPBody(http_body); 1191 request.setHTTPBody(http_body);
1192 request.setHTTPMethod(WebString::fromUTF8(params.request.method));
1193 std::string type = params.request.headers.find("Content-Type")->second;
1194 request.setHTTPHeaderField(
1195 WebString::fromUTF8("Content-Type"),
1196 WebString::fromUTF8(type));
1146 } 1197 }
1147 1198
1148 main_frame->loadRequest(request); 1199 main_frame->loadRequest(request);
1149 } 1200 }
1150
1151 // In case LoadRequest failed before DidCreateDataSource was called. 1201 // In case LoadRequest failed before DidCreateDataSource was called.
1152 pending_navigation_params_.reset(); 1202 pending_navigation_params_.reset();
1153 } 1203 }
1154 1204
1155 bool RenderViewImpl::IsBackForwardToStaleEntry( 1205 bool RenderViewImpl::IsBackForwardToStaleEntry(
1156 const ViewMsg_Navigate_Params& params, 1206 const ViewMsg_Navigate_Params& params,
1157 bool is_reload) { 1207 bool is_reload) {
1158 // Make sure this isn't a back/forward to an entry we have already cropped 1208 // Make sure this isn't a back/forward to an entry we have already cropped
1159 // or replaced from our history, before the browser knew about it. If so, 1209 // or replaced from our history, before the browser knew about it. If so,
1160 // a new navigation has committed in the mean time, and we can ignore this. 1210 // a new navigation has committed in the mean time, and we can ignore this.
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 const Referrer& referrer, 1707 const Referrer& referrer,
1658 WebNavigationPolicy policy) { 1708 WebNavigationPolicy policy) {
1659 Send(new ViewHostMsg_OpenURL( 1709 Send(new ViewHostMsg_OpenURL(
1660 routing_id_, 1710 routing_id_,
1661 url, 1711 url,
1662 referrer, 1712 referrer,
1663 NavigationPolicyToDisposition(policy), 1713 NavigationPolicyToDisposition(policy),
1664 frame->identifier())); 1714 frame->identifier()));
1665 } 1715 }
1666 1716
1717 // Not sure whether to change the original OpenURL API by adding a
1718 // new argument. To avoid too much change, use OpenPostURL API do
1719 // send ViewHostMsg_OpenPostURL message to browser process.
1720 void RenderViewImpl::OpenPostURL(WebFrame* frame,
1721 const GURL& url,
1722 const Referrer& referrer,
1723 WebNavigationPolicy policy,
1724 const ViewMsg_Request& request) {
1725 Send(new ViewHostMsg_OpenPostURL(
1726 routing_id_,
1727 url,
1728 referrer,
1729 NavigationPolicyToDisposition(policy),
1730 frame->identifier(),
1731 request));
1732 }
1733
1667 // WebViewDelegate ------------------------------------------------------------ 1734 // WebViewDelegate ------------------------------------------------------------
1668 1735
1669 void RenderViewImpl::LoadNavigationErrorPage( 1736 void RenderViewImpl::LoadNavigationErrorPage(
1670 WebFrame* frame, 1737 WebFrame* frame,
1671 const WebURLRequest& failed_request, 1738 const WebURLRequest& failed_request,
1672 const WebURLError& error, 1739 const WebURLError& error,
1673 const std::string& html, 1740 const std::string& html,
1674 bool replace) { 1741 bool replace) {
1675 std::string alt_html; 1742 std::string alt_html;
1676 const std::string* error_html; 1743 const std::string* error_html;
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after
2717 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 2784 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2718 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) && 2785 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) &&
2719 !frame->parent() && (is_content_initiated || is_redirect)) { 2786 !frame->parent() && (is_content_initiated || is_redirect)) {
2720 WebString origin_str = frame->document().securityOrigin().toString(); 2787 WebString origin_str = frame->document().securityOrigin().toString();
2721 GURL frame_url(origin_str.utf8().data()); 2788 GURL frame_url(origin_str.utf8().data());
2722 // TODO(cevans): revisit whether this site check is still necessary once 2789 // TODO(cevans): revisit whether this site check is still necessary once
2723 // crbug.com/101395 is fixed. 2790 // crbug.com/101395 is fixed.
2724 if (!net::RegistryControlledDomainService::SameDomainOrHost(frame_url, 2791 if (!net::RegistryControlledDomainService::SameDomainOrHost(frame_url,
2725 url) || 2792 url) ||
2726 frame_url.scheme() != url.scheme()) { 2793 frame_url.scheme() != url.scheme()) {
2727 OpenURL(frame, url, referrer, default_policy); 2794 WebString method = request.httpMethod();
2728 return WebKit::WebNavigationPolicyIgnore; 2795 if(method != WebString("POST")) {
2796 OpenURL(frame, url, referrer, default_policy);
2797 return WebKit::WebNavigationPolicyIgnore;
2798 }
2799 else {
michaeln 2012/11/02 00:08:23 style nit : } else {
irobert 2012/11/02 17:22:55 Done.
2800 ViewMsg_Request params;
2801
2802 // Convert WebHTTPBody to ResourceRequestBody
2803 scoped_refptr<ResourceRequestBody> request_body =
2804 new ResourceRequestBody();
2805 WebHTTPBody body = request.httpBody();
2806 WebKit::WebHTTPBody::Element element;
2807 for (int i=0; body.elementAt(i, element); i++) {
2808 switch (element.type) {
2809 case WebHTTPBody::Element::TypeData:
2810 if (!element.data.isEmpty())
2811 request_body->AppendBytes(
2812 element.data.data(), static_cast<int>(element.data.size()));
2813 break;
2814 case WebHTTPBody::Element::TypeFile: {
2815 #if defined(OS_POSIX)
2816 const FilePath::StringType kFilePath = FILE_PATH_LITERAL(
michaeln 2012/11/02 00:08:23 use of FILE_PATH_LITERAL seems odd since the value
irobert 2012/11/02 17:22:55 Also looks odd to me. But I just followed the usag
2817 base::SysWideToNativeMB(UTF16ToWideHack(element.filePath)));
2818 #elif defined(OS_WIN)
2819 const FilePath::StringType kFilePath = FILE_PATH_LITERAL(
2820 UTF16ToWideHack(element.filePath));
2821 #endif
2822 if (element.fileLength == -1) {
2823 request_body->AppendFileRange(
2824 FilePath(kFilePath), 0, kuint64max, base::Time());
2825 } else {
2826 request_body->AppendFileRange(
2827 FilePath(kFilePath),
2828 static_cast<uint64>(element.fileStart),
2829 static_cast<uint64>(element.fileLength),
2830 base::Time::FromDoubleT(element.modificationTime));
2831 }
2832 break;
2833 }
2834 case WebHTTPBody::Element::TypeURL: {
2835 GURL gurl = GURL(element.url);
2836 DCHECK(gurl.SchemeIsFileSystem());
2837 request_body->AppendFileSystemFileRange(
2838 gurl,
2839 static_cast<uint64>(element.fileStart),
2840 static_cast<uint64>(element.fileLength),
2841 base::Time::FromDoubleT(element.modificationTime));
2842 break;
2843 }
2844 case WebHTTPBody::Element::TypeBlob:
2845 request_body->AppendBlob(GURL(element.blobURL));
2846 break;
2847 default:
2848 NOTREACHED();
2849 }
2850 request_body->set_identifier(body.identifier());
2851 }
2852 params.request_body = request_body;
2853 params.method = "POST";
2854 params.url = url;
2855 // Extract Header Info.
2856 WebString ContentType =
2857 request.httpHeaderField(WebString::fromUTF8("Content-Type"));
2858 std::string ContentTypeStr (ContentType.utf8().data(),
2859 ContentType.utf8().length());
2860 params.headers.insert(std::pair<std::string,std::string>(
michaeln 2012/11/02 00:08:23 if there's at most one header value in here, maybe
irobert 2012/11/02 17:22:55 For Cross-Process Post Submission, I think Content
2861 "Content-Type", ContentTypeStr));
2862
2863 OpenPostURL(frame, url, referrer, default_policy, params);
2864 return default_policy;
michaeln 2012/11/02 00:08:23 return default_policy? Is that right? Seems like
irobert 2012/11/02 17:22:55 Yes. return WebKit::WebNavigationPolicyIgnor will
Charlie Reis 2012/11/05 16:21:40 Ignore is the correct thing to return. There must
2865 }
2729 } 2866 }
2730 } 2867 }
2731 2868
2732 // If the browser is interested, then give it a chance to look at the request. 2869 // If the browser is interested, then give it a chance to look at the request.
2733 if (is_content_initiated) { 2870 if (is_content_initiated) {
2734 bool browser_handles_request = 2871 bool browser_handles_request =
2735 renderer_preferences_.browser_handles_non_local_top_level_requests && 2872 renderer_preferences_.browser_handles_non_local_top_level_requests &&
2736 IsNonLocalTopLevelNavigation(url, frame, type); 2873 IsNonLocalTopLevelNavigation(url, frame, type);
2737 if (!browser_handles_request) { 2874 if (!browser_handles_request) {
2738 browser_handles_request = 2875 browser_handles_request =
2739 renderer_preferences_.browser_handles_all_top_level_requests && 2876 renderer_preferences_.browser_handles_all_top_level_requests &&
2740 IsTopLevelNavigation(frame); 2877 IsTopLevelNavigation(frame);
2741 } 2878 }
2742 2879
2743 if (browser_handles_request) { 2880 if (browser_handles_request) {
2744 // Reset these counters as the RenderView could be reused for the next 2881 // Reset these counters as the RenderView could be reused for the next
2745 // navigation. 2882 // navigation.
2746 page_id_ = -1; 2883 page_id_ = -1;
2747 last_page_id_sent_to_browser_ = -1; 2884 last_page_id_sent_to_browser_ = -1;
2748 OpenURL(frame, url, referrer, default_policy); 2885 OpenURL(frame, url, referrer, default_policy);
michaeln 2012/11/02 00:08:23 What is the difference between the cross-site hand
irobert 2012/11/02 17:22:55 The above code deal with the case when flag --enab
Charlie Reis 2012/11/05 16:21:40 Hmm, that's not correct. We'd like this new appro
2749 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here. 2886 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
2750 } 2887 }
2751 } 2888 }
2752 2889
2753 // Use the frame's original request's URL rather than the document's URL for 2890 // Use the frame's original request's URL rather than the document's URL for
2754 // subsequent checks. For a popup, the document's URL may become the opener 2891 // subsequent checks. For a popup, the document's URL may become the opener
2755 // window's URL if the opener has called document.write(). 2892 // window's URL if the opener has called document.write().
2756 // See http://crbug.com/93517. 2893 // See http://crbug.com/93517.
2757 GURL old_url(frame->dataSource()->request().url()); 2894 GURL old_url(frame->dataSource()->request().url());
2758 2895
(...skipping 3582 matching lines...) Expand 10 before | Expand all | Expand 10 after
6341 } 6478 }
6342 #endif 6479 #endif
6343 6480
6344 void RenderViewImpl::OnReleaseDisambiguationPopupDIB( 6481 void RenderViewImpl::OnReleaseDisambiguationPopupDIB(
6345 TransportDIB::Handle dib_handle) { 6482 TransportDIB::Handle dib_handle) {
6346 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle); 6483 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle);
6347 RenderProcess::current()->ReleaseTransportDIB(dib); 6484 RenderProcess::current()->ReleaseTransportDIB(dib);
6348 } 6485 }
6349 6486
6350 } // namespace content 6487 } // namespace content
OLDNEW
« content/public/common/frame_navigate_params.h ('K') | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698