• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
LinearCongruentialGenerator(uint32 seed)26 LinearCongruentialGenerator::LinearCongruentialGenerator(uint32 seed)
27     : current_(seed) {}
28 
Generate()29 uint32 LinearCongruentialGenerator::Generate() {
30   uint64 result = current_;
31   current_ = (current_ * kA + kC) % kM;
32   return static_cast<uint32>(result >> 16);
33 }
34 
WebSocketStandardRequest(const std::string & path,const std::string & origin,const std::string & extra_headers)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 
WebSocketStandardResponse(const std::string & extra_headers)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::
WebSocketDeterministicMockClientSocketFactoryMaker()82     WebSocketDeterministicMockClientSocketFactoryMaker()
83     : detail_(new Detail) {}
84 
85 WebSocketDeterministicMockClientSocketFactoryMaker::
~WebSocketDeterministicMockClientSocketFactoryMaker()86     ~WebSocketDeterministicMockClientSocketFactoryMaker() {}
87 
88 DeterministicMockClientSocketFactory*
factory()89 WebSocketDeterministicMockClientSocketFactoryMaker::factory() {
90   return &detail_->factory;
91 }
92 
SetExpectations(const std::string & expect_written,const std::string & return_to_read)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 
AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data)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
AddSSLSocketDataProvider(scoped_ptr<SSLSocketDataProvider> ssl_socket_data)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 
WebSocketTestURLRequestContextHost()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 
~WebSocketTestURLRequestContextHost()143 WebSocketTestURLRequestContextHost::~WebSocketTestURLRequestContextHost() {}
144 
AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data)145 void WebSocketTestURLRequestContextHost::AddRawExpectations(
146     scoped_ptr<DeterministicSocketData> socket_data) {
147   maker_.AddRawExpectations(socket_data.Pass());
148 }
149 
AddSSLSocketDataProvider(scoped_ptr<SSLSocketDataProvider> ssl_socket_data)150 void WebSocketTestURLRequestContextHost::AddSSLSocketDataProvider(
151     scoped_ptr<SSLSocketDataProvider> ssl_socket_data) {
152   maker_.AddSSLSocketDataProvider(ssl_socket_data.Pass());
153 }
154 
155 TestURLRequestContext*
GetURLRequestContext()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