| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/server/http_server.h" | 5 #include "net/server/http_server.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/sys_byteorder.h" | 13 #include "base/sys_byteorder.h" |
| 14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 16 #include "net/server/http_connection.h" | 16 #include "net/server/http_connection.h" |
| 17 #include "net/server/http_server_request_info.h" | 17 #include "net/server/http_server_request_info.h" |
| 18 #include "net/server/http_server_response_info.h" | 18 #include "net/server/http_server_response_info.h" |
| 19 #include "net/server/web_socket.h" | 19 #include "net/server/web_socket.h" |
| 20 #include "net/socket/tcp_listen_socket.h" | 20 #include "net/socket/tcp_listen_socket.h" |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 | 23 |
| 24 HttpServer::HttpServer(const StreamListenSocketFactory& factory, | 24 HttpServer::HttpServer(const StreamListenSocketFactory& factory, |
| 25 HttpServer::Delegate* delegate) | 25 HttpServer::Delegate* delegate) |
| 26 : delegate_(delegate), | 26 : delegate_(delegate), server_(factory.CreateAndListen(this)) { |
| 27 server_(factory.CreateAndListen(this)) { | |
| 28 } | 27 } |
| 29 | 28 |
| 30 void HttpServer::AcceptWebSocket( | 29 void HttpServer::AcceptWebSocket(int connection_id, |
| 31 int connection_id, | 30 const HttpServerRequestInfo& request) { |
| 32 const HttpServerRequestInfo& request) { | |
| 33 HttpConnection* connection = FindConnection(connection_id); | 31 HttpConnection* connection = FindConnection(connection_id); |
| 34 if (connection == NULL) | 32 if (connection == NULL) |
| 35 return; | 33 return; |
| 36 | 34 |
| 37 DCHECK(connection->web_socket_.get()); | 35 DCHECK(connection->web_socket_.get()); |
| 38 connection->web_socket_->Accept(request); | 36 connection->web_socket_->Accept(request); |
| 39 } | 37 } |
| 40 | 38 |
| 41 void HttpServer::SendOverWebSocket(int connection_id, | 39 void HttpServer::SendOverWebSocket(int connection_id, const std::string& data) { |
| 42 const std::string& data) { | |
| 43 HttpConnection* connection = FindConnection(connection_id); | 40 HttpConnection* connection = FindConnection(connection_id); |
| 44 if (connection == NULL) | 41 if (connection == NULL) |
| 45 return; | 42 return; |
| 46 DCHECK(connection->web_socket_.get()); | 43 DCHECK(connection->web_socket_.get()); |
| 47 connection->web_socket_->Send(data); | 44 connection->web_socket_->Send(data); |
| 48 } | 45 } |
| 49 | 46 |
| 50 void HttpServer::SendRaw(int connection_id, const std::string& data) { | 47 void HttpServer::SendRaw(int connection_id, const std::string& data) { |
| 51 HttpConnection* connection = FindConnection(connection_id); | 48 HttpConnection* connection = FindConnection(connection_id); |
| 52 if (connection == NULL) | 49 if (connection == NULL) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 HttpServerRequestInfo request; | 134 HttpServerRequestInfo request; |
| 138 size_t pos = 0; | 135 size_t pos = 0; |
| 139 if (!ParseHeaders(connection, &request, &pos)) | 136 if (!ParseHeaders(connection, &request, &pos)) |
| 140 break; | 137 break; |
| 141 | 138 |
| 142 // Sets peer address if exists. | 139 // Sets peer address if exists. |
| 143 socket->GetPeerAddress(&request.peer); | 140 socket->GetPeerAddress(&request.peer); |
| 144 | 141 |
| 145 std::string connection_header = request.GetHeaderValue("connection"); | 142 std::string connection_header = request.GetHeaderValue("connection"); |
| 146 if (connection_header == "Upgrade") { | 143 if (connection_header == "Upgrade") { |
| 147 connection->web_socket_.reset(WebSocket::CreateWebSocket(connection, | 144 connection->web_socket_.reset( |
| 148 request, | 145 WebSocket::CreateWebSocket(connection, request, &pos)); |
| 149 &pos)); | |
| 150 | 146 |
| 151 if (!connection->web_socket_.get()) // Not enough data was received. | 147 if (!connection->web_socket_.get()) // Not enough data was received. |
| 152 break; | 148 break; |
| 153 delegate_->OnWebSocketRequest(connection->id(), request); | 149 delegate_->OnWebSocketRequest(connection->id(), request); |
| 154 connection->Shift(pos); | 150 connection->Shift(pos); |
| 155 continue; | 151 continue; |
| 156 } | 152 } |
| 157 | 153 |
| 158 const char kContentLength[] = "content-length"; | 154 const char kContentLength[] = "content-length"; |
| 159 if (request.headers.count(kContentLength)) { | 155 if (request.headers.count(kContentLength)) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 182 | 178 |
| 183 void HttpServer::DidClose(StreamListenSocket* socket) { | 179 void HttpServer::DidClose(StreamListenSocket* socket) { |
| 184 HttpConnection* connection = FindConnection(socket); | 180 HttpConnection* connection = FindConnection(socket); |
| 185 DCHECK(connection != NULL); | 181 DCHECK(connection != NULL); |
| 186 id_to_connection_.erase(connection->id()); | 182 id_to_connection_.erase(connection->id()); |
| 187 socket_to_connection_.erase(connection->socket_.get()); | 183 socket_to_connection_.erase(connection->socket_.get()); |
| 188 delete connection; | 184 delete connection; |
| 189 } | 185 } |
| 190 | 186 |
| 191 HttpServer::~HttpServer() { | 187 HttpServer::~HttpServer() { |
| 192 STLDeleteContainerPairSecondPointers( | 188 STLDeleteContainerPairSecondPointers(id_to_connection_.begin(), |
| 193 id_to_connection_.begin(), id_to_connection_.end()); | 189 id_to_connection_.end()); |
| 194 } | 190 } |
| 195 | 191 |
| 196 // | 192 // |
| 197 // HTTP Request Parser | 193 // HTTP Request Parser |
| 198 // This HTTP request parser uses a simple state machine to quickly parse | 194 // This HTTP request parser uses a simple state machine to quickly parse |
| 199 // through the headers. The parser is not 100% complete, as it is designed | 195 // through the headers. The parser is not 100% complete, as it is designed |
| 200 // for use in this simple test driver. | 196 // for use in this simple test driver. |
| 201 // | 197 // |
| 202 // Known issues: | 198 // Known issues: |
| 203 // - does not handle whitespace on first HTTP line correctly. Expects | 199 // - does not handle whitespace on first HTTP line correctly. Expects |
| (...skipping 18 matching lines...) Expand all Loading... |
| 222 ST_NAME, // Receiving a request header name | 218 ST_NAME, // Receiving a request header name |
| 223 ST_SEPARATOR, // Receiving the separator between header name and value | 219 ST_SEPARATOR, // Receiving the separator between header name and value |
| 224 ST_VALUE, // Receiving a request header value | 220 ST_VALUE, // Receiving a request header value |
| 225 ST_DONE, // Parsing is complete and successful | 221 ST_DONE, // Parsing is complete and successful |
| 226 ST_ERR, // Parsing encountered invalid syntax. | 222 ST_ERR, // Parsing encountered invalid syntax. |
| 227 MAX_STATES | 223 MAX_STATES |
| 228 }; | 224 }; |
| 229 | 225 |
| 230 // State transition table | 226 // State transition table |
| 231 int parser_state[MAX_STATES][MAX_INPUTS] = { | 227 int parser_state[MAX_STATES][MAX_INPUTS] = { |
| 232 /* METHOD */ { ST_URL, ST_ERR, ST_ERR, ST_ERR, ST_METHOD }, | 228 /* METHOD */ {ST_URL, ST_ERR, ST_ERR, ST_ERR, ST_METHOD}, |
| 233 /* URL */ { ST_PROTO, ST_ERR, ST_ERR, ST_URL, ST_URL }, | 229 /* URL */ {ST_PROTO, ST_ERR, ST_ERR, ST_URL, ST_URL}, |
| 234 /* PROTOCOL */ { ST_ERR, ST_HEADER, ST_NAME, ST_ERR, ST_PROTO }, | 230 /* PROTOCOL */ {ST_ERR, ST_HEADER, ST_NAME, ST_ERR, ST_PROTO}, |
| 235 /* HEADER */ { ST_ERR, ST_ERR, ST_NAME, ST_ERR, ST_ERR }, | 231 /* HEADER */ {ST_ERR, ST_ERR, ST_NAME, ST_ERR, ST_ERR}, |
| 236 /* NAME */ { ST_SEPARATOR, ST_DONE, ST_ERR, ST_VALUE, ST_NAME }, | 232 /* NAME */ {ST_SEPARATOR, ST_DONE, ST_ERR, ST_VALUE, ST_NAME}, |
| 237 /* SEPARATOR */ { ST_SEPARATOR, ST_ERR, ST_ERR, ST_VALUE, ST_ERR }, | 233 /* SEPARATOR */ {ST_SEPARATOR, ST_ERR, ST_ERR, ST_VALUE, ST_ERR}, |
| 238 /* VALUE */ { ST_VALUE, ST_HEADER, ST_NAME, ST_VALUE, ST_VALUE }, | 234 /* VALUE */ {ST_VALUE, ST_HEADER, ST_NAME, ST_VALUE, ST_VALUE}, |
| 239 /* DONE */ { ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE }, | 235 /* DONE */ {ST_DONE, ST_DONE, ST_DONE, ST_DONE, ST_DONE}, |
| 240 /* ERR */ { ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR } | 236 /* ERR */ {ST_ERR, ST_ERR, ST_ERR, ST_ERR, ST_ERR}}; |
| 241 }; | |
| 242 | 237 |
| 243 // Convert an input character to the parser's input token. | 238 // Convert an input character to the parser's input token. |
| 244 int charToInput(char ch) { | 239 int charToInput(char ch) { |
| 245 switch(ch) { | 240 switch (ch) { |
| 246 case ' ': | 241 case ' ': |
| 247 return INPUT_SPACE; | 242 return INPUT_SPACE; |
| 248 case '\r': | 243 case '\r': |
| 249 return INPUT_CR; | 244 return INPUT_CR; |
| 250 case '\n': | 245 case '\n': |
| 251 return INPUT_LF; | 246 return INPUT_LF; |
| 252 case ':': | 247 case ':': |
| 253 return INPUT_COLON; | 248 return INPUT_COLON; |
| 254 } | 249 } |
| 255 return INPUT_DEFAULT; | 250 return INPUT_DEFAULT; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 } | 326 } |
| 332 | 327 |
| 333 HttpConnection* HttpServer::FindConnection(StreamListenSocket* socket) { | 328 HttpConnection* HttpServer::FindConnection(StreamListenSocket* socket) { |
| 334 SocketToConnectionMap::iterator it = socket_to_connection_.find(socket); | 329 SocketToConnectionMap::iterator it = socket_to_connection_.find(socket); |
| 335 if (it == socket_to_connection_.end()) | 330 if (it == socket_to_connection_.end()) |
| 336 return NULL; | 331 return NULL; |
| 337 return it->second; | 332 return it->second; |
| 338 } | 333 } |
| 339 | 334 |
| 340 } // namespace net | 335 } // namespace net |
| OLD | NEW |