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
|
// 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.
|
// after calling this function.
|
||||||
///
|
///
|
||||||
CEF_EXPORT cef_urlrequest_t* cef_urlrequest_create(
|
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
|
// 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
|
// methods are supported. Multiple post data elements are not supported and
|
||||||
// after calling this method.
|
// 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()--*/
|
/*--cef()--*/
|
||||||
static CefRefPtr<CefURLRequest> Create(
|
static CefRefPtr<CefURLRequest> Create(
|
||||||
|
|
|
@ -221,20 +221,34 @@ class CefBrowserURLRequest::Context
|
||||||
if (post_data.get()) {
|
if (post_data.get()) {
|
||||||
CefPostData::ElementVector elements;
|
CefPostData::ElementVector elements;
|
||||||
post_data->GetElements(elements);
|
post_data->GetElements(elements);
|
||||||
if (elements.size() == 1 && elements[0]->GetType() == PDE_TYPE_BYTES) {
|
if (elements.size() == 1) {
|
||||||
CefPostDataElementImpl* impl =
|
|
||||||
static_cast<CefPostDataElementImpl*>(elements[0].get());
|
|
||||||
|
|
||||||
// Default to URL encoding if not specified.
|
// Default to URL encoding if not specified.
|
||||||
if (content_type.empty())
|
if (content_type.empty())
|
||||||
content_type = "application/x-www-form-urlencoded";
|
content_type = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
upload_data_size = impl->GetBytesCount();
|
CefPostDataElementImpl* impl =
|
||||||
fetcher_->SetUploadData(content_type,
|
static_cast<CefPostDataElementImpl*>(elements[0].get());
|
||||||
std::string(static_cast<char*>(impl->GetBytes()),
|
|
||||||
upload_data_size));
|
switch (elements[0]->GetType())
|
||||||
} else {
|
case PDE_TYPE_BYTES: {
|
||||||
NOTIMPLEMENTED() << "multi-part form data is not supported";
|
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
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
|
#include "base/files/scoped_temp_dir.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@ enum RequestTestMode {
|
||||||
REQTEST_GET_ALLOWCOOKIES,
|
REQTEST_GET_ALLOWCOOKIES,
|
||||||
REQTEST_GET_REDIRECT,
|
REQTEST_GET_REDIRECT,
|
||||||
REQTEST_POST,
|
REQTEST_POST,
|
||||||
|
REQTEST_POST_FILE,
|
||||||
REQTEST_POST_WITHPROGRESS,
|
REQTEST_POST_WITHPROGRESS,
|
||||||
REQTEST_HEAD,
|
REQTEST_HEAD,
|
||||||
};
|
};
|
||||||
|
@ -108,6 +111,15 @@ void SetUploadData(CefRefPtr<CefRequest> request,
|
||||||
request->SetPostData(postData);
|
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,
|
void GetUploadData(CefRefPtr<CefRequest> request,
|
||||||
std::string& data) {
|
std::string& data) {
|
||||||
CefRefPtr<CefPostData> postData = request->GetPostData();
|
CefRefPtr<CefPostData> postData = request->GetPostData();
|
||||||
|
@ -532,6 +544,7 @@ class RequestTestRunner {
|
||||||
GenericRunTest);
|
GenericRunTest);
|
||||||
REGISTER_TEST(REQTEST_GET_REDIRECT, SetupGetRedirectTest, GenericRunTest);
|
REGISTER_TEST(REQTEST_GET_REDIRECT, SetupGetRedirectTest, GenericRunTest);
|
||||||
REGISTER_TEST(REQTEST_POST, SetupPostTest, GenericRunTest);
|
REGISTER_TEST(REQTEST_POST, SetupPostTest, GenericRunTest);
|
||||||
|
REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, GenericRunTest);
|
||||||
REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest,
|
REGISTER_TEST(REQTEST_POST_WITHPROGRESS, SetupPostWithProgressTest,
|
||||||
GenericRunTest);
|
GenericRunTest);
|
||||||
REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, GenericRunTest);
|
REGISTER_TEST(REQTEST_HEAD, SetupHeadTest, GenericRunTest);
|
||||||
|
@ -630,6 +643,28 @@ class RequestTestRunner {
|
||||||
settings_.response_data = "POST TEST SUCCESS";
|
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() {
|
void SetupPostWithProgressTest() {
|
||||||
// Start with the normal post test.
|
// Start with the normal post test.
|
||||||
SetupPostTest();
|
SetupPostTest();
|
||||||
|
@ -755,6 +790,9 @@ class RequestTestRunner {
|
||||||
scheme_factory_ = NULL;
|
scheme_factory_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (post_file_tmpdir_.IsValid())
|
||||||
|
EXPECT_TRUE(post_file_tmpdir_.Delete());
|
||||||
|
|
||||||
delegate_->DestroyTest(settings_);
|
delegate_->DestroyTest(settings_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,6 +838,8 @@ class RequestTestRunner {
|
||||||
std::string scheme_name_;
|
std::string scheme_name_;
|
||||||
CefRefPtr<RequestSchemeHandlerFactory> scheme_factory_;
|
CefRefPtr<RequestSchemeHandlerFactory> scheme_factory_;
|
||||||
|
|
||||||
|
base::ScopedTempDir post_file_tmpdir_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RequestRunSettings settings_;
|
RequestRunSettings settings_;
|
||||||
};
|
};
|
||||||
|
@ -1044,6 +1084,7 @@ REQ_TEST(BrowserGETNoData, REQTEST_GET_NODATA, true);
|
||||||
REQ_TEST(BrowserGETAllowCookies, REQTEST_GET_ALLOWCOOKIES, true);
|
REQ_TEST(BrowserGETAllowCookies, REQTEST_GET_ALLOWCOOKIES, true);
|
||||||
REQ_TEST(BrowserGETRedirect, REQTEST_GET_REDIRECT, true);
|
REQ_TEST(BrowserGETRedirect, REQTEST_GET_REDIRECT, true);
|
||||||
REQ_TEST(BrowserPOST, REQTEST_POST, true);
|
REQ_TEST(BrowserPOST, REQTEST_POST, true);
|
||||||
|
REQ_TEST(BrowserPOSTFile, REQTEST_POST_FILE, true);
|
||||||
REQ_TEST(BrowserPOSTWithProgress, REQTEST_POST_WITHPROGRESS, true);
|
REQ_TEST(BrowserPOSTWithProgress, REQTEST_POST_WITHPROGRESS, true);
|
||||||
REQ_TEST(BrowserHEAD, REQTEST_HEAD, true);
|
REQ_TEST(BrowserHEAD, REQTEST_HEAD, true);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue