blob: 7b417be0fbc53ab1c0b9f2f2a289c508808aaa7d [file] [log] [blame]
// Copyright 2014 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.
#ifndef LIBWEBSERV_SERVER_H_
#define LIBWEBSERV_SERVER_H_
#include <map>
#include <memory>
#include <string>
#include <base/callback_forward.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/strings/string_piece.h>
#include "libwebserv/export.h"
#include "libwebserv/request_handler_interface.h"
struct MHD_Daemon;
namespace base {
class TaskRunner;
} // namespace base
namespace libwebserv {
// Top-level wrapper class around HTTP server and provides an interface to
// the web server. It allows the users to start the server and
// register request handlers.
class LIBWEBSERV_EXPORT Server final {
public:
Server();
~Server();
// Starts the server and makes it listen to requests on the given port.
bool Start(uint16_t port);
// Stops the server.
bool Stop();
// Adds a request handler for given |url|. If the |url| ends with a '/', this
// makes the handler respond to any URL beneath this path.
// Note that it is not possible to add a specific handler just for the root
// path "/". Doing so means "respond to any URL".
// |method| is optional request method verb, such as "GET" or "POST".
// If |method| is empty, the handler responds to any request verb.
// If there are more than one handler for a given request, the most specific
// match is chosen. For example, if there are the following handlers provided:
// - A["/foo/", ""]
// - B["/foo/bar", "GET"]
// - C["/foo/bar", ""]
// Here is what handlers are called when making certain requests:
// - GET("/foo/bar") => B[]
// - POST("/foo/bar") => C[]
// - PUT("/foo/bar") => C[]
// - GET("/foo/baz") => A[]
// - GET("/foo") => 404 Not Found
// This functions returns a handler ID which can be used later to remove
// the handler.
int AddHandler(const base::StringPiece& url,
const base::StringPiece& method,
std::unique_ptr<RequestHandlerInterface> handler);
// Similar to AddHandler() above but the handler is just a callback function.
int AddHandlerCallback(
const base::StringPiece& url,
const base::StringPiece& method,
const base::Callback<RequestHandlerInterface::HandlerSignature>&
handler_callback);
// Removes the handler with the specified |handler_id|.
// Returns false if the handler with the given ID is not found.
bool RemoveHandler(int handler_id);
// Finds the handler ID given the exact match criteria. Note that using
// this function could cause unexpected side effects if there are more than
// one handler registered for given URL/Method parameters.
// It is better to remember the handler ID from AddHandler() method and use
// that ID to remove the handler, instead of looking the handler up using
// URL/Method.
int GetHandlerId(const base::StringPiece& url,
const base::StringPiece& method) const;
// Finds a handler for given URL/Method. This method does the criteria
// matching and not exact match performed by GetHandlerId. This is the method
// used to look up the handler for incoming HTTP requests.
RequestHandlerInterface* FindHandler(
const base::StringPiece& url,
const base::StringPiece& method) const;
private:
MHD_Daemon* server_ = nullptr;
scoped_refptr<base::TaskRunner> task_runner_;
struct LIBWEBSERV_PRIVATE HandlerMapEntry {
std::string url;
std::string method;
std::unique_ptr<RequestHandlerInterface> handler;
};
std::map<int, HandlerMapEntry> request_handlers_;
int last_handler_id_{0};
friend class ServerHelper;
friend class Connection;
DISALLOW_COPY_AND_ASSIGN(Server);
};
} // namespace libwebserv
#endif // LIBWEBSERV_SERVER_H_