blob: 6221115a46be09999776e5e2be94672742ddce1b [file] [log] [blame]
Alex Vakulenko039da312015-02-03 08:58:55 -08001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef WEBSERVER_LIBWEBSERV_SERVER_H_
6#define WEBSERVER_LIBWEBSERV_SERVER_H_
7
8#include <map>
9#include <memory>
10#include <string>
11
12#include <base/callback_forward.h>
13#include <base/macros.h>
14#include <base/memory/ref_counted.h>
15#include <base/strings/string_piece.h>
16#include <chromeos/secure_blob.h>
17#include <libwebserv/export.h>
18#include <libwebserv/request_handler_interface.h>
19
20struct MHD_Daemon;
21
22namespace base {
23class TaskRunner;
24} // namespace base
25
26namespace libwebserv {
27
28// Top-level wrapper class around HTTP server and provides an interface to
29// the web server. It allows the users to start the server and
30// register request handlers.
31class LIBWEBSERV_EXPORT Server final {
32 public:
33 Server();
34 ~Server();
35
36 // Starts the server and makes it listen to HTTP requests on the given port.
37 //
38 // Note that a valid message loop must exist before calling Start.
39 bool Start(uint16_t port);
40
41 // Starts the server and makes it listen to HTTPS requests on the given port.
42 //
43 // Note that a valid message loop must exist before calling StartWithTLS.
44 bool StartWithTLS(uint16_t port,
45 const chromeos::SecureBlob& private_key,
46 const chromeos::Blob& certificate);
47
48 // Stops the server.
49 bool Stop();
50
51 // Adds a request handler for given |url|. If the |url| ends with a '/', this
52 // makes the handler respond to any URL beneath this path.
53 // Note that it is not possible to add a specific handler just for the root
54 // path "/". Doing so means "respond to any URL".
55 // |method| is optional request method verb, such as "GET" or "POST".
56 // If |method| is empty, the handler responds to any request verb.
57 // If there are more than one handler for a given request, the most specific
58 // match is chosen. For example, if there are the following handlers provided:
59 // - A["/foo/", ""]
60 // - B["/foo/bar", "GET"]
61 // - C["/foo/bar", ""]
62 // Here is what handlers are called when making certain requests:
63 // - GET("/foo/bar") => B[]
64 // - POST("/foo/bar") => C[]
65 // - PUT("/foo/bar") => C[]
66 // - GET("/foo/baz") => A[]
67 // - GET("/foo") => 404 Not Found
68 // This functions returns a handler ID which can be used later to remove
69 // the handler.
70 int AddHandler(const base::StringPiece& url,
71 const base::StringPiece& method,
72 std::unique_ptr<RequestHandlerInterface> handler);
73
74 // Similar to AddHandler() above but the handler is just a callback function.
75 int AddHandlerCallback(
76 const base::StringPiece& url,
77 const base::StringPiece& method,
78 const base::Callback<RequestHandlerInterface::HandlerSignature>&
79 handler_callback);
80
81 // Removes the handler with the specified |handler_id|.
82 // Returns false if the handler with the given ID is not found.
83 bool RemoveHandler(int handler_id);
84
85 // Finds the handler ID given the exact match criteria. Note that using
86 // this function could cause unexpected side effects if there are more than
87 // one handler registered for given URL/Method parameters.
88 // It is better to remember the handler ID from AddHandler() method and use
89 // that ID to remove the handler, instead of looking the handler up using
90 // URL/Method.
91 int GetHandlerId(const base::StringPiece& url,
92 const base::StringPiece& method) const;
93
94 // Finds a handler for given URL/Method. This method does the criteria
95 // matching and not exact match performed by GetHandlerId. This is the method
96 // used to look up the handler for incoming HTTP requests.
97 RequestHandlerInterface* FindHandler(
98 const base::StringPiece& url,
99 const base::StringPiece& method) const;
100
101 private:
102 MHD_Daemon* server_ = nullptr;
103 scoped_refptr<base::TaskRunner> task_runner_;
104
105 struct LIBWEBSERV_PRIVATE HandlerMapEntry {
106 std::string url;
107 std::string method;
108 std::unique_ptr<RequestHandlerInterface> handler;
109 };
110
111 std::map<int, HandlerMapEntry> request_handlers_;
112 int last_handler_id_{0};
113
114 friend class ServerHelper;
115 friend class Connection;
116 DISALLOW_COPY_AND_ASSIGN(Server);
117};
118
119} // namespace libwebserv
120
121#endif // WEBSERVER_LIBWEBSERV_SERVER_H_