Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Unified Diff: net/server/http_server.cc

Issue 296053012: Replace StreamListenSocket with StreamSocket in HttpServer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/server/http_server.cc
diff --git a/net/server/http_server.cc b/net/server/http_server.cc
index f746f066e421798b681ac362b8767682d7883a63..e164f8fc50ea9c6f03a5bf88283915026ffec753 100644
--- a/net/server/http_server.cc
+++ b/net/server/http_server.cc
@@ -17,14 +17,24 @@
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"
#include "net/server/web_socket.h"
-#include "net/socket/tcp_listen_socket.h"
+#include "net/socket/server_socket.h"
+#include "net/socket/stream_socket.h"
+#include "net/socket/tcp_server_socket.h"
namespace net {
-HttpServer::HttpServer(const StreamListenSocketFactory& factory,
+HttpServer::HttpServer(scoped_ptr<ServerSocket> server_socket,
HttpServer::Delegate* delegate)
- : delegate_(delegate),
- server_(factory.CreateAndListen(this)) {
+ : server_socket_(server_socket.Pass()),
+ delegate_(delegate),
+ last_id_(0) {
+ DCHECK(server_socket_);
+ DoAcceptLoop(OK);
+}
+
+HttpServer::~HttpServer() {
+ STLDeleteContainerPairSecondPointers(
+ id_to_connection_.begin(), id_to_connection_.end());
}
void HttpServer::AcceptWebSocket(
@@ -33,9 +43,8 @@ void HttpServer::AcceptWebSocket(
HttpConnection* connection = FindConnection(connection_id);
if (connection == NULL)
return;
-
- DCHECK(connection->web_socket_.get());
- connection->web_socket_->Accept(request);
+ DCHECK(connection->web_socket());
+ connection->web_socket()->Accept(request);
}
void HttpServer::SendOverWebSocket(int connection_id,
@@ -43,8 +52,8 @@ void HttpServer::SendOverWebSocket(int connection_id,
HttpConnection* connection = FindConnection(connection_id);
if (connection == NULL)
return;
- DCHECK(connection->web_socket_.get());
- connection->web_socket_->Send(data);
+ DCHECK(connection->web_socket());
+ connection->web_socket()->Send(data);
}
void HttpServer::SendRaw(int connection_id, const std::string& data) {
@@ -89,45 +98,55 @@ void HttpServer::Close(int connection_id) {
HttpConnection* connection = FindConnection(connection_id);
if (connection == NULL)
return;
-
- // Initiating close from server-side does not lead to the DidClose call.
- // Do it manually here.
- DidClose(connection->socket_.get());
+ connection->Close();
}
int HttpServer::GetLocalAddress(IPEndPoint* address) {
- if (!server_)
- return ERR_SOCKET_NOT_CONNECTED;
- return server_->GetLocalAddress(address);
+ return server_socket_->GetLocalAddress(address);
}
-void HttpServer::DidAccept(StreamListenSocket* server,
- scoped_ptr<StreamListenSocket> socket) {
- HttpConnection* connection = new HttpConnection(this, socket.Pass());
- id_to_connection_[connection->id()] = connection;
- // TODO(szym): Fix socket access. Make HttpConnection the Delegate.
- socket_to_connection_[connection->socket_.get()] = connection;
+void HttpServer::DoAcceptLoop(int rv) {
+ while (rv == OK) {
+ rv = server_socket_->Accept(&accepted_socket_,
+ base::Bind(&HttpServer::OnAcceptCompleted,
+ AsWeakPtr()));
+ if (rv == ERR_IO_PENDING) {
+ break;
+ }
+ rv = DidAccept(rv);
+ }
}
-void HttpServer::DidRead(StreamListenSocket* socket,
- const char* data,
- int len) {
- HttpConnection* connection = FindConnection(socket);
- DCHECK(connection != NULL);
- if (connection == NULL)
- return;
+void HttpServer::OnAcceptCompleted(int rv) {
+ if (DidAccept(rv) == OK) {
+ DoAcceptLoop(OK);
+ }
+}
- connection->recv_data_.append(data, len);
- while (connection->recv_data_.length()) {
- if (connection->web_socket_.get()) {
+int HttpServer::DidAccept(int rv) {
+ if (rv < 0) {
+ LOG(ERROR) << "Accept error: rv=" << rv;
+ return rv;
+ }
+
+ HttpConnection* connection =
+ new HttpConnection(++last_id_, accepted_socket_.Pass(), this);
+ id_to_connection_[connection->id()] = connection;
+ return OK;
+}
+
+void HttpServer::DidRead(HttpConnection* connection) {
+ HttpConnection::ReadIOBuffer* read_buf = connection->read_buf();
+ while (read_buf->GetUnconsumedSize() > 0) {
+ if (connection->web_socket()) {
std::string message;
- WebSocket::ParseResult result = connection->web_socket_->Read(&message);
+ WebSocket::ParseResult result = connection->web_socket()->Read(&message);
if (result == WebSocket::FRAME_INCOMPLETE)
break;
if (result == WebSocket::FRAME_CLOSE ||
result == WebSocket::FRAME_ERROR) {
- Close(connection->id());
+ connection->Close();
break;
}
delegate_->OnWebSocketMessage(connection->id(), message);
@@ -136,26 +155,24 @@ void HttpServer::DidRead(StreamListenSocket* socket,
HttpServerRequestInfo request;
size_t pos = 0;
- if (!ParseHeaders(connection, &request, &pos))
+ if (!ParseHeaders(read_buf->data(), read_buf->GetUnconsumedSize(),
+ &request, &pos))
break;
// Sets peer address if exists.
- socket->GetPeerAddress(&request.peer);
+ connection->socket()->GetPeerAddress(&request.peer);
if (request.HasHeaderValue("connection", "upgrade")) {
- connection->web_socket_.reset(WebSocket::CreateWebSocket(connection,
- request,
- &pos));
-
- if (!connection->web_socket_.get()) // Not enough data was received.
+ connection->UpgradeToWebSocket(request, &pos);
+ if (!connection->web_socket()) // Not enough data was received.
break;
+ read_buf->DidConsume(pos);
delegate_->OnWebSocketRequest(connection->id(), request);
- connection->Shift(pos);
continue;
}
const char kContentLength[] = "content-length";
- if (request.headers.count(kContentLength)) {
+ if (request.headers.count(kContentLength) > 0) {
size_t content_length = 0;
const size_t kMaxBodySize = 100 << 20;
if (!base::StringToSizeT(request.GetHeaderValue(kContentLength),
@@ -164,32 +181,26 @@ void HttpServer::DidRead(StreamListenSocket* socket,
connection->Send(HttpServerResponseInfo::CreateFor500(
"request content-length too big or unknown: " +
request.GetHeaderValue(kContentLength)));
- DidClose(socket);
+ connection->Close();
break;
}
- if (connection->recv_data_.length() - pos < content_length)
+ if (read_buf->GetUnconsumedSize() - pos < content_length)
break; // Not enough data was received yet.
- request.data = connection->recv_data_.substr(pos, content_length);
+ request.data.assign(read_buf->data() + pos, content_length);
pos += content_length;
}
+ read_buf->DidConsume(pos);
delegate_->OnHttpRequest(connection->id(), request);
- connection->Shift(pos);
}
}
-void HttpServer::DidClose(StreamListenSocket* socket) {
- HttpConnection* connection = FindConnection(socket);
- DCHECK(connection != NULL);
- id_to_connection_.erase(connection->id());
- socket_to_connection_.erase(connection->socket_.get());
+void HttpServer::DidClose(HttpConnection* connection) {
+ int id = connection->id();
+ id_to_connection_.erase(id);
delete connection;
-}
-
-HttpServer::~HttpServer() {
- STLDeleteContainerPairSecondPointers(
- id_to_connection_.begin(), id_to_connection_.end());
+ delegate_->OnClose(id);
}
//
@@ -255,17 +266,17 @@ int charToInput(char ch) {
return INPUT_DEFAULT;
}
-bool HttpServer::ParseHeaders(HttpConnection* connection,
+bool HttpServer::ParseHeaders(const char* data,
+ size_t data_len,
HttpServerRequestInfo* info,
size_t* ppos) {
size_t& pos = *ppos;
- size_t data_len = connection->recv_data_.length();
int state = ST_METHOD;
std::string buffer;
std::string header_name;
std::string header_value;
while (pos < data_len) {
- char ch = connection->recv_data_[pos++];
+ char ch = data[pos++];
int input = charToInput(ch);
int next_state = parser_state[state][input];
@@ -337,11 +348,4 @@ HttpConnection* HttpServer::FindConnection(int connection_id) {
return it->second;
}
-HttpConnection* HttpServer::FindConnection(StreamListenSocket* socket) {
- SocketToConnectionMap::iterator it = socket_to_connection_.find(socket);
- if (it == socket_to_connection_.end())
- return NULL;
- return it->second;
-}
-
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698