Custom scheme handler ignored within iframe

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.

Custom scheme handler ignored within iframe

Postby Plinker1961 » Tue Oct 06, 2015 1:16 pm

I have added a custom scheme handler (named rtg) to our CEF application, whose job is to trigger certain application internal commands when triggered by the web site. For testing purposes, I have modified the other_tests.html page in cefclient and added the following entry after the client:// test:

Code: Select all
<li><a href="rtg://app/webcmd?action=login&accountname=gamer1&password=1111111111">RTG App Command</a></li>

This command works perfectly fine when the page is loaded as either HTTP or HTTPS. However, if the page is loaded within an iframe under HTTPS, I get this error:
[1006/140202:INFO:CONSOLE(0)] "Mixed Content: The page at 'https://localhost:2100/admin/other_tests2.html' was loaded over HTTPS, but requested an insecure resource 'rtg://app/webcmd?action=login&accountname=gamer1&password=1111111111'. This request has been blocked; the content must be served over HTTPS.", source: https://localhost:2100/admin/other_tests2.html (0)


Please note that other_tests2.html is as follows:
Code: Select all
<html>
<head>
<title>Other Tests 2</title>
</head>
<body bgcolor="white">
<iframe src=".\other_tests.html" />
</body>
</html>

Is this a known limitation of CEF custom schemes or am I doing something wrong? Any advice is appreciated.
Plinker1961
Mentor
 
Posts: 65
Joined: Thu Feb 26, 2015 5:14 pm

Re: Custom scheme handler ignored within iframe

Postby magreenblatt » Tue Oct 06, 2015 2:44 pm

When do you get this error? Is other_tests.html hosted at https://localhost:2100/admin/other_tests.html ? Are you then clicking the link to load the "rtg" URI?

What CEF version are you using? How did you register the "rtg" scheme?
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: Custom scheme handler ignored within iframe

Postby Plinker1961 » Tue Oct 06, 2015 3:03 pm

When do you get this error? Is other_tests.html hosted at https://localhost:2100/admin/other_tests.html ? Are you then clicking the link to load the "rtg" URI?

Yes to both.

What CEF version are you using?

3.2171.2069

How did you register the "rtg" scheme?

Pretty much exactly the same as in scheme_test:

Code: Select all
// Implementation of the schema handler for rtg:// requests.
class RTGSchemeHandler : public CefResourceHandler {
public:
    RTGSchemeHandler() {
    }

    virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
                                CefRefPtr<CefCallback> callback) OVERRIDE{
        CEF_REQUIRE_IO_THREAD();

        std::string url = request->GetURL();

        // TODO: pass RTG command to application

        // Return false so that nothing is loaded
        return false;
    }

    virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
                                    int64& response_length,
                                    CefString& redirectUrl) OVERRIDE {
        CEF_REQUIRE_IO_THREAD();

        response->SetMimeType("text/plain");
        response->SetStatus(200);
        response_length = 0;
    }

    virtual void Cancel() OVERRIDE {
        CEF_REQUIRE_IO_THREAD();
    }

    virtual bool ReadResponse(void* data_out,
                              int bytes_to_read,
                              int& bytes_read,
                              CefRefPtr<CefCallback> callback) OVERRIDE {
        CEF_REQUIRE_IO_THREAD();

        const bool has_data = false;
        bytes_read = 0;
        return has_data;
    }

private:
    IMPLEMENT_REFCOUNTING(RTGSchemeHandler);
};

// Implementation of the factory for for creating schema handlers.
class RTGSchemeHandlerFactory : public CefSchemeHandlerFactory {
public:
    // Return a new scheme handler instance to handle the request.
    virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
                                                 CefRefPtr<CefFrame> frame,
                                                 const CefString& scheme_name,
                                                 CefRefPtr<CefRequest> request) OVERRIDE {
        CEF_REQUIRE_IO_THREAD();
        return new RTGSchemeHandler();
    }

    IMPLEMENT_REFCOUNTING(RTGSchemeHandlerFactory);
};

void RegisterCustomSchemes(CefRefPtr<CefSchemeRegistrar> registrar,
                           std::vector<CefString>& cookiable_schemes) {
  registrar->AddCustomScheme("client", true, false, false);
  registrar->AddCustomScheme("rtg", true, false, false);
}

void InitTest() {
  CefRegisterSchemeHandlerFactory("client", "tests", new ClientSchemeHandlerFactory());
  CefRegisterSchemeHandlerFactory("rtg", "", new RTGSchemeHandlerFactory());
}


I have since found this post which seems to be the same issue: http://www.magpcss.org/ceforum/viewtopic.php?f=10&t=12325&p=23443

But like I said originally, this all works according to plan when not using iframe . . . or not using https.
Plinker1961
Mentor
 
Posts: 65
Joined: Thu Feb 26, 2015 5:14 pm

Re: Custom scheme handler ignored within iframe

Postby magreenblatt » Tue Oct 06, 2015 4:10 pm

Mixed content warnings are to be expected when you try to access non-HTTPS content from an HTTPS page. One possible fix is described in https://bitbucket.org/chromiumembedded/cef/issues/1723.
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: Custom scheme handler ignored within iframe

Postby Plinker1961 » Wed Oct 07, 2015 5:57 am

For now, I have been able to work around the issue by dropping my usage of custom schemes and changing all app command links to prefix the command with either http:// or https://, whichever is appropriate. As an example, here is the revised link/command shown previously:
Code: Select all
<li><a href="https://rtg//app/webcmd?action=login&accountname=gamer1&password=1111111111">RTG App Command</a></li>

I then process the command within ClientHandler::OnBeforeBrowse as follows:
Code: Select all
bool ClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                                   CefRefPtr<CefFrame> frame,
                                   CefRefPtr<CefRequest> request,
                                   bool is_redirect) {
  CEF_REQUIRE_UI_THREAD();

  // Check to see if new page is actually an RTG application command
  bool isRTGCommand = false;
  CefString rtgCmd;
  CefString cefURL = request->GetURL();
  std::string sURL = cefURL.ToString();
  if (isRTGCommand = (sURL.substr(0, 3).compare("rtg") == 0))
  {
      rtgCmd = cefURL;
  }
  else if (isRTGCommand = (sURL.substr(0, 12).compare("http://rtg//") == 0))
  {
      rtgCmd = "rtg://" + sURL.substr(12);
  }
  else if (isRTGCommand = (sURL.substr(0, 13).compare("https://rtg//") == 0))
  {
      rtgCmd = "rtg://" + sURL.substr(13);
  }

  if (isRTGCommand)
  {
      HWND hwndClientHandler = GetMainWindowHandle();
      LPARAM lparam = reinterpret_cast<LPARAM>(_wcsdup(rtgCmd.c_str()));
      PostMessage(hwndClientHandler, RTG_OPENURI, 0, lparam);
      return true;
  }

  message_router_->OnBeforeBrowse(browser, frame);
  return false;
}

It's admittedly a bit of a hack, but it gets me around the issue for now. The far better and cleaner solution is to have schemes treated as secure. You can vote to support this feature here: https://bitbucket.org/chromiumembedded/cef/issues/1723
Plinker1961
Mentor
 
Posts: 65
Joined: Thu Feb 26, 2015 5:14 pm


Return to Support Forum

Who is online

Users browsing this forum: No registered users and 36 guests