mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-18 13:10:42 +01:00
Add ability to stop CefURLRequest on redirect (issue #1329)
This commit is contained in:
parent
bcb7529ed3
commit
5211ca6298
@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=561e4711432158fd3da971f3c0240dcf5e8e782a$
|
||||
// $hash=fd2cbc427bccf30298e26dd6c3bcef9551433f8b$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_RESPONSE_CAPI_H_
|
||||
@ -127,6 +127,18 @@ typedef struct _cef_response_t {
|
||||
///
|
||||
void(CEF_CALLBACK* set_header_map)(struct _cef_response_t* self,
|
||||
cef_string_multimap_t headerMap);
|
||||
|
||||
///
|
||||
// Get the resolved URL after redirects or changed as a result of HSTS.
|
||||
///
|
||||
// The resulting string must be freed by calling cef_string_userfree_free().
|
||||
cef_string_userfree_t(CEF_CALLBACK* get_url)(struct _cef_response_t* self);
|
||||
|
||||
///
|
||||
// Set the resolved URL after redirects or changed as a result of HSTS.
|
||||
///
|
||||
void(CEF_CALLBACK* set_url)(struct _cef_response_t* self,
|
||||
const cef_string_t* url);
|
||||
} cef_response_t;
|
||||
|
||||
///
|
||||
|
@ -128,6 +128,18 @@ class CefResponse : public virtual CefBaseRefCounted {
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SetHeaderMap(const HeaderMap& headerMap) = 0;
|
||||
|
||||
///
|
||||
// Get the resolved URL after redirects or changed as a result of HSTS.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual CefString GetURL() = 0;
|
||||
|
||||
///
|
||||
// Set the resolved URL after redirects or changed as a result of HSTS.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SetURL(const CefString& url) = 0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_RESPONSE_H_
|
||||
|
@ -1264,6 +1264,12 @@ typedef enum {
|
||||
// originated in the browser process.
|
||||
///
|
||||
UR_FLAG_NO_RETRY_ON_5XX = 1 << 5,
|
||||
|
||||
///
|
||||
// If set 3XX responses will cause the fetch to halt immediately rather than
|
||||
// continue through the redirect.
|
||||
///
|
||||
UR_FLAG_STOP_ON_REDIRECT = 1 << 6,
|
||||
} cef_urlrequest_flags_t;
|
||||
|
||||
///
|
||||
|
@ -356,6 +356,9 @@ class CefBrowserURLRequest::Context
|
||||
CefResponseImpl* responseImpl =
|
||||
static_cast<CefResponseImpl*>(response_.get());
|
||||
|
||||
responseImpl->SetURL(fetcher_->GetURL().spec());
|
||||
responseImpl->SetStatus(fetcher_->GetResponseCode());
|
||||
|
||||
net::HttpResponseHeaders* headers = fetcher_->GetResponseHeaders();
|
||||
if (headers)
|
||||
responseImpl->SetResponseHeaders(*headers);
|
||||
|
@ -336,6 +336,14 @@ bool CefResourceRequestJob::GetCharset(std::string* charset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int CefResourceRequestJob::GetResponseCode() const {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
if (response_.get())
|
||||
return response_->GetStatus();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CefResourceRequestJob::SendHeaders() {
|
||||
CEF_REQUIRE_IOT();
|
||||
|
||||
|
@ -41,6 +41,7 @@ class CefResourceRequestJob : public net::URLRequestJob {
|
||||
bool IsRedirectResponse(GURL* location, int* http_status_code) override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
bool GetCharset(std::string* charset) override;
|
||||
int GetResponseCode() const override;
|
||||
|
||||
void SendHeaders();
|
||||
|
||||
|
@ -745,6 +745,8 @@ void CefRequestImpl::Get(net::URLFetcher& fetcher,
|
||||
|
||||
if (flags & UR_FLAG_NO_RETRY_ON_5XX)
|
||||
fetcher.SetAutomaticallyRetryOn5xx(false);
|
||||
if (flags & UR_FLAG_STOP_ON_REDIRECT)
|
||||
fetcher.SetStopOnRedirect(true);
|
||||
|
||||
int net_flags = 0;
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
|
||||
#include "third_party/WebKit/public/platform/WebString.h"
|
||||
#include "third_party/WebKit/public/platform/WebURL.h"
|
||||
#include "third_party/WebKit/public/platform/WebURLResponse.h"
|
||||
|
||||
#define CHECK_READONLY_RETURN_VOID() \
|
||||
@ -95,6 +96,17 @@ CefString CefResponseImpl::GetHeader(const CefString& name) {
|
||||
return value;
|
||||
}
|
||||
|
||||
CefString CefResponseImpl::GetURL() {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
return url_;
|
||||
}
|
||||
|
||||
void CefResponseImpl::SetURL(const CefString& url) {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
CHECK_READONLY_RETURN_VOID();
|
||||
url_ = url;
|
||||
}
|
||||
|
||||
void CefResponseImpl::GetHeaderMap(HeaderMap& map) {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
map = header_map_;
|
||||
@ -190,6 +202,8 @@ void CefResponseImpl::Set(const blink::WebURLResponse& response) {
|
||||
status_text_ = str.Utf16();
|
||||
str = response.MimeType();
|
||||
mime_type_ = str.Utf16();
|
||||
str = response.Url().GetString();
|
||||
url_ = str.Utf16();
|
||||
|
||||
class HeaderVisitor : public blink::WebHTTPHeaderVisitor {
|
||||
public:
|
||||
|
@ -13,7 +13,7 @@
|
||||
namespace net {
|
||||
class HttpResponseHeaders;
|
||||
class URLRequest;
|
||||
}
|
||||
} // namespace net
|
||||
|
||||
namespace blink {
|
||||
class WebURLResponse;
|
||||
@ -37,6 +37,8 @@ class CefResponseImpl : public CefResponse {
|
||||
CefString GetHeader(const CefString& name) override;
|
||||
void GetHeaderMap(HeaderMap& headerMap) override;
|
||||
void SetHeaderMap(const HeaderMap& headerMap) override;
|
||||
CefString GetURL() override;
|
||||
void SetURL(const CefString& url) override;
|
||||
|
||||
net::HttpResponseHeaders* GetResponseHeaders();
|
||||
void SetResponseHeaders(const net::HttpResponseHeaders& headers);
|
||||
@ -51,6 +53,7 @@ class CefResponseImpl : public CefResponse {
|
||||
int status_code_;
|
||||
CefString status_text_;
|
||||
CefString mime_type_;
|
||||
CefString url_;
|
||||
HeaderMap header_map_;
|
||||
bool read_only_;
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "third_party/WebKit/public/platform/WebURLRequest.h"
|
||||
#include "third_party/WebKit/public/platform/WebURLResponse.h"
|
||||
|
||||
using blink::WebReferrerPolicy;
|
||||
using blink::WebString;
|
||||
using blink::WebURL;
|
||||
using blink::WebURLError;
|
||||
@ -52,6 +53,13 @@ class CefWebURLLoaderClient : public blink::WebURLLoaderClient {
|
||||
int64_t total_encoded_data_length,
|
||||
int64_t total_encoded_body_length,
|
||||
int64_t total_decoded_body_length) override;
|
||||
bool WillFollowRedirect(const WebURL& new_url,
|
||||
const WebURL& new_site_for_cookies,
|
||||
const WebString& new_referrer,
|
||||
WebReferrerPolicy new_referrer_policy,
|
||||
const WebString& new_method,
|
||||
const WebURLResponse& passed_redirect_response,
|
||||
bool& report_raw_headers) override;
|
||||
|
||||
protected:
|
||||
// The context_ pointer will outlive this object.
|
||||
@ -127,6 +135,28 @@ class CefRenderURLRequest::Context
|
||||
loader_->Cancel();
|
||||
}
|
||||
|
||||
void OnStopRedirect(const WebURL& redirect_url,
|
||||
const WebURLResponse& response) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
|
||||
response_was_cached_ = webkit_glue::ResponseWasCached(response);
|
||||
response_ = CefResponse::Create();
|
||||
CefResponseImpl* responseImpl =
|
||||
static_cast<CefResponseImpl*>(response_.get());
|
||||
|
||||
// In case of StopOnRedirect we only set these fields. Everything else is
|
||||
// left blank. This also replicates the behaviour of the browser urlrequest
|
||||
// fetcher.
|
||||
responseImpl->SetStatus(response.HttpStatusCode());
|
||||
responseImpl->SetURL(redirect_url.GetString().Utf16());
|
||||
responseImpl->SetReadOnly(true);
|
||||
|
||||
status_ = UR_CANCELED;
|
||||
error_code_ = ERR_ABORTED;
|
||||
|
||||
OnComplete();
|
||||
}
|
||||
|
||||
void OnResponse(const WebURLResponse& response) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
|
||||
@ -277,6 +307,21 @@ void CefWebURLLoaderClient::DidFail(const WebURLError& error,
|
||||
context_->OnError(error);
|
||||
}
|
||||
|
||||
bool CefWebURLLoaderClient::WillFollowRedirect(
|
||||
const WebURL& new_url,
|
||||
const WebURL& new_site_for_cookies,
|
||||
const WebString& new_referrer,
|
||||
WebReferrerPolicy new_referrer_policy,
|
||||
const WebString& new_method,
|
||||
const WebURLResponse& passed_redirect_response,
|
||||
bool& report_raw_headers) {
|
||||
if (request_flags_ & UR_FLAG_STOP_ON_REDIRECT) {
|
||||
context_->OnStopRedirect(new_url, passed_redirect_response);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CefRenderURLRequest --------------------------------------------------------
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=f2872ff67c69f164f899040c77340e116bd214c0$
|
||||
// $hash=9cf199db470205062b0c4d39f7daa739db2a95a2$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/response_cpptoc.h"
|
||||
@ -222,6 +222,37 @@ void CEF_CALLBACK response_set_header_map(struct _cef_response_t* self,
|
||||
CefResponseCppToC::Get(self)->SetHeaderMap(headerMapMultimap);
|
||||
}
|
||||
|
||||
cef_string_userfree_t CEF_CALLBACK
|
||||
response_get_url(struct _cef_response_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefString _retval = CefResponseCppToC::Get(self)->GetURL();
|
||||
|
||||
// Return type: string
|
||||
return _retval.DetachToUserFree();
|
||||
}
|
||||
|
||||
void CEF_CALLBACK response_set_url(struct _cef_response_t* self,
|
||||
const cef_string_t* url) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: url; type: string_byref_const
|
||||
DCHECK(url);
|
||||
if (!url)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefResponseCppToC::Get(self)->SetURL(CefString(url));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
@ -239,6 +270,8 @@ CefResponseCppToC::CefResponseCppToC() {
|
||||
GetStruct()->get_header = response_get_header;
|
||||
GetStruct()->get_header_map = response_get_header_map;
|
||||
GetStruct()->set_header_map = response_set_header_map;
|
||||
GetStruct()->get_url = response_get_url;
|
||||
GetStruct()->set_url = response_set_url;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=00cc7ae2c2822a50218bb1e3b9cab95ab67236a6$
|
||||
// $hash=fbfca8a1320ab81bda709202462543a658ed886d$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/response_ctocpp.h"
|
||||
@ -224,6 +224,38 @@ void CefResponseCToCpp::SetHeaderMap(const HeaderMap& headerMap) {
|
||||
cef_string_multimap_free(headerMapMultimap);
|
||||
}
|
||||
|
||||
CefString CefResponseCToCpp::GetURL() {
|
||||
cef_response_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_url))
|
||||
return CefString();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_string_userfree_t _retval = _struct->get_url(_struct);
|
||||
|
||||
// Return type: string
|
||||
CefString _retvalStr;
|
||||
_retvalStr.AttachToUserFree(_retval);
|
||||
return _retvalStr;
|
||||
}
|
||||
|
||||
void CefResponseCToCpp::SetURL(const CefString& url) {
|
||||
cef_response_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, set_url))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: url; type: string_byref_const
|
||||
DCHECK(!url.empty());
|
||||
if (url.empty())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->set_url(_struct, url.GetStruct());
|
||||
}
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefResponseCToCpp::CefResponseCToCpp() {}
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=0c155aa07dd80b78f92950d0fc8ff4fec7df9a21$
|
||||
// $hash=1b7de3f18de3231ea172447565684df6f0fcf265$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_RESPONSE_CTOCPP_H_
|
||||
@ -45,6 +45,8 @@ class CefResponseCToCpp : public CefCToCppRefCounted<CefResponseCToCpp,
|
||||
CefString GetHeader(const CefString& name) OVERRIDE;
|
||||
void GetHeaderMap(HeaderMap& headerMap) OVERRIDE;
|
||||
void SetHeaderMap(const HeaderMap& headerMap) OVERRIDE;
|
||||
CefString GetURL() OVERRIDE;
|
||||
void SetURL(const CefString& url) OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CTOCPP_RESPONSE_CTOCPP_H_
|
||||
|
@ -57,6 +57,7 @@ enum RequestTestMode {
|
||||
REQTEST_GET_NODATA,
|
||||
REQTEST_GET_ALLOWCOOKIES,
|
||||
REQTEST_GET_REDIRECT,
|
||||
REQTEST_GET_REDIRECT_STOP,
|
||||
REQTEST_GET_REFERRER,
|
||||
REQTEST_POST,
|
||||
REQTEST_POST_FILE,
|
||||
@ -1058,6 +1059,8 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
REGISTER_TEST(REQTEST_GET_ALLOWCOOKIES, SetupGetAllowCookiesTest,
|
||||
SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_GET_REDIRECT, SetupGetRedirectTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_GET_REDIRECT_STOP, SetupGetRedirectStopTest,
|
||||
SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_GET_REFERRER, SetupGetReferrerTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST, SetupPostTest, SingleRunTest);
|
||||
REGISTER_TEST(REQTEST_POST_FILE, SetupPostFileTest, SingleRunTest);
|
||||
@ -1240,6 +1243,41 @@ class RequestTestRunner : public base::RefCountedThreadSafe<RequestTestRunner> {
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupGetRedirectStopTest(const base::Closure& complete_callback) {
|
||||
settings_.request = CefRequest::Create();
|
||||
settings_.request->SetURL(GetTestURL("GetTest.html"));
|
||||
settings_.request->SetMethod("GET");
|
||||
|
||||
// With the test server only the status is expected
|
||||
// on stop redirects.
|
||||
settings_.response = CefResponse::Create();
|
||||
settings_.response->SetStatus(302);
|
||||
|
||||
// Add a redirect request.
|
||||
settings_.redirect_request = CefRequest::Create();
|
||||
settings_.redirect_request->SetURL(GetTestURL("redirect.html"));
|
||||
settings_.redirect_request->SetMethod("GET");
|
||||
settings_.redirect_request->SetFlags(UR_FLAG_STOP_ON_REDIRECT);
|
||||
|
||||
settings_.redirect_response = CefResponse::Create();
|
||||
settings_.redirect_response->SetMimeType("text/html");
|
||||
settings_.redirect_response->SetStatus(302);
|
||||
settings_.redirect_response->SetStatusText("Found");
|
||||
|
||||
CefResponse::HeaderMap headerMap;
|
||||
headerMap.insert(std::make_pair("Location", settings_.request->GetURL()));
|
||||
settings_.redirect_response->SetHeaderMap(headerMap);
|
||||
|
||||
settings_.expected_status = UR_CANCELED;
|
||||
settings_.expected_error_code = ERR_ABORTED;
|
||||
settings_.expect_download_data = false;
|
||||
settings_.expect_download_progress = false;
|
||||
settings_.expected_send_count = 1;
|
||||
settings_.expected_receive_count = 1;
|
||||
|
||||
complete_callback.Run();
|
||||
}
|
||||
|
||||
void SetupGetReferrerTest(const base::Closure& complete_callback) {
|
||||
settings_.request = CefRequest::Create();
|
||||
settings_.request->SetURL(GetTestURL("GetTest.html"));
|
||||
@ -2210,6 +2248,8 @@ void RegisterURLRequestCustomSchemes(
|
||||
context_mode, true, test_server_backend); \
|
||||
REQ_TEST(BrowserGETRedirect##suffix, REQTEST_GET_REDIRECT, context_mode, \
|
||||
true, test_server_backend); \
|
||||
REQ_TEST(BrowserGETRedirectStop##suffix, REQTEST_GET_REDIRECT_STOP, \
|
||||
context_mode, true, test_server_backend); \
|
||||
REQ_TEST(BrowserGETReferrer##suffix, REQTEST_GET_REFERRER, context_mode, \
|
||||
true, test_server_backend); \
|
||||
REQ_TEST(BrowserPOST##suffix, REQTEST_POST, context_mode, true, \
|
||||
@ -2228,6 +2268,8 @@ void RegisterURLRequestCustomSchemes(
|
||||
context_mode, false, test_server_backend); \
|
||||
REQ_TEST(RendererGETRedirect##suffix, REQTEST_GET_REDIRECT, context_mode, \
|
||||
false, test_server_backend); \
|
||||
REQ_TEST(RendererGETRedirectStop##suffix, REQTEST_GET_REDIRECT_STOP, \
|
||||
context_mode, false, test_server_backend); \
|
||||
REQ_TEST(RendererGETReferrer##suffix, REQTEST_GET_REFERRER, context_mode, \
|
||||
false, test_server_backend); \
|
||||
REQ_TEST(RendererPOST##suffix, REQTEST_POST, context_mode, false, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user