1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file. 4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <vector> 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/bind.h" 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/bind_helpers.h" 9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/compiler_specific.h" 10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/format_macros.h" 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/memory/ref_counted.h" 12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/memory/weak_ptr.h" 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/message_loop/message_loop.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/run_loop.h" 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/string_split.h" 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/string_util.h" 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/stringprintf.h" 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/time/time.h" 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/address_list.h" 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/io_buffer.h" 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/ip_endpoint.h" 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/net_errors.h" 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/net_log.h" 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/server/http_server.h" 27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/server/http_server_request_info.h" 28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/socket/tcp_client_socket.h" 29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/socket/tcp_listen_socket.h" 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/url_request/url_request_context.h" 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/url_request/url_request_test_util.h" 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace net { 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace { 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SetTimedOutAndQuitLoop(const base::WeakPtr<bool> timed_out, 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::Closure& quit_loop_func) { 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (timed_out) { 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *timed_out = true; 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) quit_loop_func.Run(); 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool RunLoopWithTimeout(base::RunLoop* run_loop) { 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool timed_out = false; 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::WeakPtrFactory<bool> timed_out_weak_factory(&timed_out); 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FROM_HERE, 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&SetTimedOutAndQuitLoop, 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) timed_out_weak_factory.GetWeakPtr(), 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) run_loop->QuitClosure()), 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta::FromSeconds(1)); 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) run_loop->Run(); 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return !timed_out; 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class TestHttpClient { 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestHttpClient() : connect_result_(OK) {} 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int ConnectAndWait(const IPEndPoint& address) { 67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AddressList addresses(address); 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NetLog::Source source; 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socket_.reset(new TCPClientSocket(addresses, NULL, source)); 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::RunLoop run_loop; 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) connect_result_ = socket_->Connect(base::Bind(&TestHttpClient::OnConnect, 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Unretained(this), 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) run_loop.QuitClosure())); 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (connect_result_ != OK && connect_result_ != ERR_IO_PENDING) 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return connect_result_; 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!RunLoopWithTimeout(&run_loop)) 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return ERR_TIMED_OUT; 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return connect_result_; 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void Send(const std::string& data) { 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) write_buffer_ = 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new DrainableIOBuffer(new StringIOBuffer(data), data.length()); 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Write(); 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private: 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void OnConnect(const base::Closure& quit_loop, int result) { 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) connect_result_ = result; 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) quit_loop.Run(); 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void Write() { 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int result = socket_->Write( 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) write_buffer_.get(), 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) write_buffer_->BytesRemaining(), 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&TestHttpClient::OnWrite, base::Unretained(this))); 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (result != ERR_IO_PENDING) 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OnWrite(result); 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void OnWrite(int result) { 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_GT(result, 0); 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) write_buffer_->DidConsume(result); 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (write_buffer_->BytesRemaining()) 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Write(); 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<DrainableIOBuffer> write_buffer_; 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<TCPClientSocket> socket_; 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int connect_result_; 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class HttpServerTest : public testing::Test, 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public HttpServer::Delegate { 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) HttpServerTest() : quit_after_request_count_(0) {} 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void SetUp() OVERRIDE { 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TCPListenSocketFactory socket_factory("127.0.0.1", 0); 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) server_ = new HttpServer(socket_factory, this); 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(OK, server_->GetLocalAddress(&server_address_)); 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void OnHttpRequest(int connection_id, 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const HttpServerRequestInfo& info) OVERRIDE { 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) requests_.push_back(info); 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (requests_.size() == quit_after_request_count_) 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) run_loop_quit_func_.Run(); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void OnWebSocketRequest(int connection_id, 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const HttpServerRequestInfo& info) OVERRIDE { 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void OnWebSocketMessage(int connection_id, 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& data) OVERRIDE { 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void OnClose(int connection_id) OVERRIDE {} 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool RunUntilRequestsReceived(size_t count) { 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) quit_after_request_count_ = count; 150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (requests_.size() == count) 151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::RunLoop run_loop; 154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) run_loop_quit_func_ = run_loop.QuitClosure(); 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool success = RunLoopWithTimeout(&run_loop); 156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) run_loop_quit_func_.Reset(); 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return success; 158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) protected: 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<HttpServer> server_; 162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) IPEndPoint server_address_; 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Closure run_loop_quit_func_; 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<HttpServerRequestInfo> requests_; 165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private: 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t quit_after_request_count_; 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HttpServerTest, Request) { 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestHttpClient client; 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client.Send("GET /test HTTP/1.1\r\n\r\n"); 174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunUntilRequestsReceived(1)); 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ("GET", requests_[0].method); 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ("/test", requests_[0].path); 177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ("", requests_[0].data); 178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(0u, requests_[0].headers.size()); 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HttpServerTest, RequestWithHeaders) { 182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestHttpClient client; 183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const char* kHeaders[][3] = { 185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) {"Header", ": ", "1"}, 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) {"HeaderWithNoWhitespace", ":", "1"}, 187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) {"HeaderWithWhitespace", " : \t ", "1 1 1 \t "}, 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) {"HeaderWithColon", ": ", "1:1"}, 189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) {"EmptyHeader", ":", ""}, 190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) {"EmptyHeaderWithWhitespace", ": \t ", ""}, 1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) {"HeaderWithNonASCII", ": ", "\xf7"}, 192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string headers; 194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < arraysize(kHeaders); ++i) { 195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) headers += 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string(kHeaders[i][0]) + kHeaders[i][1] + kHeaders[i][2] + "\r\n"; 197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client.Send("GET /test HTTP/1.1\r\n" + headers + "\r\n"); 200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunUntilRequestsReceived(1)); 201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ("", requests_[0].data); 202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < arraysize(kHeaders); ++i) { 204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string field = StringToLowerASCII(std::string(kHeaders[i][0])); 205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string value = kHeaders[i][2]; 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(1u, requests_[0].headers.count(field)) << field; 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(value, requests_[0].headers[field]) << kHeaders[i][0]; 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HttpServerTest, RequestWithBody) { 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestHttpClient client; 213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); 214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string body = "a" + std::string(1 << 10, 'b') + "c"; 215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client.Send(base::StringPrintf( 216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "GET /test HTTP/1.1\r\n" 217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "SomeHeader: 1\r\n" 218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Content-Length: %" PRIuS "\r\n\r\n%s", 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) body.length(), 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) body.c_str())); 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunUntilRequestsReceived(1)); 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(2u, requests_[0].headers.size()); 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(body.length(), requests_[0].data.length()); 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ('a', body[0]); 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ('c', *body.rbegin()); 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HttpServerTest, RequestWithTooLargeBody) { 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) class TestURLFetcherDelegate : public URLFetcherDelegate { 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestURLFetcherDelegate(const base::Closure& quit_loop_func) 232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : quit_loop_func_(quit_loop_func) {} 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual ~TestURLFetcherDelegate() {} 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE { 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(HTTP_INTERNAL_SERVER_ERROR, source->GetResponseCode()); 237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) quit_loop_func_.Run(); 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private: 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Closure quit_loop_func_; 242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::RunLoop run_loop; 245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestURLFetcherDelegate delegate(run_loop.QuitClosure()); 246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<URLRequestContextGetter> request_context_getter( 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new TestURLRequestContextGetter(base::MessageLoopProxy::current())); 249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<URLFetcher> fetcher( 250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) URLFetcher::Create(GURL(base::StringPrintf("http://127.0.0.1:%d/test", 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) server_address_.port())), 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) URLFetcher::GET, 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &delegate)); 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetcher->SetRequestContext(request_context_getter.get()); 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetcher->AddExtraRequestHeader( 256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::StringPrintf("content-length:%d", 1 << 30)); 257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetcher->Start(); 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunLoopWithTimeout(&run_loop)); 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(0u, requests_.size()); 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace { 264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class MockStreamListenSocket : public StreamListenSocket { 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public: 267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) MockStreamListenSocket(StreamListenSocket::Delegate* delegate) 268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : StreamListenSocket(kInvalidSocket, delegate) {} 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void Accept() OVERRIDE { NOTREACHED(); } 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private: 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual ~MockStreamListenSocket() {} 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HttpServerTest, RequestWithBodySplitAcrossPackets) { 27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) StreamListenSocket* socket = 28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new MockStreamListenSocket(server_.get()); 28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) server_->DidAccept(NULL, make_scoped_ptr(socket)); 282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string body("body"); 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string request = base::StringPrintf( 284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "GET /test HTTP/1.1\r\n" 285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "SomeHeader: 1\r\n" 286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Content-Length: %" PRIuS "\r\n\r\n%s", 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) body.length(), 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) body.c_str()); 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) server_->DidRead(socket, request.c_str(), request.length() - 2); 290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(0u, requests_.size()); 29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) server_->DidRead(socket, request.c_str() + request.length() - 2, 2); 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(1u, requests_.size()); 293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(body, requests_[0].data); 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(HttpServerTest, MultipleRequestsOnSameConnection) { 297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The idea behind this test is that requests with or without bodies should 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // not break parsing of the next request. 299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestHttpClient client; 300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string body = "body"; 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client.Send(base::StringPrintf( 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "GET /test HTTP/1.1\r\n" 304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Content-Length: %" PRIuS "\r\n\r\n%s", 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) body.length(), 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) body.c_str())); 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunUntilRequestsReceived(1)); 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(body, requests_[0].data); 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client.Send("GET /test2 HTTP/1.1\r\n\r\n"); 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunUntilRequestsReceived(2)); 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ("/test2", requests_[1].path); 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client.Send("GET /test3 HTTP/1.1\r\n\r\n"); 315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_TRUE(RunUntilRequestsReceived(3)); 316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ("/test3", requests_[2].path); 317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace net 320