Add the ability to observe and modify resource redirects (issue #346).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@416 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2011-12-12 17:34:24 +00:00
parent 956073100e
commit bfcc2dbb8c
7 changed files with 204 additions and 4 deletions

View File

@ -1274,6 +1274,16 @@ public:
CefRefPtr<CefResponse> response,
int loadFlags) { return false; }
///
// Called on the IO thread when a resource load is redirected. The |old_url|
// parameter will contain the old URL. The |new_url| parameter will contain
// the new URL and can be changed if desired.
///
/*--cef()--*/
virtual void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
const CefString& old_url,
CefString& new_url) {}
///
// Called on the UI thread after a response to the resource request is
// received. Set |filter| if response content needs to be monitored and/or

View File

@ -1100,6 +1100,15 @@ typedef struct _cef_request_handler_t
struct _cef_stream_reader_t** resourceStream,
struct _cef_response_t* response, int loadFlags);
///
// Called on the IO thread when a resource load is redirected. The |old_url|
// parameter will contain the old URL. The |new_url| parameter will contain
// the new URL and can be changed if desired.
///
void (CEF_CALLBACK *on_resource_redirect)(struct _cef_request_handler_t* self,
struct _cef_browser_t* browser, const cef_string_t* old_url,
cef_string_t* new_url);
///
// Called on the UI thread after a response to the resource request is
// received. Set |filter| if response content needs to be monitored and/or

View File

@ -453,10 +453,11 @@ class RequestProxy : public net::URLRequest::Delegate,
// redirect to the specified URL
handled = true;
params->url = GURL(std::string(redirectUrl));
GURL new_url = GURL(std::string(redirectUrl));
ResourceResponseInfo info;
bool defer_redirect;
OnReceivedRedirect(params->url, info, &defer_redirect);
OnReceivedRedirect(params->url, new_url, info, &defer_redirect);
params->url = new_url;
} else if (resourceStream.get()) {
// load from the provided resource stream
handled = true;
@ -630,12 +631,30 @@ class RequestProxy : public net::URLRequest::Delegate,
// by the SyncRequestProxy subclass.
virtual void OnReceivedRedirect(
const GURL& old_url,
const GURL& new_url,
const ResourceResponseInfo& info,
bool* defer_redirect) {
*defer_redirect = true; // See AsyncFollowDeferredRedirect
GURL final_url = new_url;
if (browser_.get()) {
CefRefPtr<CefClient> client = browser_->GetClient();
CefRefPtr<CefRequestHandler> handler;
if (client.get())
handler = client->GetRequestHandler();
if(handler.get()) {
CefString newUrlStr = new_url.spec();
handler->OnResourceRedirect(browser_, old_url.spec(), newUrlStr);
if (newUrlStr != new_url.spec())
final_url = GURL(std::string(newUrlStr));
}
}
owner_loop_->PostTask(FROM_HERE, base::Bind(
&RequestProxy::NotifyReceivedRedirect, this, new_url, info));
&RequestProxy::NotifyReceivedRedirect, this, final_url, info));
}
virtual void OnReceivedResponse(
@ -691,7 +710,7 @@ class RequestProxy : public net::URLRequest::Delegate,
DCHECK(request->status().is_success());
ResourceResponseInfo info;
PopulateResponseInfo(request, &info);
OnReceivedRedirect(new_url, info, defer_redirect);
OnReceivedRedirect(request->url(), new_url, info, defer_redirect);
}
virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {

View File

@ -123,6 +123,39 @@ int CEF_CALLBACK request_handler_on_before_resource_load(
}
void CEF_CALLBACK request_handler_on_resource_redirect(
struct _cef_request_handler_t* self, cef_browser_t* browser,
const cef_string_t* old_url, cef_string_t* new_url)
{
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: old_url; type: string_byref_const
DCHECK(old_url);
if (!old_url)
return;
// Verify param: new_url; type: string_byref
DCHECK(new_url);
if (!new_url)
return;
// Translate param: new_url; type: string_byref
CefString new_urlStr(new_url);
// Execute
CefRequestHandlerCppToC::Get(self)->OnResourceRedirect(
CefBrowserCToCpp::Wrap(browser),
CefString(old_url),
new_urlStr);
}
void CEF_CALLBACK request_handler_on_resource_response(
struct _cef_request_handler_t* self, cef_browser_t* browser,
const cef_string_t* url, struct _cef_response_t* response,
@ -341,6 +374,7 @@ CefRequestHandlerCppToC::CefRequestHandlerCppToC(CefRequestHandler* cls)
struct_.struct_.on_before_browse = request_handler_on_before_browse;
struct_.struct_.on_before_resource_load =
request_handler_on_before_resource_load;
struct_.struct_.on_resource_redirect = request_handler_on_resource_redirect;
struct_.struct_.on_resource_response = request_handler_on_resource_response;
struct_.struct_.on_protocol_execution = request_handler_on_protocol_execution;
struct_.struct_.get_download_handler = request_handler_get_download_handler;

View File

@ -109,6 +109,31 @@ bool CefRequestHandlerCToCpp::OnBeforeResourceLoad(
}
void CefRequestHandlerCToCpp::OnResourceRedirect(CefRefPtr<CefBrowser> browser,
const CefString& old_url, CefString& new_url)
{
if (CEF_MEMBER_MISSING(struct_, on_resource_redirect))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: old_url; type: string_byref_const
DCHECK(!old_url.empty());
if (old_url.empty())
return;
// Execute
struct_->on_resource_redirect(struct_,
CefBrowserCppToC::Wrap(browser),
old_url.GetStruct(),
new_url.GetWritableStruct());
}
void CefRequestHandlerCToCpp::OnResourceResponse(CefRefPtr<CefBrowser> browser,
const CefString& url, CefRefPtr<CefResponse> response,
CefRefPtr<CefContentFilter>& filter)

View File

@ -41,6 +41,8 @@ public:
CefRefPtr<CefRequest> request, CefString& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
CefRefPtr<CefResponse> response, int loadFlags) OVERRIDE;
virtual void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
const CefString& old_url, CefString& new_url) OVERRIDE;
virtual void OnResourceResponse(CefRefPtr<CefBrowser> browser,
const CefString& url, CefRefPtr<CefResponse> response,
CefRefPtr<CefContentFilter>& filter) OVERRIDE;

