| 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 |