remote/network/RemoteResourceRequestHandler.cpp (148 lines of code) (raw):

#include "RemoteResourceRequestHandler.h" #include "../CefUtils.h" #include "../handlers/RemoteClientHandler.h" #include "../log/Log.h" #include "RemoteCookieAccessFilter.h" #include "RemoteRequest.h" #include "RemoteResourceHandler.h" #include "RemoteResponse.h" #include "../browser/RemoteFrame.h" namespace { std::string status2str(cef_urlrequest_status_t type); const bool doTrace = getBoolEnv("CEF_SERVER_TRACE_RemoteResourceRequestHandler"); } RemoteResourceRequestHandler::RemoteResourceRequestHandler( int bid, std::shared_ptr<ServerHandlerContext> serviceIO, thrift_codegen::RObject peer) : RemoteJavaObject( serviceIO, peer.objId, [=](JavaService service) { service->ResourceRequestHandler_Dispose(peer.objId); }), myBid(bid) { TRACE(); } /// /// Called on the IO thread before a resource request is loaded. The |browser| /// and |frame| values represent the source of the request, and may be NULL /// for requests originating from service workers or CefURLRequest. To /// optionally filter cookies for the request return a CefCookieAccessFilter /// object. The |request| object cannot not be modified in this callback. /// /*--cef(optional_param=browser,optional_param=frame)--*/ CefRefPtr<CefCookieAccessFilter> RemoteResourceRequestHandler::GetCookieAccessFilter( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request ) { TRACE(); RemoteRequest::Holder req(request); RemoteFrame::Holder frm(frame); thrift_codegen::RObject remoteHandler; myCtx->javaServiceIO()->exec([&](JavaService s){ s->ResourceRequestHandler_GetCookieAccessFilter(remoteHandler, myPeerId, myBid, frm.serverId(), req.serverId()); }); return !remoteHandler.isNull ? new RemoteCookieAccessFilter(myBid, myCtx, remoteHandler) : nullptr; } /// /// Called on the IO thread before a resource request is loaded. The |browser| /// and |frame| values represent the source of the request, and may be NULL /// for requests originating from service workers or CefURLRequest. To /// redirect or change the resource load optionally modify |request|. /// Modification of the request URL will be treated as a redirect. Return /// RV_CONTINUE to continue the request immediately. Return RV_CONTINUE_ASYNC /// and call CefCallback methods at a later time to continue or cancel the /// request asynchronously. Return RV_CANCEL to cancel the request /// immediately. /// /*--cef(optional_param=browser,optional_param=frame, default_retval=RV_CONTINUE)--*/ CefResourceRequestHandler::ReturnValue RemoteResourceRequestHandler::OnBeforeResourceLoad( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefCallback> callback ) { TRACE(); RemoteRequest::Holder req(request); RemoteFrame::Holder frm(frame); CefResourceRequestHandler::ReturnValue result = RV_CONTINUE; myCtx->javaServiceIO()->exec([&](JavaService s){ bool boolRes = s->ResourceRequestHandler_OnBeforeResourceLoad(myPeerId, myBid, frm.serverId(), req.serverId()); result = (boolRes ? RV_CANCEL : RV_CONTINUE); }); return result; } /// /// Called on the IO thread before a resource is loaded. The |browser| and /// |frame| values represent the source of the request, and may be NULL for /// requests originating from service workers or CefURLRequest. To allow the /// resource to load using the default network loader return NULL. To specify /// a handler for the resource return a CefResourceHandler object. The /// |request| object cannot not be modified in this callback. /// /*--cef(optional_param=browser,optional_param=frame)--*/ CefRefPtr<CefResourceHandler> RemoteResourceRequestHandler::GetResourceHandler( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request ) { TRACE(); RemoteRequest::Holder req(request); RemoteFrame::Holder frm(frame); thrift_codegen::RObject remoteHandler; myCtx->javaServiceIO()->exec([&](JavaService s){ s->ResourceRequestHandler_GetResourceHandler(remoteHandler, myPeerId, myBid, frm.serverId(), req.serverId()); }); return !remoteHandler.isNull ? new RemoteResourceHandler(myBid, myCtx, remoteHandler) : nullptr; } /// /// Called on the IO thread when a resource load is redirected. The |browser| /// and |frame| values represent the source of the request, and may be NULL /// for requests originating from service workers or CefURLRequest. The /// |request| parameter will contain the old URL and other request-related /// information. 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| and |response| objects cannot /// be modified in this callback. /// /*--cef(optional_param=browser,optional_param=frame)--*/ void RemoteResourceRequestHandler::OnResourceRedirect( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response, CefString& new_url ) { TRACE(); RemoteRequest::Holder req(request); RemoteResponse::Holder resp(response); RemoteFrame::Holder frm(frame); std::string result; myCtx->javaServiceIO()->exec([&](JavaService s){ s->ResourceRequestHandler_OnResourceRedirect(result, myPeerId, myBid, frm.serverId(), req.serverId(), resp.serverId(), new_url.ToString()); }); CefString tmp(result); new_url.swap(tmp); } /// /// Called on the IO thread when a resource response is received. The /// |browser| and |frame| values represent the source of the request, and may /// be NULL for requests originating from service workers or CefURLRequest. To /// allow the resource load to proceed without modification return false. To /// redirect or retry the resource load optionally modify |request| and return /// true. Modification of the request URL will be treated as a redirect. /// Requests handled using the default network loader cannot be redirected in /// this callback. The |response| object cannot be modified in this callback. /// /// WARNING: Redirecting using this method is deprecated. Use /// OnBeforeResourceLoad or GetResourceHandler to perform redirects. /// /*--cef(optional_param=browser,optional_param=frame)--*/ bool RemoteResourceRequestHandler::OnResourceResponse( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response ) { TRACE(); RemoteRequest::Holder req(request); RemoteResponse::Holder resp(response); RemoteFrame::Holder frm(frame); return myCtx->javaServiceIO()->exec<bool>([&](JavaService s){ return s->ResourceRequestHandler_OnResourceResponse(myPeerId, myBid, frm.serverId(), req.serverId(), resp.serverId()); }, false); } /// /// Called on the IO thread when a resource load has completed. The |browser| /// and |frame| values represent the source of the request, and may be NULL /// for requests originating from service workers or CefURLRequest. |request| /// and |response| represent the request and response respectively and cannot /// be modified in this callback. |status| indicates the load completion /// status. |received_content_length| is the number of response bytes actually /// read. This method will be called for all requests, including requests that /// are aborted due to CEF shutdown or destruction of the associated browser. /// In cases where the associated browser is destroyed this callback may /// arrive after the CefLifeSpanHandler::OnBeforeClose callback for that /// browser. The CefFrame::IsValid method can be used to test for this /// situation, and care should be taken not to call |browser| or |frame| /// methods that modify state (like LoadURL, SendProcessMessage, etc.) if the /// frame is invalid. /// /*--cef(optional_param=browser,optional_param=frame)--*/ void RemoteResourceRequestHandler::OnResourceLoadComplete( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response, CefResourceRequestHandler::URLRequestStatus status, int64_t received_content_length ) { TRACE(); RemoteRequest::Holder req(request); RemoteResponse::Holder resp(response); RemoteFrame::Holder frm(frame); myCtx->javaServiceIO()->exec([&](JavaService s){ s->ResourceRequestHandler_OnResourceLoadComplete(myPeerId, myBid, frm.serverId(), req.serverId(), resp.serverId(), status2str(status), received_content_length); }); } /// /// Called on the IO thread to handle requests for URLs with an unknown /// protocol component. The |browser| and |frame| values represent the source /// of the request, and may be NULL for requests originating from service /// workers or CefURLRequest. |request| cannot be modified in this callback. /// Set |allow_os_execution| to true to attempt execution via the registered /// OS protocol handler, if any. SECURITY WARNING: YOU SHOULD USE THIS METHOD /// TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE /// ALLOWING OS EXECUTION. /// /*--cef(optional_param=browser,optional_param=frame)--*/ void RemoteResourceRequestHandler::OnProtocolExecution( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool& allow_os_execution) { TRACE(); RemoteRequest::Holder req(request); RemoteFrame::Holder frm(frame); myCtx->javaServiceIO()->exec([&](JavaService s){ allow_os_execution = s->ResourceRequestHandler_OnProtocolExecution(myPeerId, myBid, frm.serverId(), req.serverId(), allow_os_execution); }); } namespace { std::pair<cef_urlrequest_status_t, std::string> statuses[] = { {UR_UNKNOWN, "UR_UNKNOWN"}, {UR_SUCCESS, "UR_SUCCESS"}, {UR_IO_PENDING, "UR_IO_PENDING"}, {UR_CANCELED, "UR_CANCELED"}, {UR_FAILED, "UR_FAILED"} }; std::string status2str(cef_urlrequest_status_t type) { for (auto p : statuses) { if (p.first == type) return p.second; } return string_format("unknown_urlrequest_status_%d", type); } }