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

Side by Side Diff: chrome/browser/chromeos/drive/test_servers/http_test_server.cc

Issue 11088073: HTTP server for testing Google Drive. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed for clang. 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
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/chromeos/drive/test_servers/http_test_server.h"
6
7 #include "base/bind.h"
8 #include "base/stl_util.h"
9 #include "base/file_util.h"
10 #include "base/stringprintf.h"
11 #include "chrome/browser/chromeos/drive/test_servers/http_request.h"
12 #include "chrome/browser/chromeos/drive/test_servers/http_response.h"
13 #include "chrome/browser/google_apis/gdata_test_util.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/tools/fetch/http_listen_socket.h"
16
17 #include <sstream>
18
19 namespace drive {
20 namespace test_servers {
21
22 using content::BrowserThread;
23
24 namespace {
25
26 const int kPort = 8040;
27 const char kIp[] = "127.0.0.1";
28 const int kRetries = 10;
29
30 // Callback about success or failure in creating a server. |result| is a pointer
31 // to result passed back to HttpTestServer::CreateForTesting. |server| is a
32 // pointer to the created server or NULL in case of failure.
33 static void OnCreatedForTesting(HttpTestServer** result,
34 HttpTestServer* server) {
35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
36 *result = server;
37 MessageLoop::current()->Quit();
38 }
39
40 // Callback to handle requests with default predefined response for requests
41 // matching the address |url|.
42 scoped_ptr<HttpResponse> HandleDefaultRequest(const GURL& url,
43 const HttpResponse& response,
44 const HttpRequest* request) {
45 if (url.path() != request->uri.path())
46 return scoped_ptr<HttpResponse>(NULL);
47 return scoped_ptr<HttpResponse>(new HttpResponse(response));
48 }
49
50 } // namespace
51
52 HttpListenSocket::HttpListenSocket(const SocketDescriptor socket_descriptor,
53 net::StreamListenSocket::Delegate* delegate)
54 : net::TCPListenSocket(socket_descriptor, delegate) {
55 }
56
57 void HttpListenSocket::Listen() {
58 net::TCPListenSocket::Listen();
59 }
60
61 HttpListenSocket::~HttpListenSocket() {
62 }
63
64 // static
65 scoped_ptr<HttpTestServer> HttpTestServer::CreateForTesting() {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
67
68 HttpTestServer* result = NULL;
69 BrowserThread::PostTask(
70 BrowserThread::IO,
71 FROM_HERE,
72 base::Bind(
73 &HttpTestServer::CreateOnIOThread,
74 base::Bind(&OnCreatedForTesting, &result)));
75
76 // Wait for the task completion.
77 MessageLoop::current()->Run();
78 return scoped_ptr<HttpTestServer>(result);
79 }
80
81 // static
82 void HttpTestServer::CreateOnIOThread(const CreateCallback& callback) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
84
85 int retries_left = kRetries + 1;
86 int try_port = kPort;
87 HttpTestServer* server = NULL;
88
89 while (retries_left) {
90 SocketDescriptor socket_descriptor = net::TCPListenSocket::CreateAndBind(
91 kIp,
92 try_port);
93 if (socket_descriptor != net::TCPListenSocket::kInvalidSocket) {
94 server = new HttpTestServer(try_port, socket_descriptor);
95 break;
96 }
97 retries_left--;
98 try_port++;
99 }
100
101 BrowserThread::PostTask(BrowserThread::UI,
102 FROM_HERE,
103 base::Bind(callback, server));
104 }
105
106 HttpTestServer::HttpTestServer(int port,
107 const SocketDescriptor& socket_descriptor)
108 : listen_socket_(new HttpListenSocket(
109 socket_descriptor,
110 ALLOW_THIS_IN_INITIALIZER_LIST(this))),
111 port_(port),
112 last_unique_id_(0),
113 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
114 listen_socket_->Listen();
115 base_url_ = GURL(base::StringPrintf("http://%s:%d", kIp, port_));
116 }
117
118 HttpTestServer::~HttpTestServer() {
119 STLDeleteContainerPairSecondPointers(connections_.begin(),
120 connections_.end());
121 }
122
123 void HttpTestServer::HandleRequest(HttpConnection* connection,
124 scoped_ptr<HttpRequest> request) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
126
127 std::vector<HandleRequestCallback>::iterator current_handler =
128 request_handlers_.begin();
129 while (current_handler != request_handlers_.end()) {
130 scoped_ptr<HttpResponse> response = current_handler->Run(request.get());
131 if (response.get()) {
132 connection->SendResponse(response.Pass());
133 return;
134 }
135 current_handler++;
136 }
137
138 LOG(WARNING) << "Request not handled. Returning 404.";
139 scoped_ptr<HttpResponse> not_found_response(new HttpResponse());
140 not_found_response->code = NOT_FOUND;
141 connection->SendResponse(not_found_response.Pass());
142 }
143
144 GURL HttpTestServer::GetBaseURL() {
145 return base_url_;
146 }
147
148 void HttpTestServer::RegisterRequestHandler(
149 const HandleRequestCallback& callback) {
150 request_handlers_.push_back(callback);
151 }
152
153 GURL HttpTestServer::RegisterDefaultResponse(
154 const std::string& relative_path,
155 const HttpResponse& default_response) {
156 GURL request_url = base_url_.Resolve(relative_path);
157 const HandleRequestCallback callback =
158 base::Bind(&HandleDefaultRequest,
159 request_url,
160 default_response);
161 request_handlers_.push_back(callback);
162
163 return request_url;
164 }
165
166 GURL HttpTestServer::RegisterTextResponse(
167 const std::string& relative_path,
168 const std::string& content,
169 const std::string& content_type,
170 const ResponseCode response_code) {
171 HttpResponse default_response;
172 default_response.content = content;
173 default_response.content_type = content_type;
174 default_response.code = response_code;
175
176 return RegisterDefaultResponse(relative_path, default_response);
177 }
178
179 GURL HttpTestServer::RegisterTextResponse(
180 const std::string& content,
181 const std::string& content_type) {
182 return RegisterTextResponse(GenerateUniqueIdentifier(),
183 content,
184 content_type,
185 SUCCESS);
186 }
187
188 GURL HttpTestServer::RegisterFileResponse(
189 const std::string& relative_path,
190 const FilePath& file_path,
191 const std::string& content_type,
192 const ResponseCode response_code) {
193 HttpResponse default_response;
194
195 DCHECK(file_util::ReadFileToString(file_path, &default_response.content)) <<
196 "Failed to open the file: " << file_path.value();
197
198 default_response.content_type = content_type;
199 default_response.code = response_code;
200
201 return RegisterDefaultResponse(relative_path, default_response);
202 }
203
204 GURL HttpTestServer::RegisterFileResponse(
205 const FilePath& file_path,
206 const std::string& content_type) {
207 return RegisterFileResponse(
208 GenerateUniqueIdentifier() + "/" + file_path.BaseName().value(),
209 file_path,
210 content_type,
211 SUCCESS);
212 }
213
214 std::string HttpTestServer::GenerateUniqueIdentifier() {
215 std::stringstream result_builder;
216 result_builder << ++last_unique_id_;
217 return result_builder.str();
218 }
219
220 void HttpTestServer::DidAccept(net::StreamListenSocket* server,
221 net::StreamListenSocket* connection) {
222 HttpConnection* http_connection = new HttpConnection(
223 connection,
224 base::Bind(&HttpTestServer::HandleRequest, weak_factory_.GetWeakPtr()));
225 connections_[connection] = http_connection;
226 }
227
228 void HttpTestServer::DidRead(net::StreamListenSocket* connection,
229 const char* data,
230 int length) {
231 HttpConnection* http_connection = FindConnection(connection);
232 if (http_connection == NULL) {
233 LOG(WARNING) << "Unknown connection.";
234 return;
235 }
236 http_connection->ReceiveData(data, length);
237 }
238
239 void HttpTestServer::DidClose(net::StreamListenSocket* connection) {
240 HttpConnection* http_connection = FindConnection(connection);
241 if (http_connection == NULL) {
242 LOG(WARNING) << "Unknown connection.";
243 return;
244 }
245 delete http_connection;
246 connections_.erase(connection);
247 }
248
249 HttpConnection* HttpTestServer::FindConnection(
250 net::StreamListenSocket* socket) {
251 std::map<net::StreamListenSocket*, HttpConnection*>::iterator it =
252 connections_.find(socket);
253 if (it == connections_.end()) {
254 return NULL;
255 }
256 return it->second;
257 }
258
259 } // namespace test_servers
260 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698