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 "base/logging.h" | 5 #include "base/logging.h" |
6 #include "base/macros.h" | 6 #include "base/macros.h" |
7 #include "base/memory/linked_ptr.h" | 7 #include "base/memory/linked_ptr.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "mojo/common/data_pipe_utils.h" | 13 #include "mojo/data_pipe_utils/data_pipe_utils.h" |
14 #include "mojo/services/network/interfaces/http_connection.mojom.h" | 14 #include "mojo/services/network/interfaces/http_connection.mojom.h" |
15 #include "mojo/services/network/interfaces/http_message.mojom.h" | 15 #include "mojo/services/network/interfaces/http_message.mojom.h" |
16 #include "mojo/services/network/interfaces/http_server.mojom.h" | 16 #include "mojo/services/network/interfaces/http_server.mojom.h" |
17 #include "mojo/services/network/interfaces/net_address.mojom.h" | 17 #include "mojo/services/network/interfaces/net_address.mojom.h" |
18 #include "mojo/services/network/interfaces/network_service.mojom.h" | 18 #include "mojo/services/network/interfaces/network_service.mojom.h" |
19 #include "mojo/services/network/interfaces/web_socket.mojom.h" | 19 #include "mojo/services/network/interfaces/web_socket.mojom.h" |
20 #include "mojo/services/network/net_address_type_converters.h" | 20 #include "mojo/services/network/net_address_type_converters.h" |
21 #include "mojo/services/network/web_socket_read_queue.h" | 21 #include "mojo/services/network/web_socket_read_queue.h" |
22 #include "mojo/services/network/web_socket_write_queue.h" | 22 #include "mojo/services/network/web_socket_write_queue.h" |
23 #include "net/base/io_buffer.h" | 23 #include "net/base/io_buffer.h" |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 scoped_refptr<net::DrainableIOBuffer> write_buffer_; | 265 scoped_refptr<net::DrainableIOBuffer> write_buffer_; |
266 scoped_ptr<net::TCPClientSocket> socket_; | 266 scoped_ptr<net::TCPClientSocket> socket_; |
267 int connect_result_; | 267 int connect_result_; |
268 | 268 |
269 DISALLOW_COPY_AND_ASSIGN(TestHttpClient); | 269 DISALLOW_COPY_AND_ASSIGN(TestHttpClient); |
270 }; | 270 }; |
271 | 271 |
272 class WebSocketClientImpl : public WebSocketClient { | 272 class WebSocketClientImpl : public WebSocketClient { |
273 public: | 273 public: |
274 explicit WebSocketClientImpl() | 274 explicit WebSocketClientImpl() |
275 : binding_(this, &client_ptr_), | 275 : binding_(this, &client_handle_), |
276 wait_for_message_count_(0), | 276 wait_for_message_count_(0), |
277 run_loop_(nullptr) {} | 277 run_loop_(nullptr) {} |
278 ~WebSocketClientImpl() override {} | 278 ~WebSocketClientImpl() override {} |
279 | 279 |
280 // Establishes a connection from the client side. | 280 // Establishes a connection from the client side. |
281 void Connect(WebSocketPtr web_socket, const std::string& url) { | 281 void Connect(WebSocketPtr web_socket, const std::string& url) { |
282 web_socket_ = web_socket.Pass(); | 282 web_socket_ = web_socket.Pass(); |
283 | 283 |
284 DataPipe data_pipe; | 284 DataPipe data_pipe; |
285 send_stream_ = data_pipe.producer_handle.Pass(); | 285 send_stream_ = data_pipe.producer_handle.Pass(); |
286 write_send_stream_.reset(new WebSocketWriteQueue(send_stream_.get())); | 286 write_send_stream_.reset(new WebSocketWriteQueue(send_stream_.get())); |
287 | 287 |
288 web_socket_->Connect(url, Array<String>(0), "http://example.com", | 288 web_socket_->Connect(url, Array<String>(0), "http://example.com", |
289 data_pipe.consumer_handle.Pass(), client_ptr_.Pass()); | 289 data_pipe.consumer_handle.Pass(), |
| 290 client_handle_.Pass()); |
290 } | 291 } |
291 | 292 |
292 // Establishes a connection from the server side. | 293 // Establishes a connection from the server side. |
293 void AcceptConnectRequest( | 294 void AcceptConnectRequest( |
294 const HttpConnectionDelegate::OnReceivedWebSocketRequestCallback& | 295 const HttpConnectionDelegate::OnReceivedWebSocketRequestCallback& |
295 callback) { | 296 callback) { |
296 InterfaceRequest<WebSocket> web_socket_request = GetProxy(&web_socket_); | 297 InterfaceRequest<WebSocket> web_socket_request = GetProxy(&web_socket_); |
297 | 298 |
298 DataPipe data_pipe; | 299 DataPipe data_pipe; |
299 send_stream_ = data_pipe.producer_handle.Pass(); | 300 send_stream_ = data_pipe.producer_handle.Pass(); |
300 write_send_stream_.reset(new WebSocketWriteQueue(send_stream_.get())); | 301 write_send_stream_.reset(new WebSocketWriteQueue(send_stream_.get())); |
301 | 302 |
302 callback.Run(web_socket_request.Pass(), data_pipe.consumer_handle.Pass(), | 303 callback.Run(web_socket_request.Pass(), data_pipe.consumer_handle.Pass(), |
303 client_ptr_.Pass()); | 304 client_handle_.Pass()); |
304 } | 305 } |
305 | 306 |
306 void WaitForConnectCompletion() { | 307 void WaitForConnectCompletion() { |
307 DCHECK(!run_loop_); | 308 DCHECK(!run_loop_); |
308 | 309 |
309 if (receive_stream_.is_valid()) | 310 if (receive_stream_.is_valid()) |
310 return; | 311 return; |
311 | 312 |
312 base::RunLoop run_loop; | 313 base::RunLoop run_loop; |
313 run_loop_ = &run_loop; | 314 run_loop_ = &run_loop; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 void OnFinishedReadingReceiveStream(uint32_t num_bytes, const char* data) { | 379 void OnFinishedReadingReceiveStream(uint32_t num_bytes, const char* data) { |
379 EXPECT_TRUE(data); | 380 EXPECT_TRUE(data); |
380 | 381 |
381 received_messages_.push_back(std::string(data, num_bytes)); | 382 received_messages_.push_back(std::string(data, num_bytes)); |
382 if (run_loop_ && received_messages_.size() >= wait_for_message_count_) { | 383 if (run_loop_ && received_messages_.size() >= wait_for_message_count_) { |
383 wait_for_message_count_ = 0; | 384 wait_for_message_count_ = 0; |
384 run_loop_->Quit(); | 385 run_loop_->Quit(); |
385 } | 386 } |
386 } | 387 } |
387 | 388 |
388 WebSocketClientPtr client_ptr_; | 389 InterfaceHandle<WebSocketClient> client_handle_; |
389 Binding<WebSocketClient> binding_; | 390 Binding<WebSocketClient> binding_; |
390 WebSocketPtr web_socket_; | 391 WebSocketPtr web_socket_; |
391 | 392 |
392 ScopedDataPipeProducerHandle send_stream_; | 393 ScopedDataPipeProducerHandle send_stream_; |
393 scoped_ptr<WebSocketWriteQueue> write_send_stream_; | 394 scoped_ptr<WebSocketWriteQueue> write_send_stream_; |
394 | 395 |
395 ScopedDataPipeConsumerHandle receive_stream_; | 396 ScopedDataPipeConsumerHandle receive_stream_; |
396 scoped_ptr<WebSocketReadQueue> read_receive_stream_; | 397 scoped_ptr<WebSocketReadQueue> read_receive_stream_; |
397 | 398 |
398 std::vector<std::string> received_messages_; | 399 std::vector<std::string> received_messages_; |
399 size_t wait_for_message_count_; | 400 size_t wait_for_message_count_; |
400 | 401 |
401 // Pointing to a stack-allocated RunLoop instance. | 402 // Pointing to a stack-allocated RunLoop instance. |
402 base::RunLoop* run_loop_; | 403 base::RunLoop* run_loop_; |
403 | 404 |
404 DISALLOW_COPY_AND_ASSIGN(WebSocketClientImpl); | 405 DISALLOW_COPY_AND_ASSIGN(WebSocketClientImpl); |
405 }; | 406 }; |
406 | 407 |
407 class HttpConnectionDelegateImpl : public HttpConnectionDelegate { | 408 class HttpConnectionDelegateImpl : public HttpConnectionDelegate { |
408 public: | 409 public: |
409 struct PendingRequest { | 410 struct PendingRequest { |
410 HttpRequestPtr request; | 411 HttpRequestPtr request; |
411 OnReceivedRequestCallback callback; | 412 OnReceivedRequestCallback callback; |
412 }; | 413 }; |
413 | 414 |
414 HttpConnectionDelegateImpl(HttpConnectionPtr connection, | 415 HttpConnectionDelegateImpl(InterfaceHandle<HttpConnection> connection, |
415 InterfaceRequest<HttpConnectionDelegate> request) | 416 InterfaceRequest<HttpConnectionDelegate> request) |
416 : connection_(connection.Pass()), | 417 : connection_(HttpConnectionPtr::Create(connection.Pass())), |
417 binding_(this, request.Pass()), | 418 binding_(this, request.Pass()), |
418 wait_for_request_count_(0), | 419 wait_for_request_count_(0), |
419 run_loop_(nullptr) {} | 420 run_loop_(nullptr) {} |
420 ~HttpConnectionDelegateImpl() override {} | 421 ~HttpConnectionDelegateImpl() override {} |
421 | 422 |
422 // HttpConnectionDelegate implementation: | 423 // HttpConnectionDelegate implementation: |
423 void OnReceivedRequest(HttpRequestPtr request, | 424 void OnReceivedRequest(HttpRequestPtr request, |
424 const OnReceivedRequestCallback& callback) override { | 425 const OnReceivedRequestCallback& callback) override { |
425 linked_ptr<PendingRequest> pending_request(new PendingRequest); | 426 linked_ptr<PendingRequest> pending_request(new PendingRequest); |
426 pending_request->request = request.Pass(); | 427 pending_request->request = request.Pass(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 scoped_ptr<WebSocketClientImpl> web_socket_; | 490 scoped_ptr<WebSocketClientImpl> web_socket_; |
490 | 491 |
491 // Pointing to a stack-allocated RunLoop instance. | 492 // Pointing to a stack-allocated RunLoop instance. |
492 base::RunLoop* run_loop_; | 493 base::RunLoop* run_loop_; |
493 | 494 |
494 DISALLOW_COPY_AND_ASSIGN(HttpConnectionDelegateImpl); | 495 DISALLOW_COPY_AND_ASSIGN(HttpConnectionDelegateImpl); |
495 }; | 496 }; |
496 | 497 |
497 class HttpServerDelegateImpl : public HttpServerDelegate { | 498 class HttpServerDelegateImpl : public HttpServerDelegate { |
498 public: | 499 public: |
499 explicit HttpServerDelegateImpl(HttpServerDelegatePtr* delegate_ptr) | 500 explicit HttpServerDelegateImpl( |
500 : binding_(this, delegate_ptr), | 501 InterfaceHandle<HttpServerDelegate>* delegate_handle) |
| 502 : binding_(this, delegate_handle), |
501 wait_for_connection_count_(0), | 503 wait_for_connection_count_(0), |
502 run_loop_(nullptr) {} | 504 run_loop_(nullptr) {} |
503 ~HttpServerDelegateImpl() override {} | 505 ~HttpServerDelegateImpl() override {} |
504 | 506 |
505 // HttpServerDelegate implementation. | 507 // HttpServerDelegate implementation. |
506 void OnConnected(HttpConnectionPtr connection, | 508 void OnConnected(InterfaceHandle<HttpConnection> connection, |
507 InterfaceRequest<HttpConnectionDelegate> delegate) override { | 509 InterfaceRequest<HttpConnectionDelegate> delegate) override { |
508 connections_.push_back(make_linked_ptr( | 510 connections_.push_back(make_linked_ptr( |
509 new HttpConnectionDelegateImpl(connection.Pass(), delegate.Pass()))); | 511 new HttpConnectionDelegateImpl(connection.Pass(), delegate.Pass()))); |
510 if (run_loop_ && connections_.size() >= wait_for_connection_count_) { | 512 if (run_loop_ && connections_.size() >= wait_for_connection_count_) { |
511 wait_for_connection_count_ = 0; | 513 wait_for_connection_count_ = 0; |
512 run_loop_->Quit(); | 514 run_loop_->Quit(); |
513 } | 515 } |
514 } | 516 } |
515 | 517 |
516 void WaitForConnection(size_t count) { | 518 void WaitForConnection(size_t count) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 bool ShouldCreateDefaultRunLoop() override { return false; } | 551 bool ShouldCreateDefaultRunLoop() override { return false; } |
550 | 552 |
551 void SetUp() override { | 553 void SetUp() override { |
552 ApplicationTestBase::SetUp(); | 554 ApplicationTestBase::SetUp(); |
553 | 555 |
554 ApplicationConnection* connection = | 556 ApplicationConnection* connection = |
555 application_impl()->ConnectToApplication("mojo:network_service"); | 557 application_impl()->ConnectToApplication("mojo:network_service"); |
556 connection->ConnectToService(&network_service_); | 558 connection->ConnectToService(&network_service_); |
557 } | 559 } |
558 | 560 |
559 void CreateHttpServer(HttpServerDelegatePtr delegate, | 561 void CreateHttpServer(InterfaceHandle<HttpServerDelegate> delegate, |
560 NetAddressPtr* out_bound_to) { | 562 NetAddressPtr* out_bound_to) { |
561 network_service_->CreateHttpServer( | 563 network_service_->CreateHttpServer( |
562 GetLocalHostWithAnyPort(), delegate.Pass(), | 564 GetLocalHostWithAnyPort(), delegate.Pass(), |
563 [out_bound_to](NetworkErrorPtr result, NetAddressPtr bound_to) { | 565 [out_bound_to](NetworkErrorPtr result, NetAddressPtr bound_to) { |
564 ASSERT_EQ(net::OK, result->code); | 566 ASSERT_EQ(net::OK, result->code); |
565 EXPECT_NE(0u, bound_to->ipv4->port); | 567 EXPECT_NE(0u, bound_to->ipv4->port); |
566 *out_bound_to = bound_to.Pass(); | 568 *out_bound_to = bound_to.Pass(); |
567 }); | 569 }); |
568 network_service_.WaitForIncomingResponse(); | 570 network_service_.WaitForIncomingResponse(); |
569 } | 571 } |
570 | 572 |
571 NetworkServicePtr network_service_; | 573 NetworkServicePtr network_service_; |
572 | 574 |
573 private: | 575 private: |
574 base::MessageLoop message_loop_; | 576 base::MessageLoop message_loop_; |
575 | 577 |
576 DISALLOW_COPY_AND_ASSIGN(HttpServerAppTest); | 578 DISALLOW_COPY_AND_ASSIGN(HttpServerAppTest); |
577 }; | 579 }; |
578 | 580 |
579 } // namespace | 581 } // namespace |
580 | 582 |
581 TEST_F(HttpServerAppTest, BasicHttpRequestResponse) { | 583 TEST_F(HttpServerAppTest, BasicHttpRequestResponse) { |
582 NetAddressPtr bound_to; | 584 NetAddressPtr bound_to; |
583 HttpServerDelegatePtr server_delegate_ptr; | 585 InterfaceHandle<HttpServerDelegate> server_delegate_handle; |
584 HttpServerDelegateImpl server_delegate_impl(&server_delegate_ptr); | 586 HttpServerDelegateImpl server_delegate_impl(&server_delegate_handle); |
585 CreateHttpServer(server_delegate_ptr.Pass(), &bound_to); | 587 CreateHttpServer(server_delegate_handle.Pass(), &bound_to); |
586 | 588 |
587 TestHttpClient client; | 589 TestHttpClient client; |
588 client.Connect(bound_to.To<net::IPEndPoint>()); | 590 client.Connect(bound_to.To<net::IPEndPoint>()); |
589 | 591 |
590 server_delegate_impl.WaitForConnection(1); | 592 server_delegate_impl.WaitForConnection(1); |
591 HttpConnectionDelegateImpl& connection = | 593 HttpConnectionDelegateImpl& connection = |
592 *server_delegate_impl.connections()[0]; | 594 *server_delegate_impl.connections()[0]; |
593 | 595 |
594 TestRequest request_data = {"HEAD", "/test", {{"Hello", "World"}}, nullptr}; | 596 TestRequest request_data = {"HEAD", "/test", {{"Hello", "World"}}, nullptr}; |
595 client.Send(MakeRequestMessage(request_data)); | 597 client.Send(MakeRequestMessage(request_data)); |
596 | 598 |
597 connection.WaitForRequest(1); | 599 connection.WaitForRequest(1); |
598 | 600 |
599 CheckRequest(request_data, connection.pending_requests()[0]->request.Pass()); | 601 CheckRequest(request_data, connection.pending_requests()[0]->request.Pass()); |
600 | 602 |
601 TestResponse response_data = {200, {{"Content-Length", "4"}}, nullptr}; | 603 TestResponse response_data = {200, {{"Content-Length", "4"}}, nullptr}; |
602 connection.SendResponse(MakeResponseStruct(response_data)); | 604 connection.SendResponse(MakeResponseStruct(response_data)); |
603 // This causes the underlying TCP connection to be closed. The client can | 605 // This causes the underlying TCP connection to be closed. The client can |
604 // determine the end of the response based on that. | 606 // determine the end of the response based on that. |
605 server_delegate_impl.connections().clear(); | 607 server_delegate_impl.connections().clear(); |
606 | 608 |
607 std::string response_message; | 609 std::string response_message; |
608 client.ReadResponse(&response_message); | 610 client.ReadResponse(&response_message); |
609 | 611 |
610 CheckResponse(response_data, response_message); | 612 CheckResponse(response_data, response_message); |
611 } | 613 } |
612 | 614 |
613 TEST_F(HttpServerAppTest, HttpRequestResponseWithBody) { | 615 TEST_F(HttpServerAppTest, HttpRequestResponseWithBody) { |
614 NetAddressPtr bound_to; | 616 NetAddressPtr bound_to; |
615 HttpServerDelegatePtr server_delegate_ptr; | 617 InterfaceHandle<HttpServerDelegate> server_delegate_handle; |
616 HttpServerDelegateImpl server_delegate_impl(&server_delegate_ptr); | 618 HttpServerDelegateImpl server_delegate_impl(&server_delegate_handle); |
617 CreateHttpServer(server_delegate_ptr.Pass(), &bound_to); | 619 CreateHttpServer(server_delegate_handle.Pass(), &bound_to); |
618 | 620 |
619 TestHttpClient client; | 621 TestHttpClient client; |
620 client.Connect(bound_to.To<net::IPEndPoint>()); | 622 client.Connect(bound_to.To<net::IPEndPoint>()); |
621 | 623 |
622 server_delegate_impl.WaitForConnection(1); | 624 server_delegate_impl.WaitForConnection(1); |
623 HttpConnectionDelegateImpl& connection = | 625 HttpConnectionDelegateImpl& connection = |
624 *server_delegate_impl.connections()[0]; | 626 *server_delegate_impl.connections()[0]; |
625 | 627 |
626 TestRequest request_data = { | 628 TestRequest request_data = { |
627 "Post", | 629 "Post", |
(...skipping 15 matching lines...) Expand all Loading... |
643 connection.SendResponse(MakeResponseStruct(response_data)); | 645 connection.SendResponse(MakeResponseStruct(response_data)); |
644 | 646 |
645 std::string response_message; | 647 std::string response_message; |
646 client.ReadResponse(&response_message); | 648 client.ReadResponse(&response_message); |
647 | 649 |
648 CheckResponse(response_data, response_message); | 650 CheckResponse(response_data, response_message); |
649 } | 651 } |
650 | 652 |
651 TEST_F(HttpServerAppTest, WebSocket) { | 653 TEST_F(HttpServerAppTest, WebSocket) { |
652 NetAddressPtr bound_to; | 654 NetAddressPtr bound_to; |
653 HttpServerDelegatePtr server_delegate_ptr; | 655 InterfaceHandle<HttpServerDelegate> server_delegate_handle; |
654 HttpServerDelegateImpl server_delegate_impl(&server_delegate_ptr); | 656 HttpServerDelegateImpl server_delegate_impl(&server_delegate_handle); |
655 CreateHttpServer(server_delegate_ptr.Pass(), &bound_to); | 657 CreateHttpServer(server_delegate_handle.Pass(), &bound_to); |
656 | 658 |
657 WebSocketPtr web_socket_ptr; | 659 WebSocketPtr web_socket_ptr; |
658 network_service_->CreateWebSocket(GetProxy(&web_socket_ptr)); | 660 network_service_->CreateWebSocket(GetProxy(&web_socket_ptr)); |
659 WebSocketClientImpl socket_0; | 661 WebSocketClientImpl socket_0; |
660 socket_0.Connect( | 662 socket_0.Connect( |
661 web_socket_ptr.Pass(), | 663 web_socket_ptr.Pass(), |
662 base::StringPrintf("ws://127.0.0.1:%d/hello", bound_to->ipv4->port)); | 664 base::StringPrintf("ws://127.0.0.1:%d/hello", bound_to->ipv4->port)); |
663 | 665 |
664 server_delegate_impl.WaitForConnection(1); | 666 server_delegate_impl.WaitForConnection(1); |
665 HttpConnectionDelegateImpl& connection = | 667 HttpConnectionDelegateImpl& connection = |
(...skipping 14 matching lines...) Expand all Loading... |
680 | 682 |
681 socket_1.Send("How do"); | 683 socket_1.Send("How do"); |
682 socket_1.Send("you do?"); | 684 socket_1.Send("you do?"); |
683 | 685 |
684 socket_0.WaitForMessage(2); | 686 socket_0.WaitForMessage(2); |
685 EXPECT_EQ("How do", socket_0.received_messages()[0]); | 687 EXPECT_EQ("How do", socket_0.received_messages()[0]); |
686 EXPECT_EQ("you do?", socket_0.received_messages()[1]); | 688 EXPECT_EQ("you do?", socket_0.received_messages()[1]); |
687 } | 689 } |
688 | 690 |
689 } // namespace mojo | 691 } // namespace mojo |
OLD | NEW |