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

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: Fix FileRead Permission Created 8 years, 2 months 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 <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 using WebKit::WebView; 318 using WebKit::WebView;
319 using WebKit::WebWidget; 319 using WebKit::WebWidget;
320 using WebKit::WebWindowFeatures; 320 using WebKit::WebWindowFeatures;
321 using appcache::WebApplicationCacheHostImpl; 321 using appcache::WebApplicationCacheHostImpl;
322 using base::Time; 322 using base::Time;
323 using base::TimeDelta; 323 using base::TimeDelta;
324 using content::DocumentState; 324 using content::DocumentState;
325 using content::NavigationState; 325 using content::NavigationState;
326 using content::PasswordForm; 326 using content::PasswordForm;
327 using content::Referrer; 327 using content::Referrer;
328 using content::WebHTTPPOSTBodyParams;
328 using content::RenderThread; 329 using content::RenderThread;
329 using content::RenderViewObserver; 330 using content::RenderViewObserver;
330 using content::RenderViewVisitor; 331 using content::RenderViewVisitor;
331 using content::RendererAccessibilityComplete; 332 using content::RendererAccessibilityComplete;
332 using content::RendererAccessibilityFocusOnly; 333 using content::RendererAccessibilityFocusOnly;
333 using content::V8ValueConverter; 334 using content::V8ValueConverter;
334 using webkit_glue::AltErrorPageResourceFetcher; 335 using webkit_glue::AltErrorPageResourceFetcher;
335 using webkit_glue::ResourceFetcher; 336 using webkit_glue::ResourceFetcher;
336 using webkit_glue::WebPreferences; 337 using webkit_glue::WebPreferences;
337 using webkit_glue::WebURLResponseExtraDataImpl; 338 using webkit_glue::WebURLResponseExtraDataImpl;
338 339
339 #if defined(OS_ANDROID) 340 #if defined(OS_ANDROID)
340 using content::AddressDetector; 341 using content::AddressDetector;
341 using content::ContentDetector; 342 using content::ContentDetector;
342 using content::EmailDetector; 343 using content::EmailDetector;
343 using content::PhoneNumberDetector; 344 using content::PhoneNumberDetector;
344 using WebKit::WebContentDetectionResult; 345 using WebKit::WebContentDetectionResult;
345 using WebKit::WebFloatPoint; 346 using WebKit::WebFloatPoint;
346 using WebKit::WebFloatRect; 347 using WebKit::WebFloatRect;
347 using WebKit::WebHitTestResult; 348 using WebKit::WebHitTestResult;
348 #endif 349 #endif
349 350
351
352 // Will find a proper place to move to.
353 namespace content {
354 WebHTTPPOSTBodyParams::WebHTTPPOSTBodyParams() {
355 }
356
357 WebHTTPPOSTBodyParams::~WebHTTPPOSTBodyParams() {
358 }
359 }
360
350 //----------------------------------------------------------------------------- 361 //-----------------------------------------------------------------------------
351 362
352 typedef std::map<WebKit::WebView*, RenderViewImpl*> ViewMap; 363 typedef std::map<WebKit::WebView*, RenderViewImpl*> ViewMap;
353 static base::LazyInstance<ViewMap> g_view_map = LAZY_INSTANCE_INITIALIZER; 364 static base::LazyInstance<ViewMap> g_view_map = LAZY_INSTANCE_INITIALIZER;
354 365
355 // Time, in seconds, we delay before sending content state changes (such as form 366 // Time, in seconds, we delay before sending content state changes (such as form
356 // state and scroll position) to the browser. We delay sending changes to avoid 367 // state and scroll position) to the browser. We delay sending changes to avoid
357 // spamming the browser. 368 // spamming the browser.
358 // To avoid having tab/session restore require sending a message to get the 369 // To avoid having tab/session restore require sending a message to get the
359 // current content state during tab closing we use a shorter timeout for the 370 // current content state during tab closing we use a shorter timeout for the
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; 1096 CHECK(false) << "Unable to deserialize message in RenderViewImpl.";
1086 } 1097 }
1087 1098
1088 return handled; 1099 return handled;
1089 } 1100 }
1090 1101
1091 void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) { 1102 void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) {
1092 // If we don't have guest-to-embedder channel associated with this RenderView 1103 // If we don't have guest-to-embedder channel associated with this RenderView
1093 // but we need one, grab one now. 1104 // but we need one, grab one now.
1094 if (!params.embedder_channel_name.empty() && !GetGuestToEmbedderChannel()) { 1105 if (!params.embedder_channel_name.empty() && !GetGuestToEmbedderChannel()) {
1095 content::old::GuestToEmbedderChannel* embedder_channel = 1106 content::old::GuestToEmbedderChannel* embedder_channel =
michaeln 2012/10/23 23:22:18 oh... interesting... this is a direct channel btwn
Charlie Reis 2012/11/05 16:21:40 That code was from the old implementation of Brows
1096 RenderThreadImpl::current()->browser_plugin_channel_manager()-> 1107 RenderThreadImpl::current()->browser_plugin_channel_manager()->
1097 GetChannelByName(params.embedder_channel_name); 1108 GetChannelByName(params.embedder_channel_name);
1098 DCHECK(embedder_channel); 1109 DCHECK(embedder_channel);
1099 SetGuestToEmbedderChannel(embedder_channel); 1110 SetGuestToEmbedderChannel(embedder_channel);
1100 host_window_set_ = false; 1111 host_window_set_ = false;
1101 // TODO(fsamuel): This is test code. Need to find a better way to tell 1112 // TODO(fsamuel): This is test code. Need to find a better way to tell
1102 // a WebView to drop its context. This needs to change in 1113 // a WebView to drop its context. This needs to change in
1103 // GuestToEmbedderChannel::OnContextLost. 1114 // GuestToEmbedderChannel::OnContextLost.
1104 GetWebView()->loseCompositorContext(1); 1115 GetWebView()->loseCompositorContext(1);
1105 RenderThreadImpl::current()->browser_plugin_channel_manager()-> 1116 RenderThreadImpl::current()->browser_plugin_channel_manager()->
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 1219
1209 if (!params.extra_headers.empty()) { 1220 if (!params.extra_headers.empty()) {
1210 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(), 1221 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
1211 params.extra_headers.end(), "\n"); 1222 params.extra_headers.end(), "\n");
1212 i.GetNext(); ) { 1223 i.GetNext(); ) {
1213 request.addHTTPHeaderField(WebString::fromUTF8(i.name()), 1224 request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
1214 WebString::fromUTF8(i.values())); 1225 WebString::fromUTF8(i.values()));
1215 } 1226 }
1216 } 1227 }
1217 1228
1218 if (params.is_post) { 1229 // Deal With Cross-Process Post Submission
1219 request.setHTTPMethod(WebString::fromUTF8("POST")); 1230 if(params.is_post) {
1220
1221 // Set post data.
1222 WebHTTPBody http_body; 1231 WebHTTPBody http_body;
1223 http_body.initialize(); 1232 http_body.initialize();
1224 http_body.appendData(WebData( 1233 std::vector<content::WebHTTPPOSTBodyParams> post_data = params.post_data;
1225 reinterpret_cast<const char*>( 1234 for (std::vector<content::WebHTTPPOSTBodyParams>::iterator it=post_data.be gin();
1226 &params.browser_initiated_post_data.front()), 1235 it < post_data.end(); it++) {
1227 params.browser_initiated_post_data.size())); 1236 if ((*it).type == content::WebHTTPPOSTBodyParams::TypeData) {
1237 std::string postdata = (*it).data;
1238 http_body.appendData(WebData(postdata.c_str(), postdata.length()));
1239 } else if ((*it).type == content::WebHTTPPOSTBodyParams::TypeFile) {
1240 http_body.appendFileRange(WebString::fromUTF8((*it).filePath),
1241 (*it).fileStart,
1242 (*it).fileLength,
1243 (*it).modificationTime);
1244 } else if ((*it).type == content::WebHTTPPOSTBodyParams::TypeURL) {
1245 http_body.appendURLRange((*it).url,
1246 (*it).fileStart,
1247 (*it).fileLength,
1248 (*it).modificationTime);
1249 } else if ((*it).type == content::WebHTTPPOSTBodyParams::TypeBlob) {
1250 }
1251 }
1228 request.setHTTPBody(http_body); 1252 request.setHTTPBody(http_body);
1253 request.setHTTPMethod(WebString::fromUTF8("POST"));
1254 WebString content_type_header = WebString::fromUTF8("Content-Type");
1255 request.setHTTPHeaderField(
1256 content_type_header,
1257 WebString::fromUTF8(post_data[0].ContentType));
1229 } 1258 }
1230 1259
1231 main_frame->loadRequest(request); 1260 main_frame->loadRequest(request);
michaeln 2012/10/24 23:45:39 I see... this is where the new request is initiate
Charlie Reis 2012/11/05 16:21:40 Yeah, actually this concerns me. Keeping the data
1232 } 1261 }
1233
1234 // In case LoadRequest failed before DidCreateDataSource was called. 1262 // In case LoadRequest failed before DidCreateDataSource was called.
1235 pending_navigation_params_.reset(); 1263 pending_navigation_params_.reset();
1236 } 1264 }
1237 1265
1238 bool RenderViewImpl::IsBackForwardToStaleEntry( 1266 bool RenderViewImpl::IsBackForwardToStaleEntry(
1239 const ViewMsg_Navigate_Params& params, 1267 const ViewMsg_Navigate_Params& params,
1240 bool is_reload) { 1268 bool is_reload) {
1241 // Make sure this isn't a back/forward to an entry we have already cropped 1269 // Make sure this isn't a back/forward to an entry we have already cropped
1242 // or replaced from our history, before the browser knew about it. If so, 1270 // or replaced from our history, before the browser knew about it. If so,
1243 // a new navigation has committed in the mean time, and we can ignore this. 1271 // 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
1740 const Referrer& referrer, 1768 const Referrer& referrer,
1741 WebNavigationPolicy policy) { 1769 WebNavigationPolicy policy) {
1742 Send(new ViewHostMsg_OpenURL( 1770 Send(new ViewHostMsg_OpenURL(
1743 routing_id_, 1771 routing_id_,
1744 url, 1772 url,
1745 referrer, 1773 referrer,
1746 NavigationPolicyToDisposition(policy), 1774 NavigationPolicyToDisposition(policy),
1747 frame->identifier())); 1775 frame->identifier()));
1748 } 1776 }
1749 1777
1778 // Do not sure whether to change the original OpenURL API by adding a new argume nt.
1779 // To avoid too much change, use OpenPostURL API do send ViewHostMsg_OpenPostURL
1780 // message to browser process.
1781 void RenderViewImpl::OpenPostURL(WebFrame* frame,
1782 const GURL& url,
1783 const Referrer& referrer,
1784 WebNavigationPolicy policy,
1785 std::vector<content::WebHTTPPOSTBodyParams> post_da ta) {
1786 Send(new ViewHostMsg_OpenPostURL(
1787 routing_id_,
1788 url,
1789 referrer,
1790 NavigationPolicyToDisposition(policy),
1791 frame->identifier(),
1792 post_data));
1793 }
1794
1750 // WebViewDelegate ------------------------------------------------------------ 1795 // WebViewDelegate ------------------------------------------------------------
1751 1796
1752 void RenderViewImpl::LoadNavigationErrorPage( 1797 void RenderViewImpl::LoadNavigationErrorPage(
1753 WebFrame* frame, 1798 WebFrame* frame,
1754 const WebURLRequest& failed_request, 1799 const WebURLRequest& failed_request,
1755 const WebURLError& error, 1800 const WebURLError& error,
1756 const std::string& html, 1801 const std::string& html,
1757 bool replace) { 1802 bool replace) {
1758 std::string alt_html; 1803 std::string alt_html;
1759 const std::string* error_html; 1804 const std::string* error_html;
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 2836 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2792 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) && 2837 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) &&
2793 !frame->parent() && (is_content_initiated || is_redirect)) { 2838 !frame->parent() && (is_content_initiated || is_redirect)) {
2794 WebString origin_str = frame->document().securityOrigin().toString(); 2839 WebString origin_str = frame->document().securityOrigin().toString();
2795 GURL frame_url(origin_str.utf8().data()); 2840 GURL frame_url(origin_str.utf8().data());
2796 // TODO(cevans): revisit whether this site check is still necessary once 2841 // TODO(cevans): revisit whether this site check is still necessary once
2797 // crbug.com/101395 is fixed. 2842 // crbug.com/101395 is fixed.
2798 if (!net::RegistryControlledDomainService::SameDomainOrHost(frame_url, 2843 if (!net::RegistryControlledDomainService::SameDomainOrHost(frame_url,
2799 url) || 2844 url) ||
2800 frame_url.scheme() != url.scheme()) { 2845 frame_url.scheme() != url.scheme()) {
2801 OpenURL(frame, url, referrer, default_policy); 2846 WebString method = request.httpMethod();
2802 return WebKit::WebNavigationPolicyIgnore; 2847 if(method != WebString("POST")) {
2848 OpenURL(frame, url, referrer, default_policy);
michaeln 2012/10/23 23:22:18 I see, so in navigations that get initiated in one
Charlie Reis 2012/10/24 00:40:37 I haven't looked at the rest of this CL yet, but I
michaeln 2012/11/02 01:19:24 It might be slick if post data delivered from rend
Charlie Reis 2012/11/05 16:21:40 Matt Perry added that for doing a process swap dur
2849 return WebKit::WebNavigationPolicyIgnore;
2850 }
2851 else {
2852 // Extract Body Info
2853 WebHTTPBody body = request.httpBody();
2854 std::vector<content::WebHTTPPOSTBodyParams> post_data;
2855 WebKit::WebHTTPBody::Element element;
2856 for (int i=0; body.elementAt(i, element); i++) {
2857 content::WebHTTPPOSTBodyParams post_param;
2858 post_param.method = "POST";
2859 if (element.type == WebHTTPBody::Element::TypeData) {
2860 post_param.type = content::WebHTTPPOSTBodyParams::TypeData;
2861 post_param.data = "";
2862 post_param.data.append(element.data.data(), element.data.size());
2863 post_data.push_back(post_param);
2864 } else if (element.type == WebHTTPBody::Element::TypeFile) {
2865 post_param.type = content::WebHTTPPOSTBodyParams::TypeFile;
2866 #if defined(OS_POSIX)
2867 post_param.filePath = base::SysWideToNativeMB(UTF16ToWideHack(elem ent.filePath));
2868 #elif defined(OS_WIN)
2869 post_param.filePath = UTF16ToWideHack(element.filePath);
2870 #endif
2871 if (element.fileLength == -1) {
2872 post_param.fileStart = 0;
2873 post_param.fileLength = kuint64max;
2874 post_param.modificationTime = base::Time().ToDoubleT();
2875 } else {
2876 post_param.fileStart = element.fileStart;
2877 post_param.fileLength = element.fileLength;
2878 post_param.modificationTime = element.modificationTime;
2879 }
2880 post_data.push_back(post_param);
2881 } else if (element.type == WebHTTPBody::Element::TypeURL) {
2882 GURL url = GURL(element.url);
2883 DCHECK(url.SchemeIsFileSystem());
2884 post_param.url = url;
2885 post_param.fileStart = element.fileStart;
2886 post_param.fileLength = element.fileLength;
2887 post_param.modificationTime = element.modificationTime;
2888 post_data.push_back(post_param);
2889 } else if (element.type == WebHTTPBody::Element::TypeBlob) {
2890 }
2891 }
2892 // Extract Header Info
2893 WebString ContentType = request.httpHeaderField(WebString::fromUTF8("Con tent-Type"));
2894 post_data[0].ContentType = "";
2895 post_data[0].ContentType.append(ContentType.utf8().data(), ContentType.u tf8().length());
2896
2897 OpenPostURL(frame, url, referrer, default_policy, post_data);
michaeln 2012/10/23 23:22:18 return WebKit::WebNavigationPolicyIgnore here?
2898 }
2803 } 2899 }
2804 } 2900 }
2805 2901
2806 // If the browser is interested, then give it a chance to look at the request. 2902 // If the browser is interested, then give it a chance to look at the request.
2807 if (is_content_initiated) { 2903 if (is_content_initiated) {
2808 bool browser_handles_request = 2904 bool browser_handles_request =
2809 renderer_preferences_.browser_handles_non_local_top_level_requests && 2905 renderer_preferences_.browser_handles_non_local_top_level_requests &&
2810 IsNonLocalTopLevelNavigation(url, frame, type); 2906 IsNonLocalTopLevelNavigation(url, frame, type);
2811 if (!browser_handles_request) { 2907 if (!browser_handles_request) {
2812 browser_handles_request = 2908 browser_handles_request =
2813 renderer_preferences_.browser_handles_all_top_level_requests && 2909 renderer_preferences_.browser_handles_all_top_level_requests &&
2814 IsTopLevelNavigation(frame); 2910 IsTopLevelNavigation(frame);
2815 } 2911 }
2816 2912
2817 if (browser_handles_request) { 2913 if (browser_handles_request) {
2818 // Reset these counters as the RenderView could be reused for the next 2914 // Reset these counters as the RenderView could be reused for the next
2819 // navigation. 2915 // navigation.
2820 page_id_ = -1; 2916 page_id_ = -1;
2821 last_page_id_sent_to_browser_ = -1; 2917 last_page_id_sent_to_browser_ = -1;
2822 OpenURL(frame, url, referrer, default_policy); 2918 OpenURL(frame, url, referrer, default_policy);
michaeln 2012/10/23 23:22:18 POST case here too?
2823 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here. 2919 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
2824 } 2920 }
2825 } 2921 }
2826 2922
2827 // Use the frame's original request's URL rather than the document's URL for 2923 // Use the frame's original request's URL rather than the document's URL for
2828 // subsequent checks. For a popup, the document's URL may become the opener 2924 // subsequent checks. For a popup, the document's URL may become the opener
2829 // window's URL if the opener has called document.write(). 2925 // window's URL if the opener has called document.write().
2830 // See http://crbug.com/93517. 2926 // See http://crbug.com/93517.
2831 GURL old_url(frame->dataSource()->request().url()); 2927 GURL old_url(frame->dataSource()->request().url());
2832 2928
(...skipping 3593 matching lines...) Expand 10 before | Expand all | Expand 10 after
6426 transport_dib->id())); 6522 transport_dib->id()));
6427 6523
6428 return true; 6524 return true;
6429 } 6525 }
6430 6526
6431 void RenderViewImpl::OnReleaseDisambiguationPopupDIB( 6527 void RenderViewImpl::OnReleaseDisambiguationPopupDIB(
6432 TransportDIB::Handle dib_handle) { 6528 TransportDIB::Handle dib_handle) {
6433 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle); 6529 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle);
6434 RenderProcess::current()->ReleaseTransportDIB(dib); 6530 RenderProcess::current()->ReleaseTransportDIB(dib);
6435 } 6531 }
OLDNEW
« content/renderer/render_view_impl.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