diff --git a/include/capi/cef_request_handler_capi.h b/include/capi/cef_request_handler_capi.h index 70e6b3c14..b1aeb849c 100644 --- a/include/capi/cef_request_handler_capi.h +++ b/include/capi/cef_request_handler_capi.h @@ -146,12 +146,15 @@ typedef struct _cef_request_handler_t { /// // Called on the IO thread when a resource load is redirected. The |request| // parameter will contain the old URL and other request-related information. - // The |new_url| parameter will contain the new URL and can be changed if - // desired. The |request| object cannot be modified in this callback. + // The |response| parameter will contain the response that resulted in the + // redirect. The |new_url| parameter will contain the new URL and can be + // changed if desired. The |request| object cannot be modified in this + // callback. /// void (CEF_CALLBACK *on_resource_redirect)(struct _cef_request_handler_t* self, struct _cef_browser_t* browser, struct _cef_frame_t* frame, - struct _cef_request_t* request, cef_string_t* new_url); + struct _cef_request_t* request, struct _cef_response_t* response, + cef_string_t* new_url); /// // Called on the IO thread when a resource response is received. To allow the diff --git a/include/cef_request_handler.h b/include/cef_request_handler.h index 5ffb3b9b6..a4f097083 100644 --- a/include/cef_request_handler.h +++ b/include/cef_request_handler.h @@ -159,13 +159,16 @@ class CefRequestHandler : public virtual CefBase { /// // Called on the IO thread when a resource load is redirected. The |request| // parameter will contain the old URL and other request-related information. - // The |new_url| parameter will contain the new URL and can be changed if - // desired. The |request| object cannot be modified in this callback. + // The |response| parameter will contain the response that resulted in the + // redirect. The |new_url| parameter will contain the new URL and can be + // changed if desired. The |request| object cannot be modified in this + // callback. /// /*--cef()--*/ virtual void OnResourceRedirect(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, + CefRefPtr response, CefString& new_url) {} /// diff --git a/libcef/browser/net/url_request_interceptor.cc b/libcef/browser/net/url_request_interceptor.cc index 772e77884..aa744caa1 100644 --- a/libcef/browser/net/url_request_interceptor.cc +++ b/libcef/browser/net/url_request_interceptor.cc @@ -73,10 +73,14 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRedirect( static_cast(cefRequest.get())->Set(request); static_cast(cefRequest.get())->SetReadOnly(true); + CefRefPtr cefResponse = new CefResponseImpl(); + static_cast(cefResponse.get())->Set(request); + static_cast(cefResponse.get())->SetReadOnly(true); + // Give the client an opportunity to redirect the request. CefString newUrlStr = location.spec(); handler->OnResourceRedirect(browser.get(), frame, cefRequest, - newUrlStr); + cefResponse, newUrlStr); if (newUrlStr != location.spec()) { const GURL new_url = GURL(newUrlStr.ToString()); if (!new_url.is_empty() && new_url.is_valid()) { diff --git a/libcef_dll/cpptoc/request_handler_cpptoc.cc b/libcef_dll/cpptoc/request_handler_cpptoc.cc index ae53d1aee..fae349b42 100644 --- a/libcef_dll/cpptoc/request_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/request_handler_cpptoc.cc @@ -164,7 +164,8 @@ struct _cef_resource_handler_t* CEF_CALLBACK request_handler_get_resource_handle void CEF_CALLBACK request_handler_on_resource_redirect( struct _cef_request_handler_t* self, cef_browser_t* browser, - cef_frame_t* frame, cef_request_t* request, cef_string_t* new_url) { + cef_frame_t* frame, cef_request_t* request, + struct _cef_response_t* response, cef_string_t* new_url) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); @@ -182,6 +183,10 @@ void CEF_CALLBACK request_handler_on_resource_redirect( DCHECK(request); if (!request) return; + // Verify param: response; type: refptr_diff + DCHECK(response); + if (!response) + return; // Verify param: new_url; type: string_byref DCHECK(new_url); if (!new_url) @@ -195,6 +200,7 @@ void CEF_CALLBACK request_handler_on_resource_redirect( CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame), CefRequestCToCpp::Wrap(request), + CefResponseCToCpp::Wrap(response), new_urlStr); } diff --git a/libcef_dll/ctocpp/request_handler_ctocpp.cc b/libcef_dll/ctocpp/request_handler_ctocpp.cc index 70069557f..1e1433370 100644 --- a/libcef_dll/ctocpp/request_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/request_handler_ctocpp.cc @@ -162,7 +162,7 @@ CefRefPtr CefRequestHandlerCToCpp::GetResourceHandler( void CefRequestHandlerCToCpp::OnResourceRedirect(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, - CefString& new_url) { + CefRefPtr response, CefString& new_url) { cef_request_handler_t* _struct = GetStruct(); if (CEF_MEMBER_MISSING(_struct, on_resource_redirect)) return; @@ -181,12 +181,17 @@ void CefRequestHandlerCToCpp::OnResourceRedirect(CefRefPtr browser, DCHECK(request.get()); if (!request.get()) return; + // Verify param: response; type: refptr_diff + DCHECK(response.get()); + if (!response.get()) + return; // Execute _struct->on_resource_redirect(_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame), CefRequestCppToC::Wrap(request), + CefResponseCppToC::Wrap(response), new_url.GetWritableStruct()); } diff --git a/libcef_dll/ctocpp/request_handler_ctocpp.h b/libcef_dll/ctocpp/request_handler_ctocpp.h index 28b2052ee..2e8faf04c 100644 --- a/libcef_dll/ctocpp/request_handler_ctocpp.h +++ b/libcef_dll/ctocpp/request_handler_ctocpp.h @@ -44,7 +44,7 @@ class CefRequestHandlerCToCpp CefRefPtr request) override; void OnResourceRedirect(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, - CefString& new_url) override; + CefRefPtr response, CefString& new_url) override; bool OnResourceResponse(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, CefRefPtr response) override; diff --git a/tests/unittests/navigation_unittest.cc b/tests/unittests/navigation_unittest.cc index f0f7e34bd..3770b3d99 100644 --- a/tests/unittests/navigation_unittest.cc +++ b/tests/unittests/navigation_unittest.cc @@ -780,6 +780,7 @@ class RedirectTestHandler : public TestHandler { void OnResourceRedirect(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, + CefRefPtr response, CefString& new_url) override { // Should be called for each redirected URL. @@ -788,14 +789,29 @@ class RedirectTestHandler : public TestHandler { // Called due to the nav1 redirect response. got_nav1_redirect_.yes(); + EXPECT_EQ(302, response->GetStatus()); + EXPECT_STREQ("Found", response->GetStatusText().ToString().c_str()); + EXPECT_STREQ("text/html", response->GetMimeType().ToString().c_str()); + EXPECT_STREQ(kRNav2, response->GetHeader("Location").ToString().c_str()); + // Change the redirect to the 3rd URL. new_url = kRNav3; } else if (old_url == kRNav1 && new_url == kRNav3) { // Called due to the redirect change above. got_nav2_redirect_.yes(); + + EXPECT_EQ(307, response->GetStatus()); + EXPECT_STREQ("Internal Redirect", + response->GetStatusText().ToString().c_str()); + EXPECT_TRUE(response->GetMimeType().empty()); + EXPECT_STREQ(kRNav3, response->GetHeader("Location").ToString().c_str()); } else if (old_url == kRNav3 && new_url == kRNav4) { // Called due to the nav3 redirect response. got_nav3_redirect_.yes(); + + EXPECT_EQ(200, response->GetStatus()); + EXPECT_TRUE(response->GetStatusText().empty()); + EXPECT_STREQ("text/html", response->GetMimeType().ToString().c_str()); } else { got_invalid_redirect_.yes(); } @@ -862,6 +878,7 @@ class RedirectDestroyTestHandler : public TestHandler { void OnResourceRedirect(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, + CefRefPtr response, CefString& new_url) override { const std::string& old_url = request->GetURL(); if (old_url == kRNav1 && new_url == kRNav2) { diff --git a/tests/unittests/request_handler_unittest.cc b/tests/unittests/request_handler_unittest.cc index ce3a184ff..0ac0b15f7 100644 --- a/tests/unittests/request_handler_unittest.cc +++ b/tests/unittests/request_handler_unittest.cc @@ -643,6 +643,7 @@ class ResourceResponseTest : public TestHandler { void OnResourceRedirect(CefRefPtr browser, CefRefPtr frame, CefRefPtr request, + CefRefPtr response, CefString& new_url) override { EXPECT_IO_THREAD(); EXPECT_EQ(browser_id_, browser->GetIdentifier());