Пример #1
0
void CWebView::ConvertURL ( const CefString& url, SString& convertedURL )
{
    CefURLParts urlParts;
    if ( !CefParseURL ( url, urlParts ) )
    {
        convertedURL = "";
        return;
    }
    WString scheme = urlParts.scheme.str;
    
    if ( scheme == L"http" || scheme == L"https" )
    {
        convertedURL = UTF16ToMbUTF8 ( urlParts.spec.str );
    }
    else
    {
        // Get the file name (charsequence after last /)
        WString tempStr = urlParts.path.str;
        size_t pos = tempStr.find_last_of ( L"/" );

        if ( pos != std::wstring::npos && pos < tempStr.size () )
            convertedURL = UTF16ToMbUTF8 ( tempStr.SubStr ( pos + 1 ) );
        else
            convertedURL = "";
    }
}
Пример #2
0
////////////////////////////////////////////////////////////////////
//                                                                //
// Implementation: CefRequestHandler::OnBeforeResourceLoad        //
// http://magpcss.org/ceforum/apidocs3/projects/(default)/CefRequestHandler.html#OnBeforeResourceLoad(CefRefPtr%3CCefBrowser%3E,CefRefPtr%3CCefFrame%3E,CefRefPtr%3CCefRequest%3E) //
//                                                                //
////////////////////////////////////////////////////////////////////
bool CWebView::OnBeforeResourceLoad ( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request )
{
    // Mostly the same as CWebView::OnBeforeBrowse
    CefURLParts urlParts;
    if ( !CefParseURL ( request->GetURL (), urlParts ) )
        return true; // Cancel if invalid URL (this line will normally not be executed)

    WString scheme = urlParts.scheme.str;
    if ( scheme == L"http" || scheme == L"https" )
    {
        if ( IsLocal () )
            return true; // Block remote requests in local mode generally

        if ( g_pCore->GetWebCore ()->GetURLState ( UTF16ToMbUTF8 ( urlParts.host.str ) ) != eURLState::WEBPAGE_ALLOWED )
            return true; // Block if explicitly forbidden

        // Allow
        return false;
    }
    else if ( scheme == L"mtalocal" )
    {
        // Allow :)
        return false;
    }

    // Block everything else
    return true;
}
Пример #3
0
////////////////////////////////////////////////////////////////////
//                                                                //
// Implementation: CefRequestHandler::OnBeforeBrowe               //
// http://magpcss.org/ceforum/apidocs3/projects/(default)/CefRequestHandler.html#OnBeforeBrowse(CefRefPtr%3CCefBrowser%3E,CefRefPtr%3CCefFrame%3E,CefRefPtr%3CCefRequest%3E,bool) //
//                                                                //
////////////////////////////////////////////////////////////////////
bool CWebView::OnBeforeBrowse ( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool isRedirect )
{
    /*
        From documentation:
        The |request| object cannot be modified in this callback.
        CefLoadHandler::OnLoadingStateChange will be called twice in all cases. If the navigation is allowed CefLoadHandler::OnLoadStart and CefLoadHandler::OnLoadEnd will be called.
        If the navigation is canceled CefLoadHandler::OnLoadError will be called with an |errorCode| value of ERR_ABORTED. 
    */

    CefURLParts urlParts;
    if ( !CefParseURL ( request->GetURL(), urlParts ) )
        return true; // Cancel if invalid URL (this line will normally not be executed)
    
    WString scheme = urlParts.scheme.str;
    if ( scheme == L"http" || scheme == L"https" )
    {
        if ( IsLocal () )
            return true; // Block remote here requests generally

        if ( g_pCore->GetWebCore ()->GetURLState ( UTF16ToMbUTF8 ( urlParts.host.str ) ) != eURLState::WEBPAGE_ALLOWED )
            return true;

        return false;
    }
    else if ( scheme == L"mtalocal" )
        return false;
    
    // Block everything else
    return true;
}
Пример #4
0
SString CWebCore::GetDomainFromURL ( const SString& strURL )
{
    CefURLParts urlParts;
    if ( !CefParseURL ( strURL, urlParts ) || !urlParts.host.str )
        return "";

    return UTF16ToMbUTF8 ( urlParts.host.str );
}
Пример #5
0
CefRefPtr<CefResourceHandler> VTFSchemeHandlerFactory::Create(CefRefPtr<CefBrowser> browser,
											CefRefPtr<CefFrame> frame,
											const CefString& scheme_name,
											CefRefPtr<CefRequest> request)
{
	CefRefPtr<CefResourceHandler> pResourceHandler = NULL;

	CefURLParts parts;
	CefParseURL(request->GetURL(), parts);

	std::string strVtfPath = CefString(&parts.path);

	char vtfPath[MAX_PATH];
	V_snprintf( vtfPath, sizeof( vtfPath ), "materials/%s", strVtfPath.c_str() );
	V_FixupPathName( vtfPath, sizeof( vtfPath ), vtfPath );

	if (!filesystem->FileExists(vtfPath))
	{
		Warning( "VTFSchemeHandlerFactory: invalid vtf %s\n", vtfPath );
		return NULL;
	}

	CUtlBuffer imageDataBuffer( 0, filesystem->Size(vtfPath), 0 );
	if( !filesystem->ReadFile( vtfPath, NULL, imageDataBuffer ) ) 
	{
		Warning( "VTFSchemeHandlerFactory: failed to read vtf %s\n", vtfPath );
		return NULL;
	}

	IVTFTexture *pVTFTexture = CreateVTFTexture();
	if( pVTFTexture->Unserialize( imageDataBuffer ) )
	{
		pVTFTexture->ConvertImageFormat( IMAGE_FORMAT_RGB888, false, false );

		if( pVTFTexture->Format() == IMAGE_FORMAT_RGB888 )
		{
			uint8 *pImageData = pVTFTexture->ImageData();

			CUtlBuffer buf;
			VTFHandler_ConvertImageToJPG( buf, pImageData, pVTFTexture->Width(), pVTFTexture->Height() );

			if( buf.Size() > 0 )
			{
				CefRefPtr<CefStreamReader> stream =
					CefStreamReader::CreateForData(static_cast<void*>(buf.Base()), buf.Size());

				pResourceHandler = new CefStreamResourceHandler("image/jpeg", stream);
			}
		}
		else
		{
			Warning( "VTFSchemeHandlerFactory: unable to convert vtf %s to rgb format\n", vtfPath );
		}
	}
	DestroyVTFTexture( pVTFTexture );

	return pResourceHandler;
}
Пример #6
0
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;
}
Пример #7
0
bool CWebView::LoadURL ( const SString& strURL, bool bFilterEnabled, const SString& strPostData, bool bURLEncoded )
{
    if ( !m_pWebView )
        return false;

    CefURLParts urlParts;
    if ( !CefParseURL ( strURL, urlParts ) )
        return false; // Invalid URL

    // Are we allowed to browse this website?
    if ( bFilterEnabled && g_pCore->GetWebCore ()->GetURLState ( UTF16ToMbUTF8 ( urlParts.host.str ), true ) != eURLState::WEBPAGE_ALLOWED )
        return false;

    // Load it!
    auto pFrame = m_pWebView->GetMainFrame ();
    if ( strPostData.empty () )
    {
        pFrame->LoadURL ( strURL );
    }
    else
    {
        // Load URL first, see https://bitbucket.org/chromiumembedded/cef/issue/579
        pFrame->LoadURL ( "about:blank" );

        // Perform HTTP POST
        auto request = CefRequest::Create ();
        auto postData = CefPostData::Create ();
        auto postDataElement = CefPostDataElement::Create ();
        postDataElement->SetToBytes ( strPostData.size (), strPostData.c_str () );
        postData->AddElement ( postDataElement );

        if ( bURLEncoded )
        {
            CefRequest::HeaderMap headerMap;
            headerMap.insert ( std::make_pair ( "Content-Type", "application/x-www-form-urlencoded" ) );
            headerMap.insert ( std::make_pair ( "Content-Length", std::to_string ( strPostData.size () ) ) );
            //headerMap.insert ( std::make_pair ( "Connection", "close" ) );
            request->SetHeaderMap ( headerMap );
        }

        request->SetURL ( strURL );
        request->SetMethod ( "POST" );
        request->SetPostData ( postData );
        pFrame->LoadRequest ( request );
    }
   
    return true;
}
Пример #8
0
bool CWebView::LoadURL ( const SString& strURL, bool bFilterEnabled )
{
    if ( !m_pWebView )
        return false;

    CefURLParts urlParts;
    if ( !CefParseURL ( strURL, urlParts ) )
        return false; // Invalid URL

    // Are we allowed to browse this website?
    if ( bFilterEnabled && g_pCore->GetWebCore ()->GetURLState ( UTF16ToMbUTF8 ( urlParts.host.str ) ) != eURLState::WEBPAGE_ALLOWED )
        return false;

    // Load it!
    m_pWebView->GetMainFrame ()->LoadURL ( strURL );
   
    return true;
}
Пример #9
0
// First method called
bool BrowserSchemeHandler::ProcessRequest(CefRefPtr<CefRequest> request,
		CefRefPtr<CefCallback> callback)
{
	CefURLParts parts;
	CefParseURL(request->GetURL(), parts);

	std::string path = CefString(&parts.path);
	fileName = path.substr(path.find_last_of("/") + 1);

	inputStream.open(path, std::ifstream::binary);
	if (!inputStream.is_open()) {
		callback->Cancel();
		return false;
	}

	inputStream.seekg(0, std::ifstream::end);
	length = remaining = inputStream.tellg();
	inputStream.seekg(0, std::ifstream::beg);
	callback->Continue();
	return true;
}
Пример #10
0
////////////////////////////////////////////////////////////////////
//                                                                //
// Implementation: CefRequestHandler::OnBeforeBrowe               //
// http://magpcss.org/ceforum/apidocs3/projects/(default)/CefRequestHandler.html#OnBeforeBrowse(CefRefPtr%3CCefBrowser%3E,CefRefPtr%3CCefFrame%3E,CefRefPtr%3CCefRequest%3E,bool) //
//                                                                //
////////////////////////////////////////////////////////////////////
bool CWebView::OnBeforeBrowse ( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool isRedirect )
{
    /*
        From documentation:
        The |request| object cannot be modified in this callback.
        CefLoadHandler::OnLoadingStateChange will be called twice in all cases. If the navigation is allowed CefLoadHandler::OnLoadStart and CefLoadHandler::OnLoadEnd will be called.
        If the navigation is canceled CefLoadHandler::OnLoadError will be called with an |errorCode| value of ERR_ABORTED. 
    */

    CefURLParts urlParts;
    if ( !CefParseURL ( request->GetURL(), urlParts ) )
        return true; // Cancel if invalid URL (this line will normally not be executed)
    
    bool bResult;
    WString scheme = urlParts.scheme.str;
    if ( scheme == L"http" || scheme == L"https" )
    {
        SString host = UTF16ToMbUTF8 ( urlParts.host.str );
        if ( host != "mta" )
        {
            if ( IsLocal () || g_pCore->GetWebCore ()->GetURLState ( host, true ) != eURLState::WEBPAGE_ALLOWED )
                bResult = true; // Block remote here
            else
                bResult = false; // Allow
        }
        else
            bResult = false;
    }
    else if ( scheme == L"mtalocal" )
        bResult = false; // Allow mtalocal:// URLs
    else
        bResult = true; // Block other schemes
    
    // Queue event to run on the main thread
    auto func = std::bind ( &CWebBrowserEventsInterface::Events_OnNavigate, m_pEventsInterface, SString ( request->GetURL () ), bResult );
    g_pCore->GetWebCore ()->AddEventToEventQueue ( func, this, "OnNavigate" );

    // Return execution to CEF
    return bResult;
}
Пример #11
0
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;
}
Пример #12
0
////////////////////////////////////////////////////////////////////
//                                                                //
// Implementation: CefRequestHandler::OnBeforeResourceLoad        //
// http://magpcss.org/ceforum/apidocs3/projects/(default)/CefRequestHandler.html#OnBeforeResourceLoad(CefRefPtr%3CCefBrowser%3E,CefRefPtr%3CCefFrame%3E,CefRefPtr%3CCefRequest%3E) //
//                                                                //
////////////////////////////////////////////////////////////////////
CefRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad ( CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefRequestCallback> callback )
{
    // Mostly the same as CWebView::OnBeforeBrowse
    CefURLParts urlParts;
    if ( !CefParseURL ( request->GetURL (), urlParts ) )
        return RV_CANCEL; // Cancel if invalid URL (this line will normally not be executed)

    // Add some information to the HTTP header
    {
        CefRequest::HeaderMap headerMap;
        request->GetHeaderMap ( headerMap );
        auto iter = headerMap.find ( "User-Agent" );

        if ( iter != headerMap.end () )
        {
            // Add MTA:SA "watermark"
            iter->second = iter->second.ToString () + "; " MTA_CEF_USERAGENT;

            // Add 'Android' to get the mobile version
            SString strPropertyValue;
            if ( GetProperty ( "mobile", strPropertyValue ) && strPropertyValue == "1" )
                iter->second = iter->second.ToString () + "; Mobile Android";

            request->SetHeaderMap ( headerMap );
        }
    }

    WString scheme = urlParts.scheme.str;
    if ( scheme == L"http" || scheme == L"https" )
    {
        SString domain = UTF16ToMbUTF8 ( urlParts.host.str );
        if ( domain != "mta" )
        {
            if ( IsLocal () )
                return RV_CANCEL; // Block remote requests in local mode generally

            eURLState urlState = g_pCore->GetWebCore ()->GetURLState ( domain, true );
            if ( urlState != eURLState::WEBPAGE_ALLOWED )
            {
                // Trigger onClientBrowserResourceBlocked event
                auto func = std::bind ( &CWebBrowserEventsInterface::Events_OnResourceBlocked, m_pEventsInterface,
                    SString ( request->GetURL () ), domain, urlState == eURLState::WEBPAGE_NOT_LISTED ? 0 : 1 );
                g_pCore->GetWebCore ()->AddEventToEventQueue ( func, this, "OnResourceBlocked" );

                return RV_CANCEL; // Block if explicitly forbidden
            }

            // Allow
            return RV_CONTINUE;
        }
        else
            return RV_CONTINUE;
    }
    else if ( scheme == L"mtalocal" )
    {
        // Allow :)
        return RV_CONTINUE;
    }

     // Trigger onClientBrowserResourceBlocked event
    auto func = std::bind ( &CWebBrowserEventsInterface::Events_OnResourceBlocked, m_pEventsInterface, SString ( request->GetURL () ), "", 2 ); // reason 1 := blocked protocol scheme
    g_pCore->GetWebCore ()->AddEventToEventQueue ( func, this, "OnResourceBlocked" );

    // Block everything else
    return RV_CANCEL;
}
Пример #13
0
	virtual bool ProcessRequest(CefRefPtr<CefRequest> request, CefRefPtr<CefCallback> callback)
	{
		std::string url = request->GetURL();
		std::wstring hostname;
		std::wstring path;
		uint16_t port;

		CefURLParts parts;
		CefParseURL(url, parts);

		hostname = CefString(&parts.host);
		path = CefString(&parts.path);

		if (hostname == L"game")
		{
			filename_ = "citizen:/";
			
			filename_ += std::string(path.begin(), path.end());
		}
		else
		{
			filename_ = "resources:/";
			filename_ += std::string(hostname.begin(), hostname.end()) + "/";
			filename_ += std::string(path.begin(), path.end());
		}

		//filename_ = exeName + std::wstring(L"/citiv/ui/") + url.substr(11);

		// remove # parts
		auto hash = filename_.find_first_of(L'#');

		if (hash != std::string::npos)
		{
			//filename_.resize(hash);
			filename_.erase(hash);
		}

		hash = filename_.find_first_of(L'?');

		if (hash != std::string::npos)
		{
			//filename_.resize(hash);
			filename_.erase(hash);
		}

		//file_ = _wfopen(filename_.c_str(), "rb");
		device_ = rage::fiDevice::GetDevice(filename_.c_str(), true);
		
		if (device_)
		{
			file_ = device_->open(filename_.c_str(), true);
		}

		// set mime type
		std::string ext = url.substr(url.rfind('.') + 1);

		mimeType_ = "text/html";

		if (ext == "png")
		{
			mimeType_ = "image/png";
		}
		else if (ext == "js")
		{
			mimeType_ = "application/javascript";
		}
		else if (ext == "css")
		{
			mimeType_ = "text/css";
		}

		callback->Continue();

		return true;
	}