diff options
-rw-r--r-- | chrome/browser/debugger/devtools_http_protocol_handler.cc | 290 | ||||
-rw-r--r-- | chrome/browser/debugger/devtools_http_protocol_handler.h | 43 | ||||
-rw-r--r-- | net/server/http_listen_socket.cc | 68 | ||||
-rw-r--r-- | net/server/http_listen_socket.h | 16 | ||||
-rw-r--r-- | net/server/http_server_request_info.h | 2 |
5 files changed, 319 insertions, 100 deletions
diff --git a/chrome/browser/debugger/devtools_http_protocol_handler.cc b/chrome/browser/debugger/devtools_http_protocol_handler.cc index 2f24e07..df2e592 100644 --- a/chrome/browser/debugger/devtools_http_protocol_handler.cc +++ b/chrome/browser/debugger/devtools_http_protocol_handler.cc @@ -37,7 +37,10 @@ class DevToolsClientHostImpl : public DevToolsClientHost { ~DevToolsClientHostImpl() {} // DevToolsClientHost interface - virtual void InspectedTabClosing() {} + virtual void InspectedTabClosing() { + socket_->Close(); + } + virtual void SendMessageToClient(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg) IPC_MESSAGE_HANDLER(DevToolsClientMsg_RpcMessage, OnRpcMessage); @@ -45,6 +48,9 @@ class DevToolsClientHostImpl : public DevToolsClientHost { IPC_END_MESSAGE_MAP() } + void NotifyCloseListener() { + DevToolsClientHost::NotifyCloseListener(); + } private: // Message handling routines void OnRpcMessage(const DevToolsMessageData& data) { @@ -82,9 +88,29 @@ void DevToolsHttpProtocolHandler::Stop() { NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Teardown)); } -void DevToolsHttpProtocolHandler::OnHttpRequest(HttpListenSocket* socket, - HttpServerRequestInfo* info) { - URLRequest* request = new URLRequest(GURL("chrome:/" + info->path), this); +void DevToolsHttpProtocolHandler::OnHttpRequest( + HttpListenSocket* socket, + const HttpServerRequestInfo& info) { + if (info.path == "" || info.path == "/") { + // Pages discovery request. + ChromeThread::PostTask( + ChromeThread::UI, + FROM_HERE, + NewRunnableMethod(this, + &DevToolsHttpProtocolHandler::OnHttpRequestUI, + socket, + info)); + return; + } + + size_t pos = info.path.find("/devtools/"); + if (pos != 0) { + socket->Send404(); + return; + } + + // Proxy static files from chrome://devtools/*. + URLRequest* request = new URLRequest(GURL("chrome:/" + info.path), this); Bind(request, socket); request->set_context( Profile::GetDefaultRequestContext()->GetURLRequestContext()); @@ -93,8 +119,15 @@ void DevToolsHttpProtocolHandler::OnHttpRequest(HttpListenSocket* socket, void DevToolsHttpProtocolHandler::OnWebSocketRequest( HttpListenSocket* socket, - HttpServerRequestInfo* request) { - socket->AcceptWebSocket(request); + const HttpServerRequestInfo& request) { + ChromeThread::PostTask( + ChromeThread::UI, + FROM_HERE, + NewRunnableMethod( + this, + &DevToolsHttpProtocolHandler::OnWebSocketRequestUI, + socket, + request)); } void DevToolsHttpProtocolHandler::OnWebSocketMessage(HttpListenSocket* socket, @@ -109,58 +142,142 @@ void DevToolsHttpProtocolHandler::OnWebSocketMessage(HttpListenSocket* socket, data)); } +void DevToolsHttpProtocolHandler::OnClose(HttpListenSocket* socket) { + SocketToRequestsMap::iterator it = socket_to_requests_io_.find(socket); + if (it != socket_to_requests_io_.end()) { + // Dispose delegating socket. + for (std::set<URLRequest*>::iterator it2 = it->second.begin(); + it2 != it->second.end(); ++it2) { + URLRequest* request = *it2; + request->Cancel(); + request_to_socket_io_.erase(request); + request_to_buffer_io_.erase(request); + delete request; + } + socket_to_requests_io_.erase(socket); + } + + ChromeThread::PostTask( + ChromeThread::UI, + FROM_HERE, + NewRunnableMethod( + this, + &DevToolsHttpProtocolHandler::OnCloseUI, + socket)); +} + +void DevToolsHttpProtocolHandler::OnHttpRequestUI( + HttpListenSocket* socket, + const HttpServerRequestInfo& info) { + std::string response = "<html><body>"; + for (BrowserList::const_iterator it = BrowserList::begin(), + end = BrowserList::end(); it != end; ++it) { + TabStripModel* model = (*it)->tabstrip_model(); + for (int i = 0, size = model->count(); i < size; ++i) { + TabContents* tab_contents = model->GetTabContentsAt(i); + NavigationController& controller = tab_contents->controller(); + NavigationEntry* entry = controller.GetActiveEntry(); + if (entry == NULL) + continue; + + if (!entry->url().is_valid()) + continue; + + DevToolsClientHost* client_host = DevToolsManager::GetInstance()-> + GetDevToolsClientHostFor(tab_contents->render_view_host()); + if (!client_host) { + response += StringPrintf( + "<a href='/devtools/devtools.html?page=%d'>%s (%s)</a><br>", + controller.session_id().id(), + UTF16ToUTF8(entry->title()).c_str(), + entry->url().spec().c_str()); + } else { + response += StringPrintf( + "%s (%s)<br>", + UTF16ToUTF8(entry->title()).c_str(), + entry->url().spec().c_str()); + } + } + } + response += "</body></html>"; + Send200(socket, response, "text/html"); +} + +void DevToolsHttpProtocolHandler::OnWebSocketRequestUI( + HttpListenSocket* socket, + const HttpServerRequestInfo& request) { + std::string prefix = "/devtools/page/"; + size_t pos = request.path.find(prefix); + if (pos != 0) { + Send404(socket); + return; + } + std::string page_id = request.path.substr(prefix.length()); + int id = 0; + if (!StringToInt(page_id, &id)) { + Send500(socket, "Invalid page id: " + page_id); + return; + } + + TabContents* tab_contents = GetTabContents(id); + if (tab_contents == NULL) { + Send500(socket, "No such page id: " + page_id); + return; + } + + DevToolsManager* manager = DevToolsManager::GetInstance(); + if (manager->GetDevToolsClientHostFor(tab_contents->render_view_host())) { + Send500(socket, "Page with given id is being inspected: " + page_id); + return; + } + + DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl(socket); + socket_to_client_host_ui_[socket] = client_host; + + manager->RegisterDevToolsClientHostFor( + tab_contents->render_view_host(), + client_host); + AcceptWebSocket(socket, request); +} + void DevToolsHttpProtocolHandler::OnWebSocketMessageUI( HttpListenSocket* socket, const std::string& d) { - std::string data = d; - if (!client_host_.get() && data == "attach") { - client_host_.reset(new DevToolsClientHostImpl(socket)); - BrowserList::const_iterator it = BrowserList::begin(); - TabContents* tab_contents = (*it)->tabstrip_model()->GetTabContentsAt(0); - DevToolsManager* manager = DevToolsManager::GetInstance(); - manager->RegisterDevToolsClientHostFor(tab_contents->render_view_host(), - client_host_.get()); - } else { - // TODO(pfeldman): Replace with proper parsing / dispatching. - DevToolsMessageData message_data; - message_data.class_name = "ToolsAgent"; - message_data.method_name = "dispatchOnInspectorController"; + SocketToClientHostMap::iterator it = socket_to_client_host_ui_.find(socket); + if (it == socket_to_client_host_ui_.end()) + return; - size_t pos = data.find(" "); - message_data.arguments.push_back(data.substr(0, pos)); - data = data.substr(pos + 1); + std::string data = d; + // TODO(pfeldman): Replace with proper parsing / dispatching. + DevToolsMessageData message_data; + message_data.class_name = "ToolsAgent"; + message_data.method_name = "dispatchOnInspectorController"; - pos = data.find(" "); - message_data.arguments.push_back(data.substr(0, pos)); - data = data.substr(pos + 1); + size_t pos = data.find(" "); + message_data.arguments.push_back(data.substr(0, pos)); + data = data.substr(pos + 1); - message_data.arguments.push_back(data); + message_data.arguments.push_back(data); - DevToolsManager* manager = DevToolsManager::GetInstance(); - manager->ForwardToDevToolsAgent(client_host_.get(), - DevToolsAgentMsg_RpcMessage(DevToolsMessageData(message_data))); - } + DevToolsManager* manager = DevToolsManager::GetInstance(); + manager->ForwardToDevToolsAgent(it->second, + DevToolsAgentMsg_RpcMessage(DevToolsMessageData(message_data))); } -void DevToolsHttpProtocolHandler::OnClose(HttpListenSocket* socket) { - SocketToRequestsMap::iterator it = socket_to_requests_.find(socket); - if (it == socket_to_requests_.end()) +void DevToolsHttpProtocolHandler::OnCloseUI(HttpListenSocket* socket) { + SocketToClientHostMap::iterator it = socket_to_client_host_ui_.find(socket); + if (it == socket_to_client_host_ui_.end()) return; - - for (std::set<URLRequest*>::iterator it2 = it->second.begin(); - it2 != it->second.end(); ++it2) { - URLRequest* request = *it2; - request->Cancel(); - request_to_socket_.erase(request); - request_to_buffer_.erase(request); - delete request; - } - socket_to_requests_.erase(socket); + DevToolsClientHostImpl* client_host = + static_cast<DevToolsClientHostImpl*>(it->second); + client_host->NotifyCloseListener(); + delete client_host; + socket_to_client_host_ui_.erase(socket); } void DevToolsHttpProtocolHandler::OnResponseStarted(URLRequest* request) { - RequestToSocketMap::iterator it = request_to_socket_.find(request); - if (it == request_to_socket_.end()) + RequestToSocketMap::iterator it = request_to_socket_io_.find(request); + if (it == request_to_socket_io_.end()) return; HttpListenSocket* socket = it->second; @@ -178,9 +295,7 @@ void DevToolsHttpProtocolHandler::OnResponseStarted(URLRequest* request) { content_type.c_str(), expected_size)); } else { - socket->Send("HTTP/1.1 404 Not Found\r\n" - "Content-Length: 0\r\n" - "\r\n"); + socket->Send404(); } int bytes_read = 0; @@ -188,7 +303,7 @@ void DevToolsHttpProtocolHandler::OnResponseStarted(URLRequest* request) { // network connection as soon as possible, signal that the request has // completed immediately, without trying to read any data back (all we care // about is the response code and headers, which we already have). - net::IOBuffer* buffer = request_to_buffer_[request].get(); + net::IOBuffer* buffer = request_to_buffer_io_[request].get(); if (request->status().is_success()) request->Read(buffer, kBufferSize, &bytes_read); OnReadCompleted(request, bytes_read); @@ -196,13 +311,13 @@ void DevToolsHttpProtocolHandler::OnResponseStarted(URLRequest* request) { void DevToolsHttpProtocolHandler::OnReadCompleted(URLRequest* request, int bytes_read) { - RequestToSocketMap::iterator it = request_to_socket_.find(request); - if (it == request_to_socket_.end()) + RequestToSocketMap::iterator it = request_to_socket_io_.find(request); + if (it == request_to_socket_io_.end()) return; HttpListenSocket* socket = it->second; - net::IOBuffer* buffer = request_to_buffer_[request].get(); + net::IOBuffer* buffer = request_to_buffer_io_[request].get(); do { if (!request->status().is_success() || bytes_read <= 0) break; @@ -230,27 +345,78 @@ void DevToolsHttpProtocolHandler::Teardown() { void DevToolsHttpProtocolHandler::Bind(URLRequest* request, HttpListenSocket* socket) { - request_to_socket_[request] = socket; - SocketToRequestsMap::iterator it = socket_to_requests_.find(socket); - if (it == socket_to_requests_.end()) { + request_to_socket_io_[request] = socket; + SocketToRequestsMap::iterator it = socket_to_requests_io_.find(socket); + if (it == socket_to_requests_io_.end()) { std::pair<HttpListenSocket*, std::set<URLRequest*> > value( socket, std::set<URLRequest*>()); - it = socket_to_requests_.insert(value).first; + it = socket_to_requests_io_.insert(value).first; } it->second.insert(request); - request_to_buffer_[request] = new net::IOBuffer(kBufferSize); + request_to_buffer_io_[request] = new net::IOBuffer(kBufferSize); } void DevToolsHttpProtocolHandler::RequestCompleted(URLRequest* request) { - RequestToSocketMap::iterator it = request_to_socket_.find(request); - if (it == request_to_socket_.end()) + RequestToSocketMap::iterator it = request_to_socket_io_.find(request); + if (it == request_to_socket_io_.end()) return; HttpListenSocket* socket = it->second; - request_to_socket_.erase(request); - SocketToRequestsMap::iterator it2 = socket_to_requests_.find(socket); + request_to_socket_io_.erase(request); + SocketToRequestsMap::iterator it2 = socket_to_requests_io_.find(socket); it2->second.erase(request); - request_to_buffer_.erase(request); + request_to_buffer_io_.erase(request); delete request; } + +void DevToolsHttpProtocolHandler::Send200(HttpListenSocket* socket, + const std::string& data, + const std::string& mime_type) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(socket, + &HttpListenSocket::Send200, + data, + mime_type)); +} + +void DevToolsHttpProtocolHandler::Send404(HttpListenSocket* socket) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(socket, + &HttpListenSocket::Send404)); +} + +void DevToolsHttpProtocolHandler::Send500(HttpListenSocket* socket, + const std::string& message) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(socket, + &HttpListenSocket::Send500, + message)); +} + +void DevToolsHttpProtocolHandler::AcceptWebSocket( + HttpListenSocket* socket, + const HttpServerRequestInfo& request) { + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod(socket, + &HttpListenSocket::AcceptWebSocket, + request)); +} + +TabContents* DevToolsHttpProtocolHandler::GetTabContents(int session_id) { + for (BrowserList::const_iterator it = BrowserList::begin(), + end = BrowserList::end(); it != end; ++it) { + TabStripModel* model = (*it)->tabstrip_model(); + for (int i = 0, size = model->count(); i < size; ++i) { + NavigationController& controller = + model->GetTabContentsAt(i)->controller(); + if (controller.session_id().id() == session_id) + return controller.tab_contents(); + } + } + return NULL; +} diff --git a/chrome/browser/debugger/devtools_http_protocol_handler.h b/chrome/browser/debugger/devtools_http_protocol_handler.h index 14163d5..b4d80ce 100644 --- a/chrome/browser/debugger/devtools_http_protocol_handler.h +++ b/chrome/browser/debugger/devtools_http_protocol_handler.h @@ -15,6 +15,7 @@ class DevToolsClientHost; class DevToolsHttpServer; +class TabContents; class DevToolsHttpProtocolHandler : public HttpListenSocket::Delegate, @@ -29,41 +30,61 @@ class DevToolsHttpProtocolHandler // This method should be called before the object destruction. void Stop(); + private: + friend class base::RefCountedThreadSafe<DevToolsHttpProtocolHandler>; + virtual ~DevToolsHttpProtocolHandler(); + // HttpListenSocket::Delegate implementation. virtual void OnHttpRequest(HttpListenSocket* socket, - HttpServerRequestInfo* info); + const HttpServerRequestInfo& info); virtual void OnWebSocketRequest(HttpListenSocket* socket, - HttpServerRequestInfo* info); + const HttpServerRequestInfo& info); virtual void OnWebSocketMessage(HttpListenSocket* socket, const std::string& data); virtual void OnClose(HttpListenSocket* socket); + virtual void OnHttpRequestUI(HttpListenSocket* socket, + const HttpServerRequestInfo& info); + virtual void OnWebSocketRequestUI(HttpListenSocket* socket, + const HttpServerRequestInfo& info); + virtual void OnWebSocketMessageUI(HttpListenSocket* socket, + const std::string& data); + virtual void OnCloseUI(HttpListenSocket* socket); + // URLRequest::Delegate implementation. virtual void OnResponseStarted(URLRequest* request); virtual void OnReadCompleted(URLRequest* request, int bytes_read); - private: - friend class base::RefCountedThreadSafe<DevToolsHttpProtocolHandler>; - virtual ~DevToolsHttpProtocolHandler(); - void Init(); void Teardown(); void Bind(URLRequest* request, HttpListenSocket* socket); void RequestCompleted(URLRequest* request); - void OnWebSocketMessageUI(HttpListenSocket* socket, const std::string& data); + + void Send200(HttpListenSocket* socket, + const std::string& data, + const std::string& mime_type = "text/html"); + void Send404(HttpListenSocket* socket); + void Send500(HttpListenSocket* socket, + const std::string& message); + void AcceptWebSocket(HttpListenSocket* socket, + const HttpServerRequestInfo& request); + + TabContents* GetTabContents(int session_id); int port_; scoped_refptr<HttpListenSocket> server_; typedef std::map<URLRequest*, HttpListenSocket*> RequestToSocketMap; - RequestToSocketMap request_to_socket_; + RequestToSocketMap request_to_socket_io_; typedef std::map<HttpListenSocket*, std::set<URLRequest*> > SocketToRequestsMap; - SocketToRequestsMap socket_to_requests_; + SocketToRequestsMap socket_to_requests_io_; typedef std::map<URLRequest*, scoped_refptr<net::IOBuffer> > BuffersMap; - BuffersMap request_to_buffer_; - scoped_ptr<DevToolsClientHost> client_host_; + BuffersMap request_to_buffer_io_; + typedef std::map<HttpListenSocket*, DevToolsClientHost*> + SocketToClientHostMap; + SocketToClientHostMap socket_to_client_host_ui_; DISALLOW_COPY_AND_ASSIGN(DevToolsHttpProtocolHandler); }; diff --git a/net/server/http_listen_socket.cc b/net/server/http_listen_socket.cc index 16c664e..cdc6c71 100644 --- a/net/server/http_listen_socket.cc +++ b/net/server/http_listen_socket.cc @@ -58,11 +58,11 @@ HttpListenSocket* HttpListenSocket::Listen( } std::string GetHeaderValue( - HttpServerRequestInfo* request, + const HttpServerRequestInfo& request, const std::string& header_name) { HttpServerRequestInfo::HeadersMap::iterator it = - request->headers.find(header_name); - if (it != request->headers.end()) + request.headers.find(header_name); + if (it != request.headers.end()) return it->second; return ""; } @@ -86,7 +86,7 @@ uint32 WebSocketKeyFingerprint(const std::string& str) { return htonl(static_cast<uint32>(number / spaces)); } -void HttpListenSocket::AcceptWebSocket(HttpServerRequestInfo* request) { +void HttpListenSocket::AcceptWebSocket(const HttpServerRequestInfo& request) { std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1"); std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2"); @@ -96,14 +96,14 @@ void HttpListenSocket::AcceptWebSocket(HttpServerRequestInfo* request) { char data[16]; memcpy(data, &fp1, 4); memcpy(data + 4, &fp2, 4); - memcpy(data + 8, &request->data[0], 8); + memcpy(data + 8, &request.data[0], 8); MD5Digest digest; MD5Sum(data, 16, &digest); std::string origin = GetHeaderValue(request, "Origin"); std::string host = GetHeaderValue(request, "Host"); - std::string location = "ws://" + host + request->path; + std::string location = "ws://" + host + request.path; is_web_socket_ = true; Send(StringPrintf("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" "Upgrade: WebSocket\r\n" @@ -125,6 +125,33 @@ void HttpListenSocket::SendOverWebSocket(const std::string& data) { Send(&message_end, 1); } +void HttpListenSocket::Send200(const std::string& data, + const std::string& content_type) { + Send(StringPrintf("HTTP/1.1 200 OK\r\n" + "Content-Type:%s\r\n" + "Content-Length:%d\r\n" + "\r\n", + content_type.c_str(), + static_cast<int>(data.length()))); + Send(data); +} + +void HttpListenSocket::Send404() { + Send("HTTP/1.1 404 Not Found\r\n" + "Content-Length: 0\r\n" + "\r\n"); +} + +void HttpListenSocket::Send500(const std::string& message) { + Send(StringPrintf("HTTP/1.1 500 Internal Error\r\n" + "Content-Type:text/html\r\n" + "Content-Length:%d\r\n" + "\r\n" + "%s", + static_cast<int>(message.length()), + message.c_str())); +} + // // HTTP Request Parser // This HTTP request parser uses a simple state machine to quickly parse @@ -199,11 +226,10 @@ int charToInput(char ch) { return INPUT_DEFAULT; } -HttpServerRequestInfo* HttpListenSocket::ParseHeaders() { +bool HttpListenSocket::ParseHeaders(HttpServerRequestInfo* info) { int pos = 0; int data_len = recv_data_.length(); int state = is_web_socket_ ? ST_WS_READY : ST_METHOD; - scoped_ptr<HttpServerRequestInfo> info(new HttpServerRequestInfo()); std::string buffer; std::string header_name; std::string header_value; @@ -247,7 +273,7 @@ HttpServerRequestInfo* HttpListenSocket::ParseHeaders() { recv_data_ = recv_data_.substr(pos); info->data = buffer; buffer.clear(); - return info.release(); + return true; break; } state = next_state; @@ -266,17 +292,17 @@ HttpServerRequestInfo* HttpListenSocket::ParseHeaders() { recv_data_ = recv_data_.substr(pos); info->data = recv_data_; recv_data_.clear(); - return info.release(); + return true; case ST_WS_CLOSE: is_web_socket_ = false; - return NULL; + return false; case ST_ERR: - return NULL; + return false; } } } // No more characters, but we haven't finished parsing yet. - return NULL; + return false; } void HttpListenSocket::DidAccept(ListenSocket* server, @@ -289,26 +315,26 @@ void HttpListenSocket::DidRead(ListenSocket*, int len) { recv_data_.append(data, len); while (recv_data_.length()) { - scoped_ptr<HttpServerRequestInfo> request(ParseHeaders()); - if (!request.get()) + HttpServerRequestInfo request; + if (!ParseHeaders(&request)) break; if (is_web_socket_) { - delegate_->OnWebSocketMessage(this, request->data); + delegate_->OnWebSocketMessage(this, request.data); continue; } - std::string connection = GetHeaderValue(request.get(), "Connection"); + std::string connection = GetHeaderValue(request, "Connection"); if (connection == "Upgrade") { // Is this WebSocket and if yes, upgrade the connection. - std::string key1 = GetHeaderValue(request.get(), "Sec-WebSocket-Key1"); - std::string key2 = GetHeaderValue(request.get(), "Sec-WebSocket-Key2"); + std::string key1 = GetHeaderValue(request, "Sec-WebSocket-Key1"); + std::string key2 = GetHeaderValue(request, "Sec-WebSocket-Key2"); if (!key1.empty() && !key2.empty()) { - delegate_->OnWebSocketRequest(this, request.get()); + delegate_->OnWebSocketRequest(this, request); continue; } } - delegate_->OnHttpRequest(this, request.get()); + delegate_->OnHttpRequest(this, request); } } diff --git a/net/server/http_listen_socket.h b/net/server/http_listen_socket.h index 5517af0..536abb2 100644 --- a/net/server/http_listen_socket.h +++ b/net/server/http_listen_socket.h @@ -16,10 +16,10 @@ class HttpListenSocket : public ListenSocket, class Delegate { public: virtual void OnHttpRequest(HttpListenSocket* socket, - HttpServerRequestInfo* info) = 0; + const HttpServerRequestInfo& info) = 0; virtual void OnWebSocketRequest(HttpListenSocket* socket, - HttpServerRequestInfo* info) = 0; + const HttpServerRequestInfo& info) = 0; virtual void OnWebSocketMessage(HttpListenSocket* socket, const std::string& data) = 0; @@ -29,16 +29,22 @@ class HttpListenSocket : public ListenSocket, virtual ~Delegate() {} }; + virtual void Accept(); + static HttpListenSocket* Listen(const std::string& ip, int port, HttpListenSocket::Delegate* delegate); - void AcceptWebSocket(HttpServerRequestInfo* request); + void AcceptWebSocket(const HttpServerRequestInfo& request); void SendOverWebSocket(const std::string& data); + void Send200(const std::string& data, const std::string& mime_type); + void Send404(); + void Send500(const std::string& message); + + void Close() { ListenSocket::Close(); } void Listen() { ListenSocket::Listen(); } - virtual void Accept(); // ListenSocketDelegate virtual void DidAccept(ListenSocket* server, ListenSocket* connection); @@ -53,7 +59,7 @@ class HttpListenSocket : public ListenSocket, // Expects the raw data to be stored in recv_data_. If parsing is successful, // will remove the data parsed from recv_data_, leaving only the unused // recv data. - HttpServerRequestInfo* ParseHeaders(); + bool ParseHeaders(HttpServerRequestInfo* info); HttpListenSocket::Delegate* delegate_; bool is_web_socket_; diff --git a/net/server/http_server_request_info.h b/net/server/http_server_request_info.h index 84f767f..39689c7 100644 --- a/net/server/http_server_request_info.h +++ b/net/server/http_server_request_info.h @@ -29,7 +29,7 @@ class HttpServerRequestInfo { // A map of the names -> values for HTTP headers. typedef std::map<std::string, std::string> HeadersMap; - HeadersMap headers; + mutable HeadersMap headers; }; #endif // NET_SERVER_HTTP_SERVER_REQUEST_INFO_H_ |