Support file uploads in CefURLRequests originating from the browser process (issue #1013).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1525 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
ec8b64e88a
commit
43d2ca32fa
|
@ -101,7 +101,14 @@ typedef struct _cef_urlrequest_t {
|
|||
|
||||
///
|
||||
// Create a new URL request. Only GET, POST, HEAD, DELETE and PUT request
|
||||
// functions are supported. The |request| object will be marked as read-only
|
||||
// functions are supported. Multiple post data elements are not supported and
|
||||
// elements of type PDE_TYPE_FILE are only supported for requests originating
|
||||
// from the browser process. Requests originating from the render process will
|
||||
// receive the same handling as requests originating from Web content -- if the
|
||||
// response contains Content-Disposition or Mime-Type header values that would
|
||||
// not normally be rendered then the response may receive special handling
|
||||
// inside the browser (for example, via the file download code path instead of
|
||||
// the URL request code path). The |request| object will be marked as read-only
|
||||
// after calling this function.
|
||||
///
|
||||
CEF_EXPORT cef_urlrequest_t* cef_urlrequest_create(
|
||||
|
|
|
@ -60,8 +60,15 @@ class CefURLRequest : public virtual CefBase {
|
|||
|
||||
///
|
||||
// Create a new URL request. Only GET, POST, HEAD, DELETE and PUT request
|
||||
// methods are supported. The |request| object will be marked as read-only
|
||||
// after calling this method.
|
||||
// methods are supported. Multiple post data elements are not supported and
|
||||
// elements of type PDE_TYPE_FILE are only supported for requests originating
|
||||
// from the browser process. Requests originating from the render process will
|
||||
// receive the same handling as requests originating from Web content -- if
|
||||
// the response contains Content-Disposition or Mime-Type header values that
|
||||
// would not normally be rendered then the response may receive special
|
||||
// handling inside the browser (for example, via the file download code path
|
||||
// instead of the URL request code path). The |request| object will be marked
|
||||
// as read-only after calling this method.
|
||||
///
|
||||
/*--cef()--*/
|
||||
static CefRefPtr<CefURLRequest> Create(
|
||||
|
|
|
@ -221,20 +221,34 @@ class CefBrowserURLRequest::Context
|
|||
if (post_data.get()) {
|
||||
CefPostData::ElementVector elements;
|
||||
post_data->GetElements(elements);
|
||||
if (elements.size() == 1 && elements[0]->GetType() == PDE_TYPE_BYTES) {
|
||||
CefPostDataElementImpl* impl =
|
||||
static_cast<CefPostDataElementImpl*>(elements[0].get());
|
||||
|
||||
if (elements.size() == 1) {
|
||||
// Default to URL encoding if not specified.
|
||||
if (content_type.empty())
|
||||
content_type = "application/x-www-form-urlencoded";
|
||||
|
||||
upload_data_size = impl->GetBytesCount();
|
||||
fetcher_->SetUploadData(content_type,
|
||||
std::string(static_cast<char*>(impl->GetBytes()),
|
||||
upload_data_size));
|
||||
} else {
|
||||
NOTIMPLEMENTED() << "multi-part form data is not supported";
|
||||
CefPostDataElementImpl* impl =
|
||||
static_cast<CefPostDataElementImpl*>(elements[0].get());
|
||||
|
||||
switch (elements[0]->GetType())
|
||||
case PDE_TYPE_BYTES: {
|
||||
upload_data_size = impl->GetBytesCount();
|
||||
fetcher_->SetUploadData(content_type,
|
||||
std::string(static_cast<char*>(impl->GetBytes()),
|
||||
upload_data_size));
|
||||
break;
|
||||
case PDE_TYPE_FILE:
|
||||
fetcher_->SetUploadFilePath(
|
||||
content_type,
|
||||
base::FilePath(impl->GetFile()),
|
||||
0, kuint64max,
|
||||
content::BrowserThread::GetMessageLoopProxyForThread(
|
||||
content::BrowserThread::FILE).get());
|
||||
break;
|
||||
case PDE_TYPE_EMPTY:
|
||||
break;
|
||||
}
|
||||
} else if (elements.size() > 1) {
|
||||
NOTIMPLEMENTED() << " multi-part form data is not supported";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -14,6 +15,7 @@
|
|||
|
||||
#include "base/bind.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
|
@ -45,6 +47,7 @@ enum RequestTestMode {
|
|||
REQTEST_GET_ALLOWCOOKIES,
|
||||
REQTEST_GET_REDIRECT,
|
||||
REQTEST_POST,
|
||||
REQTEST_POST_FILE,
|
||||
REQTEST_POST_WITHPROGRESS,
|
||||
REQTEST_HEAD,
|
||||
};
|
||||
|
@ -108,6 +111,15 @@ void SetUploadData(CefRefPtr<CefRequest> request,
|
|||
request->SetPostData(postData);
|
||||
}
|
||||
|
||||
void SetUploadFile(CefRefPtr<CefRequest> request,
|
||||
const base::FilePath& file) {
|
||||
CefRefPtr<CefPostData> postData = CefPostData::Create();
|
||||
CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();
|
||||
element->SetToFile(file.value());
|
||||
postData->AddElement(element);
|
||||
request->SetPostData(postData);
|
||||
}
|
||||
|
||||
void GetUploadData(CefRefPtr<CefRequest> request,
|
||||
std::string& data) {
|
||||
CefRefPtr<CefPostData> postData = request->GetPostData();
|
||||
|
@ -532,6 +544,7 @@ class RequestTestRunner {
|
|||
GenericRunTest);
|
||||
REGISTER_TEST(REQTEST_GET_REDIRECT, SetupGetRedirectTest, GenericRunTest);
|
||||
REGISTER_TEST(REQTEST_POST, SetupPostTest, GenericRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, GenericRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest,
|
||||
GenericRunTest);
|
||||
REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, GenericRunTest);
|
||||
|
@ -630,6 +643,28 @@ class RequestTestRunner {
|
|||
settings_.response_data = "POST TEST SUCCESS";
|
||||
}
|
||||
|
||||
void SetupPostFileTest() {
|
||||
settings_.request = CefRequest::Create();
|
||||
settings_.request->SetURL(MakeSchemeURL("PostFileTest.html"));
|
||||
settings_.request->SetMethod("POST");
|
||||
|
||||
EXPECT_TRUE(post_file_tmpdir_.CreateUniqueTempDir());
|
||||
base::FilePath path =
|
||||
post_file_tmpdir_.path().Append(FILE_PATH_LITERAL("example.txt"));
|
||||
std::ofstream myfile;
|
||||
myfile.open(path.value());
|
||||
myfile << "HELLO FRIEND!";
|
||||
myfile.close();
|
||||
SetUploadFile(settings_.request, path);
|
||||
|
||||
settings_.response = CefResponse::Create();
|
||||
settings_.response->SetMimeType("text/html");
|
||||
settings_.response->SetStatus(200);
|
||||
settings_.response->SetStatusText("OK");
|
||||
|
||||
settings_.response_data = "POST TEST SUCCESS";
|
||||
}
|
||||
|
||||
void SetupPostWithProgressTest() {
|
||||
// Start with the normal post test.
|
||||
SetupPostTest();
|
||||
|
@ -755,6 +790,9 @@ class RequestTestRunner {
|
|||
scheme_factory_ = NULL;
|
||||
}
|
||||
|
||||
if (post_file_tmpdir_.IsValid())
|
||||
EXPECT_TRUE(post_file_tmpdir_.Delete());
|
||||
|
||||
delegate_->DestroyTest(settings_);
|
||||
}
|
||||
|
||||
|
@ -800,6 +838,8 @@ class RequestTestRunner {
|
|||
std::string scheme_name_;
|
||||
CefRefPtr<RequestSchemeHandlerFactory> scheme_factory_;
|
||||
|
||||
base::ScopedTempDir post_file_tmpdir_;
|
||||
|
||||
public:
|
||||
RequestRunSettings settings_;
|
||||
};
|
||||
|
@ -1044,6 +1084,7 @@ REQ_TEST(BrowserGETNoData, REQTEST_GET_NODATA, true);
|
|||
REQ_TEST(BrowserGETAllowCookies, REQTEST_GET_ALLOWCOOKIES, true);
|
||||
REQ_TEST(BrowserGETRedirect, REQTEST_GET_REDIRECT, true);
|
||||
REQ_TEST(BrowserPOST, REQTEST_POST, true);
|
||||
REQ_TEST(BrowserPOSTFile, REQTEST_POST_FILE, true);
|
||||
REQ_TEST(BrowserPOSTWithProgress, REQTEST_POST_WITHPROGRESS, true);
|
||||
REQ_TEST(BrowserHEAD, REQTEST_HEAD, true);
|
||||
|
||||
|
|
Loading…
Reference in New Issue