blob: 5bea1ddcde601fddbc4753695e40ff503fbab590 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The callback server listens for http connections on port 5199 (by default),
// and dispatches valid requests to javascript function registered by the
// policy.
// The incoming request must be an HTTP POST (libevent doesn't have an https
// server) to the uri "/dispatch". It must have a content-type of
// "application/json", an "X-Entd-Request" header set to "magic", and a
// request entity no larger than 1k which represents a valid JSON object.
// The JSON object must have a property named "function" which contains the
// function name we want to dispatch, and may optionally contain an property
// named "argument", which is passed as the only argument to the target
// function.
// A policy can opt in to starting the callback server by calling
// "entd.callbackServer.start(callbacks[, port]). The callbacks parameter is
// required and must be a js object containing the callbacks to be served.
// The optional port can be used to specify the port to listen on. The server
// will bind to only.
#include <base/basictypes.h>
#include <base/logging.h>
#include <event.h>
#include <evhttp.h>
#include <v8.h>
#include "entd/js_object_wrapper.h"
#include "entd/utils.h"
namespace entd {
class Entd;
class CallbackServer : public JSObjectWrapper<CallbackServer> {
explicit CallbackServer(Entd* entd);
virtual ~CallbackServer();
// JSObjectWrapper methods
static const char* GetClassName() { return "CallbackServer"; }
static void SetTemplateBindings(
v8::Handle<v8::ObjectTemplate> template_object);
// Initialize the CallbackServer instance. Must be called before any
// other method.
virtual bool Initialize() {
return true;
virtual std::string request_header_value() {
return request_header_value_;
virtual void set_request_header_value(std::string value) {
request_header_value_ = value;
// Start the callback server with a particular set of callbacks and
// on a given port number.
virtual bool Start(v8::Handle<v8::Object> callbacks, int port);
// Stop the server.
virtual void Stop();
// Return true if the callback server has been started.
virtual bool IsRunning();
// Dispatch a given http request.
virtual void OnRequest(struct evhttp_request* request);
// Sets whether or not the server is busy. While busy, it cannot be stopped.
// This should only matter when someone attempts to stop the server from
// script during a callback. In other cases, the single threadedness of
// entd should keep us from ever trying to stop while busy. This is not
// nestable.
virtual void SetBusy(bool state) {
if (state == busy_)
LOG(WARNING) << "Busy status is already " << (state ? "set" : "clear");
busy_ = state;
virtual bool IsBusy() { return busy_; }
static std::string required_origin;
// State for SetBusy/IsBusy.
bool busy_;
// Parent entd object.
Entd* entd_;
// JS Object containing the callback functions we might dispatch to.
v8::Persistent<v8::Object> callbacks_;
// The value required in the X-Entd-Request header.
std::string request_header_value_;
// Non-null if the server is running.
struct evhttp* evhttp_;
// Port we're listening on, or 0 if not running.
int port_;
} // namespace entd