Home | History | Annotate | Download | only in shill
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "shill/http_proxy.h"
     18 
     19 #include <netinet/in.h>
     20 
     21 #include <memory>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/strings/stringprintf.h>
     26 #include <gtest/gtest.h>
     27 
     28 #include "shill/mock_async_connection.h"
     29 #include "shill/mock_connection.h"
     30 #include "shill/mock_control.h"
     31 #include "shill/mock_device_info.h"
     32 #include "shill/mock_dns_client.h"
     33 #include "shill/mock_event_dispatcher.h"
     34 #include "shill/net/ip_address.h"
     35 #include "shill/net/mock_sockets.h"
     36 
     37 using base::StringPrintf;
     38 using std::string;
     39 using std::vector;
     40 using ::testing::_;
     41 using ::testing::AnyNumber;
     42 using ::testing::AtLeast;
     43 using ::testing::DoAll;
     44 using ::testing::Invoke;
     45 using ::testing::NiceMock;
     46 using ::testing::Return;
     47 using ::testing::ReturnArg;
     48 using ::testing::ReturnNew;
     49 using ::testing::ReturnRef;
     50 using ::testing::SetArgumentPointee;
     51 using ::testing::StrEq;
     52 using ::testing::StrictMock;
     53 using ::testing::Test;
     54 
     55 namespace shill {
     56 
     57 namespace {
     58 const char kBadHeaderMissingURL[] = "BLAH\r\n";
     59 const char kBadHeaderMissingVersion[] = "BLAH http://hostname\r\n";
     60 const char kBadHostnameLine[] = "GET HTTP/1.1 http://hostname\r\n";
     61 const char kBasicGetHeader[] = "GET / HTTP/1.1\r\n";
     62 const char kBasicGetHeaderWithURL[] =
     63     "GET http://www.chromium.org/ HTTP/1.1\r\n";
     64 const char kBasicGetHeaderWithURLNoTrailingSlash[] =
     65     "GET http://www.chromium.org HTTP/1.1\r\n";
     66 const char kConnectQuery[] =
     67     "CONNECT 10.10.10.10:443 HTTP/1.1\r\n"
     68     "Host: 10.10.10.10:443\r\n\r\n";
     69 const char kQueryTemplate[] = "GET %s HTTP/%s\r\n%s"
     70     "User-Agent: Mozilla/5.0 (X11; CrOS i686 1299.0.2011) "
     71     "AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.936.0 Safari/535.8\r\n"
     72     "Accept: text/html,application/xhtml+xml,application/xml;"
     73     "q=0.9,*/*;q=0.8\r\n"
     74     "Accept-Encoding: gzip,deflate,sdch\r\n"
     75     "Accept-Language: en-US,en;q=0.8,ja;q=0.6\r\n"
     76     "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
     77     "Cookie: PREF=ID=xxxxxxxxxxxxxxxx:U=xxxxxxxxxxxxxxxx:FF=0:"
     78     "TM=1317340083:LM=1317390705:GM=1:S=_xxxxxxxxxxxxxxx; "
     79     "NID=52=xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
     80     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxx; "
     81     "HSID=xxxxxxxxxxxx-xxxx; APISID=xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxx; "
     82     "SID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxx"
     83     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx"
     84     "xxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxx"
     85     "_xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx-xx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
     86     "xxxxxxxxxxxxxxxx\r\n\r\n";
     87 const char kInterfaceName[] = "int0";
     88 const char kDNSServer0[] = "8.8.8.8";
     89 const char kDNSServer1[] = "8.8.4.4";
     90 const char kServerAddress[] = "10.10.10.10";
     91 const char* kDNSServers[] = { kDNSServer0, kDNSServer1 };
     92 const int kProxyFD = 10203;
     93 const int kServerFD = 10204;
     94 const int kClientFD = 10205;
     95 const int kServerPort = 40506;
     96 const int kConnectPort = 443;
     97 }  // namespace
     98 
     99 MATCHER_P(IsIPAddress, address, "") {
    100   IPAddress ip_address(IPAddress::kFamilyIPv4);
    101   EXPECT_TRUE(ip_address.SetAddressFromString(address));
    102   return ip_address.Equals(arg);
    103 }
    104 
    105 MATCHER_P(CallbackEq, callback, "") {
    106   return arg.Equals(callback);
    107 }
    108 
    109 class HTTPProxyTest : public Test {
    110  public:
    111   HTTPProxyTest()
    112       : interface_name_(kInterfaceName),
    113         server_async_connection_(nullptr),
    114         dns_servers_(kDNSServers, kDNSServers + 2),
    115         dns_client_(nullptr),
    116         device_info_(
    117             new NiceMock<MockDeviceInfo>(&control_, nullptr, nullptr, nullptr)),
    118         connection_(new StrictMock<MockConnection>(device_info_.get())),
    119         proxy_(connection_) {}
    120 
    121  protected:
    122   virtual void SetUp() {
    123     EXPECT_CALL(*connection_.get(), interface_name())
    124         .WillRepeatedly(ReturnRef(interface_name_));
    125     EXPECT_CALL(*connection_.get(), dns_servers())
    126         .WillRepeatedly(ReturnRef(dns_servers_));
    127   }
    128   virtual void TearDown() {
    129     if (proxy_.sockets_) {
    130       ExpectStop();
    131     }
    132     const int proxy_fds[] = {
    133       proxy_.client_socket_,
    134       proxy_.server_socket_,
    135       proxy_.proxy_socket_
    136     };
    137     for (const int fd : proxy_fds) {
    138       if (fd != -1) {
    139         EXPECT_CALL(sockets_, Close(fd));
    140       }
    141     }
    142   }
    143   string CreateRequest(const string& url, const string& http_version,
    144                        const string& extra_lines) {
    145     string append_lines(extra_lines);
    146     if (append_lines.size()) {
    147       append_lines.append("\r\n");
    148     }
    149     return StringPrintf(kQueryTemplate, url.c_str(), http_version.c_str(),
    150                         append_lines.c_str());
    151   }
    152   int InvokeGetSockName(int fd, struct sockaddr* addr_out,
    153                         socklen_t* sockaddr_size) {
    154     struct sockaddr_in addr;
    155     EXPECT_EQ(kProxyFD, fd);
    156     EXPECT_GE(sizeof(sockaddr_in), *sockaddr_size);
    157     addr.sin_addr.s_addr = 0;
    158     addr.sin_port = kServerPort;
    159     memcpy(addr_out, &addr, sizeof(addr));
    160     *sockaddr_size = sizeof(sockaddr_in);
    161     return 0;
    162   }
    163   void  InvokeSyncConnect(const IPAddress& /*address*/, int /*port*/) {
    164     proxy_.OnConnectCompletion(true, kServerFD);
    165   }
    166   size_t FindInRequest(const string& find_string) {
    167     const ByteString& request_data = GetClientData();
    168     string request_string(
    169         reinterpret_cast<const char*>(request_data.GetConstData()),
    170         request_data.GetLength());
    171     return request_string.find(find_string);
    172   }
    173   // Accessors
    174   const ByteString& GetClientData() {
    175     return proxy_.client_data_;
    176   }
    177   HTTPProxy* proxy() { return &proxy_; }
    178   HTTPProxy::State GetProxyState() {
    179     return proxy_.state_;
    180   }
    181   const ByteString& GetServerData() {
    182     return proxy_.server_data_;
    183   }
    184   MockSockets& sockets() { return sockets_; }
    185   MockEventDispatcher& dispatcher() { return dispatcher_; }
    186 
    187 
    188   // Expectations
    189   void ExpectClientReset() {
    190     EXPECT_EQ(-1, proxy_.client_socket_);
    191     EXPECT_TRUE(proxy_.client_version_.empty());
    192     EXPECT_EQ(HTTPProxy::kDefaultServerPort, proxy_.server_port_);
    193     EXPECT_EQ(-1, proxy_.server_socket_);
    194     EXPECT_TRUE(proxy_.idle_timeout_.IsCancelled());
    195     EXPECT_TRUE(proxy_.client_headers_.empty());
    196     EXPECT_TRUE(proxy_.server_hostname_.empty());
    197     EXPECT_TRUE(proxy_.client_data_.IsEmpty());
    198     EXPECT_TRUE(proxy_.server_data_.IsEmpty());
    199     EXPECT_FALSE(proxy_.read_client_handler_.get());
    200     EXPECT_FALSE(proxy_.write_client_handler_.get());
    201     EXPECT_FALSE(proxy_.read_server_handler_.get());
    202     EXPECT_FALSE(proxy_.write_server_handler_.get());
    203     EXPECT_FALSE(proxy_.is_route_requested_);
    204   }
    205   void ExpectReset() {
    206     EXPECT_FALSE(proxy_.accept_handler_.get());
    207     EXPECT_EQ(proxy_.connection_.get(), connection_.get());
    208     EXPECT_FALSE(proxy_.dispatcher_);
    209     EXPECT_FALSE(proxy_.dns_client_.get());
    210     EXPECT_EQ(-1, proxy_.proxy_port_);
    211     EXPECT_EQ(-1, proxy_.proxy_socket_);
    212     EXPECT_FALSE(proxy_.server_async_connection_.get());
    213     EXPECT_FALSE(proxy_.sockets_);
    214     EXPECT_EQ(HTTPProxy::kStateIdle, proxy_.state_);
    215     ExpectClientReset();
    216   }
    217   void ExpectStart() {
    218     EXPECT_CALL(sockets(), Socket(_, _, _))
    219         .WillOnce(Return(kProxyFD));
    220     EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
    221         .WillOnce(Return(0));
    222     EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
    223         .WillOnce(Invoke(this, &HTTPProxyTest::InvokeGetSockName));
    224     EXPECT_CALL(sockets(), SetNonBlocking(kProxyFD))
    225         .WillOnce(Return(0));
    226     EXPECT_CALL(sockets(), Listen(kProxyFD, _))
    227         .WillOnce(Return(0));
    228     EXPECT_CALL(dispatcher_,
    229                 CreateReadyHandler(kProxyFD,
    230                                    IOHandler::kModeInput,
    231                                    CallbackEq(proxy_.accept_callback_)))
    232         .WillOnce(ReturnNew<IOHandler>());
    233   }
    234   void ExpectStop() {
    235      if (dns_client_) {
    236        EXPECT_CALL(*dns_client_, Stop())
    237            .Times(AtLeast(1));
    238      }
    239      if (server_async_connection_) {
    240        EXPECT_CALL(*server_async_connection_, Stop())
    241            .Times(AtLeast(1));
    242      }
    243      if (proxy_.is_route_requested_) {
    244        EXPECT_CALL(*connection_.get(), ReleaseRouting());
    245      }
    246   }
    247   void ExpectClientInput(int fd) {
    248     EXPECT_CALL(sockets(), Accept(kProxyFD, _, _))
    249         .WillOnce(Return(fd));
    250     EXPECT_CALL(sockets(), SetNonBlocking(fd))
    251         .WillOnce(Return(0));
    252     EXPECT_CALL(dispatcher(),
    253                 CreateInputHandler(fd,
    254                                    CallbackEq(proxy_.read_client_callback_), _))
    255         .WillOnce(ReturnNew<IOHandler>());
    256     ExpectTransactionTimeout();
    257     ExpectClientHeaderTimeout();
    258   }
    259   void ExpectTimeout(int timeout) {
    260     EXPECT_CALL(dispatcher_, PostDelayedTask(_, timeout * 1000));
    261   }
    262   void ExpectClientHeaderTimeout() {
    263     ExpectTimeout(HTTPProxy::kClientHeaderTimeoutSeconds);
    264   }
    265   void ExpectConnectTimeout() {
    266     ExpectTimeout(HTTPProxy::kConnectTimeoutSeconds);
    267   }
    268   void ExpectInputTimeout() {
    269     ExpectTimeout(HTTPProxy::kInputTimeoutSeconds);
    270   }
    271   void ExpectRepeatedInputTimeout() {
    272     EXPECT_CALL(dispatcher_,
    273                 PostDelayedTask(_, HTTPProxy::kInputTimeoutSeconds * 1000))
    274         .Times(AnyNumber());
    275   }
    276   void ExpectTransactionTimeout() {
    277     ExpectTimeout(HTTPProxy::kTransactionTimeoutSeconds);
    278   }
    279   void ExpectInClientResponse(const string& response_data) {
    280     string server_data(reinterpret_cast<char*>(proxy_.server_data_.GetData()),
    281                        proxy_.server_data_.GetLength());
    282     EXPECT_NE(string::npos, server_data.find(response_data));
    283   }
    284   void ExpectClientError(int code, const string& error) {
    285     EXPECT_EQ(HTTPProxy::kStateFlushResponse, GetProxyState());
    286     string status_line = StringPrintf("HTTP/1.1 %d ERROR", code);
    287     ExpectInClientResponse(status_line);
    288     ExpectInClientResponse(error);
    289   }
    290   void ExpectClientInternalError() {
    291     ExpectClientError(500, HTTPProxy::kInternalErrorMsg);
    292   }
    293   void ExpectClientVersion(const string& version) {
    294     EXPECT_EQ(version, proxy_.client_version_);
    295   }
    296   void ExpectServerHostname(const string& hostname) {
    297     EXPECT_EQ(hostname, proxy_.server_hostname_);
    298   }
    299   void ExpectFirstLine(const string& line) {
    300     EXPECT_EQ(line, proxy_.client_headers_[0] + "\r\n");
    301   }
    302   void ExpectDNSRequest(const string& host, bool return_value) {
    303     EXPECT_CALL(*dns_client_, Start(StrEq(host), _))
    304         .WillOnce(Return(return_value));
    305   }
    306   void ExpectAsyncConnect(const string& address, int port,
    307                           bool return_value) {
    308     EXPECT_CALL(*server_async_connection_, Start(IsIPAddress(address), port))
    309         .WillOnce(Return(return_value));
    310   }
    311   void ExpectSyncConnect(const string& address, int port) {
    312     EXPECT_CALL(*server_async_connection_, Start(IsIPAddress(address), port))
    313         .WillOnce(DoAll(Invoke(this, &HTTPProxyTest::InvokeSyncConnect),
    314                         Return(true)));
    315   }
    316   void ExpectClientData() {
    317     EXPECT_CALL(dispatcher(),
    318                 CreateReadyHandler(kClientFD,
    319                                    IOHandler::kModeOutput,
    320                                    CallbackEq(proxy_.write_client_callback_)))
    321         .WillOnce(ReturnNew<IOHandler>());
    322   }
    323   void ExpectClientResult() {
    324     ExpectClientData();
    325     ExpectInputTimeout();
    326   }
    327   void ExpectServerInput() {
    328     EXPECT_CALL(dispatcher(),
    329                 CreateInputHandler(kServerFD,
    330                                    CallbackEq(proxy_.read_server_callback_), _))
    331         .WillOnce(ReturnNew<IOHandler>());
    332     ExpectInputTimeout();
    333   }
    334   void ExpectServerOutput() {
    335     EXPECT_CALL(dispatcher(),
    336                 CreateReadyHandler(kServerFD,
    337                                    IOHandler::kModeOutput,
    338                                    CallbackEq(proxy_.write_server_callback_)))
    339         .WillOnce(ReturnNew<IOHandler>());
    340     ExpectInputTimeout();
    341   }
    342   void ExpectRepeatedServerOutput() {
    343     EXPECT_CALL(dispatcher(),
    344                 CreateReadyHandler(kServerFD, IOHandler::kModeOutput,
    345                                    CallbackEq(proxy_.write_server_callback_)))
    346         .WillOnce(ReturnNew<IOHandler>());
    347     ExpectRepeatedInputTimeout();
    348   }
    349   void ExpectTunnelClose() {
    350     EXPECT_CALL(sockets(), Close(kClientFD))
    351         .WillOnce(Return(0));
    352     EXPECT_CALL(sockets(), Close(kServerFD))
    353         .WillOnce(Return(0));
    354     ExpectStop();
    355   }
    356   void ExpectRouteRequest() {
    357     EXPECT_CALL(*connection_.get(), RequestRouting());
    358   }
    359   void ExpectRouteRelease() {
    360     EXPECT_CALL(*connection_.get(), ReleaseRouting());
    361   }
    362 
    363   // Callers for various private routines in the proxy
    364   bool StartProxy() {
    365     bool ret = proxy_.Start(&dispatcher_, &sockets_);
    366     if (ret) {
    367       dns_client_ = new StrictMock<MockDNSClient>();
    368       // Passes ownership.
    369       proxy_.dns_client_.reset(dns_client_);
    370       server_async_connection_ = new StrictMock<MockAsyncConnection>();
    371       // Passes ownership.
    372       proxy_.server_async_connection_.reset(server_async_connection_);
    373     }
    374     return ret;
    375   }
    376   void AcceptClient(int fd) {
    377     proxy_.AcceptClient(fd);
    378   }
    379   void GetDNSResultFailure(const string& error_msg) {
    380     Error error(Error::kOperationFailed, error_msg);
    381     IPAddress address(IPAddress::kFamilyUnknown);
    382     proxy_.GetDNSResult(error, address);
    383   }
    384   void GetDNSResultSuccess(const IPAddress& address) {
    385     Error error;
    386     proxy_.GetDNSResult(error, address);
    387   }
    388   void OnConnectCompletion(bool result, int sockfd) {
    389     proxy_.OnConnectCompletion(result, sockfd);
    390   }
    391   void ReadFromClient(const string& data) {
    392     const unsigned char* ptr =
    393         reinterpret_cast<const unsigned char*>(data.c_str());
    394     vector<unsigned char> data_bytes(ptr, ptr + data.length());
    395     InputData proxy_data(data_bytes.data(), data_bytes.size());
    396     proxy_.ReadFromClient(&proxy_data);
    397   }
    398   void ReadFromServer(const string& data) {
    399     const unsigned char* ptr =
    400         reinterpret_cast<const unsigned char*>(data.c_str());
    401     vector<unsigned char> data_bytes(ptr, ptr + data.length());
    402     InputData proxy_data(data_bytes.data(), data_bytes.size());
    403     proxy_.ReadFromServer(&proxy_data);
    404   }
    405   void SendClientError(int code, const string& error) {
    406     proxy_.SendClientError(code, error);
    407     EXPECT_FALSE(proxy_.server_data_.IsEmpty());
    408   }
    409   void StopClient() {
    410     EXPECT_CALL(*dns_client_, Stop());
    411     EXPECT_CALL(*server_async_connection_, Stop());
    412     proxy_.StopClient();
    413   }
    414   void StopProxy() {
    415     ExpectStop();
    416     proxy_.Stop();
    417     server_async_connection_ = nullptr;
    418     dns_client_ = nullptr;
    419     ExpectReset();
    420   }
    421   void WriteToClient(int fd) {
    422     proxy_.WriteToClient(fd);
    423   }
    424   void WriteToServer(int fd) {
    425     proxy_.WriteToServer(fd);
    426   }
    427 
    428   void SetupClient() {
    429     ExpectStart();
    430     ASSERT_TRUE(StartProxy());
    431     ExpectClientInput(kClientFD);
    432     AcceptClient(kProxyFD);
    433     EXPECT_EQ(HTTPProxy::kStateReadClientHeader, GetProxyState());
    434   }
    435   void SetupConnectWithRequest(const string& url, const string& http_version,
    436                                const string& extra_lines) {
    437     ExpectDNSRequest("www.chromium.org", true);
    438     ExpectRouteRequest();
    439     ReadFromClient(CreateRequest(url, http_version, extra_lines));
    440     IPAddress addr(IPAddress::kFamilyIPv4);
    441     EXPECT_TRUE(addr.SetAddressFromString(kServerAddress));
    442     GetDNSResultSuccess(addr);
    443   }
    444   void SetupConnect() {
    445     SetupConnectWithRequest("/", "1.1", "Host: www.chromium.org:40506");
    446   }
    447   void SetupConnectAsync() {
    448     SetupClient();
    449     ExpectAsyncConnect(kServerAddress, kServerPort, true);
    450     ExpectConnectTimeout();
    451     SetupConnect();
    452   }
    453   void SetupConnectComplete() {
    454     SetupConnectAsync();
    455     ExpectServerOutput();
    456     OnConnectCompletion(true, kServerFD);
    457     EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
    458   }
    459   void CauseReadError() {
    460     proxy_.OnReadError(string());
    461   }
    462 
    463  private:
    464   const string interface_name_;
    465   // Owned by the HTTPProxy, but tracked here for EXPECT().
    466   StrictMock<MockAsyncConnection>* server_async_connection_;
    467   vector<string> dns_servers_;
    468   // Owned by the HTTPProxy, but tracked here for EXPECT().
    469   StrictMock<MockDNSClient>* dns_client_;
    470   MockEventDispatcher dispatcher_;
    471   MockControl control_;
    472   std::unique_ptr<MockDeviceInfo> device_info_;
    473   scoped_refptr<MockConnection> connection_;
    474   StrictMock<MockSockets> sockets_;
    475   HTTPProxy proxy_;  // Destroy first, before anything it references.
    476 };
    477 
    478 TEST_F(HTTPProxyTest, StartFailSocket) {
    479   EXPECT_CALL(sockets(), Socket(_, _, _))
    480       .WillOnce(Return(-1));
    481   EXPECT_FALSE(StartProxy());
    482   ExpectReset();
    483 }
    484 
    485 TEST_F(HTTPProxyTest, StartFailBind) {
    486   EXPECT_CALL(sockets(), Socket(_, _, _))
    487       .WillOnce(Return(kProxyFD));
    488   EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
    489       .WillOnce(Return(-1));
    490   EXPECT_CALL(sockets(), Close(kProxyFD))
    491       .WillOnce(Return(0));
    492   EXPECT_FALSE(StartProxy());
    493   ExpectReset();
    494 }
    495 
    496 TEST_F(HTTPProxyTest, StartFailGetSockName) {
    497   EXPECT_CALL(sockets(), Socket(_, _, _))
    498       .WillOnce(Return(kProxyFD));
    499   EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
    500       .WillOnce(Return(0));
    501   EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
    502       .WillOnce(Return(-1));
    503   EXPECT_CALL(sockets(), Close(kProxyFD))
    504       .WillOnce(Return(0));
    505   EXPECT_FALSE(StartProxy());
    506   ExpectReset();
    507 }
    508 
    509 TEST_F(HTTPProxyTest, StartFailSetNonBlocking) {
    510   EXPECT_CALL(sockets(), Socket(_, _, _))
    511       .WillOnce(Return(kProxyFD));
    512   EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
    513       .WillOnce(Return(0));
    514   EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
    515       .WillOnce(Return(0));
    516   EXPECT_CALL(sockets(), SetNonBlocking(kProxyFD))
    517       .WillOnce(Return(-1));
    518   EXPECT_CALL(sockets(), Close(kProxyFD))
    519       .WillOnce(Return(0));
    520   EXPECT_FALSE(StartProxy());
    521   ExpectReset();
    522 }
    523 
    524 TEST_F(HTTPProxyTest, StartFailListen) {
    525   EXPECT_CALL(sockets(), Socket(_, _, _))
    526       .WillOnce(Return(kProxyFD));
    527   EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
    528       .WillOnce(Return(0));
    529   EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
    530       .WillOnce(Return(0));
    531   EXPECT_CALL(sockets(), SetNonBlocking(kProxyFD))
    532       .WillOnce(Return(0));
    533   EXPECT_CALL(sockets(), Listen(kProxyFD, _))
    534       .WillOnce(Return(-1));
    535   EXPECT_CALL(sockets(), Close(kProxyFD))
    536       .WillOnce(Return(0));
    537   EXPECT_FALSE(StartProxy());
    538   ExpectReset();
    539 }
    540 
    541 TEST_F(HTTPProxyTest, StartSuccess) {
    542   ExpectStart();
    543   EXPECT_TRUE(StartProxy());
    544 }
    545 
    546 TEST_F(HTTPProxyTest, SendClientError) {
    547   SetupClient();
    548   ExpectClientResult();
    549   SendClientError(500, "This is an error");
    550   ExpectClientError(500, "This is an error");
    551 
    552   // We succeed in sending all but one byte of the client response.
    553   int buf_len = GetServerData().GetLength();
    554   EXPECT_CALL(sockets(), Send(kClientFD, _, buf_len, 0))
    555       .WillOnce(Return(buf_len - 1));
    556   ExpectInputTimeout();
    557   WriteToClient(kClientFD);
    558   EXPECT_EQ(1, GetServerData().GetLength());
    559   EXPECT_EQ(HTTPProxy::kStateFlushResponse, GetProxyState());
    560 
    561   // When we are able to send the last byte, we close the connection.
    562   EXPECT_CALL(sockets(), Send(kClientFD, _, 1, 0))
    563       .WillOnce(Return(1));
    564   EXPECT_CALL(sockets(), Close(kClientFD))
    565       .WillOnce(Return(0));
    566   ExpectStop();
    567   WriteToClient(kClientFD);
    568   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    569 }
    570 
    571 TEST_F(HTTPProxyTest, ReadMissingURL) {
    572   SetupClient();
    573   ExpectClientResult();
    574   ReadFromClient(kBadHeaderMissingURL);
    575   ExpectClientError(501, "Server could not parse HTTP method");
    576 }
    577 
    578 TEST_F(HTTPProxyTest, ReadMissingVersion) {
    579   SetupClient();
    580   ExpectClientResult();
    581   ReadFromClient(kBadHeaderMissingVersion);
    582   ExpectClientError(501, "Server only accepts HTTP/1.x requests");
    583 }
    584 
    585 TEST_F(HTTPProxyTest, ReadBadHostname) {
    586   SetupClient();
    587   ExpectClientResult();
    588   ReadFromClient(kBadHostnameLine);
    589   ExpectClientInternalError();
    590 }
    591 
    592 TEST_F(HTTPProxyTest, GoodFirstLineWithoutURL) {
    593   SetupClient();
    594   ExpectClientHeaderTimeout();
    595   ReadFromClient(kBasicGetHeader);
    596   ExpectClientVersion("1.1");
    597   ExpectServerHostname("");
    598   ExpectFirstLine(kBasicGetHeader);
    599 }
    600 
    601 TEST_F(HTTPProxyTest, GoodFirstLineWithURL) {
    602   SetupClient();
    603   ExpectClientHeaderTimeout();
    604   ReadFromClient(kBasicGetHeaderWithURL);
    605   ExpectClientVersion("1.1");
    606   ExpectServerHostname("www.chromium.org");
    607   ExpectFirstLine(kBasicGetHeader);
    608 }
    609 
    610 TEST_F(HTTPProxyTest, GoodFirstLineWithURLNoSlash) {
    611   SetupClient();
    612   ExpectClientHeaderTimeout();
    613   ReadFromClient(kBasicGetHeaderWithURLNoTrailingSlash);
    614   ExpectClientVersion("1.1");
    615   ExpectServerHostname("www.chromium.org");
    616   ExpectFirstLine(kBasicGetHeader);
    617 }
    618 
    619 TEST_F(HTTPProxyTest, NoHostInRequest) {
    620   SetupClient();
    621   ExpectClientResult();
    622   ReadFromClient(CreateRequest("/", "1.1", ""));
    623   ExpectClientError(400, "I don't know what host you want me to connect to");
    624 }
    625 
    626 TEST_F(HTTPProxyTest, TooManyColonsInHost) {
    627   SetupClient();
    628   ExpectClientResult();
    629   ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:80:40506"));
    630   ExpectClientError(400, "Too many colons in hostname");
    631 }
    632 
    633 TEST_F(HTTPProxyTest, ClientReadError) {
    634   SetupClient();
    635   EXPECT_CALL(sockets(), Close(kClientFD))
    636       .WillOnce(Return(0));
    637   ExpectStop();
    638   CauseReadError();
    639   ExpectClientReset();
    640 }
    641 
    642 TEST_F(HTTPProxyTest, DNSRequestFailure) {
    643   SetupClient();
    644   ExpectRouteRequest();
    645   ExpectDNSRequest("www.chromium.org", false);
    646   ExpectClientResult();
    647   ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:40506"));
    648   ExpectClientError(502, "Could not resolve hostname");
    649 }
    650 
    651 TEST_F(HTTPProxyTest, DNSRequestDelayedFailure) {
    652   SetupClient();
    653   ExpectRouteRequest();
    654   ExpectDNSRequest("www.chromium.org", true);
    655   ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:40506"));
    656   ExpectClientResult();
    657   const std::string not_found_error(DNSClient::kErrorNotFound);
    658   GetDNSResultFailure(not_found_error);
    659   ExpectClientError(502, string("Could not resolve hostname: ") +
    660                     not_found_error);
    661 }
    662 
    663 TEST_F(HTTPProxyTest, TrailingClientData) {
    664   SetupClient();
    665   ExpectRouteRequest();
    666   ExpectDNSRequest("www.chromium.org", true);
    667   const string trailing_data("Trailing client data");
    668   ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:40506") +
    669                  trailing_data);
    670   EXPECT_EQ(GetClientData().GetLength() - trailing_data.length(),
    671             FindInRequest(trailing_data));
    672   EXPECT_EQ(HTTPProxy::kStateLookupServer, GetProxyState());
    673 }
    674 
    675 TEST_F(HTTPProxyTest, LineContinuation) {
    676   SetupClient();
    677   ExpectRouteRequest();
    678   ExpectDNSRequest("www.chromium.org", true);
    679   string text_to_keep("X-Long-Header: this is one line\r\n"
    680                       "\tand this is another");
    681   ReadFromClient(CreateRequest("http://www.chromium.org/", "1.1",
    682                                text_to_keep));
    683   EXPECT_NE(string::npos, FindInRequest(text_to_keep));
    684 }
    685 
    686 // NB: This tests two different things:
    687 //   1) That the system replaces the value for "Proxy-Connection" headers.
    688 //   2) That when it replaces a header, it also removes the text in the line
    689 //      continuation.
    690 TEST_F(HTTPProxyTest, LineContinuationRemoval) {
    691   SetupClient();
    692   ExpectRouteRequest();
    693   ExpectDNSRequest("www.chromium.org", true);
    694   string text_to_remove("remove this text please");
    695   ReadFromClient(CreateRequest("http://www.chromium.org/", "1.1",
    696                                string("Proxy-Connection: stuff\r\n\t") +
    697                                text_to_remove));
    698   EXPECT_EQ(string::npos, FindInRequest(text_to_remove));
    699   EXPECT_NE(string::npos, FindInRequest("Proxy-Connection: close\r\n"));
    700 }
    701 
    702 TEST_F(HTTPProxyTest, ConnectSynchronousFailure) {
    703   SetupClient();
    704   ExpectAsyncConnect(kServerAddress, kServerPort, false);
    705   ExpectClientResult();
    706   SetupConnect();
    707   ExpectClientError(500, "Could not create socket to connect to server");
    708 }
    709 
    710 TEST_F(HTTPProxyTest, ConnectAsyncConnectFailure) {
    711   SetupConnectAsync();
    712   ExpectClientResult();
    713   OnConnectCompletion(false, -1);
    714   ExpectClientError(500, "Socket connection delayed failure");
    715 }
    716 
    717 TEST_F(HTTPProxyTest, ConnectSynchronousSuccess) {
    718   SetupClient();
    719   ExpectSyncConnect(kServerAddress, 999);
    720   ExpectRepeatedServerOutput();
    721   SetupConnectWithRequest("/", "1.1", "Host: www.chromium.org:999");
    722   EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
    723 }
    724 
    725 TEST_F(HTTPProxyTest, ConnectIPAddresss) {
    726   SetupClient();
    727   ExpectSyncConnect(kServerAddress, 999);
    728   ExpectRepeatedServerOutput();
    729   ExpectRouteRequest();
    730   ReadFromClient(CreateRequest("/", "1.1",
    731                                StringPrintf("Host: %s:999", kServerAddress)));
    732   EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
    733 }
    734 
    735 TEST_F(HTTPProxyTest, ConnectAsyncConnectSuccess) {
    736   SetupConnectComplete();
    737 }
    738 
    739 TEST_F(HTTPProxyTest, HTTPConnectMethod) {
    740   SetupClient();
    741   ExpectAsyncConnect(kServerAddress, kConnectPort, true);
    742   ExpectConnectTimeout();
    743   ExpectRouteRequest();
    744   ReadFromClient(kConnectQuery);
    745   ExpectRepeatedInputTimeout();
    746   ExpectClientData();
    747   OnConnectCompletion(true, kServerFD);
    748   ExpectInClientResponse("HTTP/1.1 200 OK\r\n\r\n");
    749 }
    750 
    751 TEST_F(HTTPProxyTest, TunnelData) {
    752   SetupConnectComplete();
    753 
    754   // The proxy is waiting for the server to be ready to accept data.
    755   EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
    756       .WillOnce(Return(10));
    757   ExpectServerInput();
    758   WriteToServer(kServerFD);
    759   EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
    760       .WillOnce(ReturnArg<2>());
    761   ExpectInputTimeout();
    762   WriteToServer(kServerFD);
    763   EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
    764 
    765   // Tunnel a reply back to the client.
    766   const string server_result("200 OK ... and so on");
    767   ExpectClientResult();
    768   ReadFromServer(server_result);
    769   EXPECT_EQ(server_result,
    770             string(reinterpret_cast<const char*>(
    771                 GetServerData().GetConstData()),
    772                    GetServerData().GetLength()));
    773 
    774   // Allow part of the result string to be sent to the client.
    775   const int part = server_result.length() / 2;
    776   EXPECT_CALL(sockets(), Send(kClientFD, _, server_result.length(), 0))
    777       .WillOnce(Return(part));
    778   ExpectInputTimeout();
    779   WriteToClient(kClientFD);
    780   EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
    781 
    782   // The Server closes the connection while the client is still reading.
    783   ExpectInputTimeout();
    784   ReadFromServer("");
    785   EXPECT_EQ(HTTPProxy::kStateFlushResponse, GetProxyState());
    786 
    787   // When the last part of the response is written to the client, we close
    788   // all connections.
    789   EXPECT_CALL(sockets(), Send(kClientFD, _, server_result.length() - part, 0))
    790       .WillOnce(ReturnArg<2>());
    791   ExpectTunnelClose();
    792   WriteToClient(kClientFD);
    793   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    794 }
    795 
    796 TEST_F(HTTPProxyTest, TunnelDataFailWriteClient) {
    797   SetupConnectComplete();
    798   EXPECT_CALL(sockets(), Send(kClientFD, _, _, 0))
    799       .WillOnce(Return(-1));
    800   ExpectTunnelClose();
    801   WriteToClient(kClientFD);
    802   ExpectClientReset();
    803   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    804 }
    805 
    806 TEST_F(HTTPProxyTest, TunnelDataFailWriteServer) {
    807   SetupConnectComplete();
    808   EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
    809       .WillOnce(Return(-1));
    810   ExpectTunnelClose();
    811   WriteToServer(kServerFD);
    812   ExpectClientReset();
    813   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    814 }
    815 
    816 TEST_F(HTTPProxyTest, TunnelDataFailReadServer) {
    817   SetupConnectComplete();
    818   EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
    819       .WillOnce(Return(10));
    820   ExpectServerInput();
    821   WriteToServer(kServerFD);
    822   ExpectTunnelClose();
    823   CauseReadError();
    824   ExpectClientReset();
    825   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    826 }
    827 
    828 TEST_F(HTTPProxyTest, TunnelDataFailClientClose) {
    829   SetupConnectComplete();
    830   ExpectTunnelClose();
    831   ReadFromClient("");
    832   ExpectClientReset();
    833   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    834 }
    835 
    836 TEST_F(HTTPProxyTest, TunnelDataFailServerClose) {
    837   SetupConnectComplete();
    838   ExpectTunnelClose();
    839   ReadFromServer("");
    840   ExpectClientReset();
    841   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    842 }
    843 
    844 TEST_F(HTTPProxyTest, StopClient) {
    845   SetupConnectComplete();
    846   EXPECT_CALL(sockets(), Close(kClientFD))
    847       .WillOnce(Return(0));
    848   EXPECT_CALL(sockets(), Close(kServerFD))
    849       .WillOnce(Return(0));
    850   ExpectRouteRelease();
    851   StopClient();
    852   ExpectClientReset();
    853   EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
    854 }
    855 
    856 }  // namespace shill
    857