mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-17 20:50:42 +01:00
Add CefServer API for handling HTTP/WebSocket requests (issue #2278)
This commit is contained in:
parent
39e689d80a
commit
4b39753c41
2
BUILD.gn
2
BUILD.gn
@ -523,6 +523,8 @@ static_library("libcef_static") {
|
||||
"libcef/browser/request_context_impl.cc",
|
||||
"libcef/browser/request_context_impl.h",
|
||||
"libcef/browser/scheme_impl.cc",
|
||||
"libcef/browser/server_impl.cc",
|
||||
"libcef/browser/server_impl.h",
|
||||
"libcef/browser/speech_recognition_manager_delegate.cc",
|
||||
"libcef/browser/speech_recognition_manager_delegate.h",
|
||||
"libcef/browser/ssl_host_state_delegate.cc",
|
||||
|
@ -8,7 +8,7 @@
|
||||
# by hand. See the translator.README.txt file in the tools directory for
|
||||
# more information.
|
||||
#
|
||||
# $hash=2a6e7c37a8421d3c0d032cc907fb3058790ac71d$
|
||||
# $hash=a508906eb96c55e83eda7f17639a9ddcc0632f45$
|
||||
#
|
||||
|
||||
{
|
||||
@ -67,6 +67,7 @@
|
||||
'include/cef_response.h',
|
||||
'include/cef_response_filter.h',
|
||||
'include/cef_scheme.h',
|
||||
'include/cef_server.h',
|
||||
'include/cef_ssl_info.h',
|
||||
'include/cef_ssl_status.h',
|
||||
'include/cef_stream.h',
|
||||
@ -159,6 +160,7 @@
|
||||
'include/capi/cef_response_capi.h',
|
||||
'include/capi/cef_response_filter_capi.h',
|
||||
'include/capi/cef_scheme_capi.h',
|
||||
'include/capi/cef_server_capi.h',
|
||||
'include/capi/cef_ssl_info_capi.h',
|
||||
'include/capi/cef_ssl_status_capi.h',
|
||||
'include/capi/cef_stream_capi.h',
|
||||
@ -390,6 +392,10 @@
|
||||
'libcef_dll/cpptoc/views/scroll_view_cpptoc.h',
|
||||
'libcef_dll/cpptoc/select_client_certificate_callback_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/select_client_certificate_callback_cpptoc.h',
|
||||
'libcef_dll/cpptoc/server_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/server_cpptoc.h',
|
||||
'libcef_dll/ctocpp/server_handler_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/server_handler_ctocpp.h',
|
||||
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/set_cookie_callback_ctocpp.h',
|
||||
'libcef_dll/cpptoc/stream_reader_cpptoc.cc',
|
||||
@ -672,6 +678,10 @@
|
||||
'libcef_dll/ctocpp/views/scroll_view_ctocpp.h',
|
||||
'libcef_dll/ctocpp/select_client_certificate_callback_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/select_client_certificate_callback_ctocpp.h',
|
||||
'libcef_dll/ctocpp/server_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/server_ctocpp.h',
|
||||
'libcef_dll/cpptoc/server_handler_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/server_handler_cpptoc.h',
|
||||
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/set_cookie_callback_cpptoc.h',
|
||||
'libcef_dll/ctocpp/stream_reader_ctocpp.cc',
|
||||
|
@ -240,6 +240,8 @@
|
||||
'tests/cefclient/browser/root_window_manager.h',
|
||||
'tests/cefclient/browser/scheme_test.cc',
|
||||
'tests/cefclient/browser/scheme_test.h',
|
||||
'tests/cefclient/browser/server_test.cc',
|
||||
'tests/cefclient/browser/server_test.h',
|
||||
'tests/cefclient/browser/temp_window.h',
|
||||
'tests/cefclient/browser/test_runner.cc',
|
||||
'tests/cefclient/browser/test_runner.h',
|
||||
@ -278,8 +280,10 @@
|
||||
'tests/cefclient/resources/performance2.html',
|
||||
'tests/cefclient/resources/preferences.html',
|
||||
'tests/cefclient/resources/response_filter.html',
|
||||
'tests/cefclient/resources/server.html',
|
||||
'tests/cefclient/resources/transparency.html',
|
||||
'tests/cefclient/resources/urlrequest.html',
|
||||
'tests/cefclient/resources/websocket.html',
|
||||
'tests/cefclient/resources/window.html',
|
||||
'tests/cefclient/resources/xmlhttprequest.html',
|
||||
],
|
||||
@ -464,6 +468,7 @@
|
||||
'tests/ceftests/run_all_unittests.cc',
|
||||
'tests/ceftests/scheme_handler_unittest.cc',
|
||||
'tests/ceftests/scoped_temp_dir_unittest.cc',
|
||||
'tests/ceftests/server_unittest.cc',
|
||||
'tests/ceftests/stream_unittest.cc',
|
||||
'tests/ceftests/stream_resource_handler_unittest.cc',
|
||||
'tests/ceftests/string_unittest.cc',
|
||||
|
@ -64,6 +64,16 @@ typedef int int32;
|
||||
typedef unsigned int uint32;
|
||||
#endif
|
||||
|
||||
#ifndef _INT16
|
||||
#define _INT16
|
||||
typedef short int16;
|
||||
#endif
|
||||
|
||||
#ifndef _UINT16
|
||||
#define _UINT16
|
||||
typedef unsigned short uint16;
|
||||
#endif
|
||||
|
||||
// UTF-16 character type.
|
||||
// This should be kept synchronized with base/strings/string16.h
|
||||
#ifndef char16
|
||||
|
@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=81e857497b1f5e1732af7fca2250edf78c0e5415$
|
||||
// $hash=35342e59ba48fc8b9783fae8e04ddc36448f72d2$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
|
||||
@ -244,7 +244,7 @@ typedef struct _cef_request_context_t {
|
||||
///
|
||||
// Clears all active and idle connections that Chromium currently has. This is
|
||||
// only recommended if you have released all other CEF objects but don't yet
|
||||
// want to call cef_shutdown(). If |callback| is non-NULL it will be executed
|
||||
// want to call Cefshutdown(). If |callback| is non-NULL it will be executed
|
||||
// on the UI thread after completion.
|
||||
///
|
||||
void(CEF_CALLBACK* close_all_connections)(
|
||||
|
327
include/capi/cef_server_capi.h
Normal file
327
include/capi/cef_server_capi.h
Normal file
@ -0,0 +1,327 @@
|
||||
// Copyright (c) 2017 Marshall A. Greenblatt. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||
// Framework nor the names of its contributors may be used to endorse
|
||||
// or promote products derived from this software without specific prior
|
||||
// written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool and should not edited
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=92c646f789ec75664bf0c9f6bc21a44ff75686cf$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_SERVER_CAPI_H_
|
||||
#define CEF_INCLUDE_CAPI_CEF_SERVER_CAPI_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/capi/cef_base_capi.h"
|
||||
#include "include/capi/cef_callback_capi.h"
|
||||
#include "include/capi/cef_request_capi.h"
|
||||
#include "include/capi/cef_task_capi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _cef_server_handler_t;
|
||||
|
||||
///
|
||||
// Structure representing a server that supports HTTP and WebSocket requests.
|
||||
// Server capacity is limited and is intended to handle only a small number of
|
||||
// simultaneous connections (e.g. for communicating between applications on
|
||||
// localhost). The functions of this structure are safe to call from any thread
|
||||
// in the brower process unless otherwise indicated.
|
||||
///
|
||||
typedef struct _cef_server_t {
|
||||
///
|
||||
// Base structure.
|
||||
///
|
||||
cef_base_ref_counted_t base;
|
||||
|
||||
///
|
||||
// Returns the task runner for the dedicated server thread.
|
||||
///
|
||||
struct _cef_task_runner_t*(CEF_CALLBACK* get_task_runner)(
|
||||
struct _cef_server_t* self);
|
||||
|
||||
///
|
||||
// Stop the server and shut down the dedicated server thread. See
|
||||
// cef_server_handler_t::OnServerCreated documentation for a description of
|
||||
// server lifespan.
|
||||
///
|
||||
void(CEF_CALLBACK* shutdown)(struct _cef_server_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if the server is currently running and accepting incoming
|
||||
// connections. See cef_server_handler_t::OnServerCreated documentation for a
|
||||
// description of server lifespan. This function must be called on the
|
||||
// dedicated server thread.
|
||||
///
|
||||
int(CEF_CALLBACK* is_running)(struct _cef_server_t* self);
|
||||
|
||||
///
|
||||
// Returns the server address including the port number.
|
||||
///
|
||||
// The resulting string must be freed by calling cef_string_userfree_free().
|
||||
cef_string_userfree_t(CEF_CALLBACK* get_address)(struct _cef_server_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if the server currently has a connection. This function
|
||||
// must be called on the dedicated server thread.
|
||||
///
|
||||
int(CEF_CALLBACK* has_connection)(struct _cef_server_t* self);
|
||||
|
||||
///
|
||||
// Returns true (1) if |connection_id| represents a valid connection. This
|
||||
// function must be called on the dedicated server thread.
|
||||
///
|
||||
int(CEF_CALLBACK* is_valid_connection)(struct _cef_server_t* self,
|
||||
int connection_id);
|
||||
|
||||
///
|
||||
// Send an HTTP 200 "OK" response to the connection identified by
|
||||
// |connection_id|. |content_type| is the response content type (e.g.
|
||||
// "text/html"), |data| is the response content, and |data_size| is the size
|
||||
// of |data| in bytes. The contents of |data| will be copied. The connection
|
||||
// will be closed automatically after the response is sent.
|
||||
///
|
||||
void(CEF_CALLBACK* send_http200response)(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const cef_string_t* content_type,
|
||||
const void* data,
|
||||
size_t data_size);
|
||||
|
||||
///
|
||||
// Send an HTTP 404 "Not Found" response to the connection identified by
|
||||
// |connection_id|. The connection will be closed automatically after the
|
||||
// response is sent.
|
||||
///
|
||||
void(CEF_CALLBACK* send_http404response)(struct _cef_server_t* self,
|
||||
int connection_id);
|
||||
|
||||
///
|
||||
// Send an HTTP 500 "Internal Server Error" response to the connection
|
||||
// identified by |connection_id|. |error_message| is the associated error
|
||||
// message. The connection will be closed automatically after the response is
|
||||
// sent.
|
||||
///
|
||||
void(CEF_CALLBACK* send_http500response)(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const cef_string_t* error_message);
|
||||
|
||||
///
|
||||
// Send a custom HTTP response to the connection identified by
|
||||
// |connection_id|. |response_code| is the HTTP response code sent in the
|
||||
// status line (e.g. 200), |content_type| is the response content type sent as
|
||||
// the "Content-Type" header (e.g. "text/html"), |content_length| is the
|
||||
// expected content length, and |extra_headers| is the map of extra response
|
||||
// headers. If |content_length| is >= 0 then the "Content-Length" header will
|
||||
// be sent. If |content_length| is 0 then no content is expected and the
|
||||
// connection will be closed automatically after the response is sent. If
|
||||
// |content_length| is < 0 then no "Content-Length" header will be sent and
|
||||
// the client will continue reading until the connection is closed. Use the
|
||||
// SendRawData function to send the content, if applicable, and call
|
||||
// CloseConnection after all content has been sent.
|
||||
///
|
||||
void(CEF_CALLBACK* send_http_response)(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
int response_code,
|
||||
const cef_string_t* content_type,
|
||||
int64 content_length,
|
||||
cef_string_multimap_t extra_headers);
|
||||
|
||||
///
|
||||
// Send raw data directly to the connection identified by |connection_id|.
|
||||
// |data| is the raw data and |data_size| is the size of |data| in bytes. The
|
||||
// contents of |data| will be copied. No validation of |data| is performed
|
||||
// internally so the client should be careful to send the amount indicated by
|
||||
// the "Content-Length" header, if specified. See SendHttpResponse
|
||||
// documentation for intended usage.
|
||||
///
|
||||
void(CEF_CALLBACK* send_raw_data)(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size);
|
||||
|
||||
///
|
||||
// Close the connection identified by |connection_id|. See SendHttpResponse
|
||||
// documentation for intended usage.
|
||||
///
|
||||
void(CEF_CALLBACK* close_connection)(struct _cef_server_t* self,
|
||||
int connection_id);
|
||||
|
||||
///
|
||||
// Send a WebSocket message to the connection identified by |connection_id|.
|
||||
// |data| is the response content and |data_size| is the size of |data| in
|
||||
// bytes. The contents of |data| will be copied. See
|
||||
// cef_server_handler_t::OnWebSocketRequest documentation for intended usage.
|
||||
///
|
||||
void(CEF_CALLBACK* send_web_socket_message)(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size);
|
||||
} cef_server_t;
|
||||
|
||||
///
|
||||
// Create a new server that binds to |address| and |port|. |address| must be a
|
||||
// valid IPv4 or IPv6 address (e.g. 127.0.0.1 or ::1) and |port| must be a port
|
||||
// number outside of the reserved range (e.g. between 1025 and 65535 on most
|
||||
// platforms). |backlog| is the maximum number of pending connections. A new
|
||||
// thread will be created for each CreateServer call (the "dedicated server
|
||||
// thread"). It is therefore recommended to use a different cef_server_handler_t
|
||||
// instance for each CreateServer call to avoid thread safety issues in the
|
||||
// cef_server_handler_t implementation. The
|
||||
// cef_server_handler_t::OnServerCreated function will be called on the
|
||||
// dedicated server thread to report success or failure. See
|
||||
// cef_server_handler_t::OnServerCreated documentation for a description of
|
||||
// server lifespan.
|
||||
///
|
||||
CEF_EXPORT void cef_server_create(const cef_string_t* address,
|
||||
uint16 port,
|
||||
int backlog,
|
||||
struct _cef_server_handler_t* handler);
|
||||
|
||||
///
|
||||
// Implement this structure to handle HTTP server requests. A new thread will be
|
||||
// created for each cef_server_t::CreateServer call (the "dedicated server
|
||||
// thread"), and the functions of this structure will be called on that thread.
|
||||
// It is therefore recommended to use a different cef_server_handler_t instance
|
||||
// for each cef_server_t::CreateServer call to avoid thread safety issues in the
|
||||
// cef_server_handler_t implementation.
|
||||
///
|
||||
typedef struct _cef_server_handler_t {
|
||||
///
|
||||
// Base structure.
|
||||
///
|
||||
cef_base_ref_counted_t base;
|
||||
|
||||
///
|
||||
// Called when |server| is created. If the server was started successfully
|
||||
// then cef_server_t::IsRunning will return true (1). The server will continue
|
||||
// running until cef_server_t::Shutdown is called, after which time
|
||||
// OnServerDestroyed will be called. If the server failed to start then
|
||||
// OnServerDestroyed will be called immediately after this function returns.
|
||||
///
|
||||
void(CEF_CALLBACK* on_server_created)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server);
|
||||
|
||||
///
|
||||
// Called when |server| is destroyed. The server thread will be stopped after
|
||||
// this function returns. The client should release any references to |server|
|
||||
// when this function is called. See OnServerCreated documentation for a
|
||||
// description of server lifespan.
|
||||
///
|
||||
void(CEF_CALLBACK* on_server_destroyed)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server);
|
||||
|
||||
///
|
||||
// Called when a client connects to |server|. |connection_id| uniquely
|
||||
// identifies the connection. Each call to this function will have a matching
|
||||
// call to OnClientDisconnected.
|
||||
///
|
||||
void(CEF_CALLBACK* on_client_connected)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server,
|
||||
int connection_id);
|
||||
|
||||
///
|
||||
// Called when a client disconnects from |server|. |connection_id| uniquely
|
||||
// identifies the connection. The client should release any data associated
|
||||
// with |connection_id| when this function is called and |connection_id|
|
||||
// should no longer be passed to cef_server_t functions. Disconnects can
|
||||
// originate from either the client or the server. For example, the server
|
||||
// will disconnect automatically after a cef_server_t::SendHttpXXXResponse
|
||||
// function is called.
|
||||
///
|
||||
void(CEF_CALLBACK* on_client_disconnected)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server,
|
||||
int connection_id);
|
||||
|
||||
///
|
||||
// Called when |server| receives an HTTP request. |connection_id| uniquely
|
||||
// identifies the connection, |client_address| is the requesting IPv4 or IPv6
|
||||
// client address including port number, and |request| contains the request
|
||||
// contents (URL, function, headers and optional POST data). Call cef_server_t
|
||||
// functions either synchronously or asynchronusly to send a response.
|
||||
///
|
||||
void(CEF_CALLBACK* on_http_request)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server,
|
||||
int connection_id,
|
||||
const cef_string_t* client_address,
|
||||
struct _cef_request_t* request);
|
||||
|
||||
///
|
||||
// Called when |server| receives a WebSocket request. |connection_id| uniquely
|
||||
// identifies the connection, |client_address| is the requesting IPv4 or IPv6
|
||||
// client address including port number, and |request| contains the request
|
||||
// contents (URL, function, headers and optional POST data). Execute
|
||||
// |callback| either synchronously or asynchronously to accept or decline the
|
||||
// WebSocket connection. If the request is accepted then OnWebSocketConnected
|
||||
// will be called after the WebSocket has connected and incoming messages will
|
||||
// be delivered to the OnWebSocketMessage callback. If the request is declined
|
||||
// then the client will be disconnected and OnClientDisconnected will be
|
||||
// called. Call the cef_server_t::SendWebSocketMessage function after
|
||||
// receiving the OnWebSocketConnected callback to respond with WebSocket
|
||||
// messages.
|
||||
///
|
||||
void(CEF_CALLBACK* on_web_socket_request)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server,
|
||||
int connection_id,
|
||||
const cef_string_t* client_address,
|
||||
struct _cef_request_t* request,
|
||||
struct _cef_callback_t* callback);
|
||||
|
||||
///
|
||||
// Called after the client has accepted the WebSocket connection for |server|
|
||||
// and |connection_id| via the OnWebSocketRequest callback. See
|
||||
// OnWebSocketRequest documentation for intended usage.
|
||||
///
|
||||
void(CEF_CALLBACK* on_web_socket_connected)(
|
||||
struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server,
|
||||
int connection_id);
|
||||
|
||||
///
|
||||
// Called when |server| receives an WebSocket message. |connection_id|
|
||||
// uniquely identifies the connection, |data| is the message content and
|
||||
// |data_size| is the size of |data| in bytes. Do not keep a reference to
|
||||
// |data| outside of this function. See OnWebSocketRequest documentation for
|
||||
// intended usage.
|
||||
///
|
||||
void(CEF_CALLBACK* on_web_socket_message)(struct _cef_server_handler_t* self,
|
||||
struct _cef_server_t* server,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size);
|
||||
} cef_server_handler_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CEF_INCLUDE_CAPI_CEF_SERVER_CAPI_H_
|
315
include/cef_server.h
Normal file
315
include/cef_server.h
Normal file
@ -0,0 +1,315 @@
|
||||
// Copyright (c) 2017 Marshall A. Greenblatt. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||
// Framework nor the names of its contributors may be used to endorse
|
||||
// or promote products derived from this software without specific prior
|
||||
// written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// The contents of this file must follow a specific format in order to
|
||||
// support the CEF translator tool. See the translator.README.txt file in the
|
||||
// tools directory for more information.
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CEF_SERVER_H_
|
||||
#define CEF_INCLUDE_CEF_SERVER_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_callback.h"
|
||||
#include "include/cef_request.h"
|
||||
#include "include/cef_task.h"
|
||||
|
||||
class CefServerHandler;
|
||||
|
||||
///
|
||||
// Class representing a server that supports HTTP and WebSocket requests. Server
|
||||
// capacity is limited and is intended to handle only a small number of
|
||||
// simultaneous connections (e.g. for communicating between applications on
|
||||
// localhost). The methods of this class are safe to call from any thread in the
|
||||
// brower process unless otherwise indicated.
|
||||
///
|
||||
/*--cef(source=library)--*/
|
||||
class CefServer : public CefBaseRefCounted {
|
||||
public:
|
||||
typedef std::multimap<CefString, CefString> HeaderMap;
|
||||
|
||||
///
|
||||
// Create a new server that binds to |address| and |port|. |address| must be a
|
||||
// valid IPv4 or IPv6 address (e.g. 127.0.0.1 or ::1) and |port| must be a
|
||||
// port number outside of the reserved range (e.g. between 1025 and 65535 on
|
||||
// most platforms). |backlog| is the maximum number of pending connections.
|
||||
// A new thread will be created for each CreateServer call (the "dedicated
|
||||
// server thread"). It is therefore recommended to use a different
|
||||
// CefServerHandler instance for each CreateServer call to avoid thread safety
|
||||
// issues in the CefServerHandler implementation. The
|
||||
// CefServerHandler::OnServerCreated method will be called on the dedicated
|
||||
// server thread to report success or failure. See
|
||||
// CefServerHandler::OnServerCreated documentation for a description of server
|
||||
// lifespan.
|
||||
///
|
||||
/*--cef()--*/
|
||||
static void CreateServer(const CefString& address,
|
||||
uint16 port,
|
||||
int backlog,
|
||||
CefRefPtr<CefServerHandler> handler);
|
||||
|
||||
///
|
||||
// Returns the task runner for the dedicated server thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual CefRefPtr<CefTaskRunner> GetTaskRunner() = 0;
|
||||
|
||||
///
|
||||
// Stop the server and shut down the dedicated server thread. See
|
||||
// CefServerHandler::OnServerCreated documentation for a description of
|
||||
// server lifespan.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
///
|
||||
// Returns true if the server is currently running and accepting incoming
|
||||
// connections. See CefServerHandler::OnServerCreated documentation for a
|
||||
// description of server lifespan. This method must be called on the dedicated
|
||||
// server thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsRunning() = 0;
|
||||
|
||||
///
|
||||
// Returns the server address including the port number.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual CefString GetAddress() = 0;
|
||||
|
||||
///
|
||||
// Returns true if the server currently has a connection. This method must be
|
||||
// called on the dedicated server thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool HasConnection() = 0;
|
||||
|
||||
///
|
||||
// Returns true if |connection_id| represents a valid connection. This method
|
||||
// must be called on the dedicated server thread.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsValidConnection(int connection_id) = 0;
|
||||
|
||||
///
|
||||
// Send an HTTP 200 "OK" response to the connection identified by
|
||||
// |connection_id|. |content_type| is the response content type (e.g.
|
||||
// "text/html"), |data| is the response content, and |data_size| is the size
|
||||
// of |data| in bytes. The contents of |data| will be copied. The connection
|
||||
// will be closed automatically after the response is sent.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SendHttp200Response(int connection_id,
|
||||
const CefString& content_type,
|
||||
const void* data,
|
||||
size_t data_size) = 0;
|
||||
|
||||
///
|
||||
// Send an HTTP 404 "Not Found" response to the connection identified by
|
||||
// |connection_id|. The connection will be closed automatically after the
|
||||
// response is sent.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SendHttp404Response(int connection_id) = 0;
|
||||
|
||||
///
|
||||
// Send an HTTP 500 "Internal Server Error" response to the connection
|
||||
// identified by |connection_id|. |error_message| is the associated error
|
||||
// message. The connection will be closed automatically after the response is
|
||||
// sent.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SendHttp500Response(int connection_id,
|
||||
const CefString& error_message) = 0;
|
||||
|
||||
///
|
||||
// Send a custom HTTP response to the connection identified by
|
||||
// |connection_id|. |response_code| is the HTTP response code sent in the
|
||||
// status line (e.g. 200), |content_type| is the response content type sent
|
||||
// as the "Content-Type" header (e.g. "text/html"), |content_length| is the
|
||||
// expected content length, and |extra_headers| is the map of extra response
|
||||
// headers. If |content_length| is >= 0 then the "Content-Length" header will
|
||||
// be sent. If |content_length| is 0 then no content is expected and the
|
||||
// connection will be closed automatically after the response is sent. If
|
||||
// |content_length| is < 0 then no "Content-Length" header will be sent and
|
||||
// the client will continue reading until the connection is closed. Use the
|
||||
// SendRawData method to send the content, if applicable, and call
|
||||
// CloseConnection after all content has been sent.
|
||||
///
|
||||
/*--cef(optional_param=extra_headers)--*/
|
||||
virtual void SendHttpResponse(int connection_id,
|
||||
int response_code,
|
||||
const CefString& content_type,
|
||||
int64 content_length,
|
||||
const HeaderMap& extra_headers) = 0;
|
||||
|
||||
///
|
||||
// Send raw data directly to the connection identified by |connection_id|.
|
||||
// |data| is the raw data and |data_size| is the size of |data| in bytes.
|
||||
// The contents of |data| will be copied. No validation of |data| is
|
||||
// performed internally so the client should be careful to send the amount
|
||||
// indicated by the "Content-Length" header, if specified. See
|
||||
// SendHttpResponse documentation for intended usage.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SendRawData(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) = 0;
|
||||
|
||||
///
|
||||
// Close the connection identified by |connection_id|. See SendHttpResponse
|
||||
// documentation for intended usage.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void CloseConnection(int connection_id) = 0;
|
||||
|
||||
///
|
||||
// Send a WebSocket message to the connection identified by |connection_id|.
|
||||
// |data| is the response content and |data_size| is the size of |data| in
|
||||
// bytes. The contents of |data| will be copied. See
|
||||
// CefServerHandler::OnWebSocketRequest documentation for intended usage.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SendWebSocketMessage(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) = 0;
|
||||
};
|
||||
|
||||
///
|
||||
// Implement this interface to handle HTTP server requests. A new thread will be
|
||||
// created for each CefServer::CreateServer call (the "dedicated server
|
||||
// thread"), and the methods of this class will be called on that thread. It is
|
||||
// therefore recommended to use a different CefServerHandler instance for each
|
||||
// CefServer::CreateServer call to avoid thread safety issues in the
|
||||
// CefServerHandler implementation.
|
||||
///
|
||||
/*--cef(source=client)--*/
|
||||
class CefServerHandler : public virtual CefBaseRefCounted {
|
||||
public:
|
||||
///
|
||||
// Called when |server| is created. If the server was started successfully
|
||||
// then CefServer::IsRunning will return true. The server will continue
|
||||
// running until CefServer::Shutdown is called, after which time
|
||||
// OnServerDestroyed will be called. If the server failed to start then
|
||||
// OnServerDestroyed will be called immediately after this method returns.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnServerCreated(CefRefPtr<CefServer> server) = 0;
|
||||
|
||||
///
|
||||
// Called when |server| is destroyed. The server thread will be stopped after
|
||||
// this method returns. The client should release any references to |server|
|
||||
// when this method is called. See OnServerCreated documentation for a
|
||||
// description of server lifespan.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnServerDestroyed(CefRefPtr<CefServer> server) = 0;
|
||||
|
||||
///
|
||||
// Called when a client connects to |server|. |connection_id| uniquely
|
||||
// identifies the connection. Each call to this method will have a matching
|
||||
// call to OnClientDisconnected.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnClientConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) = 0;
|
||||
|
||||
///
|
||||
// Called when a client disconnects from |server|. |connection_id| uniquely
|
||||
// identifies the connection. The client should release any data associated
|
||||
// with |connection_id| when this method is called and |connection_id| should
|
||||
// no longer be passed to CefServer methods. Disconnects can originate from
|
||||
// either the client or the server. For example, the server will disconnect
|
||||
// automatically after a CefServer::SendHttpXXXResponse method is called.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) = 0;
|
||||
|
||||
///
|
||||
// Called when |server| receives an HTTP request. |connection_id| uniquely
|
||||
// identifies the connection, |client_address| is the requesting IPv4 or IPv6
|
||||
// client address including port number, and |request| contains the request
|
||||
// contents (URL, method, headers and optional POST data). Call CefServer
|
||||
// methods either synchronously or asynchronusly to send a response.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnHttpRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request) = 0;
|
||||
|
||||
///
|
||||
// Called when |server| receives a WebSocket request. |connection_id| uniquely
|
||||
// identifies the connection, |client_address| is the requesting IPv4 or
|
||||
// IPv6 client address including port number, and |request| contains the
|
||||
// request contents (URL, method, headers and optional POST data). Execute
|
||||
// |callback| either synchronously or asynchronously to accept or decline the
|
||||
// WebSocket connection. If the request is accepted then OnWebSocketConnected
|
||||
// will be called after the WebSocket has connected and incoming messages will
|
||||
// be delivered to the OnWebSocketMessage callback. If the request is declined
|
||||
// then the client will be disconnected and OnClientDisconnected will be
|
||||
// called. Call the CefServer::SendWebSocketMessage method after receiving the
|
||||
// OnWebSocketConnected callback to respond with WebSocket messages.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnWebSocketRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) = 0;
|
||||
|
||||
///
|
||||
// Called after the client has accepted the WebSocket connection for |server|
|
||||
// and |connection_id| via the OnWebSocketRequest callback. See
|
||||
// OnWebSocketRequest documentation for intended usage.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnWebSocketConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) = 0;
|
||||
|
||||
///
|
||||
// Called when |server| receives an WebSocket message. |connection_id|
|
||||
// uniquely identifies the connection, |data| is the message content and
|
||||
// |data_size| is the size of |data| in bytes. Do not keep a reference to
|
||||
// |data| outside of this method. See OnWebSocketRequest documentation for
|
||||
// intended usage.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnWebSocketMessage(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) = 0;
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_SERVER_H_
|
643
libcef/browser/server_impl.cc
Normal file
643
libcef/browser/server_impl.cc
Normal file
@ -0,0 +1,643 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework 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/server_impl.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/request_impl.h"
|
||||
#include "libcef/common/task_runner_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/format_macros.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/http/http_request_headers.h"
|
||||
#include "net/server/http_server_request_info.h"
|
||||
#include "net/server/http_server_response_info.h"
|
||||
#include "net/socket/server_socket.h"
|
||||
#include "net/socket/tcp_server_socket.h"
|
||||
|
||||
#define CEF_CURRENTLY_ON_HT() CurrentlyOnHandlerThread()
|
||||
#define CEF_REQUIRE_HT() DCHECK(CEF_CURRENTLY_ON_HT())
|
||||
|
||||
#define CEF_REQUIRE_HT_RETURN(var) \
|
||||
if (!CEF_CURRENTLY_ON_HT()) { \
|
||||
NOTREACHED() << "called on invalid thread"; \
|
||||
return var; \
|
||||
}
|
||||
|
||||
#define CEF_REQUIRE_HT_RETURN_VOID() \
|
||||
if (!CEF_CURRENTLY_ON_HT()) { \
|
||||
NOTREACHED() << "called on invalid thread"; \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define CEF_POST_TASK_HT(task) task_runner_->PostTask(FROM_HERE, task);
|
||||
|
||||
namespace {
|
||||
|
||||
// Wrap a string in a unique_ptr to avoid extra copies.
|
||||
std::unique_ptr<std::string> CreateUniqueString(const void* data,
|
||||
size_t data_size) {
|
||||
std::unique_ptr<std::string> ptr;
|
||||
if (data && data_size > 0) {
|
||||
ptr.reset(new std::string(static_cast<const char*>(data), data_size));
|
||||
} else {
|
||||
ptr.reset(new std::string());
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequest> CreateRequest(const std::string& address,
|
||||
const net::HttpServerRequestInfo& info,
|
||||
bool is_websocket) {
|
||||
DCHECK(!address.empty());
|
||||
DCHECK(!info.method.empty());
|
||||
DCHECK(!info.path.empty());
|
||||
|
||||
CefRefPtr<CefPostData> post_data;
|
||||
if (!info.data.empty()) {
|
||||
post_data = CefPostData::Create();
|
||||
CefRefPtr<CefPostDataElement> post_element = CefPostDataElement::Create();
|
||||
post_element->SetToBytes(info.data.size(), info.data.data());
|
||||
post_data->AddElement(post_element);
|
||||
}
|
||||
|
||||
CefRequest::HeaderMap header_map;
|
||||
if (!info.headers.empty()) {
|
||||
net::HttpServerRequestInfo::HeadersMap::const_iterator it =
|
||||
info.headers.begin();
|
||||
for (; it != info.headers.end(); ++it) {
|
||||
header_map.insert(std::make_pair(it->first, it->second));
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestImpl> request = new CefRequestImpl();
|
||||
request->Set((is_websocket ? "ws://" : "http://") + address + info.path,
|
||||
info.method, post_data, header_map);
|
||||
request->SetReadOnly(true);
|
||||
return request;
|
||||
}
|
||||
|
||||
// Callback implementation for WebSocket acceptance. Always executes on the UI
|
||||
// thread so we can avoid multiple execution by clearing the |impl_| reference.
|
||||
class AcceptWebSocketCallback : public CefCallback {
|
||||
public:
|
||||
AcceptWebSocketCallback(CefRefPtr<CefServerImpl> impl,
|
||||
int connection_id,
|
||||
net::HttpServerRequestInfo request_info)
|
||||
: impl_(impl),
|
||||
connection_id_(connection_id),
|
||||
request_info_(request_info) {}
|
||||
|
||||
~AcceptWebSocketCallback() override {
|
||||
if (impl_)
|
||||
impl_->ContinueWebSocketRequest(connection_id_, request_info_, false);
|
||||
}
|
||||
|
||||
void Continue() override {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&AcceptWebSocketCallback::Continue, this));
|
||||
return;
|
||||
}
|
||||
if (!impl_)
|
||||
return;
|
||||
impl_->ContinueWebSocketRequest(connection_id_, request_info_, true);
|
||||
impl_ = nullptr;
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&AcceptWebSocketCallback::Cancel, this));
|
||||
return;
|
||||
}
|
||||
if (!impl_)
|
||||
return;
|
||||
impl_->ContinueWebSocketRequest(connection_id_, request_info_, false);
|
||||
impl_ = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<CefServerImpl> impl_;
|
||||
int connection_id_;
|
||||
net::HttpServerRequestInfo request_info_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(AcceptWebSocketCallback);
|
||||
DISALLOW_COPY_AND_ASSIGN(AcceptWebSocketCallback);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// CefServer
|
||||
|
||||
// static
|
||||
void CefServer::CreateServer(const CefString& address,
|
||||
uint16 port,
|
||||
int backlog,
|
||||
CefRefPtr<CefServerHandler> handler) {
|
||||
CefRefPtr<CefServerImpl> server(new CefServerImpl(handler));
|
||||
server->Start(address, port, backlog);
|
||||
}
|
||||
|
||||
// CefServerImpl
|
||||
|
||||
struct CefServerImpl::ConnectionInfo {
|
||||
ConnectionInfo() : is_websocket(false), is_websocket_pending(false) {}
|
||||
|
||||
// True if this connection is a WebSocket connection.
|
||||
bool is_websocket;
|
||||
bool is_websocket_pending;
|
||||
};
|
||||
|
||||
CefServerImpl::CefServerImpl(CefRefPtr<CefServerHandler> handler)
|
||||
: handler_(handler) {
|
||||
DCHECK(handler_);
|
||||
}
|
||||
|
||||
void CefServerImpl::Start(const std::string& address,
|
||||
uint16 port,
|
||||
int backlog) {
|
||||
DCHECK(!address.empty());
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefServerImpl::StartOnUIThread, this,
|
||||
address, port, backlog));
|
||||
}
|
||||
|
||||
CefRefPtr<CefTaskRunner> CefServerImpl::GetTaskRunner() {
|
||||
if (task_runner_)
|
||||
return new CefTaskRunnerImpl(task_runner_);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefServerImpl::Shutdown() {
|
||||
CEF_POST_TASK_HT(
|
||||
base::BindOnce(&CefServerImpl::ShutdownOnHandlerThread, this));
|
||||
}
|
||||
|
||||
bool CefServerImpl::IsRunning() {
|
||||
CEF_REQUIRE_HT_RETURN(false);
|
||||
return !!server_.get();
|
||||
}
|
||||
|
||||
CefString CefServerImpl::GetAddress() {
|
||||
return address_;
|
||||
}
|
||||
|
||||
bool CefServerImpl::HasConnection() {
|
||||
CEF_REQUIRE_HT_RETURN(false);
|
||||
return !connection_info_map_.empty();
|
||||
}
|
||||
|
||||
bool CefServerImpl::IsValidConnection(int connection_id) {
|
||||
CEF_REQUIRE_HT_RETURN(false);
|
||||
return connection_info_map_.find(connection_id) != connection_info_map_.end();
|
||||
}
|
||||
|
||||
void CefServerImpl::SendHttp200Response(int connection_id,
|
||||
const CefString& content_type,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
SendHttp200ResponseInternal(connection_id, content_type,
|
||||
CreateUniqueString(data, data_size));
|
||||
}
|
||||
|
||||
void CefServerImpl::SendHttp404Response(int connection_id) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::SendHttp404Response, this,
|
||||
connection_id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (info->is_websocket) {
|
||||
LOG(ERROR) << "Invalid attempt to send HTTP response for connection_id "
|
||||
<< connection_id;
|
||||
return;
|
||||
}
|
||||
|
||||
server_->Send404(connection_id);
|
||||
server_->Close(connection_id);
|
||||
}
|
||||
|
||||
void CefServerImpl::SendHttp500Response(int connection_id,
|
||||
const CefString& error_message) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::SendHttp500Response, this,
|
||||
connection_id, error_message));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (info->is_websocket) {
|
||||
LOG(ERROR) << "Invalid attempt to send HTTP response for connection_id "
|
||||
<< connection_id;
|
||||
return;
|
||||
}
|
||||
|
||||
server_->Send500(connection_id, error_message);
|
||||
server_->Close(connection_id);
|
||||
}
|
||||
|
||||
void CefServerImpl::SendHttpResponse(int connection_id,
|
||||
int response_code,
|
||||
const CefString& content_type,
|
||||
int64 content_length,
|
||||
const HeaderMap& extra_headers) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::SendHttpResponse, this,
|
||||
connection_id, response_code, content_type,
|
||||
content_length, extra_headers));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (info->is_websocket) {
|
||||
LOG(ERROR) << "Invalid attempt to send HTTP response for connection_id "
|
||||
<< connection_id;
|
||||
return;
|
||||
}
|
||||
|
||||
net::HttpServerResponseInfo response(
|
||||
static_cast<net::HttpStatusCode>(response_code));
|
||||
|
||||
HeaderMap::const_iterator it = extra_headers.begin();
|
||||
for (; it != extra_headers.end(); ++it)
|
||||
response.AddHeader(it->first, it->second);
|
||||
|
||||
response.AddHeader(net::HttpRequestHeaders::kContentType, content_type);
|
||||
if (content_length >= 0) {
|
||||
response.AddHeader(
|
||||
net::HttpRequestHeaders::kContentLength,
|
||||
base::StringPrintf("%" PRIuS, static_cast<size_t>(content_length)));
|
||||
}
|
||||
|
||||
server_->SendResponse(connection_id, response);
|
||||
if (content_length == 0) {
|
||||
server_->Close(connection_id);
|
||||
}
|
||||
}
|
||||
|
||||
void CefServerImpl::SendRawData(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
if (!data || data_size == 0)
|
||||
return;
|
||||
SendRawDataInternal(connection_id, CreateUniqueString(data, data_size));
|
||||
}
|
||||
|
||||
void CefServerImpl::CloseConnection(int connection_id) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(
|
||||
base::BindOnce(&CefServerImpl::CloseConnection, this, connection_id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ValidateServer() && GetConnectionInfo(connection_id)) {
|
||||
server_->Close(connection_id);
|
||||
}
|
||||
}
|
||||
|
||||
void CefServerImpl::SendWebSocketMessage(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
if (!data || data_size == 0)
|
||||
return;
|
||||
SendWebSocketMessageInternal(connection_id,
|
||||
CreateUniqueString(data, data_size));
|
||||
}
|
||||
|
||||
void CefServerImpl::ContinueWebSocketRequest(
|
||||
int connection_id,
|
||||
const net::HttpServerRequestInfo& request_info,
|
||||
bool allow) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::ContinueWebSocketRequest,
|
||||
this, connection_id, request_info, allow));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
DCHECK(info);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
DCHECK(info->is_websocket);
|
||||
DCHECK(info->is_websocket_pending);
|
||||
if (!info->is_websocket || !info->is_websocket_pending)
|
||||
return;
|
||||
|
||||
info->is_websocket_pending = false;
|
||||
|
||||
if (allow) {
|
||||
server_->AcceptWebSocket(connection_id, request_info);
|
||||
handler_->OnWebSocketConnected(this, connection_id);
|
||||
} else {
|
||||
server_->Close(connection_id);
|
||||
}
|
||||
}
|
||||
|
||||
void CefServerImpl::SendHttp200ResponseInternal(
|
||||
int connection_id,
|
||||
const CefString& content_type,
|
||||
std::unique_ptr<std::string> data) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::SendHttp200ResponseInternal,
|
||||
this, connection_id, content_type,
|
||||
base::Passed(std::move(data))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (info->is_websocket) {
|
||||
LOG(ERROR) << "Invalid attempt to send HTTP response for connection_id "
|
||||
<< connection_id;
|
||||
return;
|
||||
}
|
||||
|
||||
server_->Send200(connection_id, *data, content_type);
|
||||
server_->Close(connection_id);
|
||||
}
|
||||
|
||||
void CefServerImpl::SendRawDataInternal(int connection_id,
|
||||
std::unique_ptr<std::string> data) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::SendRawDataInternal, this,
|
||||
connection_id,
|
||||
base::Passed(std::move(data))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
if (!GetConnectionInfo(connection_id))
|
||||
return;
|
||||
|
||||
server_->SendRaw(connection_id, *data);
|
||||
}
|
||||
|
||||
void CefServerImpl::SendWebSocketMessageInternal(
|
||||
int connection_id,
|
||||
std::unique_ptr<std::string> data) {
|
||||
if (!CEF_CURRENTLY_ON_HT()) {
|
||||
CEF_POST_TASK_HT(
|
||||
base::BindOnce(&CefServerImpl::SendWebSocketMessageInternal, this,
|
||||
connection_id, base::Passed(std::move(data))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateServer())
|
||||
return;
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (!info->is_websocket || info->is_websocket_pending) {
|
||||
LOG(ERROR) << "Invalid attempt to send WebSocket message for connection_id "
|
||||
<< connection_id;
|
||||
return;
|
||||
}
|
||||
|
||||
server_->SendOverWebSocket(connection_id, *data);
|
||||
}
|
||||
|
||||
void CefServerImpl::OnConnect(int connection_id) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
CreateConnectionInfo(connection_id);
|
||||
handler_->OnClientConnected(this, connection_id);
|
||||
}
|
||||
|
||||
void CefServerImpl::OnHttpRequest(
|
||||
int connection_id,
|
||||
const net::HttpServerRequestInfo& request_info) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
DCHECK(info);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
DCHECK(!info->is_websocket);
|
||||
|
||||
handler_->OnHttpRequest(this, connection_id, request_info.peer.ToString(),
|
||||
CreateRequest(address_, request_info, false));
|
||||
}
|
||||
|
||||
void CefServerImpl::OnWebSocketRequest(
|
||||
int connection_id,
|
||||
const net::HttpServerRequestInfo& request_info) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
DCHECK(info);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
DCHECK(!info->is_websocket);
|
||||
info->is_websocket = true;
|
||||
info->is_websocket_pending = true;
|
||||
|
||||
// Will eventually result in a call to ContinueWebSocketRequest.
|
||||
CefRefPtr<CefCallback> callback =
|
||||
new AcceptWebSocketCallback(this, connection_id, request_info);
|
||||
handler_->OnWebSocketRequest(
|
||||
this, connection_id, request_info.peer.ToString(),
|
||||
CreateRequest(address_, request_info, true), callback);
|
||||
}
|
||||
|
||||
void CefServerImpl::OnWebSocketMessage(int connection_id,
|
||||
const std::string& data) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
ConnectionInfo* info = GetConnectionInfo(connection_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
DCHECK(info->is_websocket);
|
||||
DCHECK(!info->is_websocket_pending);
|
||||
|
||||
handler_->OnWebSocketMessage(this, connection_id, data.data(), data.size());
|
||||
}
|
||||
|
||||
void CefServerImpl::OnClose(int connection_id) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
RemoveConnectionInfo(connection_id);
|
||||
handler_->OnClientDisconnected(this, connection_id);
|
||||
}
|
||||
|
||||
void CefServerImpl::StartOnUIThread(const std::string& address,
|
||||
uint16 port,
|
||||
int backlog) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!thread_);
|
||||
|
||||
std::unique_ptr<base::Thread> thread(
|
||||
new base::Thread(base::StringPrintf("%s:%d", address.c_str(), port)));
|
||||
base::Thread::Options options;
|
||||
options.message_loop_type = base::MessageLoop::TYPE_IO;
|
||||
if (thread->StartWithOptions(options)) {
|
||||
// Add a reference that will be released in ShutdownOnUIThread().
|
||||
AddRef();
|
||||
|
||||
thread_ = std::move(thread);
|
||||
task_runner_ = thread_->task_runner();
|
||||
|
||||
CEF_POST_TASK_HT(base::BindOnce(&CefServerImpl::StartOnHandlerThread, this,
|
||||
address, port, backlog));
|
||||
}
|
||||
}
|
||||
|
||||
void CefServerImpl::StartOnHandlerThread(const std::string& address,
|
||||
uint16 port,
|
||||
int backlog) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
std::unique_ptr<net::ServerSocket> socket(
|
||||
new net::TCPServerSocket(nullptr, net::NetLogSource()));
|
||||
if (socket->ListenWithAddressAndPort(address, port, backlog) == net::OK) {
|
||||
server_.reset(new net::HttpServer(std::move(socket), this));
|
||||
|
||||
net::IPEndPoint address;
|
||||
if (server_->GetLocalAddress(&address) == net::OK)
|
||||
address_ = address.ToString();
|
||||
}
|
||||
|
||||
handler_->OnServerCreated(this);
|
||||
|
||||
if (!server_) {
|
||||
// Server failed to start.
|
||||
handler_->OnServerDestroyed(this);
|
||||
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&CefServerImpl::ShutdownOnUIThread, this));
|
||||
}
|
||||
}
|
||||
|
||||
void CefServerImpl::ShutdownOnHandlerThread() {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
if (server_) {
|
||||
// Stop the server.
|
||||
server_.reset();
|
||||
|
||||
if (!connection_info_map_.empty()) {
|
||||
// Clear |connection_info_map_| first so any calls from
|
||||
// OnClientDisconnected will fail as expected.
|
||||
ConnectionInfoMap temp_map;
|
||||
temp_map.swap(connection_info_map_);
|
||||
|
||||
// OnClose won't be called for clients that are connected when the server
|
||||
// shuts down, so send the disconnected notification here.
|
||||
ConnectionInfoMap::const_iterator it = temp_map.begin();
|
||||
for (; it != temp_map.end(); ++it) {
|
||||
handler_->OnClientDisconnected(this, it->first);
|
||||
}
|
||||
}
|
||||
|
||||
handler_->OnServerDestroyed(this);
|
||||
}
|
||||
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&CefServerImpl::ShutdownOnUIThread, this));
|
||||
}
|
||||
|
||||
void CefServerImpl::ShutdownOnUIThread() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
handler_ = nullptr;
|
||||
|
||||
if (thread_) {
|
||||
// Stop the handler thread as a background task so the UI thread isn't
|
||||
// blocked.
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
|
||||
BindOnce([](std::unique_ptr<base::Thread>) {}, std::move(thread_)));
|
||||
|
||||
// Release the reference that was added in StartupOnUIThread().
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
bool CefServerImpl::ValidateServer() const {
|
||||
CEF_REQUIRE_HT();
|
||||
if (!server_) {
|
||||
LOG(ERROR) << "Server is not running";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CefServerImpl::ConnectionInfo* CefServerImpl::CreateConnectionInfo(
|
||||
int connection_id) {
|
||||
CEF_REQUIRE_HT();
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
ConnectionInfoMap::const_iterator it =
|
||||
connection_info_map_.find(connection_id);
|
||||
DCHECK(it == connection_info_map_.end());
|
||||
#endif
|
||||
|
||||
ConnectionInfo* info = new ConnectionInfo();
|
||||
connection_info_map_.insert(
|
||||
std::make_pair(connection_id, base::WrapUnique(info)));
|
||||
return info;
|
||||
}
|
||||
|
||||
CefServerImpl::ConnectionInfo* CefServerImpl::GetConnectionInfo(
|
||||
int connection_id) const {
|
||||
CEF_REQUIRE_HT();
|
||||
ConnectionInfoMap::const_iterator it =
|
||||
connection_info_map_.find(connection_id);
|
||||
if (it != connection_info_map_.end())
|
||||
return it->second.get();
|
||||
|
||||
LOG(ERROR) << "Invalid connection_id " << connection_id;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefServerImpl::RemoveConnectionInfo(int connection_id) {
|
||||
CEF_REQUIRE_HT();
|
||||
ConnectionInfoMap::iterator it = connection_info_map_.find(connection_id);
|
||||
DCHECK(it != connection_info_map_.end());
|
||||
if (it != connection_info_map_.end())
|
||||
connection_info_map_.erase(it);
|
||||
}
|
||||
|
||||
bool CefServerImpl::CurrentlyOnHandlerThread() const {
|
||||
return task_runner_ && task_runner_->BelongsToCurrentThread();
|
||||
}
|
113
libcef/browser/server_impl.h
Normal file
113
libcef/browser/server_impl.h
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_SERVER_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_SERVER_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "include/cef_server.h"
|
||||
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "net/server/http_server.h"
|
||||
|
||||
namespace base {
|
||||
class Thread;
|
||||
};
|
||||
|
||||
class CefServerImpl : public CefServer, net::HttpServer::Delegate {
|
||||
public:
|
||||
explicit CefServerImpl(CefRefPtr<CefServerHandler> handler);
|
||||
|
||||
void Start(const std::string& address, uint16 port, int backlog);
|
||||
|
||||
// CefServer methods:
|
||||
CefRefPtr<CefTaskRunner> GetTaskRunner() override;
|
||||
void Shutdown() override;
|
||||
bool IsRunning() override;
|
||||
CefString GetAddress() override;
|
||||
bool HasConnection() override;
|
||||
bool IsValidConnection(int connection_id) override;
|
||||
void SendHttp200Response(int connection_id,
|
||||
const CefString& content_type,
|
||||
const void* data,
|
||||
size_t data_size) override;
|
||||
void SendHttp404Response(int connection_id) override;
|
||||
void SendHttp500Response(int connection_id,
|
||||
const CefString& error_message) override;
|
||||
void SendHttpResponse(int connection_id,
|
||||
int response_code,
|
||||
const CefString& content_type,
|
||||
int64 content_length,
|
||||
const HeaderMap& extra_headers) override;
|
||||
void SendRawData(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) override;
|
||||
void CloseConnection(int connection_id) override;
|
||||
void SendWebSocketMessage(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) override;
|
||||
|
||||
void ContinueWebSocketRequest(int connection_id,
|
||||
const net::HttpServerRequestInfo& request_info,
|
||||
bool allow);
|
||||
|
||||
private:
|
||||
void SendHttp200ResponseInternal(int connection_id,
|
||||
const CefString& content_type,
|
||||
std::unique_ptr<std::string> data);
|
||||
void SendRawDataInternal(int connection_id,
|
||||
std::unique_ptr<std::string> data);
|
||||
void SendWebSocketMessageInternal(int connection_id,
|
||||
std::unique_ptr<std::string> data);
|
||||
|
||||
// HttpServer::Delegate methods:
|
||||
void OnConnect(int connection_id) override;
|
||||
void OnHttpRequest(int connection_id,
|
||||
const net::HttpServerRequestInfo& request_info) override;
|
||||
void OnWebSocketRequest(
|
||||
int connection_id,
|
||||
const net::HttpServerRequestInfo& request_info) override;
|
||||
void OnWebSocketMessage(int connection_id, const std::string& data) override;
|
||||
void OnClose(int connection_id) override;
|
||||
|
||||
void StartOnUIThread(const std::string& address, uint16 port, int backlog);
|
||||
void StartOnHandlerThread(const std::string& address,
|
||||
uint16 port,
|
||||
int backlog);
|
||||
|
||||
void ShutdownOnHandlerThread();
|
||||
void ShutdownOnUIThread();
|
||||
|
||||
bool ValidateServer() const;
|
||||
|
||||
struct ConnectionInfo;
|
||||
ConnectionInfo* CreateConnectionInfo(int connection_id);
|
||||
ConnectionInfo* GetConnectionInfo(int connection_id) const;
|
||||
void RemoveConnectionInfo(int connection_id);
|
||||
|
||||
bool CurrentlyOnHandlerThread() const;
|
||||
|
||||
// Safe to access from any thread.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
||||
std::string address_;
|
||||
|
||||
// Only accessed on the UI thread.
|
||||
std::unique_ptr<base::Thread> thread_;
|
||||
|
||||
// Only accessed on the server thread.
|
||||
CefRefPtr<CefServerHandler> handler_;
|
||||
std::unique_ptr<net::HttpServer> server_;
|
||||
|
||||
// Map of connection_id to ConnectionInfo.
|
||||
using ConnectionInfoMap = std::map<int, std::unique_ptr<ConnectionInfo>>;
|
||||
ConnectionInfoMap connection_info_map_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefServerImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefServerImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_SERVER_IMPL_H_
|
301
libcef_dll/cpptoc/server_cpptoc.cc
Normal file
301
libcef_dll/cpptoc/server_cpptoc.cc
Normal file
@ -0,0 +1,301 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=aa194ad76a31d7a0497333d78595e8b349a0551e$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/server_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/task_runner_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/server_handler_ctocpp.h"
|
||||
#include "libcef_dll/transfer_util.h"
|
||||
|
||||
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
CEF_EXPORT void cef_server_create(const cef_string_t* address,
|
||||
uint16 port,
|
||||
int backlog,
|
||||
struct _cef_server_handler_t* handler) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: address; type: string_byref_const
|
||||
DCHECK(address);
|
||||
if (!address)
|
||||
return;
|
||||
// Verify param: handler; type: refptr_diff
|
||||
DCHECK(handler);
|
||||
if (!handler)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServer::CreateServer(CefString(address), port, backlog,
|
||||
CefServerHandlerCToCpp::Wrap(handler));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
struct _cef_task_runner_t* CEF_CALLBACK
|
||||
server_get_task_runner(struct _cef_server_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefTaskRunner> _retval =
|
||||
CefServerCppToC::Get(self)->GetTaskRunner();
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefTaskRunnerCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK server_shutdown(struct _cef_server_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->Shutdown();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK server_is_running(struct _cef_server_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefServerCppToC::Get(self)->IsRunning();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
cef_string_userfree_t CEF_CALLBACK
|
||||
server_get_address(struct _cef_server_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefString _retval = CefServerCppToC::Get(self)->GetAddress();
|
||||
|
||||
// Return type: string
|
||||
return _retval.DetachToUserFree();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK server_has_connection(struct _cef_server_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefServerCppToC::Get(self)->HasConnection();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK server_is_valid_connection(struct _cef_server_t* self,
|
||||
int connection_id) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefServerCppToC::Get(self)->IsValidConnection(connection_id);
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK server_send_http200response(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const cef_string_t* content_type,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: content_type; type: string_byref_const
|
||||
DCHECK(content_type);
|
||||
if (!content_type)
|
||||
return;
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->SendHttp200Response(
|
||||
connection_id, CefString(content_type), data, data_size);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK server_send_http404response(struct _cef_server_t* self,
|
||||
int connection_id) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->SendHttp404Response(connection_id);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_send_http500response(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const cef_string_t* error_message) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: error_message; type: string_byref_const
|
||||
DCHECK(error_message);
|
||||
if (!error_message)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->SendHttp500Response(connection_id,
|
||||
CefString(error_message));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_send_http_response(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
int response_code,
|
||||
const cef_string_t* content_type,
|
||||
int64 content_length,
|
||||
cef_string_multimap_t extra_headers) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: content_type; type: string_byref_const
|
||||
DCHECK(content_type);
|
||||
if (!content_type)
|
||||
return;
|
||||
// Unverified params: extra_headers
|
||||
|
||||
// Translate param: extra_headers; type: string_map_multi_byref_const
|
||||
std::multimap<CefString, CefString> extra_headersMultimap;
|
||||
transfer_string_multimap_contents(extra_headers, extra_headersMultimap);
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->SendHttpResponse(
|
||||
connection_id, response_code, CefString(content_type), content_length,
|
||||
extra_headersMultimap);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK server_send_raw_data(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->SendRawData(connection_id, data, data_size);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK server_close_connection(struct _cef_server_t* self,
|
||||
int connection_id) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->CloseConnection(connection_id);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK server_send_web_socket_message(struct _cef_server_t* self,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerCppToC::Get(self)->SendWebSocketMessage(connection_id, data,
|
||||
data_size);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefServerCppToC::CefServerCppToC() {
|
||||
GetStruct()->get_task_runner = server_get_task_runner;
|
||||
GetStruct()->shutdown = server_shutdown;
|
||||
GetStruct()->is_running = server_is_running;
|
||||
GetStruct()->get_address = server_get_address;
|
||||
GetStruct()->has_connection = server_has_connection;
|
||||
GetStruct()->is_valid_connection = server_is_valid_connection;
|
||||
GetStruct()->send_http200response = server_send_http200response;
|
||||
GetStruct()->send_http404response = server_send_http404response;
|
||||
GetStruct()->send_http500response = server_send_http500response;
|
||||
GetStruct()->send_http_response = server_send_http_response;
|
||||
GetStruct()->send_raw_data = server_send_raw_data;
|
||||
GetStruct()->close_connection = server_close_connection;
|
||||
GetStruct()->send_web_socket_message = server_send_web_socket_message;
|
||||
}
|
||||
|
||||
template <>
|
||||
CefRefPtr<CefServer>
|
||||
CefCppToCRefCounted<CefServerCppToC, CefServer, cef_server_t>::UnwrapDerived(
|
||||
CefWrapperType type,
|
||||
cef_server_t* s) {
|
||||
NOTREACHED() << "Unexpected class type: " << type;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
template <>
|
||||
base::AtomicRefCount
|
||||
CefCppToCRefCounted<CefServerCppToC, CefServer, cef_server_t>::DebugObjCt
|
||||
ATOMIC_DECLARATION;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
CefWrapperType CefCppToCRefCounted<CefServerCppToC, CefServer, cef_server_t>::
|
||||
kWrapperType = WT_SERVER;
|
35
libcef_dll/cpptoc/server_cpptoc.h
Normal file
35
libcef_dll/cpptoc/server_cpptoc.h
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=0f4a3453e43f2aa85bfdfaed15772373c43eccb8$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CPPTOC_SERVER_CPPTOC_H_
|
||||
#define CEF_LIBCEF_DLL_CPPTOC_SERVER_CPPTOC_H_
|
||||
#pragma once
|
||||
|
||||
#if !defined(BUILDING_CEF_SHARED)
|
||||
#error This file can be included DLL-side only
|
||||
#endif
|
||||
|
||||
#include "include/capi/cef_server_capi.h"
|
||||
#include "include/cef_server.h"
|
||||
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
|
||||
|
||||
// Wrap a C++ class with a C structure.
|
||||
// This class may be instantiated and accessed DLL-side only.
|
||||
class CefServerCppToC
|
||||
: public CefCppToCRefCounted<CefServerCppToC, CefServer, cef_server_t> {
|
||||
public:
|
||||
CefServerCppToC();
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CPPTOC_SERVER_CPPTOC_H_
|
244
libcef_dll/cpptoc/server_handler_cpptoc.cc
Normal file
244
libcef_dll/cpptoc/server_handler_cpptoc.cc
Normal file
@ -0,0 +1,244 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=36e97984dadd60442c0eba6189c08b6512d05f78$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/server_handler_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/request_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/server_ctocpp.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_server_created(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnServerCreated(
|
||||
CefServerCToCpp::Wrap(server));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_server_destroyed(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnServerDestroyed(
|
||||
CefServerCToCpp::Wrap(server));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_client_connected(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server,
|
||||
int connection_id) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnClientConnected(
|
||||
CefServerCToCpp::Wrap(server), connection_id);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_client_disconnected(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server,
|
||||
int connection_id) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnClientDisconnected(
|
||||
CefServerCToCpp::Wrap(server), connection_id);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_http_request(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server,
|
||||
int connection_id,
|
||||
const cef_string_t* client_address,
|
||||
cef_request_t* request) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
// Verify param: client_address; type: string_byref_const
|
||||
DCHECK(client_address);
|
||||
if (!client_address)
|
||||
return;
|
||||
// Verify param: request; type: refptr_diff
|
||||
DCHECK(request);
|
||||
if (!request)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnHttpRequest(
|
||||
CefServerCToCpp::Wrap(server), connection_id, CefString(client_address),
|
||||
CefRequestCToCpp::Wrap(request));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_web_socket_request(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server,
|
||||
int connection_id,
|
||||
const cef_string_t* client_address,
|
||||
cef_request_t* request,
|
||||
cef_callback_t* callback) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
// Verify param: client_address; type: string_byref_const
|
||||
DCHECK(client_address);
|
||||
if (!client_address)
|
||||
return;
|
||||
// Verify param: request; type: refptr_diff
|
||||
DCHECK(request);
|
||||
if (!request)
|
||||
return;
|
||||
// Verify param: callback; type: refptr_diff
|
||||
DCHECK(callback);
|
||||
if (!callback)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnWebSocketRequest(
|
||||
CefServerCToCpp::Wrap(server), connection_id, CefString(client_address),
|
||||
CefRequestCToCpp::Wrap(request), CefCallbackCToCpp::Wrap(callback));
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_web_socket_connected(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server,
|
||||
int connection_id) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnWebSocketConnected(
|
||||
CefServerCToCpp::Wrap(server), connection_id);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
server_handler_on_web_socket_message(struct _cef_server_handler_t* self,
|
||||
cef_server_t* server,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server);
|
||||
if (!server)
|
||||
return;
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefServerHandlerCppToC::Get(self)->OnWebSocketMessage(
|
||||
CefServerCToCpp::Wrap(server), connection_id, data, data_size);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefServerHandlerCppToC::CefServerHandlerCppToC() {
|
||||
GetStruct()->on_server_created = server_handler_on_server_created;
|
||||
GetStruct()->on_server_destroyed = server_handler_on_server_destroyed;
|
||||
GetStruct()->on_client_connected = server_handler_on_client_connected;
|
||||
GetStruct()->on_client_disconnected = server_handler_on_client_disconnected;
|
||||
GetStruct()->on_http_request = server_handler_on_http_request;
|
||||
GetStruct()->on_web_socket_request = server_handler_on_web_socket_request;
|
||||
GetStruct()->on_web_socket_connected = server_handler_on_web_socket_connected;
|
||||
GetStruct()->on_web_socket_message = server_handler_on_web_socket_message;
|
||||
}
|
||||
|
||||
template <>
|
||||
CefRefPtr<CefServerHandler> CefCppToCRefCounted<
|
||||
CefServerHandlerCppToC,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t>::UnwrapDerived(CefWrapperType type,
|
||||
cef_server_handler_t* s) {
|
||||
NOTREACHED() << "Unexpected class type: " << type;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
template <>
|
||||
base::AtomicRefCount CefCppToCRefCounted<CefServerHandlerCppToC,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t>::DebugObjCt
|
||||
ATOMIC_DECLARATION;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
CefWrapperType CefCppToCRefCounted<CefServerHandlerCppToC,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t>::kWrapperType =
|
||||
WT_SERVER_HANDLER;
|
37
libcef_dll/cpptoc/server_handler_cpptoc.h
Normal file
37
libcef_dll/cpptoc/server_handler_cpptoc.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=01080491feb0e65e1385fcc5547ecb9c88de70c3$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CPPTOC_SERVER_HANDLER_CPPTOC_H_
|
||||
#define CEF_LIBCEF_DLL_CPPTOC_SERVER_HANDLER_CPPTOC_H_
|
||||
#pragma once
|
||||
|
||||
#if !defined(WRAPPING_CEF_SHARED)
|
||||
#error This file can be included wrapper-side only
|
||||
#endif
|
||||
|
||||
#include "include/capi/cef_server_capi.h"
|
||||
#include "include/cef_server.h"
|
||||
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
|
||||
|
||||
// Wrap a C++ class with a C structure.
|
||||
// This class may be instantiated and accessed wrapper-side only.
|
||||
class CefServerHandlerCppToC
|
||||
: public CefCppToCRefCounted<CefServerHandlerCppToC,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t> {
|
||||
public:
|
||||
CefServerHandlerCppToC();
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CPPTOC_SERVER_HANDLER_CPPTOC_H_
|
282
libcef_dll/ctocpp/server_ctocpp.cc
Normal file
282
libcef_dll/ctocpp/server_ctocpp.cc
Normal file
@ -0,0 +1,282 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=ffa6d8f2bc0fd724a50856dfa867cf275345716c$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/server_ctocpp.h"
|
||||
#include "libcef_dll/cpptoc/server_handler_cpptoc.h"
|
||||
#include "libcef_dll/ctocpp/task_runner_ctocpp.h"
|
||||
#include "libcef_dll/transfer_util.h"
|
||||
|
||||
// STATIC METHODS - Body may be edited by hand.
|
||||
|
||||
void CefServer::CreateServer(const CefString& address,
|
||||
uint16 port,
|
||||
int backlog,
|
||||
CefRefPtr<CefServerHandler> handler) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: address; type: string_byref_const
|
||||
DCHECK(!address.empty());
|
||||
if (address.empty())
|
||||
return;
|
||||
// Verify param: handler; type: refptr_diff
|
||||
DCHECK(handler.get());
|
||||
if (!handler.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
cef_server_create(address.GetStruct(), port, backlog,
|
||||
CefServerHandlerCppToC::Wrap(handler));
|
||||
}
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
CefRefPtr<CefTaskRunner> CefServerCToCpp::GetTaskRunner() {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_task_runner))
|
||||
return NULL;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_task_runner_t* _retval = _struct->get_task_runner(_struct);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefTaskRunnerCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
void CefServerCToCpp::Shutdown() {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, shutdown))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->shutdown(_struct);
|
||||
}
|
||||
|
||||
bool CefServerCToCpp::IsRunning() {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_running))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_running(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
CefString CefServerCToCpp::GetAddress() {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_address))
|
||||
return CefString();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_string_userfree_t _retval = _struct->get_address(_struct);
|
||||
|
||||
// Return type: string
|
||||
CefString _retvalStr;
|
||||
_retvalStr.AttachToUserFree(_retval);
|
||||
return _retvalStr;
|
||||
}
|
||||
|
||||
bool CefServerCToCpp::HasConnection() {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, has_connection))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->has_connection(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
bool CefServerCToCpp::IsValidConnection(int connection_id) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_valid_connection))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_valid_connection(_struct, connection_id);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
void CefServerCToCpp::SendHttp200Response(int connection_id,
|
||||
const CefString& content_type,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_http200response))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: content_type; type: string_byref_const
|
||||
DCHECK(!content_type.empty());
|
||||
if (content_type.empty())
|
||||
return;
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->send_http200response(_struct, connection_id,
|
||||
content_type.GetStruct(), data, data_size);
|
||||
}
|
||||
|
||||
void CefServerCToCpp::SendHttp404Response(int connection_id) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_http404response))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->send_http404response(_struct, connection_id);
|
||||
}
|
||||
|
||||
void CefServerCToCpp::SendHttp500Response(int connection_id,
|
||||
const CefString& error_message) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_http500response))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: error_message; type: string_byref_const
|
||||
DCHECK(!error_message.empty());
|
||||
if (error_message.empty())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->send_http500response(_struct, connection_id,
|
||||
error_message.GetStruct());
|
||||
}
|
||||
|
||||
void CefServerCToCpp::SendHttpResponse(int connection_id,
|
||||
int response_code,
|
||||
const CefString& content_type,
|
||||
int64 content_length,
|
||||
const HeaderMap& extra_headers) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_http_response))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: content_type; type: string_byref_const
|
||||
DCHECK(!content_type.empty());
|
||||
if (content_type.empty())
|
||||
return;
|
||||
// Unverified params: extra_headers
|
||||
|
||||
// Translate param: extra_headers; type: string_map_multi_byref_const
|
||||
cef_string_multimap_t extra_headersMultimap = cef_string_multimap_alloc();
|
||||
DCHECK(extra_headersMultimap);
|
||||
if (extra_headersMultimap)
|
||||
transfer_string_multimap_contents(extra_headers, extra_headersMultimap);
|
||||
|
||||
// Execute
|
||||
_struct->send_http_response(_struct, connection_id, response_code,
|
||||
content_type.GetStruct(), content_length,
|
||||
extra_headersMultimap);
|
||||
|
||||
// Restore param:extra_headers; type: string_map_multi_byref_const
|
||||
if (extra_headersMultimap)
|
||||
cef_string_multimap_free(extra_headersMultimap);
|
||||
}
|
||||
|
||||
void CefServerCToCpp::SendRawData(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_raw_data))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->send_raw_data(_struct, connection_id, data, data_size);
|
||||
}
|
||||
|
||||
void CefServerCToCpp::CloseConnection(int connection_id) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, close_connection))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->close_connection(_struct, connection_id);
|
||||
}
|
||||
|
||||
void CefServerCToCpp::SendWebSocketMessage(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
cef_server_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_web_socket_message))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->send_web_socket_message(_struct, connection_id, data, data_size);
|
||||
}
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefServerCToCpp::CefServerCToCpp() {}
|
||||
|
||||
template <>
|
||||
cef_server_t*
|
||||
CefCToCppRefCounted<CefServerCToCpp, CefServer, cef_server_t>::UnwrapDerived(
|
||||
CefWrapperType type,
|
||||
CefServer* c) {
|
||||
NOTREACHED() << "Unexpected class type: " << type;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
template <>
|
||||
base::AtomicRefCount
|
||||
CefCToCppRefCounted<CefServerCToCpp, CefServer, cef_server_t>::DebugObjCt
|
||||
ATOMIC_DECLARATION;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
CefWrapperType CefCToCppRefCounted<CefServerCToCpp, CefServer, cef_server_t>::
|
||||
kWrapperType = WT_SERVER;
|
62
libcef_dll/ctocpp/server_ctocpp.h
Normal file
62
libcef_dll/ctocpp/server_ctocpp.h
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=7218e524c29b0837d4759117c81ffa1401759596$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_SERVER_CTOCPP_H_
|
||||
#define CEF_LIBCEF_DLL_CTOCPP_SERVER_CTOCPP_H_
|
||||
#pragma once
|
||||
|
||||
#if !defined(WRAPPING_CEF_SHARED)
|
||||
#error This file can be included wrapper-side only
|
||||
#endif
|
||||
|
||||
#include "include/capi/cef_server_capi.h"
|
||||
#include "include/cef_server.h"
|
||||
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
|
||||
|
||||
// Wrap a C structure with a C++ class.
|
||||
// This class may be instantiated and accessed wrapper-side only.
|
||||
class CefServerCToCpp
|
||||
: public CefCToCppRefCounted<CefServerCToCpp, CefServer, cef_server_t> {
|
||||
public:
|
||||
CefServerCToCpp();
|
||||
|
||||
// CefServer methods.
|
||||
CefRefPtr<CefTaskRunner> GetTaskRunner() OVERRIDE;
|
||||
void Shutdown() OVERRIDE;
|
||||
bool IsRunning() OVERRIDE;
|
||||
CefString GetAddress() OVERRIDE;
|
||||
bool HasConnection() OVERRIDE;
|
||||
bool IsValidConnection(int connection_id) OVERRIDE;
|
||||
void SendHttp200Response(int connection_id,
|
||||
const CefString& content_type,
|
||||
const void* data,
|
||||
size_t data_size) OVERRIDE;
|
||||
void SendHttp404Response(int connection_id) OVERRIDE;
|
||||
void SendHttp500Response(int connection_id,
|
||||
const CefString& error_message) OVERRIDE;
|
||||
void SendHttpResponse(int connection_id,
|
||||
int response_code,
|
||||
const CefString& content_type,
|
||||
int64 content_length,
|
||||
const HeaderMap& extra_headers) OVERRIDE;
|
||||
void SendRawData(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) OVERRIDE;
|
||||
void CloseConnection(int connection_id) OVERRIDE;
|
||||
void SendWebSocketMessage(int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CTOCPP_SERVER_CTOCPP_H_
|
223
libcef_dll/ctocpp/server_handler_ctocpp.cc
Normal file
223
libcef_dll/ctocpp/server_handler_ctocpp.cc
Normal file
@ -0,0 +1,223 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=262176ac6f772f186c59e0bf07e07d3514fa3440$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/server_handler_ctocpp.h"
|
||||
#include "libcef_dll/cpptoc/callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/request_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/server_cpptoc.h"
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
void CefServerHandlerCToCpp::OnServerCreated(CefRefPtr<CefServer> server) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_server_created))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_server_created(_struct, CefServerCppToC::Wrap(server));
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnServerDestroyed(CefRefPtr<CefServer> server) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_server_destroyed))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_server_destroyed(_struct, CefServerCppToC::Wrap(server));
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnClientConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_client_connected))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_client_connected(_struct, CefServerCppToC::Wrap(server),
|
||||
connection_id);
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_client_disconnected))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_client_disconnected(_struct, CefServerCppToC::Wrap(server),
|
||||
connection_id);
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnHttpRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_http_request))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
// Verify param: client_address; type: string_byref_const
|
||||
DCHECK(!client_address.empty());
|
||||
if (client_address.empty())
|
||||
return;
|
||||
// Verify param: request; type: refptr_diff
|
||||
DCHECK(request.get());
|
||||
if (!request.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_http_request(_struct, CefServerCppToC::Wrap(server),
|
||||
connection_id, client_address.GetStruct(),
|
||||
CefRequestCppToC::Wrap(request));
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnWebSocketRequest(
|
||||
CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_web_socket_request))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
// Verify param: client_address; type: string_byref_const
|
||||
DCHECK(!client_address.empty());
|
||||
if (client_address.empty())
|
||||
return;
|
||||
// Verify param: request; type: refptr_diff
|
||||
DCHECK(request.get());
|
||||
if (!request.get())
|
||||
return;
|
||||
// Verify param: callback; type: refptr_diff
|
||||
DCHECK(callback.get());
|
||||
if (!callback.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_web_socket_request(_struct, CefServerCppToC::Wrap(server),
|
||||
connection_id, client_address.GetStruct(),
|
||||
CefRequestCppToC::Wrap(request),
|
||||
CefCallbackCppToC::Wrap(callback));
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnWebSocketConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_web_socket_connected))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_web_socket_connected(_struct, CefServerCppToC::Wrap(server),
|
||||
connection_id);
|
||||
}
|
||||
|
||||
void CefServerHandlerCToCpp::OnWebSocketMessage(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) {
|
||||
cef_server_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_web_socket_message))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: server; type: refptr_diff
|
||||
DCHECK(server.get());
|
||||
if (!server.get())
|
||||
return;
|
||||
// Verify param: data; type: simple_byaddr
|
||||
DCHECK(data);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
_struct->on_web_socket_message(_struct, CefServerCppToC::Wrap(server),
|
||||
connection_id, data, data_size);
|
||||
}
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefServerHandlerCToCpp::CefServerHandlerCToCpp() {}
|
||||
|
||||
template <>
|
||||
cef_server_handler_t*
|
||||
CefCToCppRefCounted<CefServerHandlerCToCpp,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t>::UnwrapDerived(CefWrapperType type,
|
||||
CefServerHandler* c) {
|
||||
NOTREACHED() << "Unexpected class type: " << type;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
template <>
|
||||
base::AtomicRefCount CefCToCppRefCounted<CefServerHandlerCToCpp,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t>::DebugObjCt
|
||||
ATOMIC_DECLARATION;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
CefWrapperType CefCToCppRefCounted<CefServerHandlerCToCpp,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t>::kWrapperType =
|
||||
WT_SERVER_HANDLER;
|
60
libcef_dll/ctocpp/server_handler_ctocpp.h
Normal file
60
libcef_dll/ctocpp/server_handler_ctocpp.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool. If making changes by
|
||||
// hand only do so within the body of existing method and function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=a5012dffe69ac9161fce2e11bc2f65772bd21ff4$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_SERVER_HANDLER_CTOCPP_H_
|
||||
#define CEF_LIBCEF_DLL_CTOCPP_SERVER_HANDLER_CTOCPP_H_
|
||||
#pragma once
|
||||
|
||||
#if !defined(BUILDING_CEF_SHARED)
|
||||
#error This file can be included DLL-side only
|
||||
#endif
|
||||
|
||||
#include "include/capi/cef_server_capi.h"
|
||||
#include "include/cef_server.h"
|
||||
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
|
||||
|
||||
// Wrap a C structure with a C++ class.
|
||||
// This class may be instantiated and accessed DLL-side only.
|
||||
class CefServerHandlerCToCpp
|
||||
: public CefCToCppRefCounted<CefServerHandlerCToCpp,
|
||||
CefServerHandler,
|
||||
cef_server_handler_t> {
|
||||
public:
|
||||
CefServerHandlerCToCpp();
|
||||
|
||||
// CefServerHandler methods.
|
||||
void OnServerCreated(CefRefPtr<CefServer> server) override;
|
||||
void OnServerDestroyed(CefRefPtr<CefServer> server) override;
|
||||
void OnClientConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) override;
|
||||
void OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) override;
|
||||
void OnHttpRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request) override;
|
||||
void OnWebSocketRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override;
|
||||
void OnWebSocketConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) override;
|
||||
void OnWebSocketMessage(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) override;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CTOCPP_SERVER_HANDLER_CTOCPP_H_
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=2df1182745ef1d14ed20428c53ed7638742c13f9$
|
||||
// $hash=4ae6ce5d8ccf3b39d55d6d8a67f8daf547242271$
|
||||
//
|
||||
|
||||
#include "include/capi/cef_app_capi.h"
|
||||
@ -74,6 +74,7 @@
|
||||
#include "libcef_dll/cpptoc/run_context_menu_callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/scheme_registrar_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/select_client_certificate_callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/server_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/sslinfo_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/sslstatus_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/stream_reader_cpptoc.h"
|
||||
@ -152,6 +153,7 @@
|
||||
#include "libcef_dll/ctocpp/response_filter_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/server_handler_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/set_cookie_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/string_visitor_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/task_ctocpp.h"
|
||||
@ -344,6 +346,8 @@ CEF_EXPORT void cef_shutdown() {
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefScrollViewCppToC::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(
|
||||
&CefSelectClientCertificateCallbackCppToC::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefServerCppToC::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefServerHandlerCToCpp::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefSetCookieCallbackCToCpp::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefStreamReaderCppToC::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefStreamWriterCppToC::DebugObjCt));
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=82e24ebf13dbb1b7430a4710fd3d296b98311d1d$
|
||||
// $hash=8f5702806c240c66d2b9235cf44e58ba52fe3b63$
|
||||
//
|
||||
|
||||
#include "include/capi/cef_app_capi.h"
|
||||
@ -81,6 +81,7 @@
|
||||
#include "libcef_dll/cpptoc/response_filter_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/server_handler_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/set_cookie_callback_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/string_visitor_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/task_cpptoc.h"
|
||||
@ -134,6 +135,7 @@
|
||||
#include "libcef_dll/ctocpp/run_context_menu_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/scheme_registrar_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/select_client_certificate_callback_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/server_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/sslinfo_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/sslstatus_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/stream_reader_ctocpp.h"
|
||||
@ -335,6 +337,8 @@ CEF_GLOBAL void CefShutdown() {
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefScrollViewCToCpp::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(
|
||||
&CefSelectClientCertificateCallbackCToCpp::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefServerCToCpp::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefServerHandlerCppToC::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefSetCookieCallbackCppToC::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefStreamReaderCToCpp::DebugObjCt));
|
||||
DCHECK(base::AtomicRefCountIsZero(&CefStreamWriterCToCpp::DebugObjCt));
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=0e103b8e82d15405eb5fdb2efc48992dae1e9656$
|
||||
// $hash=9a3b6de92214d6b132bd66d84724272c886a3758$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
|
||||
@ -115,6 +115,8 @@ enum CefWrapperType {
|
||||
WT_SCHEME_REGISTRAR,
|
||||
WT_SCROLL_VIEW,
|
||||
WT_SELECT_CLIENT_CERTIFICATE_CALLBACK,
|
||||
WT_SERVER,
|
||||
WT_SERVER_HANDLER,
|
||||
WT_SET_COOKIE_CALLBACK,
|
||||
WT_STREAM_READER,
|
||||
WT_STREAM_WRITER,
|
||||
|
@ -7,12 +7,14 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace binding_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/binding";
|
||||
const char kTestUrlPath[] = "/binding";
|
||||
const char kTestMessageName[] = "BindingTest";
|
||||
|
||||
// Handle messages in the browser process.
|
||||
@ -29,7 +31,7 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
CefRefPtr<Callback> callback) OVERRIDE {
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return false;
|
||||
|
||||
const std::string& message_name = request;
|
||||
|
@ -8,13 +8,14 @@
|
||||
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace dialog_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/dialogs";
|
||||
const char kTestUrlPath[] = "/dialogs";
|
||||
const char kFileOpenMessageName[] = "DialogTest.FileOpen";
|
||||
const char kFileOpenMultipleMessageName[] = "DialogTest.FileOpenMultiple";
|
||||
const char kFileOpenFolderMessageName[] = "DialogTest.FileOpenFolder";
|
||||
@ -109,7 +110,7 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return false;
|
||||
|
||||
if (!dialog_state_.get())
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/cef_parser.h"
|
||||
#include "include/cef_web_plugin.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace drm_test {
|
||||
@ -19,7 +20,7 @@ namespace {
|
||||
const int kMessageFormatError = 1;
|
||||
const int kCdmLoadError = 2;
|
||||
|
||||
const char kTestUrl[] = "http://tests/drm";
|
||||
const char kTestUrlPath[] = "/drm";
|
||||
const char kWidevineCdmPathKey[] = "widevine_cdm_path";
|
||||
|
||||
// Callback executed once CDM registration is complete.
|
||||
@ -49,7 +50,7 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
public:
|
||||
Handler() {}
|
||||
|
||||
// Called due to cefQuery execution in binding.html.
|
||||
// Called due to cefQuery execution in drm.html.
|
||||
virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64 query_id,
|
||||
@ -58,7 +59,7 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
CefRefPtr<Callback> callback) OVERRIDE {
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return false;
|
||||
|
||||
// Parse |request| as a JSON dictionary.
|
||||
|
@ -11,13 +11,14 @@
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "include/cef_parser.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace preferences_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/preferences";
|
||||
const char kTestUrlPath[] = "/preferences";
|
||||
|
||||
// Application-specific error codes.
|
||||
const int kMessageFormatError = 1;
|
||||
@ -52,8 +53,8 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Only handle messages from the test URL.
|
||||
std::string url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
const std::string& url = frame->GetURL();
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return false;
|
||||
|
||||
// Parse |request| as a JSON dictionary.
|
||||
|
@ -58,12 +58,14 @@
|
||||
#define IDS_PERFORMANCE2_HTML 1013
|
||||
#define IDS_PREFERENCES_HTML 1014
|
||||
#define IDS_RESPONSE_FILTER_HTML 1015
|
||||
#define IDS_TRANSPARENCY_HTML 1016
|
||||
#define IDS_URLREQUEST_HTML 1017
|
||||
#define IDS_WINDOW_HTML 1018
|
||||
#define IDS_WINDOW_ICON_1X_PNG 1019
|
||||
#define IDS_WINDOW_ICON_2X_PNG 1020
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1021
|
||||
#define IDS_SERVER_HTML 1016
|
||||
#define IDS_TRANSPARENCY_HTML 1017
|
||||
#define IDS_URLREQUEST_HTML 1018
|
||||
#define IDS_WEBSOCKET_HTML 1019
|
||||
#define IDS_WINDOW_HTML 1020
|
||||
#define IDS_WINDOW_ICON_1X_PNG 1021
|
||||
#define IDS_WINDOW_ICON_2X_PNG 1022
|
||||
#define IDS_XMLHTTPREQUEST_HTML 1023
|
||||
|
||||
#define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
|
||||
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031
|
||||
|
@ -38,8 +38,10 @@ int GetResourceId(const char* resource_name) {
|
||||
{"performance2.html", IDS_PERFORMANCE2_HTML},
|
||||
{"preferences.html", IDS_PREFERENCES_HTML},
|
||||
{"response_filter.html", IDS_RESPONSE_FILTER_HTML},
|
||||
{"server.html", IDS_SERVER_HTML},
|
||||
{"transparency.html", IDS_TRANSPARENCY_HTML},
|
||||
{"urlrequest.html", IDS_URLREQUEST_HTML},
|
||||
{"websocket.html", IDS_WEBSOCKET_HTML},
|
||||
{"window.html", IDS_WINDOW_HTML},
|
||||
{"window_icon.1x.png", IDS_WINDOW_ICON_1X_PNG},
|
||||
{"window_icon.2x.png", IDS_WINDOW_ICON_2X_PNG},
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
#include "tests/shared/common/client_switches.h"
|
||||
|
||||
namespace client {
|
||||
@ -17,7 +18,7 @@ namespace response_filter_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/response_filter";
|
||||
const char kTestUrlPath[] = "/response_filter";
|
||||
const char kFindString[] = "REPLACE_THIS_STRING";
|
||||
const char kReplaceString[] = "This is the replaced string!";
|
||||
|
||||
@ -226,7 +227,8 @@ CefRefPtr<CefResponseFilter> GetResourceResponseFilter(
|
||||
CefRefPtr<CefResponse> response) {
|
||||
// Use the find/replace filter on the test URL.
|
||||
const std::string& url = request->GetURL();
|
||||
if (url.find(kTestUrl) == 0)
|
||||
|
||||
if (test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return new FindReplaceResponseFilter();
|
||||
|
||||
if (MatchesFilterURL(url))
|
||||
|
387
tests/cefclient/browser/server_test.cc
Normal file
387
tests/cefclient/browser/server_test.cc
Normal file
@ -0,0 +1,387 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/cefclient/browser/server_test.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_weak_ptr.h"
|
||||
#include "include/cef_parser.h"
|
||||
#include "include/cef_server.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "tests/shared/browser/resource_util.h"
|
||||
|
||||
namespace client {
|
||||
namespace server_test {
|
||||
|
||||
namespace {
|
||||
|
||||
// Application-specific error codes.
|
||||
const int kMessageFormatError = 1;
|
||||
const int kActionStateError = 1;
|
||||
|
||||
// JSON dictionary keys.
|
||||
const char kActionKey[] = "action";
|
||||
const char kResultKey[] = "result";
|
||||
const char kPortKey[] = "port";
|
||||
const char kStatusKey[] = "status";
|
||||
const char kMessageKey[] = "message";
|
||||
|
||||
// Required URL for cefQuery execution.
|
||||
const char kTestUrl[] = "http://tests/server";
|
||||
|
||||
// Server default values.
|
||||
const char kServerAddress[] = "127.0.0.1";
|
||||
const int kServerPortDefault = 8099;
|
||||
const int kServerBacklog = 10;
|
||||
const char kDefaultPath[] = "websocket.html";
|
||||
|
||||
// Handles the HTTP/WebSocket server.
|
||||
class ServerHandler : public CefServerHandler {
|
||||
public:
|
||||
typedef base::Callback<void(bool /* success */)> CompleteCallback;
|
||||
|
||||
ServerHandler() {}
|
||||
|
||||
// |complete_callback| will be executed on the UI thread after completion.
|
||||
void StartServer(int port, const CompleteCallback& complete_callback) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(!server_);
|
||||
DCHECK(port >= 1025 && port <= 65535);
|
||||
port_ = port;
|
||||
complete_callback_ = complete_callback;
|
||||
CefServer::CreateServer(kServerAddress, port, kServerBacklog, this);
|
||||
}
|
||||
|
||||
// |complete_callback| will be executed on the UI thread after completion.
|
||||
void StopServer(const CompleteCallback& complete_callback) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(server_);
|
||||
complete_callback_ = complete_callback;
|
||||
server_->Shutdown();
|
||||
}
|
||||
|
||||
// CefServerHandler methods are called on the server thread.
|
||||
|
||||
void OnServerCreated(CefRefPtr<CefServer> server) override {
|
||||
DCHECK(!server_);
|
||||
server_ = server;
|
||||
RunCompleteCallback(server->IsRunning());
|
||||
}
|
||||
|
||||
void OnServerDestroyed(CefRefPtr<CefServer> server) override {
|
||||
DCHECK(server_);
|
||||
server_ = nullptr;
|
||||
RunCompleteCallback(true);
|
||||
}
|
||||
|
||||
void OnClientConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) override {}
|
||||
|
||||
void OnClientDisconnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) override {}
|
||||
|
||||
void OnHttpRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request) override {
|
||||
// Parse the request URL and retrieve the path without leading slash.
|
||||
CefURLParts url_parts;
|
||||
CefParseURL(request->GetURL(), url_parts);
|
||||
std::string path = CefString(&url_parts.path);
|
||||
if (!path.empty() && path[0] == '/')
|
||||
path = path.substr(1);
|
||||
|
||||
if (path.empty())
|
||||
path = kDefaultPath;
|
||||
|
||||
std::string mime_type;
|
||||
const size_t sep = path.find_last_of(".");
|
||||
if (sep != std::string::npos) {
|
||||
// Determine the mime type based on the extension.
|
||||
mime_type = CefGetMimeType(path.substr(sep + 1));
|
||||
} else {
|
||||
// No extension. Assume html.
|
||||
path += ".html";
|
||||
}
|
||||
if (mime_type.empty())
|
||||
mime_type = "text/html";
|
||||
|
||||
CefRefPtr<CefStreamReader> stream;
|
||||
CefResponse::HeaderMap extra_headers;
|
||||
|
||||
if (path == "request.html") {
|
||||
// Return the request contents.
|
||||
stream = test_runner::GetDumpResponse(request, extra_headers);
|
||||
}
|
||||
|
||||
if (!stream) {
|
||||
// Load any resource supported by cefclient.
|
||||
stream = GetBinaryResourceReader(path.c_str());
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
SendHttpResponseStream(server, connection_id, mime_type, stream,
|
||||
extra_headers);
|
||||
} else {
|
||||
server->SendHttp404Response(connection_id);
|
||||
}
|
||||
}
|
||||
|
||||
void OnWebSocketRequest(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const CefString& client_address,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
// Always accept WebSocket connections.
|
||||
callback->Continue();
|
||||
}
|
||||
|
||||
void OnWebSocketConnected(CefRefPtr<CefServer> server,
|
||||
int connection_id) override {}
|
||||
|
||||
void OnWebSocketMessage(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const void* data,
|
||||
size_t data_size) override {
|
||||
// Echo the reverse of the message.
|
||||
std::string message(static_cast<const char*>(data), data_size);
|
||||
std::reverse(message.begin(), message.end());
|
||||
|
||||
server->SendWebSocketMessage(connection_id, message.data(), message.size());
|
||||
}
|
||||
|
||||
int port() const { return port_; }
|
||||
|
||||
private:
|
||||
void RunCompleteCallback(bool success) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(&ServerHandler::RunCompleteCallback, this,
|
||||
success));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!complete_callback_.is_null()) {
|
||||
complete_callback_.Run(success);
|
||||
complete_callback_.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void SendHttpResponseStream(CefRefPtr<CefServer> server,
|
||||
int connection_id,
|
||||
const std::string& mime_type,
|
||||
CefRefPtr<CefStreamReader> stream,
|
||||
CefResponse::HeaderMap extra_headers) {
|
||||
// Determine the stream size.
|
||||
stream->Seek(0, SEEK_END);
|
||||
int64 content_length = stream->Tell();
|
||||
stream->Seek(0, SEEK_SET);
|
||||
|
||||
// Send response headers.
|
||||
server->SendHttpResponse(connection_id, 200, mime_type, content_length,
|
||||
extra_headers);
|
||||
|
||||
// Send stream contents.
|
||||
char buffer[8192];
|
||||
size_t read;
|
||||
do {
|
||||
read = stream->Read(buffer, 1, sizeof(buffer));
|
||||
if (read > 0)
|
||||
server->SendRawData(connection_id, buffer, read);
|
||||
} while (!stream->Eof() && read != 0);
|
||||
|
||||
// Close the connection.
|
||||
server->CloseConnection(connection_id);
|
||||
}
|
||||
|
||||
CefRefPtr<CefServer> server_;
|
||||
|
||||
// The below members are only accessed on the UI thread.
|
||||
int port_;
|
||||
CompleteCallback complete_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ServerHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(ServerHandler);
|
||||
};
|
||||
|
||||
// Handle messages in the browser process.
|
||||
class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
public:
|
||||
Handler() : weak_ptr_factory_(this) {}
|
||||
|
||||
virtual ~Handler() {
|
||||
if (handler_) {
|
||||
handler_->StopServer(ServerHandler::CompleteCallback());
|
||||
handler_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Called due to cefQuery execution in server.html.
|
||||
virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int64 query_id,
|
||||
const CefString& request,
|
||||
bool persistent,
|
||||
CefRefPtr<Callback> callback) OVERRIDE {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
return false;
|
||||
|
||||
// Parse |request| as a JSON dictionary.
|
||||
CefRefPtr<CefDictionaryValue> request_dict = ParseJSON(request);
|
||||
if (!request_dict) {
|
||||
callback->Failure(kMessageFormatError, "Incorrect message format");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!VerifyKey(request_dict, kActionKey, VTYPE_STRING, callback))
|
||||
return true;
|
||||
|
||||
const std::string& action = request_dict->GetString(kActionKey);
|
||||
if (action == "query") {
|
||||
HandleQueryAction(request_dict, callback);
|
||||
} else if (action == "start") {
|
||||
HandleStartAction(request_dict, callback);
|
||||
} else if (action == "stop") {
|
||||
HandleStopAction(request_dict, callback);
|
||||
} else {
|
||||
callback->Failure(kMessageFormatError, "Unrecognized action: " + action);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Return current server status.
|
||||
void HandleQueryAction(CefRefPtr<CefDictionaryValue> request_dict,
|
||||
CefRefPtr<Callback> callback) {
|
||||
CefRefPtr<CefDictionaryValue> result_dict = CefDictionaryValue::Create();
|
||||
if (handler_) {
|
||||
result_dict->SetInt(kPortKey, handler_->port());
|
||||
result_dict->SetString(kStatusKey, "running");
|
||||
} else {
|
||||
result_dict->SetInt(kPortKey, kServerPortDefault);
|
||||
result_dict->SetString(kStatusKey, "stopped");
|
||||
}
|
||||
SendResponse(callback, true, result_dict);
|
||||
}
|
||||
|
||||
// Start the server.
|
||||
void HandleStartAction(CefRefPtr<CefDictionaryValue> request_dict,
|
||||
CefRefPtr<Callback> callback) {
|
||||
if (handler_) {
|
||||
callback->Failure(kActionStateError, "Server is currently running");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VerifyKey(request_dict, kPortKey, VTYPE_INT, callback))
|
||||
return;
|
||||
|
||||
const int port = request_dict->GetInt(kPortKey);
|
||||
if (port < 8000 || port > 65535) {
|
||||
callback->Failure(kMessageFormatError, "Invalid port number specified");
|
||||
return;
|
||||
}
|
||||
|
||||
handler_ = new ServerHandler();
|
||||
|
||||
// Start the server. OnComplete will be executed upon completion.
|
||||
handler_->StartServer(port,
|
||||
base::Bind(&Handler::OnStartComplete,
|
||||
weak_ptr_factory_.GetWeakPtr(), callback));
|
||||
}
|
||||
|
||||
// Stop the server.
|
||||
void HandleStopAction(CefRefPtr<CefDictionaryValue> request_dict,
|
||||
CefRefPtr<Callback> callback) {
|
||||
if (!handler_) {
|
||||
callback->Failure(kActionStateError, "Server is not currently running");
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop the server. OnComplete will be executed upon completion.
|
||||
handler_->StopServer(base::Bind(&Handler::OnStopComplete,
|
||||
weak_ptr_factory_.GetWeakPtr(), callback));
|
||||
|
||||
handler_ = nullptr;
|
||||
}
|
||||
|
||||
// Server start completed.
|
||||
void OnStartComplete(CefRefPtr<Callback> callback, bool success) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
CefRefPtr<CefDictionaryValue> result_dict = CefDictionaryValue::Create();
|
||||
if (!success) {
|
||||
handler_ = nullptr;
|
||||
result_dict->SetString(kMessageKey, "Server failed to start.");
|
||||
}
|
||||
SendResponse(callback, success, result_dict);
|
||||
}
|
||||
|
||||
// Server stop completed.
|
||||
void OnStopComplete(CefRefPtr<Callback> callback, bool success) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
CefRefPtr<CefDictionaryValue> result_dict = CefDictionaryValue::Create();
|
||||
if (!success) {
|
||||
result_dict->SetString(kMessageKey, "Server failed to stop.");
|
||||
}
|
||||
SendResponse(callback, success, result_dict);
|
||||
}
|
||||
|
||||
// Send a response in the format expected by server.html.
|
||||
static void SendResponse(CefRefPtr<Callback> callback,
|
||||
bool success,
|
||||
CefRefPtr<CefDictionaryValue> result_dict) {
|
||||
if (!result_dict) {
|
||||
result_dict = CefDictionaryValue::Create();
|
||||
}
|
||||
result_dict->SetString(kResultKey, success ? "success" : "failure");
|
||||
CefRefPtr<CefValue> value = CefValue::Create();
|
||||
value->SetDictionary(result_dict);
|
||||
const std::string& response = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
callback->Success(response);
|
||||
}
|
||||
|
||||
// Convert a JSON string to a dictionary value.
|
||||
static CefRefPtr<CefDictionaryValue> ParseJSON(const CefString& string) {
|
||||
CefRefPtr<CefValue> value = CefParseJSON(string, JSON_PARSER_RFC);
|
||||
if (value.get() && value->GetType() == VTYPE_DICTIONARY)
|
||||
return value->GetDictionary();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Verify that |key| exists in |dictionary| and has type |value_type|. Fails
|
||||
// |callback| and returns false on failure.
|
||||
static bool VerifyKey(CefRefPtr<CefDictionaryValue> dictionary,
|
||||
const char* key,
|
||||
cef_value_type_t value_type,
|
||||
CefRefPtr<Callback> callback) {
|
||||
if (!dictionary->HasKey(key) || dictionary->GetType(key) != value_type) {
|
||||
callback->Failure(
|
||||
kMessageFormatError,
|
||||
"Missing or incorrectly formatted message key: " + std::string(key));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Non-nullptr while the server is running.
|
||||
CefRefPtr<ServerHandler> handler_;
|
||||
|
||||
// Must be the last member.
|
||||
base::WeakPtrFactory<Handler> weak_ptr_factory_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
|
||||
handlers.insert(new Handler());
|
||||
}
|
||||
|
||||
} // namespace server_test
|
||||
} // namespace client
|
20
tests/cefclient/browser/server_test.h
Normal file
20
tests/cefclient/browser/server_test.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_SERVER_TEST_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_SERVER_TEST_H_
|
||||
#pragma once
|
||||
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace server_test {
|
||||
|
||||
// Create message handlers. Called from test_runner.cc.
|
||||
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
|
||||
|
||||
} // namespace server_test
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_SERVER_TEST_H_
|
@ -22,6 +22,7 @@
|
||||
#include "tests/cefclient/browser/response_filter_test.h"
|
||||
#include "tests/cefclient/browser/root_window_manager.h"
|
||||
#include "tests/cefclient/browser/scheme_test.h"
|
||||
#include "tests/cefclient/browser/server_test.h"
|
||||
#include "tests/cefclient/browser/urlrequest_test.h"
|
||||
#include "tests/cefclient/browser/window_test.h"
|
||||
#include "tests/shared/browser/resource_util.h"
|
||||
@ -31,6 +32,8 @@ namespace test_runner {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestHost[] = "tests";
|
||||
const char kLocalHost[] = "localhost";
|
||||
const char kTestOrigin[] = "http://tests/";
|
||||
|
||||
// Replace all instances of |from| with |to| in |str|.
|
||||
@ -432,13 +435,12 @@ class RequestDumpResourceProvider : public CefResourceManager::Provider {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& dump = DumpRequestContents(request->request());
|
||||
std::string str =
|
||||
"<html><body bgcolor=\"white\"><pre>" + dump + "</pre></body></html>";
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
static_cast<void*>(const_cast<char*>(str.c_str())), str.size());
|
||||
DCHECK(stream.get());
|
||||
request->Continue(new CefStreamResourceHandler("text/html", stream));
|
||||
CefResponse::HeaderMap response_headers;
|
||||
CefRefPtr<CefStreamReader> response =
|
||||
GetDumpResponse(request->request(), response_headers);
|
||||
|
||||
request->Continue(new CefStreamResourceHandler(200, "OK", "text/html",
|
||||
response_headers, response));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -592,6 +594,49 @@ std::string DumpRequestContents(CefRefPtr<CefRequest> request) {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
CefRefPtr<CefStreamReader> GetDumpResponse(
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefResponse::HeaderMap& response_headers) {
|
||||
std::string origin;
|
||||
|
||||
// Extract the origin request header, if any. It will be specified for
|
||||
// cross-origin requests.
|
||||
{
|
||||
CefRequest::HeaderMap requestMap;
|
||||
request->GetHeaderMap(requestMap);
|
||||
|
||||
CefRequest::HeaderMap::const_iterator it = requestMap.begin();
|
||||
for (; it != requestMap.end(); ++it) {
|
||||
std::string key = it->first;
|
||||
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
|
||||
if (key == "origin") {
|
||||
origin = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!origin.empty() &&
|
||||
(origin.find("http://" + std::string(kTestHost)) == 0 ||
|
||||
origin.find("http://" + std::string(kLocalHost)) == 0)) {
|
||||
// Allow cross-origin XMLHttpRequests from test origins.
|
||||
response_headers.insert(
|
||||
std::make_pair("Access-Control-Allow-Origin", origin));
|
||||
|
||||
// Allow the custom header from the xmlhttprequest.html example.
|
||||
response_headers.insert(
|
||||
std::make_pair("Access-Control-Allow-Headers", "My-Custom-Header"));
|
||||
}
|
||||
|
||||
const std::string& dump = DumpRequestContents(request);
|
||||
std::string str =
|
||||
"<html><body bgcolor=\"white\"><pre>" + dump + "</pre></body></html>";
|
||||
CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
|
||||
static_cast<void*>(const_cast<char*>(str.c_str())), str.size());
|
||||
DCHECK(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
std::string GetDataURI(const std::string& data, const std::string& mime_type) {
|
||||
return "data:" + mime_type + ";base64," +
|
||||
CefURIEncode(CefBase64Encode(data.data(), data.size()), false)
|
||||
@ -710,6 +755,18 @@ void Alert(CefRefPtr<CefBrowser> browser, const std::string& message) {
|
||||
frame->ExecuteJavaScript("alert('" + msg + "');", frame->GetURL(), 0);
|
||||
}
|
||||
|
||||
bool IsTestURL(const std::string& url, const std::string& path) {
|
||||
CefURLParts parts;
|
||||
CefParseURL(url, parts);
|
||||
|
||||
const std::string& url_host = CefString(&parts.host);
|
||||
if (url_host != kTestHost && url_host != kLocalHost)
|
||||
return false;
|
||||
|
||||
const std::string& url_path = CefString(&parts.path);
|
||||
return url_path.find(path) == 0;
|
||||
}
|
||||
|
||||
void CreateMessageHandlers(MessageHandlerSet& handlers) {
|
||||
handlers.insert(new PromptHandler);
|
||||
|
||||
@ -725,6 +782,9 @@ void CreateMessageHandlers(MessageHandlerSet& handlers) {
|
||||
// Create the preferences test handlers.
|
||||
preferences_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the server test handlers.
|
||||
server_test::CreateMessageHandlers(handlers);
|
||||
|
||||
// Create the urlrequest test handlers.
|
||||
urlrequest_test::CreateMessageHandlers(handlers);
|
||||
|
||||
|
@ -23,6 +23,12 @@ void RunTest(CefRefPtr<CefBrowser> browser, int id);
|
||||
// Returns the contents of the CefRequest as a string.
|
||||
std::string DumpRequestContents(CefRefPtr<CefRequest> request);
|
||||
|
||||
// Returns the dump response as a stream. |request| is the request.
|
||||
// |response_headers| will be populated with extra response headers, if any.
|
||||
CefRefPtr<CefStreamReader> GetDumpResponse(
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefResponse::HeaderMap& response_headers);
|
||||
|
||||
// Returns a data: URI with the specified contents.
|
||||
std::string GetDataURI(const std::string& data, const std::string& mime_type);
|
||||
|
||||
@ -35,6 +41,10 @@ void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager);
|
||||
// Show a JS alert message.
|
||||
void Alert(CefRefPtr<CefBrowser> browser, const std::string& message);
|
||||
|
||||
// Returns true if |url| is a test URL with the specified |path|. This matches
|
||||
// both http://tests/<path> and http://localhost:xxxx/<path>.
|
||||
bool IsTestURL(const std::string& url, const std::string& path);
|
||||
|
||||
// Create all CefMessageRouterBrowserSide::Handler objects. They will be
|
||||
// deleted when the ClientHandler is destroyed.
|
||||
typedef std::set<CefMessageRouterBrowserSide::Handler*> MessageHandlerSet;
|
||||
|
@ -11,13 +11,14 @@
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/cef_urlrequest.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace urlrequest_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/urlrequest";
|
||||
const char kTestUrlPath[] = "/urlrequest";
|
||||
const char kTestMessageName[] = "URLRequestTest";
|
||||
|
||||
// Implementation of CefURLRequestClient that stores response information. Only
|
||||
@ -97,13 +98,14 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Only handle messages from the test URL.
|
||||
std::string url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
const std::string& url = frame->GetURL();
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return false;
|
||||
|
||||
const std::string& message_name = request;
|
||||
if (message_name.find(kTestMessageName) == 0) {
|
||||
url = message_name.substr(sizeof(kTestMessageName));
|
||||
const std::string& load_url =
|
||||
message_name.substr(sizeof(kTestMessageName));
|
||||
|
||||
CancelPendingRequest();
|
||||
|
||||
@ -114,7 +116,7 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
|
||||
// Create a CefRequest for the specified URL.
|
||||
CefRefPtr<CefRequest> cef_request = CefRequest::Create();
|
||||
cef_request->SetURL(url);
|
||||
cef_request->SetURL(load_url);
|
||||
cef_request->SetMethod("GET");
|
||||
|
||||
// Callback to be executed on request completion.
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||
#include "tests/cefclient/browser/main_context.h"
|
||||
#include "tests/cefclient/browser/test_runner.h"
|
||||
#include "tests/cefclient/browser/window_test_runner.h"
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
@ -31,7 +32,7 @@ namespace window_test {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestUrl[] = "http://tests/window";
|
||||
const char kTestUrlPath[] = "/window";
|
||||
const char kMessagePositionName[] = "WindowTest.Position";
|
||||
const char kMessageMinimizeName[] = "WindowTest.Minimize";
|
||||
const char kMessageMaximizeName[] = "WindowTest.Maximize";
|
||||
@ -69,7 +70,7 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
CefRefPtr<Callback> callback) OVERRIDE {
|
||||
// Only handle messages from the test URL.
|
||||
const std::string& url = frame->GetURL();
|
||||
if (url.find(kTestUrl) != 0)
|
||||
if (!test_runner::IsTestURL(url, kTestUrlPath))
|
||||
return false;
|
||||
|
||||
const std::string& message_name = request;
|
||||
|
@ -3,9 +3,22 @@
|
||||
<title>Binding Test</title>
|
||||
<script language="JavaScript">
|
||||
|
||||
function setup() {
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost')
|
||||
return;
|
||||
|
||||
alert('This page can only be run from tests or localhost.');
|
||||
|
||||
// Disable all elements.
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a query to the browser process.
|
||||
function sendMessage() {
|
||||
// Results in a call to the OnQuery method in binding_test.cpp
|
||||
// Results in a call to the OnQuery method in binding_test.cc
|
||||
window.cefQuery({
|
||||
request: 'BindingTest:' + document.getElementById("message").value,
|
||||
onSuccess: function(response) {
|
||||
@ -17,8 +30,8 @@ function sendMessage() {
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<form>
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<form id="form">
|
||||
Message: <input type="text" id="message" value="My Message">
|
||||
<br/><input type="button" onclick="sendMessage();" value="Send Message">
|
||||
<br/>You should see the reverse of your message below:
|
||||
|
@ -29,6 +29,17 @@ function update_time() {
|
||||
function setup() {
|
||||
update_time();
|
||||
setInterval(update_time, 1000);
|
||||
|
||||
if (location.hostname != 'tests' && location.hostname != 'localhost') {
|
||||
alert('Parts of this page can only be run from tests or localhost.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable all elements.
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function show_file_dialog(element, test) {
|
||||
@ -49,16 +60,16 @@ window.addEventListener('load', setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<form>
|
||||
<form id="form">
|
||||
Click a button to show the associated dialog type.
|
||||
<br/><input type="button" onclick="show_alert();" value="Show Alert">
|
||||
<br/><input type="button" onclick="show_confirm();" value="Show Confirm"> <span id="cm"></span>
|
||||
<br/><input type="button" onclick="show_prompt();" value="Show Prompt"> <span id="pm"></span>
|
||||
<br/>input type="file": <input type="file" name="pic" accept="text/*,.js,.css,image/*">
|
||||
<br/><input type="button" onclick="show_file_dialog('fo', 'FileOpen');" value="Show File Open"> <span id="fo"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fom', 'FileOpenMultiple');" value="Show File Open Multiple"> <span id="fom"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fof', 'FileOpenFolder');" value="Show File Open Folder"> <span id="fof"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fs', 'FileSave');" value="Show File Save"> <span id="fs"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fo', 'FileOpen');" value="Show File Open" disabled="true"> <span id="fo"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fom', 'FileOpenMultiple');" value="Show File Open Multiple" disabled="true"> <span id="fom"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fof', 'FileOpenFolder');" value="Show File Open Folder" disabled="true"> <span id="fof"></span>
|
||||
<br/><input type="button" onclick="show_file_dialog('fs', 'FileSave');" value="Show File Save" disabled="true"> <span id="fs"></span>
|
||||
<p id="time"></p>
|
||||
</form>
|
||||
</body>
|
||||
|
@ -3,6 +3,21 @@
|
||||
<title>DRM Test</title>
|
||||
<script language="JavaScript">
|
||||
|
||||
function setup() {
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost')
|
||||
return;
|
||||
|
||||
alert('This page can only be run from tests or localhost.');
|
||||
|
||||
// Disable all elements.
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = true;
|
||||
}
|
||||
|
||||
doTest();
|
||||
}
|
||||
|
||||
// Based on DRM detection code from https://github.com/google/shaka-player
|
||||
function probeSupport() {
|
||||
var tests = [];
|
||||
@ -87,7 +102,7 @@ function sendMessage() {
|
||||
request.widevine_cdm_path =
|
||||
document.getElementById("widevine_cdm_path").value;
|
||||
|
||||
// Results in a call to the OnQuery method in drm_test.cpp
|
||||
// Results in a call to the OnQuery method in drm_test.cc
|
||||
window.cefQuery({
|
||||
request: JSON.stringify(request),
|
||||
onSuccess: function(response) {
|
||||
@ -104,7 +119,7 @@ function sendMessage() {
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body bgcolor="white" onload="doTest()">
|
||||
<body bgcolor="white" onload="setup()">
|
||||
Important notes:
|
||||
<ul>
|
||||
<li>Clearkey support is built in and should always be enabled.</li>
|
||||
@ -117,7 +132,7 @@ Important notes:
|
||||
<li>Test DRM video playback <a href="https://shaka-player-demo.appspot.com/demo/">here</a>. Select an "asset" that includes Clearkey or Widevine in the name.</li>
|
||||
</ul>
|
||||
|
||||
<form>
|
||||
<form id="form">
|
||||
Widevine CDM Path: <input type="text" id="widevine_cdm_path" value="" size="40">
|
||||
<input type="button" onclick="sendMessage();" value="Load CDM">
|
||||
</form>
|
||||
|
@ -8,32 +8,34 @@
|
||||
<li><a href="http://mudcu.be/labs/JS1k/BreathingGalaxies.html">Accelerated 2D Canvas</a></li>
|
||||
<li><a href="http://webkit.org/blog-files/3d-transforms/poster-circle.html">Accelerated Layers</a></li>
|
||||
<li><a href="http://html5advent2011.digitpaint.nl/3/index.html">Cursors</a></li>
|
||||
<li><a href="http://tests/dialogs">Dialogs</a></li>
|
||||
<li><a href="dialogs">Dialogs</a></li>
|
||||
<li><a href="http://html5demos.com/drag">Drag & Drop</a></li>
|
||||
<li><a href="http://tests/draggable">Draggable Regions</a></li>
|
||||
<li><a href="http://tests/drm">DRM (Clearkey, Widevine)</a></li>
|
||||
<li><a href="draggable">Draggable Regions</a></li>
|
||||
<li><a href="drm">DRM (Clearkey, Widevine)</a></li>
|
||||
<li><a href="http://www.adobe.com/software/flash/about/">Flash Plugin</a> - requires "enable-system-flash" flag on Win/Mac and "ppapi-flash-path", "ppapi-flash-version" flags on Linux</li>
|
||||
<li><a href="http://html5demos.com/geo">Geolocation</a></li>
|
||||
<li><a href="http://www.html5test.com">HTML5 Feature Test</a></li>
|
||||
<li><a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html">HTML5 Filesystem</a> - requires "cache-path" flag</li>
|
||||
<li><a href="http://www.youtube.com/watch?v=siOHh0uzcuY&html5=True">HTML5 Video</a></li>
|
||||
<li><a href="http://tests/binding">JavaScript Binding</a></li>
|
||||
<li><a href="http://tests/performance">JavaScript Performance Tests</a></li>
|
||||
<li><a href="http://tests/performance2">JavaScript Performance (2) Tests</a></li>
|
||||
<li><a href="http://tests/window">JavaScript Window Manipulation</a></li>
|
||||
<li><a href="http://tests/localstorage">Local Storage</a></li>
|
||||
<li><a href="http://tests/pdf.pdf">PDF Viewer direct</a></li>
|
||||
<li><a href="http://tests/pdf">PDF Viewer iframe</a></li>
|
||||
<li><a href="http://tests/preferences">Preferences</a></li>
|
||||
<li><a href="binding">JavaScript Binding</a></li>
|
||||
<li><a href="performance">JavaScript Performance Tests</a></li>
|
||||
<li><a href="performance2">JavaScript Performance (2) Tests</a></li>
|
||||
<li><a href="window">JavaScript Window Manipulation</a></li>
|
||||
<li><a href="localstorage">Local Storage</a></li>
|
||||
<li><a href="pdf.pdf">PDF Viewer direct</a></li>
|
||||
<li><a href="pdf">PDF Viewer iframe</a></li>
|
||||
<li><a href="preferences">Preferences</a></li>
|
||||
<li><a href="http://mrdoob.com/lab/javascript/requestanimationframe/">requestAnimationFrame</a></li>
|
||||
<li><a href="http://tests/response_filter">Response Filtering</a></li>
|
||||
<li><a href="response_filter">Response Filtering</a></li>
|
||||
<li><a href="client://tests/handler.html">Scheme Handler</a></li>
|
||||
<li><a href="server">HTTP/WebSocket Server</a></li>
|
||||
<li><a href="websocket">WebSocket Client</a></li>
|
||||
<li><a href="https://www.google.com/intl/en/chrome/demos/speech.html">Speech Input</a> - requires "enable-speech-input" flag</li>
|
||||
<li><a href="http://tests/transparency">Transparency</a></li>
|
||||
<li><a href="transparency">Transparency</a></li>
|
||||
<li><a href="http://webglsamples.org/field/field.html">WebGL</a></li>
|
||||
<li><a href="http://apprtc.appspot.com/">WebRTC</a> - requires "enable-media-stream" flag</li>
|
||||
<li><a href="http://tests/urlrequest">CefURLRequest</a></li>
|
||||
<li><a href="http://tests/xmlhttprequest">XMLHttpRequest</a></li>
|
||||
<li><a href="urlrequest">CefURLRequest</a></li>
|
||||
<li><a href="xmlhttprequest">XMLHttpRequest</a></li>
|
||||
<li><a href="javascript:window.print();">Print this page with "javascript:window.print();"</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
|
@ -10,8 +10,23 @@
|
||||
script hosting from http://cdnjs.com/libraries/jsoneditor -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.1/jsoneditor.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.1/jsoneditor.min.js"></script>
|
||||
|
||||
<script>
|
||||
function setup() {
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost')
|
||||
return;
|
||||
|
||||
alert('This page can only be run from tests or localhost.');
|
||||
|
||||
// Disable all elements.
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<!-- Header -->
|
||||
<div id="simple_links">
|
||||
[ <b>Simple</b> ]
|
||||
@ -22,6 +37,8 @@
|
||||
[ <b>Advanced</b> ]
|
||||
</div>
|
||||
|
||||
<form id="form">
|
||||
|
||||
<!-- Simple view -->
|
||||
<div id="simple">
|
||||
<p>
|
||||
@ -88,6 +105,8 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Reference to the JSONEditor.
|
||||
var editor = null;
|
||||
|
104
tests/cefclient/resources/server.html
Normal file
104
tests/cefclient/resources/server.html
Normal file
@ -0,0 +1,104 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Server Test</title>
|
||||
<script language="JavaScript">
|
||||
|
||||
// Send a query to the browser process.
|
||||
function sendMessage(request, success_callback) {
|
||||
// Results in a call to the OnQuery method in server_test.cc
|
||||
window.cefQuery({
|
||||
request: JSON.stringify(request),
|
||||
onSuccess: function(response) {
|
||||
success_callback(response.length == 0 ? {} : JSON.parse(response));
|
||||
},
|
||||
onFailure: function(error_code, error_message) {
|
||||
alert("Request failed with error " + error_message + "(" + error_code + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setButtonState(start_enabled, stop_enabled) {
|
||||
document.getElementById('start').disabled = !start_enabled;
|
||||
document.getElementById('stop').disabled = !stop_enabled;
|
||||
document.getElementById('open').disabled = !stop_enabled;
|
||||
}
|
||||
|
||||
function setup() {
|
||||
if (location.origin != 'http://tests') {
|
||||
document.getElementById('warning').style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the current server state.
|
||||
sendMessage({'action':'query'}, function(response) {
|
||||
if (response['result'] == 'success') {
|
||||
var running = (response['status'] == 'running')
|
||||
setButtonState(!running, running);
|
||||
|
||||
var port_element = document.getElementById('port');
|
||||
port_element.value = response['port'];
|
||||
port_element.disabled = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function startServer() {
|
||||
var port = parseInt(document.getElementById('port').value);
|
||||
if (port < 1025 || port > 65535) {
|
||||
alert('Specify a port number between 1025 and 65535');
|
||||
return;
|
||||
}
|
||||
|
||||
setButtonState(false, false);
|
||||
|
||||
sendMessage({'action':'start', 'port':port}, function(response) {
|
||||
if (response['result'] == 'success') {
|
||||
setButtonState(false, true);
|
||||
} else {
|
||||
setButtonState(true, false);
|
||||
alert(response['message']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function stopServer() {
|
||||
setButtonState(false, false);
|
||||
|
||||
sendMessage({'action':'stop'}, function(response) {
|
||||
if (response['result'] == 'success') {
|
||||
setButtonState(true, false);
|
||||
} else {
|
||||
setButtonState(false, true);
|
||||
alert(response['message']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openServer() {
|
||||
var port = document.getElementById('port').value;
|
||||
window.open('http://localhost:' + port);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<div id="warning" style="display:none;color:red;font-weight:bold;">
|
||||
This page can only be run from the http://tests origin.
|
||||
</div>
|
||||
<p>
|
||||
This page starts an HTTP/WebSocket server on localhost with the specified port number.
|
||||
After starting the server click the "Open Example" button to open the WebSocket Client test in a popup window.
|
||||
</p>
|
||||
<p>
|
||||
With this example each browser window can create/manage a separate server instance.
|
||||
The server will be stopped automatically when the managing browser window is closed.
|
||||
</p>
|
||||
<form>
|
||||
Server port: <input type="text" id="port" value="" disabled="true">
|
||||
<br/><input type="button" id="start" onclick="startServer()" value="Start Server" disabled="true">
|
||||
<input type="button" id="stop" onclick="stopServer()" value="Stop Server" disabled="true">
|
||||
<input type="button" id="open" onclick="openServer()" value="Open Example" disabled="true">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -1,7 +1,20 @@
|
||||
<html>
|
||||
<body bgcolor="white">
|
||||
<head>
|
||||
<script language="JavaScript">
|
||||
|
||||
function setup() {
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost')
|
||||
return;
|
||||
|
||||
alert('This page can only be run from tests or localhost');
|
||||
|
||||
// Disable all elements.
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a query to the browser process.
|
||||
function execURLRequest() {
|
||||
document.getElementById('ta').value = 'Request pending...';
|
||||
@ -18,7 +31,9 @@ function execURLRequest() {
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<form>
|
||||
</head>
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<form id="form">
|
||||
URL: <input type="text" id="url" value="http://www.google.com">
|
||||
<br/><input type="button" onclick="execURLRequest();" value="Execute CefURLRequest">
|
||||
<br/><textarea rows="10" cols="40" id="ta"></textarea>
|
||||
|
107
tests/cefclient/resources/websocket.html
Normal file
107
tests/cefclient/resources/websocket.html
Normal file
@ -0,0 +1,107 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>WebSocket Test</title>
|
||||
<script language="JavaScript">
|
||||
|
||||
var ws = null;
|
||||
|
||||
function setup() {
|
||||
// Match the secure state of the current origin.
|
||||
var origin = location.origin;
|
||||
if (origin.indexOf('http://') == 0) {
|
||||
origin = origin.replace('http://', 'ws://');
|
||||
} else if (origin.indexOf('https://') == 0) {
|
||||
origin = origin.replace('https://', 'wss://');
|
||||
} else {
|
||||
origin = '';
|
||||
}
|
||||
|
||||
if (origin.length > 0)
|
||||
document.getElementById('server').value = origin;
|
||||
document.getElementById('server').disabled = false;
|
||||
|
||||
if (location.hostname != 'localhost')
|
||||
document.getElementById('warning').style.display = 'block';
|
||||
|
||||
setConnected(false);
|
||||
}
|
||||
|
||||
function setConnected(connected) {
|
||||
document.getElementById('connect').disabled = connected;
|
||||
document.getElementById('disconnect').disabled = !connected;
|
||||
document.getElementById('message').disabled = !connected;
|
||||
document.getElementById('response').disabled = !connected;
|
||||
document.getElementById('send').disabled = !connected;
|
||||
}
|
||||
|
||||
function doConnect() {
|
||||
var url = document.getElementById('server').value;
|
||||
if (url.indexOf('ws://') < 0 && url.indexOf('wss://') < 0) {
|
||||
alert('Specify a valid WebSocket server URL.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (ws) {
|
||||
alert('WebSocket is already connected.');
|
||||
return;
|
||||
}
|
||||
|
||||
ws = new WebSocket(url);
|
||||
ws.onopen = function() { setConnected(true); };
|
||||
ws.onmessage = function(event) {
|
||||
document.getElementById('response').value = event.data;
|
||||
};
|
||||
ws.onclose = function(event) {
|
||||
setConnected(false);
|
||||
ws = null;
|
||||
};
|
||||
ws.onerror = function(event) {
|
||||
if (ws.readyState == 3)
|
||||
alert('WebSocket connection failed.');
|
||||
}
|
||||
}
|
||||
|
||||
function doDisconnect() {
|
||||
if (!ws) {
|
||||
alert('WebSocket is not currently connected.');
|
||||
return;
|
||||
}
|
||||
|
||||
ws.close();
|
||||
}
|
||||
|
||||
function doSend() {
|
||||
if (!ws) {
|
||||
alert('WebSocket is not currently connected.');
|
||||
return;
|
||||
}
|
||||
|
||||
var value = document.getElementById('message').value;
|
||||
if (value.length > 0)
|
||||
ws.send(value);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<div id="warning" style="display:none;color:red;font-weight:bold;">
|
||||
This page is most useful when loaded from localhost.
|
||||
You should first create a server using the <a href="http://tests/server">HTTP/WebSocket Server test</a>.
|
||||
</div>
|
||||
<p>
|
||||
This page tests a WebSocket connection.
|
||||
The example implementation in server_test.cc will then echo the message contents in reverse.
|
||||
</p>
|
||||
<form>
|
||||
Server URL: <input type="text" id="server" value="" disabled="true">
|
||||
<br/><input type="button" id="connect" onclick="doConnect()" value="Connect" disabled="true">
|
||||
<input type="button" id="disconnect" onclick="doDisconnect()" value="Disconnect" disabled="true">
|
||||
<br/>Message: <input type="text" id="message" value="Test Message" disabled="true">
|
||||
<input type="button" id="send" onclick="doSend()" value="Send" disabled="true">
|
||||
<br/>Response: <input type="text" id="response" value="" disabled="true">
|
||||
<br/><br/>
|
||||
The example implementation in server_test.cc can also serve the HTTP-based <a href="other_tests">Other Tests</a>.
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -45,8 +45,10 @@ IDS_PERFORMANCE_HTML BINARY "..\\performance.html"
|
||||
IDS_PERFORMANCE2_HTML BINARY "..\\performance2.html"
|
||||
IDS_PREFERENCES_HTML BINARY "..\\preferences.html"
|
||||
IDS_RESPONSE_FILTER_HTML BINARY "..\\response_filter.html"
|
||||
IDS_SERVER_HTML BINARY "..\\server.html"
|
||||
IDS_TRANSPARENCY_HTML BINARY "..\\transparency.html"
|
||||
IDS_URLREQUEST_HTML BINARY "..\\urlrequest.html"
|
||||
IDS_WEBSOCKET_HTML BINARY "..\\websocket.html"
|
||||
IDS_WINDOW_HTML BINARY "..\\window.html"
|
||||
IDS_WINDOW_ICON_1X_PNG BINARY "..\\..\\..\\shared\\resources\\window_icon.1x.png"
|
||||
IDS_WINDOW_ICON_2X_PNG BINARY "..\\..\\..\\shared\\resources\\window_icon.2x.png"
|
||||
|
@ -2,6 +2,19 @@
|
||||
<head>
|
||||
<title>Window Test</title>
|
||||
<script>
|
||||
function setup() {
|
||||
if (location.hostname == 'tests' || location.hostname == 'localhost')
|
||||
return;
|
||||
|
||||
alert('This page can only be run from tests or localhost.');
|
||||
|
||||
// Disable all elements.
|
||||
var elements = document.getElementById("form").elements;
|
||||
for (var i = 0, element; element = elements[i++]; ) {
|
||||
element.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
function send_message(test, params) {
|
||||
var message = 'WindowTest.' + test;
|
||||
if (typeof params != 'undefined')
|
||||
@ -36,13 +49,17 @@ function position() {
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<form>
|
||||
<body bgcolor="white" onload="setup()">
|
||||
<form id="form">
|
||||
Click a button to perform the associated window action.
|
||||
<br/><input type="button" onclick="minimize();" value="Minimize">
|
||||
<br/><input type="button" onclick="maximize();" value="Maximize">
|
||||
<br/><input type="button" onclick="restore();" value="Restore"> (minimizes and then restores the window as topmost)
|
||||
<br/><input type="button" onclick="position();" value="Set Position"> X: <input type="text" size="4" id="x" value="200"> Y: <input type="text" size="4" id="y" value="100"> Width: <input type="text" size="4" id="width" value="800"> Height: <input type="text" size="4" id="height" value="600">
|
||||
<br/><input type="button" onclick="position();" value="Set Position">
|
||||
X: <input type="text" size="4" id="x" value="200">
|
||||
Y: <input type="text" size="4" id="y" value="100">
|
||||
Width: <input type="text" size="4" id="width" value="800">
|
||||
Height: <input type="text" size="4" id="height" value="600">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -3,8 +3,20 @@
|
||||
<script language="JavaScript">
|
||||
function execXMLHttpRequest()
|
||||
{
|
||||
var url = document.getElementById("url").value;
|
||||
var warningElement = document.getElementById("warning");
|
||||
if (url.indexOf(location.origin) != 0) {
|
||||
warningElement.innerHTML =
|
||||
'For cross-origin requests to succeed the server must return CORS headers:' +
|
||||
'<pre>Access-Control-Allow-Origin: ' + location.origin +
|
||||
'<br/>Access-Control-Allow-Header: My-Custom-Header</pre>';
|
||||
warningElement.style.display = 'block';
|
||||
} else {
|
||||
warningElement.style.display = 'none';
|
||||
}
|
||||
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", document.getElementById("url").value, true);
|
||||
xhr.open("GET", url, true);
|
||||
xhr.setRequestHeader('My-Custom-Header', 'Some Value');
|
||||
xhr.onload = function(e) {
|
||||
if (xhr.readyState === 4) {
|
||||
@ -22,5 +34,6 @@ URL: <input type="text" id="url" value="http://tests/request">
|
||||
<br/><input type="button" onclick="execXMLHttpRequest();" value="Execute XMLHttpRequest">
|
||||
<br/><textarea rows="10" cols="40" id="ta"></textarea>
|
||||
</form>
|
||||
<div id="warning" style="display:none;font-weight:bold;"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
1480
tests/ceftests/server_unittest.cc
Normal file
1480
tests/ceftests/server_unittest.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -352,6 +352,8 @@ _simpletypes = {
|
||||
'void': ['void', ''],
|
||||
'void*': ['void*', 'NULL'],
|
||||
'int': ['int', '0'],
|
||||
'int16': ['int16', '0'],
|
||||
'uint16': ['uint16', '0'],
|
||||
'int32': ['int32', '0'],
|
||||
'uint32': ['uint32', '0'],
|
||||
'int64': ['int64', '0'],
|
||||
|
Loading…
x
Reference in New Issue
Block a user