Home | History | Annotate | Download | only in websockets
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/websockets/websocket_test_util.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/memory/scoped_vector.h"
     12 #include "base/stl_util.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "net/socket/socket_test_util.h"
     15 
     16 namespace net {
     17 
     18 namespace {
     19 const uint64 kA =
     20     (static_cast<uint64>(0x5851f42d) << 32) + static_cast<uint64>(0x4c957f2d);
     21 const uint64 kC = 12345;
     22 const uint64 kM = static_cast<uint64>(1) << 48;
     23 
     24 }  // namespace
     25 
     26 LinearCongruentialGenerator::LinearCongruentialGenerator(uint32 seed)
     27     : current_(seed) {}
     28 
     29 uint32 LinearCongruentialGenerator::Generate() {
     30   uint64 result = current_;
     31   current_ = (current_ * kA + kC) % kM;
     32   return static_cast<uint32>(result >> 16);
     33 }
     34 
     35 std::string WebSocketStandardRequest(const std::string& path,
     36                                      const std::string& origin,
     37                                      const std::string& extra_headers) {
     38   // Unrelated changes in net/http may change the order and default-values of
     39   // HTTP headers, causing WebSocket tests to fail. It is safe to update this
     40   // string in that case.
     41   return base::StringPrintf(
     42       "GET %s HTTP/1.1\r\n"
     43       "Host: localhost\r\n"
     44       "Connection: Upgrade\r\n"
     45       "Pragma: no-cache\r\n"
     46       "Cache-Control: no-cache\r\n"
     47       "Upgrade: websocket\r\n"
     48       "Origin: %s\r\n"
     49       "Sec-WebSocket-Version: 13\r\n"
     50       "User-Agent:\r\n"
     51       "Accept-Encoding: gzip, deflate\r\n"
     52       "Accept-Language: en-us,fr\r\n"
     53       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
     54       "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n"
     55       "%s\r\n",
     56       path.c_str(),
     57       origin.c_str(),
     58       extra_headers.c_str());
     59 }
     60 
     61 std::string WebSocketStandardResponse(const std::string& extra_headers) {
     62   return base::StringPrintf(
     63       "HTTP/1.1 101 Switching Protocols\r\n"
     64       "Upgrade: websocket\r\n"
     65       "Connection: Upgrade\r\n"
     66       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
     67       "%s\r\n",
     68       extra_headers.c_str());
     69 }
     70 
     71 struct WebSocketDeterministicMockClientSocketFactoryMaker::Detail {
     72   std::string expect_written;
     73   std::string return_to_read;
     74   std::vector<MockRead> reads;
     75   MockWrite write;
     76   ScopedVector<DeterministicSocketData> socket_data_vector;
     77   ScopedVector<SSLSocketDataProvider> ssl_socket_data_vector;
     78   DeterministicMockClientSocketFactory factory;
     79 };
     80 
     81 WebSocketDeterministicMockClientSocketFactoryMaker::
     82     WebSocketDeterministicMockClientSocketFactoryMaker()
     83     : detail_(new Detail) {}
     84 
     85 WebSocketDeterministicMockClientSocketFactoryMaker::
     86     ~WebSocketDeterministicMockClientSocketFactoryMaker() {}
     87 
     88 DeterministicMockClientSocketFactory*
     89 WebSocketDeterministicMockClientSocketFactoryMaker::factory() {
     90   return &detail_->factory;
     91 }
     92 
     93 void WebSocketDeterministicMockClientSocketFactoryMaker::SetExpectations(
     94     const std::string& expect_written,
     95     const std::string& return_to_read) {
     96   const size_t kHttpStreamParserBufferSize = 4096;
     97   // We need to extend the lifetime of these strings.
     98   detail_->expect_written = expect_written;
     99   detail_->return_to_read = return_to_read;
    100   int sequence = 0;
    101   detail_->write = MockWrite(SYNCHRONOUS,
    102                              detail_->expect_written.data(),
    103                              detail_->expect_written.size(),
    104                              sequence++);
    105   // HttpStreamParser reads 4KB at a time. We need to take this implementation
    106   // detail into account if |return_to_read| is big enough.
    107   for (size_t place = 0; place < detail_->return_to_read.size();
    108        place += kHttpStreamParserBufferSize) {
    109     detail_->reads.push_back(
    110         MockRead(SYNCHRONOUS, detail_->return_to_read.data() + place,
    111                  std::min(detail_->return_to_read.size() - place,
    112                           kHttpStreamParserBufferSize),
    113                  sequence++));
    114   }
    115   scoped_ptr<DeterministicSocketData> socket_data(
    116       new DeterministicSocketData(vector_as_array(&detail_->reads),
    117                                   detail_->reads.size(),
    118                                   &detail_->write,
    119                                   1));
    120   socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
    121   socket_data->SetStop(sequence);
    122   AddRawExpectations(socket_data.Pass());
    123 }
    124 
    125 void WebSocketDeterministicMockClientSocketFactoryMaker::AddRawExpectations(
    126     scoped_ptr<DeterministicSocketData> socket_data) {
    127   detail_->factory.AddSocketDataProvider(socket_data.get());
    128   detail_->socket_data_vector.push_back(socket_data.release());
    129 }
    130 
    131 void
    132 WebSocketDeterministicMockClientSocketFactoryMaker::AddSSLSocketDataProvider(
    133     scoped_ptr<SSLSocketDataProvider> ssl_socket_data) {
    134   detail_->factory.AddSSLSocketDataProvider(ssl_socket_data.get());
    135   detail_->ssl_socket_data_vector.push_back(ssl_socket_data.release());
    136 }
    137 
    138 WebSocketTestURLRequestContextHost::WebSocketTestURLRequestContextHost()
    139     : url_request_context_(true), url_request_context_initialized_(false) {
    140   url_request_context_.set_client_socket_factory(maker_.factory());
    141 }
    142 
    143 WebSocketTestURLRequestContextHost::~WebSocketTestURLRequestContextHost() {}
    144 
    145 void WebSocketTestURLRequestContextHost::AddRawExpectations(
    146     scoped_ptr<DeterministicSocketData> socket_data) {
    147   maker_.AddRawExpectations(socket_data.Pass());
    148 }
    149 
    150 void WebSocketTestURLRequestContextHost::AddSSLSocketDataProvider(
    151     scoped_ptr<SSLSocketDataProvider> ssl_socket_data) {
    152   maker_.AddSSLSocketDataProvider(ssl_socket_data.Pass());
    153 }
    154 
    155 TestURLRequestContext*
    156 WebSocketTestURLRequestContextHost::GetURLRequestContext() {
    157   if (!url_request_context_initialized_) {
    158     url_request_context_.Init();
    159     // A Network Delegate is required to make the URLRequest::Delegate work.
    160     url_request_context_.set_network_delegate(&network_delegate_);
    161     url_request_context_initialized_ = true;
    162   }
    163   return &url_request_context_;
    164 }
    165 
    166 }  // namespace net
    167