blob: c7ebdddd2e8faa6cb4df378af7f1188283747982 [file] [log] [blame]
// Copyright 2015 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 "mojo/services/network/http_server_impl.h"
#include "base/logging.h"
#include "mojo/services/network/http_connection_impl.h"
#include "mojo/services/network/net_adapters.h"
#include "mojo/services/network/net_address_type_converters.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
#include "net/socket/tcp_server_socket.h"
namespace mojo {
namespace {
const int kBackLog = 10;
} // namespace
// static
void HttpServerImpl::Create(
NetAddressPtr local_address,
HttpServerDelegatePtr delegate,
const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) {
HttpServerImpl* http_server = new HttpServerImpl(delegate.Pass());
int net_error = http_server->Start(local_address.Pass());
if (net_error != net::OK) {
callback.Run(MakeNetworkError(net_error), nullptr);
delete http_server;
return;
}
callback.Run(MakeNetworkError(net::OK), http_server->GetLocalAddress());
}
HttpServerImpl::HttpServerImpl(HttpServerDelegatePtr delegate)
: delegate_(delegate.Pass()) {
DCHECK(delegate_);
delegate_.set_connection_error_handler([this]() { delete this; });
}
HttpServerImpl::~HttpServerImpl() {}
int HttpServerImpl::Start(NetAddressPtr local_address) {
DCHECK(local_address);
scoped_ptr<net::ServerSocket> socket(
new net::TCPServerSocket(nullptr, net::NetLog::Source()));
int net_result = socket->Listen(local_address.To<net::IPEndPoint>(),
kBackLog);
if (net_result != net::OK)
return net_result;
server_.reset(new net::HttpServer(socket.Pass(), this));
return net::OK;
}
NetAddressPtr HttpServerImpl::GetLocalAddress() const {
if (!server_)
return nullptr;
net::IPEndPoint address;
int net_result = server_->GetLocalAddress(&address);
if (net_result != net::OK)
return nullptr;
return NetAddress::From(address);
}
void HttpServerImpl::OnConnect(int connection_id) {
DCHECK(connections_.find(connection_id) == connections_.end());
HttpConnectionPtr connection;
HttpConnectionDelegatePtr connection_delegate;
InterfaceRequest<HttpConnectionDelegate> delegate_request =
GetProxy(&connection_delegate);
linked_ptr<HttpConnectionImpl> connection_impl(
new HttpConnectionImpl(connection_id, this, connection_delegate.Pass(),
&connection));
connections_[connection_id] = connection_impl;
delegate_->OnConnected(connection.Pass(), delegate_request.Pass());
}
void HttpServerImpl::OnHttpRequest(int connection_id,
const net::HttpServerRequestInfo& info) {
DCHECK(connections_.find(connection_id) != connections_.end());
connections_[connection_id]->OnReceivedHttpRequest(info);
}
void HttpServerImpl::OnWebSocketRequest(
int connection_id,
const net::HttpServerRequestInfo& info) {
DCHECK(connections_.find(connection_id) != connections_.end());
connections_[connection_id]->OnReceivedWebSocketRequest(info);
}
void HttpServerImpl::OnWebSocketMessage(int connection_id,
const std::string& data) {
DCHECK(connections_.find(connection_id) != connections_.end());
connections_[connection_id]->OnReceivedWebSocketMessage(data);
}
void HttpServerImpl::OnClose(int connection_id) {
DCHECK(connections_.find(connection_id) != connections_.end());
connections_.erase(connection_id);
}
} // namespace mojo