| Index: chrome/browser/chromeos/gdata/test_servers/http_server.cc
|
| diff --git a/chrome/browser/chromeos/gdata/test_servers/http_server.cc b/chrome/browser/chromeos/gdata/test_servers/http_server.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0e45f195174cfca12c8aa335e045917793e9fef5
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/gdata/test_servers/http_server.cc
|
| @@ -0,0 +1,126 @@
|
| +// 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 "chrome/browser/chromeos/gdata/test_servers/http_server.h"
|
| +
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +
|
| +#include <string>
|
| +#include <sstream>
|
| +#include "base/stl_util.h"
|
| +
|
| +namespace gdata {
|
| +namespace test_servers {
|
| +
|
| +using content::BrowserThread;
|
| +
|
| +// static
|
| +scoped_refptr<HttpServer> HttpServer::CreateServer(
|
| + const std::string& address,
|
| + int port,
|
| + HttpConnectionDelegate* connection_delegate) {
|
| +
|
| + // Launching the server class in the IO thread and waiting for the result.
|
| + // TODO(mtomasz): Change it to a completely new thread.
|
| + base::WaitableEvent waiter(false, false);
|
| + HttpServer* server = NULL;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(HttpServer::CreateServerOnIOThread,
|
| + address,
|
| + port,
|
| + connection_delegate,
|
| + &waiter,
|
| + &server));
|
| + waiter.Wait();
|
| +
|
| + return server;
|
| +}
|
| +
|
| +// static
|
| +void HttpServer::CreateServerOnIOThread(
|
| + const std::string& address,
|
| + int port,
|
| + HttpConnectionDelegate* connection_delegate,
|
| + base::WaitableEvent* waiter,
|
| + HttpServer** server_ptr) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + SocketDescriptor socket_descriptor = HttpServer::CreateAndBind(address, port);
|
| + HttpServer* server = NULL;
|
| + if (socket_descriptor != HttpServer::kInvalidSocket) {
|
| + server = new HttpServer(socket_descriptor, connection_delegate);
|
| + server->Listen();
|
| + }
|
| +
|
| + // Return the value and notify the caller (if provided) that the value
|
| + // is available.
|
| + *server_ptr = server;
|
| + if (waiter)
|
| + waiter->Signal();
|
| +}
|
| +
|
| +void HttpServer::DropHttpConnection(HttpConnection* connection) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + connections_.erase(connection->socket_.get());
|
| + delete connection;
|
| +}
|
| +
|
| +HttpServer::HttpServer(SocketDescriptor& socket,
|
| + HttpConnectionDelegate* connection_delegate) :
|
| + net::TCPListenSocket(socket, ALLOW_THIS_IN_INITIALIZER_LIST(this)),
|
| + connection_delegate_(connection_delegate) {
|
| +}
|
| +
|
| +HttpServer::~HttpServer() {
|
| + STLDeleteContainerPairSecondPointers(connections_.begin(),
|
| + connections_.end());
|
| +}
|
| +
|
| +void HttpServer::DidAccept(StreamListenSocket* server,
|
| + StreamListenSocket* connection) {
|
| + HttpConnection* http_connection = new HttpConnection(connection,
|
| + connection_delegate_);
|
| + connections_[connection] = http_connection;
|
| +}
|
| +
|
| +void HttpServer::DidRead(StreamListenSocket* connection,
|
| + const char* data,
|
| + int length) {
|
| + HttpConnection* http_connection = FindConnection(connection);
|
| + if (http_connection == NULL) {
|
| + LOG(ERROR) << "Unknown connection.";
|
| + return;
|
| + }
|
| + if (!http_connection->ReceiveData(data, length)) {
|
| + // Error occured during receiving data, or the request has not been
|
| + // handled by any of request handlers, so we are dropping the connection.
|
| + DropHttpConnection(http_connection);
|
| + }
|
| +}
|
| +
|
| +void HttpServer::DidClose(StreamListenSocket* connection) {
|
| + HttpConnection* http_connection = FindConnection(connection);
|
| + if (http_connection == NULL) {
|
| + LOG(ERROR) << "Unknown connection.";
|
| + return;
|
| + }
|
| + delete http_connection;
|
| + connections_.erase(connection);
|
| +}
|
| +
|
| +HttpConnection* HttpServer::FindConnection(StreamListenSocket* socket) {
|
| + std::map<StreamListenSocket*, HttpConnection*>::iterator it =
|
| + connections_.find(socket);
|
| + if (it == connections_.end()) {
|
| + return NULL;
|
| + }
|
| + return it->second;
|
| +}
|
| +
|
| +} // namespace test_servers
|
| +} // namespace gdata
|
|
|