Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: chrome/browser/google_apis/test_server/http_server.cc

Issue 11358227: HTTP server for testing Google APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: y Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/google_apis/test_server/http_server.h"
6
7 #include "base/bind.h"
8 #include "base/stl_util.h"
9 #include "base/file_util.h"
Lei Zhang 2012/11/14 05:30:07 nit: sort this list in alphabetical order
satorux1 2012/11/14 05:47:30 Done.
10 #include "base/stringprintf.h"
11 #include "chrome/browser/google_apis/test_server/http_request.h"
12 #include "chrome/browser/google_apis/test_server/http_response.h"
13 #include "chrome/browser/google_apis/gdata_test_util.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/test/test_utils.h"
16 #include "net/tools/fetch/http_listen_socket.h"
17
18 namespace drive {
19 namespace test_server {
20
21 using content::BrowserThread;
22
23 namespace {
24
25 const int kPort = 8040;
26 const char kIp[] = "127.0.0.1";
27 const int kRetries = 10;
28
29 // Callback to handle requests with default predefined response for requests
30 // matching the address |url|.
31 scoped_ptr<HttpResponse> HandleDefaultRequest(const GURL& url,
32 const HttpResponse& response,
33 const HttpRequest& request) {
34 if (url.path() != request.uri.path())
35 return scoped_ptr<HttpResponse>(NULL);
36 return scoped_ptr<HttpResponse>(new HttpResponse(response));
37 }
38
39 } // namespace
40
41 HttpListenSocket::HttpListenSocket(const SocketDescriptor socket_descriptor,
42 net::StreamListenSocket::Delegate* delegate)
43 : net::TCPListenSocket(socket_descriptor, delegate) {
44 }
45
46 void HttpListenSocket::Listen() {
47 net::TCPListenSocket::Listen();
48 }
49
50 HttpListenSocket::~HttpListenSocket() {
51 }
52
53 bool HttpServer::InitializeAndWaitUntilReady() {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
55
56 BrowserThread::PostTask(
57 BrowserThread::IO,
58 FROM_HERE,
59 base::Bind(&HttpServer::InitializeOnIOThread,
60 base::Unretained(this),
61 InitializeCallback()));
62
63 // Wait for the task completion.
64 content::RunAllPendingInMessageLoop(BrowserThread::IO);
65 content::RunAllPendingInMessageLoop();
66
67 return Started();
68 }
69
70 void HttpServer::InitializeOnIOThread(const InitializeCallback& callback) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
72 DCHECK(!Started());
73
74 int retries_left = kRetries + 1;
75 int try_port = kPort;
76
77 while (retries_left > 0) {
78 SocketDescriptor socket_descriptor = net::TCPListenSocket::CreateAndBind(
79 kIp,
80 try_port);
81 if (socket_descriptor != net::TCPListenSocket::kInvalidSocket) {
82 listen_socket_ = new HttpListenSocket(socket_descriptor, this);
83 listen_socket_->Listen();
84 base_url_ = GURL(base::StringPrintf("http://%s:%d", kIp, try_port));
85 port_ = try_port;
86 break;
87 }
88 retries_left--;
89 try_port++;
90 }
91
92 if (!callback.is_null())
93 callback.Run(listen_socket_.get() != NULL);
94 }
95
96 HttpServer::HttpServer()
97 : port_(-1),
98 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
99 }
100
101 HttpServer::~HttpServer() {
102 STLDeleteContainerPairSecondPointers(connections_.begin(),
103 connections_.end());
104 }
105
106 void HttpServer::HandleRequest(HttpConnection* connection,
107 scoped_ptr<HttpRequest> request) {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
109
110 for (size_t i = 0; i < request_handlers_.size(); ++i) {
111 scoped_ptr<HttpResponse> response =
112 request_handlers_[i].Run(*request.get());
113 if (response.get()) {
114 connection->SendResponse(response.Pass());
115 return;
116 }
117 }
118
119 LOG(WARNING) << "Request not handled. Returning 404.";
120 scoped_ptr<HttpResponse> not_found_response(new HttpResponse());
121 not_found_response->code = NOT_FOUND;
122 connection->SendResponse(not_found_response.Pass());
123
124 // Drop the connection, since we do not support multiple requests per
125 // connection.
126 connections_.erase(connection->socket_.get());
127 delete connection;
128 }
129
130 GURL HttpServer::GetBaseURL() {
131 return base_url_;
132 }
133
134 void HttpServer::RegisterRequestHandler(
135 const HandleRequestCallback& callback) {
136 request_handlers_.push_back(callback);
137 }
138
139 GURL HttpServer::RegisterDefaultResponse(
140 const std::string& relative_path,
141 const HttpResponse& default_response) {
142 GURL request_url = base_url_.Resolve(relative_path);
143 const HandleRequestCallback callback =
144 base::Bind(&HandleDefaultRequest,
145 request_url,
146 default_response);
147 request_handlers_.push_back(callback);
148
149 return request_url;
150 }
151
152 GURL HttpServer::RegisterTextResponse(
153 const std::string& relative_path,
154 const std::string& content,
155 const std::string& content_type,
156 const ResponseCode response_code) {
157 HttpResponse default_response;
158 default_response.content = content;
159 default_response.content_type = content_type;
160 default_response.code = response_code;
161
162 return RegisterDefaultResponse(relative_path, default_response);
163 }
164
165 GURL HttpServer::RegisterFileResponse(
166 const std::string& relative_path,
167 const FilePath& file_path,
168 const std::string& content_type,
169 const ResponseCode response_code) {
170 HttpResponse default_response;
171
172 const bool success = file_util::ReadFileToString(
173 file_path, &default_response.content);
174 DCHECK(success) << "Failed to open the file: " << file_path.value();
175
176 default_response.content_type = content_type;
177 default_response.code = response_code;
178
179 return RegisterDefaultResponse(relative_path, default_response);
180 }
181
182 void HttpServer::DidAccept(net::StreamListenSocket* server,
183 net::StreamListenSocket* connection) {
184 HttpConnection* http_connection = new HttpConnection(
185 connection,
186 base::Bind(&HttpServer::HandleRequest, weak_factory_.GetWeakPtr()));
187 connections_[connection] = http_connection;
188 }
189
190 void HttpServer::DidRead(net::StreamListenSocket* connection,
191 const char* data,
192 int length) {
193 HttpConnection* http_connection = FindConnection(connection);
194 if (http_connection == NULL) {
195 LOG(WARNING) << "Unknown connection.";
196 return;
197 }
198 http_connection->ReceiveData(std::string(data, length));
199 }
200
201 void HttpServer::DidClose(net::StreamListenSocket* connection) {
202 HttpConnection* http_connection = FindConnection(connection);
203 if (http_connection == NULL) {
204 LOG(WARNING) << "Unknown connection.";
205 return;
206 }
207 delete http_connection;
208 connections_.erase(connection);
209 }
210
211 HttpConnection* HttpServer::FindConnection(
212 net::StreamListenSocket* socket) {
213 std::map<net::StreamListenSocket*, HttpConnection*>::iterator it =
214 connections_.find(socket);
215 if (it == connections_.end()) {
216 return NULL;
217 }
218 return it->second;
219 }
220
221 } // namespace test_server
222 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698