View File

@ -336,3 +336,104 @@ TEST(NavigationTest, FrameNameIdent)
ASSERT_TRUE(handler->got_frame2_ident_parent_after_);
ASSERT_TRUE(handler->got_frame3_ident_parent_after_);
}
namespace {
class RedirectTestHandler : public TestHandler
{
public:
RedirectTestHandler() {}
virtual void RunTest() OVERRIDE
{
// Create the browser.
CreateBrowser(kNav1);
}
virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
NavType navType,
bool isRedirect) OVERRIDE
{
std::string url = request->GetURL();
if (url == kNav1) {
got_nav1_before_browse_.yes();
} else if (url == kNav2) {
// should not happen
got_nav2_before_browse_.yes();
} else if (url == kNav3) {
got_nav3_before_browse_.yes();
// End of test.
DestroyTest();
}
return false;
}
virtual bool OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
CefString& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
CefRefPtr<CefResponse> response,
int loadFlags) OVERRIDE
{
std::string url = request->GetURL();
if (url == kNav1) {
got_nav1_before_resource_load_.yes();
// Redirect to the 2nd URL.
redirectUrl = kNav2;
} else if(url == kNav2) {
// Should not happen.
got_nav2_before_resource_load_.yes();
} else if(url == kNav3) {
// Should not happen.
got_nav3_before_resource_load_.yes();
}
return false;
}
virtual void OnResourceRedirect(CefRefPtr<CefBrowser> browser,
const CefString& old_url,
CefString& new_url) OVERRIDE
{
if (old_url == kNav1 && new_url == kNav2) {
got_nav1_redirect_.yes();
// Change the redirect to the 3rd URL.
new_url = kNav3;
}
}
TrackCallback got_nav1_before_browse_;
TrackCallback got_nav2_before_browse_;
TrackCallback got_nav3_before_browse_;
TrackCallback got_nav1_before_resource_load_;
TrackCallback got_nav2_before_resource_load_;
TrackCallback got_nav3_before_resource_load_;
TrackCallback got_nav1_redirect_;
};
} // namespace
// Verify frame names and identifiers.
TEST(NavigationTest, Redirect)
{
CefRefPtr<RedirectTestHandler> handler =
new RedirectTestHandler();
handler->ExecuteTest();
ASSERT_TRUE(handler->got_nav1_before_browse_);
ASSERT_FALSE(handler->got_nav2_before_browse_);
ASSERT_TRUE(handler->got_nav3_before_browse_);
ASSERT_TRUE(handler->got_nav1_before_resource_load_);
ASSERT_FALSE(handler->got_nav2_before_resource_load_);
ASSERT_FALSE(handler->got_nav3_before_resource_load_);
ASSERT_TRUE(handler->got_nav1_redirect_);
}