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

Unified 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 Android API, Helper Function and Include_rules 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_view_impl.cc
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index d145b28640812f3420bef4ccfed160cb9313f2e4..e31c69550c3f074ed4b0f31634d163a9f9f9aaf7 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -185,6 +185,7 @@
#include "webkit/glue/alt_error_page_resource_fetcher.h"
#include "webkit/glue/dom_operations.h"
#include "webkit/glue/glue_serialize.h"
+#include "webkit/glue/resource_request_body.h"
#include "webkit/glue/web_intent_service_data.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/webkit_constants.h"
@@ -320,6 +321,7 @@ using base::TimeDelta;
using webkit_glue::AltErrorPageResourceFetcher;
using webkit_glue::ResourceFetcher;
+using webkit_glue::ResourceRequestBody;
using webkit_glue::WebPreferences;
using webkit_glue::WebURLResponseExtraDataImpl;
@@ -393,6 +395,62 @@ static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
}
}
+static scoped_refptr<ResourceRequestBody> ConstructResourceRequestBody(
+ const WebURLRequest request) {
+ if (request.httpMethod() != WebString("POST") ||
+ request.httpBody().isNull())
+ return NULL;
+
+ scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody;
+ WebHTTPBody body = request.httpBody();
+ WebKit::WebHTTPBody::Element element;
+ for (int i=0; body.elementAt(i, element); i++) {
+ switch (element.type) {
+ case WebHTTPBody::Element::TypeData: {
+ if (!element.data.isEmpty())
+ request_body->AppendBytes(element.data.data(),
+ static_cast<int>(element.data.size()));
+ break;
+ }
+ case WebHTTPBody::Element::TypeFile: {
+ #if defined(OS_POSIX)
+ const FilePath::StringType kFilePath =
+ base::SysWideToNativeMB(UTF16ToWideHack(element.filePath));
+ #elif defined(OS_WIN)
+ const FilePath::StringType kFilePath =
+ UTF16ToWideHack(element.filePath);
+ #endif
+ if (element.fileLength == -1) {
+ request_body->AppendFileRange(
+ FilePath(kFilePath), 0, kuint64max, base::Time());
+ } else {
+ request_body->AppendFileRange(
+ FilePath(kFilePath),
+ static_cast<uint64>(element.fileStart),
+ static_cast<uint64>(element.fileLength),
+ base::Time::FromDoubleT(element.modificationTime));
+ }
+ break;
+ }
+ // We do not support TypeURL POST data since it not possible
+ // to make a cross-process POST navigation with this type.
+ case WebHTTPBody::Element::TypeURL: {
+ CHECK(false);
+ break;
+ }
+ // We do not support TypeBlob POST data since it not possible
+ // to make a cross-process POST navigation with this type.
+ case WebHTTPBody::Element::TypeBlob: {
+ CHECK(false);
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+ }
+ return request_body;
+}
+
// If |data_source| is non-null and has a DocumentState associated with it,
// the AltErrorPageResourceFetcher is reset.
static void StopAltErrorPageFetcher(WebDataSource* data_source) {
@@ -1140,21 +1198,52 @@ void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) {
}
if (params.is_post) {
- request.setHTTPMethod(WebString::fromUTF8("POST"));
-
- // Set post data.
WebHTTPBody http_body;
http_body.initialize();
- http_body.appendData(WebData(
- reinterpret_cast<const char*>(
- &params.browser_initiated_post_data.front()),
- params.browser_initiated_post_data.size()));
+ const std::vector<ResourceRequestBody::Element>* uploads =
+ params.browser_initiated_post_data->elements();
+ std::vector<ResourceRequestBody::Element>::const_iterator iter;
+ for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
+ switch (iter->type()) {
+ case ResourceRequestBody::Element::TYPE_BYTES: {
+ http_body.appendData(WebData(iter->bytes(),
+ static_cast<int>(iter->length())));
+ break;
+ }
+ case ResourceRequestBody::Element::TYPE_FILE: {
+ #if defined(OS_POSIX)
+ WebString filePath = WideToUTF16Hack(
+ base::SysNativeMBToWide(iter->path().value()));
+ #elif defined(OS_WIN)
+ WebString filePath = WideToUTF16Hack(iter->path().value());
+ #endif
+ http_body.appendFileRange(
+ filePath,
+ static_cast<long long>(iter->offset()),
+ static_cast<long long>(iter->length()),
+ iter->expected_modification_time().ToDoubleT());
+ break;
+ }
+ case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM: {
+ CHECK(false);
+ break;
+ }
+ case ResourceRequestBody::Element:: TYPE_BLOB: {
+ CHECK(false);
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+ }
request.setHTTPBody(http_body);
+ request.setHTTPMethod(WebString::fromUTF8("POST"));
+ request.setHTTPHeaderField(
+ WebString::fromUTF8("Content-Type"),
+ WebString::fromUTF8(params.extra_headers));
}
-
main_frame->loadRequest(request);
}
-
// In case LoadRequest failed before DidCreateDataSource was called.
pending_navigation_params_.reset();
}
@@ -1662,17 +1751,22 @@ void RenderViewImpl::SendUpdateState(const WebHistoryItem& item) {
void RenderViewImpl::OpenURL(WebFrame* frame,
const GURL& url,
const Referrer& referrer,
- WebNavigationPolicy policy) {
+ WebNavigationPolicy policy,
+ std::string extra_header,
+ scoped_refptr<ResourceRequestBody>
+ request_body) {
ViewHostMsg_OpenURL_Params params;
params.url = url;
params.referrer = referrer;
params.disposition = NavigationPolicyToDisposition(policy);
params.frame_id = frame->identifier();
+ params.extra_header = extra_header;
+ params.request_body = request_body;
+
DocumentState* document_state =
DocumentState::FromDataSource(frame->dataSource());
params.is_cross_site_redirect =
document_state->navigation_state()->is_redirect_in_progress();
-
Send(new ViewHostMsg_OpenURL(routing_id_, params));
}
@@ -2678,7 +2772,7 @@ void RenderViewImpl::loadURLExternally(
Send(new ViewHostMsg_DownloadUrl(routing_id_, request.url(), referrer,
suggested_name));
} else {
- OpenURL(frame, request.url(), referrer, policy);
+ OpenURL(frame, request.url(), referrer, policy, std::string(), NULL);
}
}
@@ -2696,6 +2790,16 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
GURL(request.httpHeaderField(WebString::fromUTF8("Referer"))),
GetReferrerPolicyFromRequest(frame, request));
+ std::string header;
+ scoped_refptr<ResourceRequestBody> request_body =
+ ConstructResourceRequestBody(request);
+ if (request_body) {
+ // Extract request header information if request body exist.
+ WebString ContentType =
+ request.httpHeaderField(WebString::fromUTF8("Content-Type"));
+ header.assign(ContentType.utf8().data(), ContentType.utf8().length());
+ }
+
if (is_swapped_out_) {
if (request.url() != GURL(kSwappedOutURL)) {
// Targeted links may try to navigate a swapped out frame. Allow the
@@ -2706,7 +2810,8 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
// TODO(creis): Ensure this supports targeted form submissions when
// fixing http://crbug.com/101395.
if (frame->parent() == NULL) {
- OpenURL(frame, request.url(), referrer, default_policy);
+ OpenURL(frame, request.url(), referrer,
+ default_policy, header, request_body);
return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
}
@@ -2748,7 +2853,7 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
if (!net::RegistryControlledDomainService::SameDomainOrHost(frame_url,
url) ||
frame_url.scheme() != url.scheme()) {
- OpenURL(frame, url, referrer, default_policy);
+ OpenURL(frame, url, referrer, default_policy, header, request_body);
return WebKit::WebNavigationPolicyIgnore;
}
}
@@ -2769,7 +2874,7 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
// navigation.
page_id_ = -1;
last_page_id_sent_to_browser_ = -1;
- OpenURL(frame, url, referrer, default_policy);
+ OpenURL(frame, url, referrer, default_policy, header, request_body);
return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
}
}
@@ -2829,17 +2934,14 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
// Give the embedder a chance.
// For now, we skip this for POST submissions. This is because
// http://crbug.com/101395 is more likely to cause compatibility issues
- // with hosted apps and extensions than WebUI pages. We will remove this
- // check when cross-process POST submissions are supported.
- if (request.httpMethod() == "GET") {
+ // with hosted apps and extensions than WebUI pages.
should_fork = GetContentClient()->renderer()->ShouldFork(
frame, url, is_initial_navigation, &send_referrer);
- }
}
if (should_fork) {
- OpenURL(
- frame, url, send_referrer ? referrer : Referrer(), default_policy);
+ OpenURL(frame, url, send_referrer ? referrer : Referrer(),
+ default_policy, header, request_body);
return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
}
}
@@ -2878,7 +2980,7 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
if (is_fork) {
// Open the URL via the browser, not via WebKit.
- OpenURL(frame, url, Referrer(), default_policy);
+ OpenURL(frame, url, Referrer(), default_policy, header, request_body);
return WebKit::WebNavigationPolicyIgnore;
}
« no previous file with comments | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698