CEF: перенаправить или создать новый `CefResourceHandler` для запроса `file://` вместо этого использовать `https://'

CEF обрабатывает все относительные URL-адреса протокола как запрос file:// в моем локальном приложении, и я хочу перехватить и изменить его, чтобы вместо этого он указывал на https://.

Я перегрузил следующие два метода из CefRequestHandler:

  virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request);

  virtual cef_return_value_t OnBeforeResourceLoad(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefRequestCallback> callback);

Где cef_return_value_t определяется как:

typedef enum {
  ///
  // Cancel immediately.
  ///
  RV_CANCEL = 0,
  ///
  // Continue immediately.
  ///
  RV_CONTINUE,
  ///
  // Continue asynchronously (usually via a callback).
  ///
  RV_CONTINUE_ASYNC,
} cef_return_value_t;

В OnBeforeResourceLoad я могу только попросить CEF либо отменить, либо продолжить выполнение запроса. Итак, я возвращаюсь RV_CONTINUE.

А в GetResourceHandler я могу предоставить пользовательский CefResourceHandler.

Но проблема в том, что я не смог найти API CEF, который помог бы мне создать собственный обработчик запросов https://.


person jha-G    schedule 31.07.2018    source источник


Ответы (1)


В файле cef/tests/ceftests/navigation_unittest.cc следующий класс можно использовать в качестве ссылки для реализации файла RedirectRequestHandler. Вам необходимо изменить внутренние компоненты и использовать либо http:302, либо redirectUrl для перенаправления.

class RedirectSchemeHandler : public CefResourceHandler {
 public:
  RedirectSchemeHandler() : offset_(0), status_(0) {}

  bool ProcessRequest(CefRefPtr<CefRequest> request,
                      CefRefPtr<CefCallback> callback) override {
    EXPECT_TRUE(CefCurrentlyOn(TID_IO));

    std::string url = request->GetURL();
    if (url == kRNav1) {
      // Redirect using HTTP 302
      g_got_nav1_request = true;
      status_ = 302;
      location_ = kRNav2;
      content_ = "<html><body>Redirected Nav1</body></html>";
    } else if (url == kRNav3) {
      // Redirect using redirectUrl
      g_got_nav3_request = true;
      status_ = -1;
      location_ = kRNav4;
      content_ = "<html><body>Redirected Nav3</body></html>";
    } else if (url == kRNav4) {
      g_got_nav4_request = true;
      status_ = 200;
      content_ = "<html><body>Nav4</body></html>";
    }

    if (status_ != 0) {
      callback->Continue();
      return true;
    } else {
      g_got_invalid_request = true;
      return false;
    }
  }

  void GetResponseHeaders(CefRefPtr<CefResponse> response,
                          int64& response_length,
                          CefString& redirectUrl) override {
    EXPECT_TRUE(CefCurrentlyOn(TID_IO));

    EXPECT_NE(status_, 0);

    response->SetStatus(status_);
    response->SetMimeType("text/html");
    response_length = content_.size();

    if (status_ == 302) {
      // Redirect using HTTP 302
      EXPECT_GT(location_.size(), static_cast<size_t>(0));
      response->SetStatusText("Found");
      CefResponse::HeaderMap headers;
      response->GetHeaderMap(headers);
      headers.insert(std::make_pair("Location", location_));
      response->SetHeaderMap(headers);
    } else if (status_ == -1) {
      // Rdirect using redirectUrl
      EXPECT_GT(location_.size(), static_cast<size_t>(0));
      redirectUrl = location_;
    }
  }

  void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }

  bool ReadResponse(void* data_out,
                    int bytes_to_read,
                    int& bytes_read,
                    CefRefPtr<CefCallback> callback) override {
    EXPECT_TRUE(CefCurrentlyOn(TID_IO));

    size_t size = content_.size();
    if (offset_ < size) {
      int transfer_size =
          std::min(bytes_to_read, static_cast<int>(size - offset_));
      memcpy(data_out, content_.c_str() + offset_, transfer_size);
      offset_ += transfer_size;

      bytes_read = transfer_size;
      return true;
    }

    return false;
  }

 protected:
  std::string content_;
  size_t offset_;
  int status_;
  std::string location_;

  IMPLEMENT_REFCOUNTING(RedirectSchemeHandler);
};

И экземпляр RedirectSchemeHandler должен быть возвращен из следующего callback:

virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
          CefRefPtr<CefBrowser> browser,
          CefRefPtr<CefFrame> frame,
          CefRefPtr<CefRequest> request)
{
      return new RedirectSchemeHandler();
}
person jha-G    schedule 20.09.2018