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 |