CefRefPtr<CefResourceHandler> LocalSchemeHandlerFactory::Create(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& scheme_name, CefRefPtr<CefRequest> request) { CefRefPtr<CefResourceHandler> pResourceHandler = NULL; CefURLParts parts; CefParseURL(request->GetURL(), parts); if( CefString(&parts.path).size() < 2 ) { return NULL; } char path[MAX_PATH]; V_strncpy( path, CefString(&parts.path).ToString().c_str() + 1, sizeof(path) ); V_FixupPathName( path, sizeof( path ), path ); if( filesystem->IsDirectory( path ) ) { V_AppendSlash( path, sizeof( path ) ); V_strcat( path, "index.html", sizeof(path) ); } if( filesystem->FileExists( path, NULL ) ) { const char *pExtension = V_GetFileExtension( path ); if( cef_scheme_debug_local_handler.GetBool() ) { Msg( "Local scheme request => Path: %s, Extension: %s, Mime Type: %s, modified path: %s, exists: %d, resource type: %d\n", CefString(&parts.path).ToString().c_str(), pExtension, CefGetMimeType(pExtension).ToString().c_str(), path, filesystem->FileExists( path ), request->GetResourceType() ); } CUtlBuffer buf( 0, filesystem->Size( path, NULL ) ); if( filesystem->ReadFile( path, NULL, buf ) ) { CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData( buf.Base(), buf.TellPut() ); if( stream != NULL ) { pResourceHandler = new CefStreamResourceHandler( CefGetMimeType(pExtension), stream ); } } } return pResourceHandler; }
void BrowserSchemeHandler::GetResponseHeaders(CefRefPtr<CefResponse> response, int64& response_length, CefString& redirectUrl) { if (!response) { response_length = -1; redirectUrl = ""; return; } std::string fileExtension = fileName.substr( fileName.find_last_of(".") + 1); std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower); response->SetStatus(200); response->SetMimeType(CefGetMimeType(fileExtension)); response->SetStatusText("OK"); response_length = length; redirectUrl = ""; }
CefRefPtr<CefResourceHandler> CCefApp::Create ( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& scheme_name, CefRefPtr<CefRequest> request ) { // browser or frame are NULL if the request does not orginate from a browser window // This is for exmaple true for the application cache or CEFURLRequests // (http://www.html5rocks.com/en/tutorials/appcache/beginner/) if ( !browser || !frame ) return nullptr; CWebCore* pWebCore = static_cast<CWebCore*> ( g_pCore->GetWebCore () ); auto pWebView = pWebCore->FindWebView ( browser ); if ( !pWebView || !pWebView->IsLocal () ) return nullptr; CefURLParts urlParts; if ( !CefParseURL ( request->GetURL (), urlParts ) ) return nullptr; if ( scheme_name == "mtalocal" ) // Backward compatibility { // Get full path SString path = UTF16ToMbUTF8 ( urlParts.path.str ).substr ( 2 ); // Check if we're dealing with an external resource if ( path[0] == ':' ) { size_t end = path.find_first_of ( '/' ); if ( end != std::string::npos ) { SString resourceName = path.substr ( 1, end-1 ); SString resourcePath = path.substr ( end ); // Call this function recursively and use the mta scheme instead request->SetURL ( "http://mta/local/" + resourceName + resourcePath ); return Create ( browser, frame, "http", request ); } return nullptr; } // Redirect mtalocal://* to http://mta/local/*, call recursively request->SetURL ( "http://mta/local/" + path ); return Create ( browser, frame, "http", request ); } SString host = UTF16ToMbUTF8 ( urlParts.host.str ); if ( scheme_name == "http" && host == "mta" ) { // Scheme format: http://mta/resourceName/file.html or http://mta/local/file.html for the current resource // Get resource name and path SString path = UTF16ToMbUTF8 ( urlParts.path.str ).substr ( 1 ); // Remove slash at the front size_t slashPos = path.find ( '/' ); if ( slashPos == std::string::npos ) return nullptr; SString resourceName = path.substr ( 0, slashPos ); SString resourcePath = path.substr ( slashPos + 1 ); if ( resourcePath.empty () ) return nullptr; // Get mime type from extension CefString mimeType; size_t pos = resourcePath.find_last_of ( '.' ); if ( pos != std::string::npos ) mimeType = CefGetMimeType ( resourcePath.substr ( pos + 1 ) ); // Make sure we provide a mime type, even // when we cannot deduct it from the file extension if ( mimeType.empty () ) mimeType = "application/octet-stream"; if ( pWebView->HasAjaxHandler ( resourcePath ) ) { std::vector<SString> vecGet; std::vector<SString> vecPost; if ( urlParts.query.str != nullptr ) { SString strGet = UTF16ToMbUTF8 ( urlParts.query.str ); std::vector<SString> vecTmp; strGet.Split ( "&", vecTmp ); SString key; SString value; for ( auto&& param : vecTmp ) { param.Split ( "=", &key, &value ); vecGet.push_back ( key ); vecGet.push_back ( value ); } } CefPostData::ElementVector vecPostElements; auto postData = request->GetPostData (); if ( postData.get () ) { request->GetPostData ()->GetElements ( vecPostElements ); SString key; SString value; for ( auto&& post : vecPostElements ) { // Limit to 5MiB and allow byte data only size_t bytesCount = post->GetBytesCount (); if ( bytesCount > 5*1024*1024 || post->GetType () != CefPostDataElement::Type::PDE_TYPE_BYTES ) continue; // Make string from buffer std::unique_ptr<char[]> buffer { new char[bytesCount] }; post->GetBytes ( bytesCount, buffer.get () ); SStringX param ( buffer.get (), bytesCount ); // Parse POST data into vector std::vector<SString> vecTmp; param.Split ( "&", vecTmp ); for ( auto&& param : vecTmp ) { param.Split ( "=", &key, &value ); vecPost.push_back ( key ); vecPost.push_back ( value ); } } } auto handler = new CAjaxResourceHandler ( vecGet, vecPost, mimeType ); pWebView->HandleAjaxRequest ( resourcePath, handler ); return handler; } else { // Calculate MTA resource path if ( resourceName != "local" ) path = ":" + resourceName + "/" + resourcePath; else path = resourcePath; // Calculate absolute path if ( !pWebView->GetFullPathFromLocal ( path ) ) return nullptr; // Finally, load the file stream auto stream = CefStreamReader::CreateForFile ( path ); if ( stream.get () ) return new CefStreamResourceHandler ( mimeType, stream ); } return nullptr; } // Return null if there is no matching scheme return nullptr; }