| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/server/web_socket_encoder.h" | 5 #include "net/server/web_socket_encoder.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 14 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
| 15 #include "net/websockets/websocket_deflate_parameters.h" | 16 #include "net/websockets/websocket_deflate_parameters.h" |
| 16 #include "net/websockets/websocket_extension.h" | 17 #include "net/websockets/websocket_extension.h" |
| 17 #include "net/websockets/websocket_extension_parser.h" | 18 #include "net/websockets/websocket_extension_parser.h" |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 const char WebSocketEncoder::kClientExtensions[] = | 22 const char WebSocketEncoder::kClientExtensions[] = |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 frame.push_back(data[i] ^ mask_bytes[i % kMaskingKeyWidthInBytes]); | 180 frame.push_back(data[i] ^ mask_bytes[i % kMaskingKeyWidthInBytes]); |
| 180 } else { | 181 } else { |
| 181 frame.insert(frame.end(), data, data + data_length); | 182 frame.insert(frame.end(), data, data + data_length); |
| 182 } | 183 } |
| 183 *output = std::string(&frame[0], frame.size()); | 184 *output = std::string(&frame[0], frame.size()); |
| 184 } | 185 } |
| 185 | 186 |
| 186 } // anonymous namespace | 187 } // anonymous namespace |
| 187 | 188 |
| 188 // static | 189 // static |
| 189 scoped_ptr<WebSocketEncoder> WebSocketEncoder::CreateServer() { | 190 std::unique_ptr<WebSocketEncoder> WebSocketEncoder::CreateServer() { |
| 190 return make_scoped_ptr(new WebSocketEncoder(FOR_SERVER, nullptr, nullptr)); | 191 return base::WrapUnique(new WebSocketEncoder(FOR_SERVER, nullptr, nullptr)); |
| 191 } | 192 } |
| 192 | 193 |
| 193 // static | 194 // static |
| 194 scoped_ptr<WebSocketEncoder> WebSocketEncoder::CreateServer( | 195 std::unique_ptr<WebSocketEncoder> WebSocketEncoder::CreateServer( |
| 195 const std::string& extensions, | 196 const std::string& extensions, |
| 196 WebSocketDeflateParameters* deflate_parameters) { | 197 WebSocketDeflateParameters* deflate_parameters) { |
| 197 WebSocketExtensionParser parser; | 198 WebSocketExtensionParser parser; |
| 198 if (!parser.Parse(extensions)) { | 199 if (!parser.Parse(extensions)) { |
| 199 // Failed to parse Sec-WebSocket-Extensions header. We MUST fail the | 200 // Failed to parse Sec-WebSocket-Extensions header. We MUST fail the |
| 200 // connection. | 201 // connection. |
| 201 return nullptr; | 202 return nullptr; |
| 202 } | 203 } |
| 203 | 204 |
| 204 for (const auto& extension : parser.extensions()) { | 205 for (const auto& extension : parser.extensions()) { |
| 205 std::string failure_message; | 206 std::string failure_message; |
| 206 WebSocketDeflateParameters offer; | 207 WebSocketDeflateParameters offer; |
| 207 if (!offer.Initialize(extension, &failure_message) || | 208 if (!offer.Initialize(extension, &failure_message) || |
| 208 !offer.IsValidAsRequest(&failure_message)) { | 209 !offer.IsValidAsRequest(&failure_message)) { |
| 209 // We decline unknown / malformed extensions. | 210 // We decline unknown / malformed extensions. |
| 210 continue; | 211 continue; |
| 211 } | 212 } |
| 212 | 213 |
| 213 WebSocketDeflateParameters response = offer; | 214 WebSocketDeflateParameters response = offer; |
| 214 if (offer.is_client_max_window_bits_specified() && | 215 if (offer.is_client_max_window_bits_specified() && |
| 215 !offer.has_client_max_window_bits_value()) { | 216 !offer.has_client_max_window_bits_value()) { |
| 216 // We need to choose one value for the response. | 217 // We need to choose one value for the response. |
| 217 response.SetClientMaxWindowBits(15); | 218 response.SetClientMaxWindowBits(15); |
| 218 } | 219 } |
| 219 DCHECK(response.IsValidAsResponse()); | 220 DCHECK(response.IsValidAsResponse()); |
| 220 DCHECK(offer.IsCompatibleWith(response)); | 221 DCHECK(offer.IsCompatibleWith(response)); |
| 221 auto deflater = make_scoped_ptr( | 222 auto deflater = base::WrapUnique( |
| 222 new WebSocketDeflater(response.server_context_take_over_mode())); | 223 new WebSocketDeflater(response.server_context_take_over_mode())); |
| 223 auto inflater = make_scoped_ptr( | 224 auto inflater = base::WrapUnique( |
| 224 new WebSocketInflater(kInflaterChunkSize, kInflaterChunkSize)); | 225 new WebSocketInflater(kInflaterChunkSize, kInflaterChunkSize)); |
| 225 if (!deflater->Initialize(response.PermissiveServerMaxWindowBits()) || | 226 if (!deflater->Initialize(response.PermissiveServerMaxWindowBits()) || |
| 226 !inflater->Initialize(response.PermissiveClientMaxWindowBits())) { | 227 !inflater->Initialize(response.PermissiveClientMaxWindowBits())) { |
| 227 // For some reason we cannot accept the parameters. | 228 // For some reason we cannot accept the parameters. |
| 228 continue; | 229 continue; |
| 229 } | 230 } |
| 230 *deflate_parameters = response; | 231 *deflate_parameters = response; |
| 231 return make_scoped_ptr(new WebSocketEncoder(FOR_SERVER, std::move(deflater), | 232 return base::WrapUnique(new WebSocketEncoder( |
| 232 std::move(inflater))); | 233 FOR_SERVER, std::move(deflater), std::move(inflater))); |
| 233 } | 234 } |
| 234 | 235 |
| 235 // We cannot find an acceptable offer. | 236 // We cannot find an acceptable offer. |
| 236 return make_scoped_ptr(new WebSocketEncoder(FOR_SERVER, nullptr, nullptr)); | 237 return base::WrapUnique(new WebSocketEncoder(FOR_SERVER, nullptr, nullptr)); |
| 237 } | 238 } |
| 238 | 239 |
| 239 // static | 240 // static |
| 240 scoped_ptr<WebSocketEncoder> WebSocketEncoder::CreateClient( | 241 std::unique_ptr<WebSocketEncoder> WebSocketEncoder::CreateClient( |
| 241 const std::string& response_extensions) { | 242 const std::string& response_extensions) { |
| 242 // TODO(yhirano): Add a way to return an error. | 243 // TODO(yhirano): Add a way to return an error. |
| 243 | 244 |
| 244 WebSocketExtensionParser parser; | 245 WebSocketExtensionParser parser; |
| 245 if (!parser.Parse(response_extensions)) { | 246 if (!parser.Parse(response_extensions)) { |
| 246 // Parse error. Note that there are two cases here. | 247 // Parse error. Note that there are two cases here. |
| 247 // 1) There is no Sec-WebSocket-Extensions header. | 248 // 1) There is no Sec-WebSocket-Extensions header. |
| 248 // 2) There is a malformed Sec-WebSocketExtensions header. | 249 // 2) There is a malformed Sec-WebSocketExtensions header. |
| 249 // We should return a deflate-disabled encoder for the former case and | 250 // We should return a deflate-disabled encoder for the former case and |
| 250 // fail the connection for the latter case. | 251 // fail the connection for the latter case. |
| 251 return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); | 252 return base::WrapUnique(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); |
| 252 } | 253 } |
| 253 if (parser.extensions().size() != 1) { | 254 if (parser.extensions().size() != 1) { |
| 254 // Only permessage-deflate extension is supported. | 255 // Only permessage-deflate extension is supported. |
| 255 // TODO (yhirano): Fail the connection. | 256 // TODO (yhirano): Fail the connection. |
| 256 return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); | 257 return base::WrapUnique(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); |
| 257 } | 258 } |
| 258 const auto& extension = parser.extensions()[0]; | 259 const auto& extension = parser.extensions()[0]; |
| 259 WebSocketDeflateParameters params; | 260 WebSocketDeflateParameters params; |
| 260 std::string failure_message; | 261 std::string failure_message; |
| 261 if (!params.Initialize(extension, &failure_message) || | 262 if (!params.Initialize(extension, &failure_message) || |
| 262 !params.IsValidAsResponse(&failure_message)) { | 263 !params.IsValidAsResponse(&failure_message)) { |
| 263 // TODO (yhirano): Fail the connection. | 264 // TODO (yhirano): Fail the connection. |
| 264 return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); | 265 return base::WrapUnique(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); |
| 265 } | 266 } |
| 266 | 267 |
| 267 auto deflater = make_scoped_ptr( | 268 auto deflater = base::WrapUnique( |
| 268 new WebSocketDeflater(params.client_context_take_over_mode())); | 269 new WebSocketDeflater(params.client_context_take_over_mode())); |
| 269 auto inflater = make_scoped_ptr( | 270 auto inflater = base::WrapUnique( |
| 270 new WebSocketInflater(kInflaterChunkSize, kInflaterChunkSize)); | 271 new WebSocketInflater(kInflaterChunkSize, kInflaterChunkSize)); |
| 271 if (!deflater->Initialize(params.PermissiveClientMaxWindowBits()) || | 272 if (!deflater->Initialize(params.PermissiveClientMaxWindowBits()) || |
| 272 !inflater->Initialize(params.PermissiveServerMaxWindowBits())) { | 273 !inflater->Initialize(params.PermissiveServerMaxWindowBits())) { |
| 273 // TODO (yhirano): Fail the connection. | 274 // TODO (yhirano): Fail the connection. |
| 274 return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); | 275 return base::WrapUnique(new WebSocketEncoder(FOR_CLIENT, nullptr, nullptr)); |
| 275 } | 276 } |
| 276 | 277 |
| 277 return make_scoped_ptr(new WebSocketEncoder(FOR_CLIENT, std::move(deflater), | 278 return base::WrapUnique(new WebSocketEncoder(FOR_CLIENT, std::move(deflater), |
| 278 std::move(inflater))); | 279 std::move(inflater))); |
| 279 } | 280 } |
| 280 | 281 |
| 281 WebSocketEncoder::WebSocketEncoder(Type type, | 282 WebSocketEncoder::WebSocketEncoder(Type type, |
| 282 scoped_ptr<WebSocketDeflater> deflater, | 283 std::unique_ptr<WebSocketDeflater> deflater, |
| 283 scoped_ptr<WebSocketInflater> inflater) | 284 std::unique_ptr<WebSocketInflater> inflater) |
| 284 : type_(type), | 285 : type_(type), |
| 285 deflater_(std::move(deflater)), | 286 deflater_(std::move(deflater)), |
| 286 inflater_(std::move(inflater)) {} | 287 inflater_(std::move(inflater)) {} |
| 287 | 288 |
| 288 WebSocketEncoder::~WebSocketEncoder() {} | 289 WebSocketEncoder::~WebSocketEncoder() {} |
| 289 | 290 |
| 290 WebSocket::ParseResult WebSocketEncoder::DecodeFrame( | 291 WebSocket::ParseResult WebSocketEncoder::DecodeFrame( |
| 291 const base::StringPiece& frame, | 292 const base::StringPiece& frame, |
| 292 int* bytes_consumed, | 293 int* bytes_consumed, |
| 293 std::string* output) { | 294 std::string* output) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 return false; | 346 return false; |
| 346 scoped_refptr<IOBufferWithSize> buffer = | 347 scoped_refptr<IOBufferWithSize> buffer = |
| 347 deflater_->GetOutput(deflater_->CurrentOutputSize()); | 348 deflater_->GetOutput(deflater_->CurrentOutputSize()); |
| 348 if (!buffer.get()) | 349 if (!buffer.get()) |
| 349 return false; | 350 return false; |
| 350 *output = std::string(buffer->data(), buffer->size()); | 351 *output = std::string(buffer->data(), buffer->size()); |
| 351 return true; | 352 return true; |
| 352 } | 353 } |
| 353 | 354 |
| 354 } // namespace net | 355 } // namespace net |
| OLD | NEW |