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