mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
This is the first pass in removing direct dependencies on the Alloy runtime from code that can potentially be shared between runtimes. CefBrowserHost and CefRequestContext APIs (including CefCookieManager, CefURLRequest, etc.) are not yet implemented for the Chrome runtime. Assert early if these API methods are called while the Chrome runtime is enabled.
205 lines
6.1 KiB
C++
205 lines
6.1 KiB
C++
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
|
|
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "libcef/browser/net/internal_scheme_handler.h"
|
|
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "libcef/common/app_manager.h"
|
|
|
|
#include "base/strings/string_util.h"
|
|
#include "base/strings/utf_string_conversions.h"
|
|
#include "base/threading/thread_restrictions.h"
|
|
#include "net/base/mime_util.h"
|
|
#include "ui/base/resource/resource_bundle.h"
|
|
|
|
namespace scheme {
|
|
|
|
namespace {
|
|
|
|
base::FilePath FilePathFromASCII(const std::string& str) {
|
|
#if defined(OS_WIN)
|
|
return base::FilePath(base::ASCIIToUTF16(str));
|
|
#else
|
|
return base::FilePath(str);
|
|
#endif
|
|
}
|
|
|
|
std::string GetMimeType(const std::string& filename) {
|
|
// Requests should not block on the disk! On POSIX this goes to disk.
|
|
// http://code.google.com/p/chromium/issues/detail?id=59849
|
|
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
|
|
|
std::string mime_type;
|
|
const base::FilePath& file_path = FilePathFromASCII(filename);
|
|
if (net::GetMimeTypeFromFile(file_path, &mime_type))
|
|
return mime_type;
|
|
|
|
// Check for newer extensions used by internal resources but not yet
|
|
// recognized by the mime type detector.
|
|
const std::string& extension = CefString(file_path.FinalExtension());
|
|
if (extension == ".woff2")
|
|
return "application/font-woff2";
|
|
|
|
NOTREACHED() << "No known mime type for file: " << filename.c_str();
|
|
return "text/plain";
|
|
}
|
|
|
|
class RedirectHandler : public CefResourceHandler {
|
|
public:
|
|
explicit RedirectHandler(const GURL& url) : url_(url) {}
|
|
|
|
bool Open(CefRefPtr<CefRequest> request,
|
|
bool& handle_request,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
// Continue immediately.
|
|
handle_request = true;
|
|
return true;
|
|
}
|
|
|
|
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
|
int64& response_length,
|
|
CefString& redirectUrl) override {
|
|
response_length = 0;
|
|
redirectUrl = url_.spec();
|
|
}
|
|
|
|
bool Read(void* data_out,
|
|
int bytes_to_read,
|
|
int& bytes_read,
|
|
CefRefPtr<CefResourceReadCallback> callback) override {
|
|
NOTREACHED();
|
|
return false;
|
|
}
|
|
|
|
void Cancel() override {}
|
|
|
|
private:
|
|
GURL url_;
|
|
|
|
IMPLEMENT_REFCOUNTING(RedirectHandler);
|
|
DISALLOW_COPY_AND_ASSIGN(RedirectHandler);
|
|
};
|
|
|
|
class InternalHandler : public CefResourceHandler {
|
|
public:
|
|
InternalHandler(const std::string& mime_type,
|
|
CefRefPtr<CefStreamReader> reader,
|
|
int size)
|
|
: mime_type_(mime_type), reader_(reader), size_(size) {}
|
|
|
|
bool Open(CefRefPtr<CefRequest> request,
|
|
bool& handle_request,
|
|
CefRefPtr<CefCallback> callback) override {
|
|
// Continue immediately.
|
|
handle_request = true;
|
|
return true;
|
|
}
|
|
|
|
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
|
int64& response_length,
|
|
CefString& redirectUrl) override {
|
|
response_length = size_;
|
|
|
|
response->SetMimeType(mime_type_);
|
|
response->SetStatus(200);
|
|
}
|
|
|
|
bool Read(void* data_out,
|
|
int bytes_to_read,
|
|
int& bytes_read,
|
|
CefRefPtr<CefResourceReadCallback> callback) override {
|
|
// Read until the buffer is full or until Read() returns 0 to indicate no
|
|
// more data.
|
|
bytes_read = 0;
|
|
int read = 0;
|
|
do {
|
|
read = static_cast<int>(
|
|
reader_->Read(static_cast<char*>(data_out) + bytes_read, 1,
|
|
bytes_to_read - bytes_read));
|
|
bytes_read += read;
|
|
} while (read != 0 && bytes_read < bytes_to_read);
|
|
|
|
return (bytes_read > 0);
|
|
}
|
|
|
|
void Cancel() override {}
|
|
|
|
private:
|
|
std::string mime_type_;
|
|
CefRefPtr<CefStreamReader> reader_;
|
|
int size_;
|
|
|
|
IMPLEMENT_REFCOUNTING(InternalHandler);
|
|
DISALLOW_COPY_AND_ASSIGN(InternalHandler);
|
|
};
|
|
|
|
class InternalHandlerFactory : public CefSchemeHandlerFactory {
|
|
public:
|
|
explicit InternalHandlerFactory(
|
|
std::unique_ptr<InternalHandlerDelegate> delegate)
|
|
: delegate_(std::move(delegate)) {}
|
|
|
|
CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
const CefString& scheme_name,
|
|
CefRefPtr<CefRequest> request) override {
|
|
GURL url = GURL(request->GetURL().ToString());
|
|
|
|
InternalHandlerDelegate::Action action;
|
|
if (delegate_->OnRequest(browser, request, &action)) {
|
|
if (!action.redirect_url.is_empty() && action.redirect_url.is_valid())
|
|
return new RedirectHandler(action.redirect_url);
|
|
|
|
if (action.mime_type.empty())
|
|
action.mime_type = GetMimeType(url.path());
|
|
|
|
if (!action.bytes && action.resource_id >= 0) {
|
|
action.bytes =
|
|
CefAppManager::Get()->GetContentClient()->GetDataResourceBytes(
|
|
action.resource_id);
|
|
if (!action.bytes) {
|
|
NOTREACHED() << "Failed to load internal resource for id: "
|
|
<< action.resource_id << " URL: " << url.spec().c_str();
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
if (action.bytes) {
|
|
action.stream = CefStreamReader::CreateForData(
|
|
const_cast<unsigned char*>(action.bytes->data()),
|
|
action.bytes->size());
|
|
action.stream_size = action.bytes->size();
|
|
}
|
|
|
|
if (action.stream.get()) {
|
|
return new InternalHandler(action.mime_type, action.stream,
|
|
action.stream_size);
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<InternalHandlerDelegate> delegate_;
|
|
|
|
IMPLEMENT_REFCOUNTING(InternalHandlerFactory);
|
|
DISALLOW_COPY_AND_ASSIGN(InternalHandlerFactory);
|
|
};
|
|
|
|
} // namespace
|
|
|
|
InternalHandlerDelegate::Action::Action() : stream_size(-1), resource_id(-1) {}
|
|
|
|
CefRefPtr<CefSchemeHandlerFactory> CreateInternalHandlerFactory(
|
|
std::unique_ptr<InternalHandlerDelegate> delegate) {
|
|
DCHECK(delegate.get());
|
|
return new InternalHandlerFactory(std::move(delegate));
|
|
}
|
|
|
|
} // namespace scheme
|