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..a7906f19670d0b65ee8582e2c4e54237a3f84461 |
--- /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); |
satorux1
2012/10/12 08:29:18
WaitableEvent should almost always be avoided.
I
mtomasz
2012/10/12 11:09:46
Correct me if I am wrong, but I think I really nee
satorux1
2012/10/16 03:12:18
I think you can make the object creation asynchron
|
+ HttpServer* server = NULL; |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(CreateServerOnIOThread, |
+ address, |
+ port, |
+ connection_delegate, |
+ &waiter, |
+ &server)); |
+ waiter.Wait(); |
+ |
+ return server; |
+} |
+ |
+void HttpServer::DropHttpConnection(HttpConnection* connection) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ connections_.erase(connection->socket_.get()); |
+ delete connection; |
+} |
+ |
+// static |
+void HttpServer::CreateServerOnIOThread( |
satorux1
2012/10/12 08:29:18
I guess you can make it a free function in anonymo
mtomasz
2012/10/12 11:09:46
I wanted to keep the constructor private. Also Lis
satorux1
2012/10/16 03:12:18
Then that's fine. Thank you for the explanation.
|
+ const std::string& address, |
+ int port, |
+ HttpConnectionDelegate* connection_delegate, |
+ base::WaitableEvent* waiter, |
+ HttpServer** server_ptr) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ SocketDescriptor socket_descriptor = CreateAndBind(address, port); |
+ HttpServer* server = NULL; |
+ if (socket_descriptor != 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(); |
+} |
+ |
+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 |