xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/Debuginfod/HTTPServer.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1753f127fSDimitry Andric //===-- llvm/Debuginfod/HTTPServer.h - HTTP server library ------*- C++ -*-===//
2753f127fSDimitry Andric //
3753f127fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4753f127fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5753f127fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6753f127fSDimitry Andric //
7753f127fSDimitry Andric //===----------------------------------------------------------------------===//
8753f127fSDimitry Andric ///
9753f127fSDimitry Andric /// \file
10753f127fSDimitry Andric /// This file contains the declarations of the HTTPServer and HTTPServerRequest
11753f127fSDimitry Andric /// classes, the HTTPResponse, and StreamingHTTPResponse structs, and the
12753f127fSDimitry Andric /// streamFile function.
13753f127fSDimitry Andric ///
14753f127fSDimitry Andric //===----------------------------------------------------------------------===//
15753f127fSDimitry Andric 
16fcaf7f86SDimitry Andric #ifndef LLVM_DEBUGINFOD_HTTPSERVER_H
17fcaf7f86SDimitry Andric #define LLVM_DEBUGINFOD_HTTPSERVER_H
18753f127fSDimitry Andric 
19753f127fSDimitry Andric #include "llvm/ADT/StringRef.h"
20753f127fSDimitry Andric #include "llvm/Support/Error.h"
21753f127fSDimitry Andric 
22753f127fSDimitry Andric #ifdef LLVM_ENABLE_HTTPLIB
23753f127fSDimitry Andric // forward declarations
24753f127fSDimitry Andric namespace httplib {
25753f127fSDimitry Andric class Request;
26753f127fSDimitry Andric class Response;
27753f127fSDimitry Andric class Server;
28753f127fSDimitry Andric } // namespace httplib
29753f127fSDimitry Andric #endif
30753f127fSDimitry Andric 
31753f127fSDimitry Andric namespace llvm {
32753f127fSDimitry Andric 
33753f127fSDimitry Andric struct HTTPResponse;
34753f127fSDimitry Andric struct StreamingHTTPResponse;
35753f127fSDimitry Andric class HTTPServer;
36753f127fSDimitry Andric 
37*06c3fb27SDimitry Andric class HTTPServerError : public ErrorInfo<HTTPServerError, ECError> {
38*06c3fb27SDimitry Andric public:
39*06c3fb27SDimitry Andric   static char ID;
40*06c3fb27SDimitry Andric   HTTPServerError(const Twine &Msg);
41*06c3fb27SDimitry Andric   void log(raw_ostream &OS) const override;
42*06c3fb27SDimitry Andric 
43*06c3fb27SDimitry Andric private:
44*06c3fb27SDimitry Andric   std::string Msg;
45*06c3fb27SDimitry Andric };
46*06c3fb27SDimitry Andric 
47753f127fSDimitry Andric class HTTPServerRequest {
48753f127fSDimitry Andric   friend HTTPServer;
49753f127fSDimitry Andric 
50753f127fSDimitry Andric #ifdef LLVM_ENABLE_HTTPLIB
51753f127fSDimitry Andric private:
52753f127fSDimitry Andric   HTTPServerRequest(const httplib::Request &HTTPLibRequest,
53753f127fSDimitry Andric                     httplib::Response &HTTPLibResponse);
54753f127fSDimitry Andric   httplib::Response &HTTPLibResponse;
55753f127fSDimitry Andric #endif
56753f127fSDimitry Andric 
57753f127fSDimitry Andric public:
58753f127fSDimitry Andric   std::string UrlPath;
59753f127fSDimitry Andric   /// The elements correspond to match groups in the url path matching regex.
60753f127fSDimitry Andric   SmallVector<std::string, 1> UrlPathMatches;
61753f127fSDimitry Andric 
62753f127fSDimitry Andric   // TODO bring in HTTP headers
63753f127fSDimitry Andric 
64753f127fSDimitry Andric   void setResponse(StreamingHTTPResponse Response);
65753f127fSDimitry Andric   void setResponse(HTTPResponse Response);
66753f127fSDimitry Andric };
67753f127fSDimitry Andric 
68753f127fSDimitry Andric struct HTTPResponse {
69753f127fSDimitry Andric   unsigned Code;
70753f127fSDimitry Andric   const char *ContentType;
71753f127fSDimitry Andric   StringRef Body;
72753f127fSDimitry Andric };
73753f127fSDimitry Andric 
74753f127fSDimitry Andric typedef std::function<void(HTTPServerRequest &)> HTTPRequestHandler;
75753f127fSDimitry Andric 
76753f127fSDimitry Andric /// An HTTPContentProvider is called by the HTTPServer to obtain chunks of the
77753f127fSDimitry Andric /// streaming response body. The returned chunk should be located at Offset
78753f127fSDimitry Andric /// bytes and have Length bytes.
79753f127fSDimitry Andric typedef std::function<StringRef(size_t /*Offset*/, size_t /*Length*/)>
80753f127fSDimitry Andric     HTTPContentProvider;
81753f127fSDimitry Andric 
82753f127fSDimitry Andric /// Wraps the content provider with HTTP Status code and headers.
83753f127fSDimitry Andric struct StreamingHTTPResponse {
84753f127fSDimitry Andric   unsigned Code;
85753f127fSDimitry Andric   const char *ContentType;
86753f127fSDimitry Andric   size_t ContentLength;
87753f127fSDimitry Andric   HTTPContentProvider Provider;
88753f127fSDimitry Andric   /// Called after the response transfer is complete with the success value of
89753f127fSDimitry Andric   /// the transfer.
90753f127fSDimitry Andric   std::function<void(bool)> CompletionHandler = [](bool Success) {};
91753f127fSDimitry Andric };
92753f127fSDimitry Andric 
93753f127fSDimitry Andric /// Sets the response to stream the file at FilePath, if available, and
94753f127fSDimitry Andric /// otherwise an HTTP 404 error response.
95753f127fSDimitry Andric bool streamFile(HTTPServerRequest &Request, StringRef FilePath);
96753f127fSDimitry Andric 
97753f127fSDimitry Andric /// An HTTP server which can listen on a single TCP/IP port for HTTP
98753f127fSDimitry Andric /// requests and delgate them to the appropriate registered handler.
99753f127fSDimitry Andric class HTTPServer {
100753f127fSDimitry Andric #ifdef LLVM_ENABLE_HTTPLIB
101753f127fSDimitry Andric   std::unique_ptr<httplib::Server> Server;
102753f127fSDimitry Andric   unsigned Port = 0;
103753f127fSDimitry Andric #endif
104753f127fSDimitry Andric public:
105753f127fSDimitry Andric   HTTPServer();
106753f127fSDimitry Andric   ~HTTPServer();
107753f127fSDimitry Andric 
108753f127fSDimitry Andric   /// Returns true only if LLVM has been compiled with a working HTTPServer.
109753f127fSDimitry Andric   static bool isAvailable();
110753f127fSDimitry Andric 
111753f127fSDimitry Andric   /// Registers a URL pattern routing rule. When the server is listening, each
112753f127fSDimitry Andric   /// request is dispatched to the first registered handler whose UrlPathPattern
113753f127fSDimitry Andric   /// matches the UrlPath.
114753f127fSDimitry Andric   Error get(StringRef UrlPathPattern, HTTPRequestHandler Handler);
115753f127fSDimitry Andric 
116753f127fSDimitry Andric   /// Attempts to assign the requested port and interface, returning an Error
117753f127fSDimitry Andric   /// upon failure.
118753f127fSDimitry Andric   Error bind(unsigned Port, const char *HostInterface = "0.0.0.0");
119753f127fSDimitry Andric 
120753f127fSDimitry Andric   /// Attempts to assign any available port and interface, returning either the
121753f127fSDimitry Andric   /// port number or an Error upon failure.
122753f127fSDimitry Andric   Expected<unsigned> bind(const char *HostInterface = "0.0.0.0");
123753f127fSDimitry Andric 
124753f127fSDimitry Andric   /// Attempts to listen for requests on the bound port. Returns an Error if
125753f127fSDimitry Andric   /// called before binding a port.
126753f127fSDimitry Andric   Error listen();
127753f127fSDimitry Andric 
128753f127fSDimitry Andric   /// If the server is listening, stop and unbind the socket.
129753f127fSDimitry Andric   void stop();
130753f127fSDimitry Andric };
131753f127fSDimitry Andric } // end namespace llvm
132753f127fSDimitry Andric 
133fcaf7f86SDimitry Andric #endif // LLVM_DEBUGINFOD_HTTPSERVER_H
134