1 // Copyright 2012 The Chromium Authors 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 NET_SERVER_HTTP_SERVER_H_ 6 #define NET_SERVER_HTTP_SERVER_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <map> 12 #include <memory> 13 #include <string> 14 #include <string_view> 15 #include <vector> 16 17 #include "base/memory/raw_ptr.h" 18 #include "base/memory/weak_ptr.h" 19 #include "net/base/net_export.h" 20 #include "net/http/http_status_code.h" 21 #include "net/traffic_annotation/network_traffic_annotation.h" 22 23 namespace net { 24 25 class HttpConnection; 26 class HttpServerRequestInfo; 27 class HttpServerResponseInfo; 28 class IPEndPoint; 29 class ServerSocket; 30 class StreamSocket; 31 32 class NET_EXPORT HttpServer { 33 public: 34 // Delegate to handle http/websocket events. Beware that it is not safe to 35 // destroy the HttpServer in any of these callbacks. 36 class Delegate { 37 public: 38 virtual ~Delegate() = default; 39 40 virtual void OnConnect(int connection_id) = 0; 41 virtual void OnHttpRequest(int connection_id, 42 const HttpServerRequestInfo& info) = 0; 43 virtual void OnWebSocketRequest(int connection_id, 44 const HttpServerRequestInfo& info) = 0; 45 virtual void OnWebSocketMessage(int connection_id, std::string data) = 0; 46 virtual void OnClose(int connection_id) = 0; 47 }; 48 49 // Instantiates a http server with |server_socket| which already started 50 // listening, but not accepting. This constructor schedules accepting 51 // connections asynchronously in case when |delegate| is not ready to get 52 // callbacks yet. 53 HttpServer(std::unique_ptr<ServerSocket> server_socket, 54 HttpServer::Delegate* delegate); 55 56 HttpServer(const HttpServer&) = delete; 57 HttpServer& operator=(const HttpServer&) = delete; 58 59 ~HttpServer(); 60 61 void AcceptWebSocket(int connection_id, 62 const HttpServerRequestInfo& request, 63 NetworkTrafficAnnotationTag traffic_annotation); 64 void SendOverWebSocket(int connection_id, 65 std::string_view data, 66 NetworkTrafficAnnotationTag traffic_annotation); 67 // Sends the provided data directly to the given connection. No validation is 68 // performed that data constitutes a valid HTTP response. A valid HTTP 69 // response may be split across multiple calls to SendRaw. 70 void SendRaw(int connection_id, 71 const std::string& data, 72 NetworkTrafficAnnotationTag traffic_annotation); 73 // TODO(byungchul): Consider replacing function name with SendResponseInfo 74 void SendResponse(int connection_id, 75 const HttpServerResponseInfo& response, 76 NetworkTrafficAnnotationTag traffic_annotation); 77 void Send(int connection_id, 78 HttpStatusCode status_code, 79 const std::string& data, 80 const std::string& mime_type, 81 NetworkTrafficAnnotationTag traffic_annotation); 82 void Send200(int connection_id, 83 const std::string& data, 84 const std::string& mime_type, 85 NetworkTrafficAnnotationTag traffic_annotation); 86 void Send404(int connection_id, 87 NetworkTrafficAnnotationTag traffic_annotation); 88 void Send500(int connection_id, 89 const std::string& message, 90 NetworkTrafficAnnotationTag traffic_annotation); 91 92 void Close(int connection_id); 93 94 void SetReceiveBufferSize(int connection_id, int32_t size); 95 void SetSendBufferSize(int connection_id, int32_t size); 96 97 // Copies the local address to |address|. Returns a network error code. 98 int GetLocalAddress(IPEndPoint* address); 99 100 private: 101 friend class HttpServerTest; 102 103 void DoAcceptLoop(); 104 void OnAcceptCompleted(int rv); 105 int HandleAcceptResult(int rv); 106 107 void DoReadLoop(HttpConnection* connection); 108 void OnReadCompleted(int connection_id, int rv); 109 int HandleReadResult(HttpConnection* connection, int rv); 110 111 void DoWriteLoop(HttpConnection* connection, 112 NetworkTrafficAnnotationTag traffic_annotation); 113 void OnWriteCompleted(int connection_id, 114 NetworkTrafficAnnotationTag traffic_annotation, 115 int rv); 116 int HandleWriteResult(HttpConnection* connection, int rv); 117 118 // Expects the raw data to be stored in recv_data_. If parsing is successful, 119 // will remove the data parsed from recv_data_, leaving only the unused 120 // recv data. If all data has been consumed successfully, but the headers are 121 // not fully parsed, *pos will be set to zero. Returns false if an error is 122 // encountered while parsing, true otherwise. 123 bool ParseHeaders(const char* data, 124 size_t data_len, 125 HttpServerRequestInfo* info, 126 size_t* pos); 127 128 HttpConnection* FindConnection(int connection_id); 129 130 // Whether or not Close() has been called during delegate callback processing. 131 bool HasClosedConnection(HttpConnection* connection); 132 133 void DestroyClosedConnections(); 134 135 const std::unique_ptr<ServerSocket> server_socket_; 136 std::unique_ptr<StreamSocket> accepted_socket_; 137 const raw_ptr<HttpServer::Delegate> delegate_; 138 139 int last_id_ = 0; 140 std::map<int, std::unique_ptr<HttpConnection>> id_to_connection_; 141 142 // Vector of connections whose destruction is pending. Connections may have 143 // WebSockets with raw pointers to `this`, so should not out live this, but 144 // also cannot safely be destroyed synchronously, so on connection close, add 145 // a Connection here, and post a task to destroy them. 146 std::vector<std::unique_ptr<HttpConnection>> closed_connections_; 147 148 base::WeakPtrFactory<HttpServer> weak_ptr_factory_{this}; 149 }; 150 151 } // namespace net 152 153 #endif // NET_SERVER_HTTP_SERVER_H_ 154