URLRequestFilter with CEF?

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

URLRequestFilter with CEF?

Postby heshiming » Fri Jul 31, 2009 2:11 am

Hi,

I'm hoping to use CEF for my project. One of the requirement is custom URL scheme handling. I consulted the source code of "chromium testshell". It looked pretty straightforward. I could just do these:

URLRequestFilter* filter = URLRequestFilter::GetInstance();
filter->AddHostnameHandler("myscheme", "myserver", &MyCustomURLRequestJob::Factory);
url_util::AddStandardScheme("myscheme");

With an implementation based on URLRequestJob, I have been able to use "myscheme://myserver/" to serve my custom content (based on testshell of course).

I'm wondering if this is possible with CEF. CEF seemed to have encapsulated everything inside chromium. It doesn't appear to have an interface for URL handlers...
heshiming
Techie
 
Posts: 29
Joined: Fri Jul 31, 2009 1:59 am

Re: URLRequestFilter with CEF?

Postby magreenblatt » Wed Aug 05, 2009 2:21 am

You're correct that CEF does not currently have an interface for custom URL scheme handlers. I think this would be a good feature to add. I've created an issue on the CEF project site to track this enhancement: http://code.google.com/p/chromiumembedd ... tail?id=49

If you would like to implement this functionality in CEF I would be happy to provide guidance.
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: URLRequestFilter with CEF?

Postby heshiming » Wed Aug 05, 2009 7:07 am

Thanks for getting back to me.

I've actually half-way done developing this scheme handler. It's not that difficult given the TestShell sample and URLRequestTestShellFileJob . I've followed your implementation of C API, CtoCPP, and CPPtoC marshaling . So it'll look like the rest of CEF. I'd love to share it and I'll prepare something to upload at the Modification section of the forum in a few days. I think this will be a great addition and hopefully be a part of the official CEF.

Incidentally, I'm compiling against the latest chromium revision. Signatures of several methods have changed since July 24. Affected ones are:

browser_resource_loader_bridge.cc , line 170, around "void NotifyReceivedRedirect", the signature of RequestProxy::NotifyReceivedRedirect now becomes: (const GURL& new_url, const ResourceLoaderBridge::ResponseInfo& info) . This method is called at line 271, and implemented at line 356.

browser_webkit_init.h , class BrowserWebKitInit : public webkit_glue::WebKitClientImpl now requires 2 additional methods: virtual WebKit::WebMessagePortChannel* createMessagePortChannel() , and virtual bool sandboxEnabled() .

And lots of vsprops files are removed, affected ones are:

$(SolutionDir)..\webkit\build\webkit_common_defines.vsprops;
$(SolutionDir)..\webkit\build\js_engine$(JS_ENGINE_TYPE).vsprops;

They caused some glitches in pre-processor macro definitions. And I have to redefine them directly in the project. This would be just a quick note to you if you would like to update chromium revision.
heshiming
Techie
 
Posts: 29
Joined: Fri Jul 31, 2009 1:59 am

Re: URLRequestFilter with CEF?

Postby magreenblatt » Wed Aug 05, 2009 7:33 am

Thanks! I'll likely update the CEF project early next week. Did you use the translator tool to generate the CppToC/CToCpp bindings? Did it handle the conversion correctly?
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: URLRequestFilter with CEF?

Postby heshiming » Wed Aug 05, 2009 9:25 pm

Oops, I didn't see the translator tool. My binding/wrapper is hand-written. My scheme api.h and impl.cc files are separate from existing CEF files to avoid problems when the CEF source requires an update.

I tried to specify the parameter of the translator tool like this:

Code: Select all
..\..\third_party\python_24\python.exe translator.py --cpp-header ..\libcef\scheme\cef_scheme.h --capi-header ..\libcef_dll\scheme\cef_scheme_api.h --cpptoc-dir ..\libcef_dll\cpptoc --ctocpp-dir ..\libcef_dll\ctocpp


It doesn't seemed to work, no bindings are generated, only the api is generated, but with no actual interface definitions of mine. It only contains the cef_base structure.

cef_scheme.h is as below:
Code: Select all
#ifndef _CEF_SCHEME_H
#define _CEF_SCHEME_H

#include <string>
#include "include/cef.h"
#include "include/cef_ptr.h"
#include "include/cef_types.h"

class CefSchemeHandler;

bool CefRegisterScheme(   const std::string& scheme_name,
                                    const std::string& host_name,
                                    CefRefPtr<CefSchemeHandler> handler);

