1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <https/ServerSocket.h> 20 #include <https/WebSocketHandler.h> 21 22 #include <functional> 23 #include <mutex> 24 #include <optional> 25 #include <string> 26 #include <unordered_map> 27 #include <variant> 28 #include <vector> 29 30 struct HTTPRequest; 31 32 struct HTTPServer { 33 explicit HTTPServer( 34 std::shared_ptr<RunLoop> runLoop, 35 const char *iface = nullptr, // defaults to 0.0.0.0, i.e. INADDR_ANY 36 uint16_t port = 8443, 37 ServerSocket::TransportType transportType = 38 ServerSocket::TransportType::TLS, 39 const std::optional<std::string> &certificate_pem_path = 40 std::nullopt, 41 const std::optional<std::string> &private_key_pem_path = 42 std::nullopt); 43 44 HTTPServer(const HTTPServer &) = delete; 45 HTTPServer &operator=(const HTTPServer &) = delete; 46 47 uint16_t getLocalPort() const; 48 49 void run(); 50 51 // Returns true iff the client should close the connection. 52 bool handleSingleRequest( 53 ClientSocket *client, const uint8_t *data, size_t size, bool isEOS); 54 55 void addStaticFile( 56 const char *at, 57 const char *path, 58 std::optional<std::string> mimeType = std::nullopt); 59 60 void addStaticContent( 61 const char *at, 62 const void *data, 63 size_t size, 64 std::optional<std::string> mimeType = std::nullopt); 65 66 using WebSocketHandlerFactory = 67 std::function<std::pair<int32_t, std::shared_ptr<WebSocketHandler>>()>; 68 69 void addWebSocketHandlerFactory( 70 const char *at, WebSocketHandlerFactory factory); 71 72 std::optional<std::string> certificate_pem_path() const; 73 std::optional<std::string> private_key_pem_path() const; 74 75 private: 76 struct StaticFileInfo { 77 std::variant<std::string, std::vector<uint8_t>> mPathOrContent; 78 std::optional<std::string> mMimeType; 79 }; 80 81 std::shared_ptr<RunLoop> mRunLoop; 82 uint16_t mLocalPort; 83 84 std::shared_ptr<ServerSocket> mSocketTLS; 85 86 // Protects mStaticFiles and mWebSocketHandlerFactories below. 87 std::mutex mContentLock; 88 89 std::unordered_map<std::string, StaticFileInfo> mStaticFiles; 90 91 std::unordered_map<std::string, WebSocketHandlerFactory> 92 mWebSocketHandlerFactories; 93 94 void handleWebSocketRequest( 95 ClientSocket *clientSocket, 96 WebSocketHandlerFactory factory, 97 const HTTPRequest &request, 98 int32_t *httpResultCode, 99 std::unordered_map<std::string, std::string> *responseHeaders, 100 std::string *body); 101 102 void handleStaticFileRequest( 103 const StaticFileInfo &info, 104 const HTTPRequest &request, 105 int32_t *httpResultCode, 106 std::unordered_map<std::string, std::string> *responseHeaders, 107 std::string *body); 108 109 static std::string GuessMimeType(const std::string &path); 110 }; 111