OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/services/network/http_connection_impl.h" | 5 #include "mojo/services/network/http_connection_impl.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
11 #include "base/callback.h" | 12 #include "base/callback.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
15 #include "mojo/message_pump/handle_watcher.h" | 16 #include "mojo/message_pump/handle_watcher.h" |
16 #include "mojo/public/cpp/bindings/type_converter.h" | 17 #include "mojo/public/cpp/bindings/type_converter.h" |
17 #include "mojo/public/cpp/system/data_pipe.h" | 18 #include "mojo/public/cpp/system/data_pipe.h" |
(...skipping 17 matching lines...) Expand all Loading... |
35 public: | 36 public: |
36 using CompletionCallback = | 37 using CompletionCallback = |
37 base::Callback<void(SimpleDataPipeReader*, scoped_ptr<std::string>)>; | 38 base::Callback<void(SimpleDataPipeReader*, scoped_ptr<std::string>)>; |
38 | 39 |
39 SimpleDataPipeReader() {} | 40 SimpleDataPipeReader() {} |
40 ~SimpleDataPipeReader() {} | 41 ~SimpleDataPipeReader() {} |
41 | 42 |
42 void Start(ScopedDataPipeConsumerHandle consumer, | 43 void Start(ScopedDataPipeConsumerHandle consumer, |
43 const CompletionCallback& completion_callback) { | 44 const CompletionCallback& completion_callback) { |
44 DCHECK(consumer.is_valid() && !consumer_.is_valid()); | 45 DCHECK(consumer.is_valid() && !consumer_.is_valid()); |
45 consumer_ = consumer.Pass(); | 46 consumer_ = std::move(consumer); |
46 completion_callback_ = completion_callback; | 47 completion_callback_ = completion_callback; |
47 buffer_.reset(new std::string); | 48 buffer_.reset(new std::string); |
48 ReadMore(); | 49 ReadMore(); |
49 } | 50 } |
50 | 51 |
51 private: | 52 private: |
52 void ReadMore() { | 53 void ReadMore() { |
53 const void* buf; | 54 const void* buf; |
54 uint32_t buf_size; | 55 uint32_t buf_size; |
55 MojoResult rv = BeginReadDataRaw(consumer_.get(), &buf, &buf_size, | 56 MojoResult rv = BeginReadDataRaw(consumer_.get(), &buf, &buf_size, |
56 MOJO_READ_DATA_FLAG_NONE); | 57 MOJO_READ_DATA_FLAG_NONE); |
57 if (rv == MOJO_RESULT_OK) { | 58 if (rv == MOJO_RESULT_OK) { |
58 buffer_->append(static_cast<const char*>(buf), buf_size); | 59 buffer_->append(static_cast<const char*>(buf), buf_size); |
59 EndReadDataRaw(consumer_.get(), buf_size); | 60 EndReadDataRaw(consumer_.get(), buf_size); |
60 WaitToReadMore(); | 61 WaitToReadMore(); |
61 } else if (rv == MOJO_RESULT_SHOULD_WAIT) { | 62 } else if (rv == MOJO_RESULT_SHOULD_WAIT) { |
62 WaitToReadMore(); | 63 WaitToReadMore(); |
63 } else if (rv == MOJO_RESULT_FAILED_PRECONDITION) { | 64 } else if (rv == MOJO_RESULT_FAILED_PRECONDITION) { |
64 // We reached end-of-file. | 65 // We reached end-of-file. |
65 completion_callback_.Run(this, buffer_.Pass()); | 66 completion_callback_.Run(this, std::move(buffer_)); |
66 // Note: This object may have been destroyed in the callback. | 67 // Note: This object may have been destroyed in the callback. |
67 } else { | 68 } else { |
68 CHECK(false); | 69 CHECK(false); |
69 } | 70 } |
70 } | 71 } |
71 | 72 |
72 void WaitToReadMore() { | 73 void WaitToReadMore() { |
73 watcher_.Start(consumer_.get(), MOJO_HANDLE_SIGNAL_READABLE, | 74 watcher_.Start(consumer_.get(), MOJO_HANDLE_SIGNAL_READABLE, |
74 MOJO_DEADLINE_INDEFINITE, | 75 MOJO_DEADLINE_INDEFINITE, |
75 base::Bind(&SimpleDataPipeReader::OnHandleReady, | 76 base::Bind(&SimpleDataPipeReader::OnHandleReady, |
(...skipping 11 matching lines...) Expand all Loading... |
87 }; | 88 }; |
88 | 89 |
89 class HttpConnectionImpl::WebSocketImpl : public WebSocket { | 90 class HttpConnectionImpl::WebSocketImpl : public WebSocket { |
90 public: | 91 public: |
91 // |connection| must outlive this object. | 92 // |connection| must outlive this object. |
92 WebSocketImpl(HttpConnectionImpl* connection, | 93 WebSocketImpl(HttpConnectionImpl* connection, |
93 InterfaceRequest<WebSocket> request, | 94 InterfaceRequest<WebSocket> request, |
94 ScopedDataPipeConsumerHandle send_stream, | 95 ScopedDataPipeConsumerHandle send_stream, |
95 WebSocketClientPtr client) | 96 WebSocketClientPtr client) |
96 : connection_(connection), | 97 : connection_(connection), |
97 binding_(this, request.Pass()), | 98 binding_(this, std::move(request)), |
98 client_(client.Pass()), | 99 client_(std::move(client)), |
99 send_stream_(send_stream.Pass()), | 100 send_stream_(std::move(send_stream)), |
100 read_send_stream_(new WebSocketReadQueue(send_stream_.get())), | 101 read_send_stream_(new WebSocketReadQueue(send_stream_.get())), |
101 pending_send_count_(0) { | 102 pending_send_count_(0) { |
102 DCHECK(binding_.is_bound()); | 103 DCHECK(binding_.is_bound()); |
103 DCHECK(client_); | 104 DCHECK(client_); |
104 DCHECK(send_stream_.is_valid()); | 105 DCHECK(send_stream_.is_valid()); |
105 | 106 |
106 binding_.set_connection_error_handler([this]() { Close(); }); | 107 binding_.set_connection_error_handler([this]() { Close(); }); |
107 client_.set_connection_error_handler([this]() { Close(); }); | 108 client_.set_connection_error_handler([this]() { Close(); }); |
108 | 109 |
109 DataPipe data_pipe; | 110 DataPipe data_pipe; |
110 receive_stream_ = data_pipe.producer_handle.Pass(); | 111 receive_stream_ = std::move(data_pipe.producer_handle); |
111 write_receive_stream_.reset(new WebSocketWriteQueue(receive_stream_.get())); | 112 write_receive_stream_.reset(new WebSocketWriteQueue(receive_stream_.get())); |
112 | 113 |
113 client_->DidConnect("", "", data_pipe.consumer_handle.Pass()); | 114 client_->DidConnect("", "", std::move(data_pipe.consumer_handle)); |
114 } | 115 } |
115 | 116 |
116 ~WebSocketImpl() override {} | 117 ~WebSocketImpl() override {} |
117 | 118 |
118 void Close() { | 119 void Close() { |
119 DCHECK(!IsClosing()); | 120 DCHECK(!IsClosing()); |
120 | 121 |
121 binding_.Close(); | 122 binding_.Close(); |
122 client_.reset(); | 123 client_.reset(); |
123 | 124 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 static HttpRequestPtr Convert(const net::HttpServerRequestInfo& obj) { | 225 static HttpRequestPtr Convert(const net::HttpServerRequestInfo& obj) { |
225 HttpRequestPtr request(HttpRequest::New()); | 226 HttpRequestPtr request(HttpRequest::New()); |
226 request->method = obj.method; | 227 request->method = obj.method; |
227 request->url = obj.path; | 228 request->url = obj.path; |
228 request->headers.resize(obj.headers.size()); | 229 request->headers.resize(obj.headers.size()); |
229 size_t index = 0; | 230 size_t index = 0; |
230 for (const auto& item : obj.headers) { | 231 for (const auto& item : obj.headers) { |
231 HttpHeaderPtr header(HttpHeader::New()); | 232 HttpHeaderPtr header(HttpHeader::New()); |
232 header->name = item.first; | 233 header->name = item.first; |
233 header->value = item.second; | 234 header->value = item.second; |
234 request->headers[index++] = header.Pass(); | 235 request->headers[index++] = std::move(header); |
235 } | 236 } |
236 if (!obj.data.empty()) { | 237 if (!obj.data.empty()) { |
237 uint32_t num_bytes = static_cast<uint32_t>(obj.data.size()); | 238 uint32_t num_bytes = static_cast<uint32_t>(obj.data.size()); |
238 MojoCreateDataPipeOptions options; | 239 MojoCreateDataPipeOptions options; |
239 options.struct_size = sizeof(MojoCreateDataPipeOptions); | 240 options.struct_size = sizeof(MojoCreateDataPipeOptions); |
240 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; | 241 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
241 options.element_num_bytes = 1; | 242 options.element_num_bytes = 1; |
242 options.capacity_num_bytes = num_bytes; | 243 options.capacity_num_bytes = num_bytes; |
243 DataPipe data_pipe(options); | 244 DataPipe data_pipe(options); |
244 request->body = data_pipe.consumer_handle.Pass(); | 245 request->body = std::move(data_pipe.consumer_handle); |
245 MojoResult result = | 246 MojoResult result = |
246 WriteDataRaw(data_pipe.producer_handle.get(), obj.data.data(), | 247 WriteDataRaw(data_pipe.producer_handle.get(), obj.data.data(), |
247 &num_bytes, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE); | 248 &num_bytes, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE); |
248 CHECK_EQ(MOJO_RESULT_OK, result); | 249 CHECK_EQ(MOJO_RESULT_OK, result); |
249 } | 250 } |
250 return request.Pass(); | 251 return request; |
251 } | 252 } |
252 }; | 253 }; |
253 | 254 |
254 HttpConnectionImpl::HttpConnectionImpl(int connection_id, | 255 HttpConnectionImpl::HttpConnectionImpl(int connection_id, |
255 HttpServerImpl* server, | 256 HttpServerImpl* server, |
256 HttpConnectionDelegatePtr delegate, | 257 HttpConnectionDelegatePtr delegate, |
257 HttpConnectionPtr* connection) | 258 HttpConnectionPtr* connection) |
258 : connection_id_(connection_id), | 259 : connection_id_(connection_id), |
259 server_(server), | 260 server_(server), |
260 delegate_(delegate.Pass()), | 261 delegate_(std::move(delegate)), |
261 binding_(this, connection) { | 262 binding_(this, connection) { |
262 DCHECK(delegate_); | 263 DCHECK(delegate_); |
263 binding_.set_connection_error_handler([this]() { Close(); }); | 264 binding_.set_connection_error_handler([this]() { Close(); }); |
264 delegate_.set_connection_error_handler([this]() { Close(); }); | 265 delegate_.set_connection_error_handler([this]() { Close(); }); |
265 } | 266 } |
266 | 267 |
267 HttpConnectionImpl::~HttpConnectionImpl() { | 268 HttpConnectionImpl::~HttpConnectionImpl() { |
268 STLDeleteElements(&response_body_readers_); | 269 STLDeleteElements(&response_body_readers_); |
269 } | 270 } |
270 | 271 |
271 void HttpConnectionImpl::OnReceivedHttpRequest( | 272 void HttpConnectionImpl::OnReceivedHttpRequest( |
272 const net::HttpServerRequestInfo& info) { | 273 const net::HttpServerRequestInfo& info) { |
273 if (IsClosing()) | 274 if (IsClosing()) |
274 return; | 275 return; |
275 | 276 |
276 delegate_->OnReceivedRequest( | 277 delegate_->OnReceivedRequest( |
277 HttpRequest::From(info), [this](HttpResponsePtr response) { | 278 HttpRequest::From(info), [this](HttpResponsePtr response) { |
278 if (response->body.is_valid()) { | 279 if (response->body.is_valid()) { |
279 SimpleDataPipeReader* reader = new SimpleDataPipeReader; | 280 SimpleDataPipeReader* reader = new SimpleDataPipeReader; |
280 response_body_readers_.insert(reader); | 281 response_body_readers_.insert(reader); |
281 ScopedDataPipeConsumerHandle body = response->body.Pass(); | 282 ScopedDataPipeConsumerHandle body = std::move(response->body); |
282 reader->Start( | 283 reader->Start( |
283 body.Pass(), | 284 std::move(body), |
284 base::Bind(&HttpConnectionImpl::OnFinishedReadingResponseBody, | 285 base::Bind(&HttpConnectionImpl::OnFinishedReadingResponseBody, |
285 base::Unretained(this), base::Passed(&response))); | 286 base::Unretained(this), base::Passed(&response))); |
286 } else { | 287 } else { |
287 OnFinishedReadingResponseBody(response.Pass(), nullptr, nullptr); | 288 OnFinishedReadingResponseBody(std::move(response), nullptr, nullptr); |
288 } | 289 } |
289 }); | 290 }); |
290 } | 291 } |
291 | 292 |
292 void HttpConnectionImpl::OnReceivedWebSocketRequest( | 293 void HttpConnectionImpl::OnReceivedWebSocketRequest( |
293 const net::HttpServerRequestInfo& info) { | 294 const net::HttpServerRequestInfo& info) { |
294 if (IsClosing()) | 295 if (IsClosing()) |
295 return; | 296 return; |
296 | 297 |
297 delegate_->OnReceivedWebSocketRequest( | 298 delegate_->OnReceivedWebSocketRequest( |
298 HttpRequest::From(info), | 299 HttpRequest::From(info), |
299 [this, info](InterfaceRequest<WebSocket> web_socket, | 300 [this, info](InterfaceRequest<WebSocket> web_socket, |
300 ScopedDataPipeConsumerHandle send_stream, | 301 ScopedDataPipeConsumerHandle send_stream, |
301 WebSocketClientPtr web_socket_client) { | 302 WebSocketClientPtr web_socket_client) { |
302 if (!web_socket.is_pending() || !send_stream.is_valid() || | 303 if (!web_socket.is_pending() || !send_stream.is_valid() || |
303 !web_socket_client) { | 304 !web_socket_client) { |
304 Close(); | 305 Close(); |
305 return; | 306 return; |
306 } | 307 } |
307 | 308 |
308 web_socket_.reset(new WebSocketImpl(this, web_socket.Pass(), | 309 web_socket_.reset(new WebSocketImpl(this, std::move(web_socket), |
309 send_stream.Pass(), | 310 std::move(send_stream), |
310 web_socket_client.Pass())); | 311 std::move(web_socket_client))); |
311 server_->server()->AcceptWebSocket(connection_id_, info); | 312 server_->server()->AcceptWebSocket(connection_id_, info); |
312 }); | 313 }); |
313 } | 314 } |
314 | 315 |
315 void HttpConnectionImpl::OnReceivedWebSocketMessage(const std::string& data) { | 316 void HttpConnectionImpl::OnReceivedWebSocketMessage(const std::string& data) { |
316 if (IsClosing()) | 317 if (IsClosing()) |
317 return; | 318 return; |
318 | 319 |
319 web_socket_->OnReceivedWebSocketMessage(data); | 320 web_socket_->OnReceivedWebSocketMessage(data); |
320 } | 321 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 // The close operation is initiated by this object. | 414 // The close operation is initiated by this object. |
414 NotifyOwnerCloseIfAllDone(); | 415 NotifyOwnerCloseIfAllDone(); |
415 } else { | 416 } else { |
416 // The close operation is initiated by |web_socket_|; start closing this | 417 // The close operation is initiated by |web_socket_|; start closing this |
417 // object. | 418 // object. |
418 Close(); | 419 Close(); |
419 } | 420 } |
420 } | 421 } |
421 | 422 |
422 } // namespace mojo | 423 } // namespace mojo |
OLD | NEW |