class CefSchemeHandler : public CefBase
{
public:
   virtual void Begin() = 0;
   virtual void StorePostData(const int type, const std::wstring& file, const std::vector<char>& data) = 0;
   virtual bool ProcessRequest(const std::string& url) = 0;
   virtual void End() = 0;
   virtual void Cancel() = 0;
   virtual int GetLength() = 0;
   virtual void* GetData() = 0;
   virtual char* GetMimeType() = 0;
   virtual bool Lock(bool bWrite) = 0;
   virtual bool Unlock(bool bWrite) = 0;
};

#endif

p.s. this is changing as we speak.
heshiming
Techie
 
Posts: 29
Joined: Fri Jul 31, 2009 1:59 am

Re: URLRequestFilter with CEF?

Postby magreenblatt » Thu Aug 06, 2009 2:08 am

You need to add the special /*--cef()--*/ comment before each function, class and method declaration. See include/cef.h for an example and the HEADER ATTRIBUTES section of tools/translator.README.txt for a detailed description.
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: URLRequestFilter with CEF?

Postby magreenblatt » Thu Aug 06, 2009 2:23 am

Depending on how the post data is provided by URLRequestFilter, you might want to use a CefPostData or CefPostDataElement object as the argument for StorePostData() instead of your current arguments. The implementations of CefPostData and CefPostDataElement provide methods for converting to/from net::UploadData and WebKit::WebHTTPBody objects.

Also, we don't use data pointers as return values in CEF so your declarations of GetData() and GetMimeType() will be a problem. See CefPostDataElement for an example of how CEF returns byte arrays and strings.
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: URLRequestFilter with CEF?

Postby heshiming » Fri Aug 07, 2009 1:59 am

I see, thanks for the info. I've changed the definition to the following:
Code: Select all
#ifndef _CEF_SCHEME_H
#define _CEF_SCHEME_H

#include <string>
#include "include/cef.h"
#include "include/cef_ptr.h"
#include "include/cef_types.h"

class CefSchemeHandler;

// Register a custom scheme handler using the CefSchemeHandler interface
// Custom scheme in the format of scheme_name://host_name/ will be handled through
// the specified handler interface.
// All URLs beginning with scheme_name://host_name/ will go through this handler
/*--cef()--*/
bool CefRegisterScheme(   const std::wstring& scheme_name,
                                    const std::wstring& host_name,
                                    CefRefPtr<CefSchemeHandler> handler);

// Class used to represent a custom scheme handler interface.
/*--cef(source=client)--*/
class CefSchemeHandler : public CefBase
{
public:
   // Tell handler to process an incoming request
   /*--cef()--*/
   virtual bool ProcessRequest(CefRefPtr<CefRequest> request) = 0;

   // Tell handler to cancel the process of current request
   /*--cef()--*/
   virtual void Cancel() = 0;

   // Let handler specify the mime type of the current request
   /*--cef()--*/
   virtual std::wstring GetMimeType() = 0;

   // Let handler specify the response length of the current request.
   // Handler may return 0 if no response is returned, ReadResponse won't be called
   // Handler may return -1 if length is unknown, ReadResponse will be called until it returns false, or *bytes_read=0
   // Handler may return a positive number for length, ReadResponse will be called until it returns false, or *bytes_read=0, or remaining_bytes_=0
   /*--cef()--*/
   virtual size_t GetResponseLength() = 0;

   // Tell handler to copy the response to data_out, for the length of bytes_to_read
   // Handler may return false to indicate a failure, in which case ReadResponse won't be called again
   // Handler may return true to indicate successful read, in which case, handler must set
   // *bytes_read to the actual number of bytes copied. This value is used to determine whether
   // additional response will be read.
   /*--cef()--*/
   virtual bool ReadResponse(void* data_out, int bytes_to_read, int *bytes_read) = 0;

   // Handler's implementation of locking, mainly used for read/write the response content
   /*--cef()--*/
   virtual bool Lock(bool write_lock) = 0;

   // Handler's implementation of unlocking, mainly used for read/write the response content
   /*--cef()--*/
   virtual bool Unlock(bool write_lock) = 0;
};

#endif


The translator script seemed to have worked properly. Binding templates are generated, which is way easier to work with. I found out that you've already written a CefRequest class that's wraps everything. CefPostDataImpl::Set works flawlessly for net::UploadData. It's good for scheme handler too. No separate StorePostData would be needed.
heshiming
Techie
 
Posts: 29
Joined: Fri Jul 31, 2009 1:59 am

Re: URLRequestFilter with CEF?

Postby heshiming » Fri Aug 07, 2009 8:26 am

Hi, I've uploaded what I've done so far at the modifications forum. Thanks for the help.
heshiming
Techie
 
Posts: 29
Joined: Fri Jul 31, 2009 1:59 am


Return to Support Forum

Who is online

Users browsing this forum: Biohazard, Majestic-12 [Bot] and 68 guests