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