• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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