| 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 |