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*>( |
- ¶ms.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; |
} |