blob: 7e103ddb4fc68fa96d1edec202a4d3f0af0b6baf [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <string>
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "net/http/http_status_code.h"
namespace net {
class HttpConnection;
class HttpServerRequestInfo;
class HttpServerResponseInfo;
class IPEndPoint;
class ServerSocket;
class StreamSocket;
class WebSocket;
class HttpServer {
// Delegate to handle http/websocket events. Beware that it is not safe to
// destroy the HttpServer in any of these callbacks.
class Delegate {
virtual ~Delegate() {}
virtual void OnConnect(int connection_id) = 0;
virtual void OnHttpRequest(int connection_id,
const HttpServerRequestInfo& info) = 0;
virtual void OnWebSocketRequest(int connection_id,
const HttpServerRequestInfo& info) = 0;
virtual void OnWebSocketMessage(int connection_id,
const std::string& data) = 0;
virtual void OnClose(int connection_id) = 0;
// Instantiates a http server with |server_socket| which already started
// listening, but not accepting. This constructor schedules accepting
// connections asynchronously in case when |delegate| is not ready to get
// callbacks yet.
HttpServer(scoped_ptr<ServerSocket> server_socket,
HttpServer::Delegate* delegate);
void AcceptWebSocket(int connection_id,
const HttpServerRequestInfo& request);
void SendOverWebSocket(int connection_id, const std::string& data);
// Sends the provided data directly to the given connection. No validation is
// performed that data constitutes a valid HTTP response. A valid HTTP
// response may be split across multiple calls to SendRaw.
void SendRaw(int connection_id, const std::string& data);
// TODO(byungchul): Consider replacing function name with SendResponseInfo
void SendResponse(int connection_id, const HttpServerResponseInfo& response);
void Send(int connection_id,
HttpStatusCode status_code,
const std::string& data,
const std::string& mime_type);
void Send200(int connection_id,
const std::string& data,
const std::string& mime_type);
void Send404(int connection_id);
void Send500(int connection_id, const std::string& message);
void Close(int connection_id);
void SetReceiveBufferSize(int connection_id, int32_t size);
void SetSendBufferSize(int connection_id, int32_t size);
// Copies the local address to |address|. Returns a network error code.
int GetLocalAddress(IPEndPoint* address);
friend class HttpServerTest;
typedef std::map<int, HttpConnection*> IdToConnectionMap;
void DoAcceptLoop();
void OnAcceptCompleted(int rv);
int HandleAcceptResult(int rv);
void DoReadLoop(HttpConnection* connection);
void OnReadCompleted(int connection_id, int rv);
int HandleReadResult(HttpConnection* connection, int rv);
void DoWriteLoop(HttpConnection* connection);
void OnWriteCompleted(int connection_id, int rv);
int HandleWriteResult(HttpConnection* connection, int rv);
// 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.
bool ParseHeaders(const char* data,
size_t data_len,
HttpServerRequestInfo* info,
size_t* pos);
HttpConnection* FindConnection(int connection_id);
// Whether or not Close() has been called during delegate callback processing.
bool HasClosedConnection(HttpConnection* connection);
const scoped_ptr<ServerSocket> server_socket_;
scoped_ptr<StreamSocket> accepted_socket_;
HttpServer::Delegate* const delegate_;
int last_id_;
IdToConnectionMap id_to_connection_;
base::WeakPtrFactory<HttpServer> weak_ptr_factory_;
} // namespace net