1 | //===-- llvm/Debuginfod/HTTPServer.h - HTTP server library ------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// \file |
10 | /// This file contains the declarations of the HTTPServer and HTTPServerRequest |
11 | /// classes, the HTTPResponse, and StreamingHTTPResponse structs, and the |
12 | /// streamFile function. |
13 | /// |
14 | //===----------------------------------------------------------------------===// |
15 | |
16 | #ifndef LLVM_DEBUGINFOD_HTTPSERVER_H |
17 | #define LLVM_DEBUGINFOD_HTTPSERVER_H |
18 | |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include "llvm/Support/Error.h" |
21 | |
22 | #ifdef LLVM_ENABLE_HTTPLIB |
23 | // forward declarations |
24 | namespace httplib { |
25 | class Request; |
26 | class Response; |
27 | class Server; |
28 | } // namespace httplib |
29 | #endif |
30 | |
31 | namespace llvm { |
32 | |
33 | struct HTTPResponse; |
34 | struct StreamingHTTPResponse; |
35 | class HTTPServer; |
36 | |
37 | class HTTPServerError : public ErrorInfo<HTTPServerError, ECError> { |
38 | public: |
39 | static char ID; |
40 | HTTPServerError(const Twine &Msg); |
41 | void log(raw_ostream &OS) const override; |
42 | |
43 | private: |
44 | std::string Msg; |
45 | }; |
46 | |
47 | class HTTPServerRequest { |
48 | friend HTTPServer; |
49 | |
50 | #ifdef LLVM_ENABLE_HTTPLIB |
51 | private: |
52 | HTTPServerRequest(const httplib::Request &HTTPLibRequest, |
53 | httplib::Response &HTTPLibResponse); |
54 | httplib::Response &HTTPLibResponse; |
55 | #endif |
56 | |
57 | public: |
58 | std::string UrlPath; |
59 | /// The elements correspond to match groups in the url path matching regex. |
60 | SmallVector<std::string, 1> UrlPathMatches; |
61 | |
62 | // TODO bring in HTTP headers |
63 | |
64 | void setResponse(StreamingHTTPResponse Response); |
65 | void setResponse(HTTPResponse Response); |
66 | }; |
67 | |
68 | struct HTTPResponse { |
69 | unsigned Code; |
70 | const char *ContentType; |
71 | StringRef Body; |
72 | }; |
73 | |
74 | typedef std::function<void(HTTPServerRequest &)> HTTPRequestHandler; |
75 | |
76 | /// An HTTPContentProvider is called by the HTTPServer to obtain chunks of the |
77 | /// streaming response body. The returned chunk should be located at Offset |
78 | /// bytes and have Length bytes. |
79 | typedef std::function<StringRef(size_t /*Offset*/, size_t /*Length*/)> |
80 | HTTPContentProvider; |
81 | |
82 | /// Wraps the content provider with HTTP Status code and headers. |
83 | struct StreamingHTTPResponse { |
84 | unsigned Code; |
85 | const char *ContentType; |
86 | size_t ContentLength; |
87 | HTTPContentProvider Provider; |
88 | /// Called after the response transfer is complete with the success value of |
89 | /// the transfer. |
90 | std::function<void(bool)> CompletionHandler = [](bool Success) {}; |
91 | }; |
92 | |
93 | /// Sets the response to stream the file at FilePath, if available, and |
94 | /// otherwise an HTTP 404 error response. |
95 | bool streamFile(HTTPServerRequest &Request, StringRef FilePath); |
96 | |
97 | /// An HTTP server which can listen on a single TCP/IP port for HTTP |
98 | /// requests and delgate them to the appropriate registered handler. |
99 | class HTTPServer { |
100 | #ifdef LLVM_ENABLE_HTTPLIB |
101 | std::unique_ptr<httplib::Server> Server; |
102 | unsigned Port = 0; |
103 | #endif |
104 | public: |
105 | HTTPServer(); |
106 | ~HTTPServer(); |
107 | |
108 | /// Returns true only if LLVM has been compiled with a working HTTPServer. |
109 | static bool isAvailable(); |
110 | |
111 | /// Registers a URL pattern routing rule. When the server is listening, each |
112 | /// request is dispatched to the first registered handler whose UrlPathPattern |
113 | /// matches the UrlPath. |
114 | Error get(StringRef UrlPathPattern, HTTPRequestHandler Handler); |
115 | |
116 | /// Attempts to assign the requested port and interface, returning an Error |
117 | /// upon failure. |
118 | Error bind(unsigned Port, const char *HostInterface = "0.0.0.0" ); |
119 | |
120 | /// Attempts to assign any available port and interface, returning either the |
121 | /// port number or an Error upon failure. |
122 | Expected<unsigned> bind(const char *HostInterface = "0.0.0.0" ); |
123 | |
124 | /// Attempts to listen for requests on the bound port. Returns an Error if |
125 | /// called before binding a port. |
126 | Error listen(); |
127 | |
128 | /// If the server is listening, stop and unbind the socket. |
129 | void stop(); |
130 | }; |
131 | } // end namespace llvm |
132 | |
133 | #endif // LLVM_DEBUGINFOD_HTTPSERVER_H |
134 | |