Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: net/websockets/websocket_basic_handshake_stream.cc

Issue 1047623002: Support parsing a Sec-WebSocket-Extensions header with multiple elements (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clear extensions_ if errored Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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/websockets/websocket_basic_handshake_stream.h" 5 #include "net/websockets/websocket_basic_handshake_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 return DeflateError( 296 return DeflateError(
297 failure_message, 297 failure_message,
298 "Received an unexpected permessage-deflate extension parameter"); 298 "Received an unexpected permessage-deflate extension parameter");
299 } 299 }
300 } 300 }
301 params->deflate_enabled = true; 301 params->deflate_enabled = true;
302 return true; 302 return true;
303 } 303 }
304 304
305 bool ValidateExtensions(const HttpResponseHeaders* headers, 305 bool ValidateExtensions(const HttpResponseHeaders* headers,
306 const std::vector<std::string>& requested_extensions, 306 std::string* accepted_extensions_descriptor,
307 std::string* extensions,
308 std::string* failure_message, 307 std::string* failure_message,
309 WebSocketExtensionParams* params) { 308 WebSocketExtensionParams* params) {
310 void* state = nullptr; 309 void* state = nullptr;
311 std::string value; 310 std::string header_value;
312 std::vector<std::string> accepted_extensions; 311 std::vector<std::string> header_values;
313 // TODO(ricea): If adding support for additional extensions, generalise this 312 // TODO(ricea): If adding support for additional extensions, generalise this
314 // code. 313 // code.
315 bool seen_permessage_deflate = false; 314 bool seen_permessage_deflate = false;
316 while (headers->EnumerateHeader( 315 while (headers->EnumerateHeader(&state, websockets::kSecWebSocketExtensions,
317 &state, websockets::kSecWebSocketExtensions, &value)) { 316 &header_value)) {
318 WebSocketExtensionParser parser; 317 WebSocketExtensionParser parser;
319 parser.Parse(value); 318 parser.Parse(header_value);
320 if (parser.has_error()) { 319 if (parser.has_error()) {
321 // TODO(yhirano) Set appropriate failure message. 320 // TODO(yhirano) Set appropriate failure message.
322 *failure_message = 321 *failure_message =
323 "'Sec-WebSocket-Extensions' header value is " 322 "'Sec-WebSocket-Extensions' header value is "
324 "rejected by the parser: " + 323 "rejected by the parser: " +
325 value; 324 header_value;
326 return false; 325 return false;
327 } 326 }
328 if (parser.extension().name() == "permessage-deflate") { 327
329 if (seen_permessage_deflate) { 328 const std::vector<WebSocketExtension>& extensions = parser.extensions();
330 *failure_message = "Received duplicate permessage-deflate response"; 329 for (size_t i = 0; i < extensions.size(); ++i) {
eroman 2015/03/31 21:11:12 optional: "for-in" loop
tyoshino (SeeGerritForStatus) 2015/04/01 04:57:57 Done.
330 const WebSocketExtension& extension = extensions[i];
331 if (extension.name() == "permessage-deflate") {
332 if (seen_permessage_deflate) {
333 *failure_message = "Received duplicate permessage-deflate response";
334 return false;
335 }
336 seen_permessage_deflate = true;
337
338 if (!ValidatePerMessageDeflateExtension(extension, failure_message,
339 params))
eroman 2015/03/31 21:11:12 Add curly braces since the if occupies more than 1
tyoshino (SeeGerritForStatus) 2015/04/01 04:57:57 Done.
340 return false;
341 header_values.push_back(header_value);
342 } else {
343 *failure_message = "Found an unsupported extension '" +
344 extension.name() +
345 "' in 'Sec-WebSocket-Extensions' header";
331 return false; 346 return false;
332 } 347 }
333 seen_permessage_deflate = true;
334 if (!ValidatePerMessageDeflateExtension(
335 parser.extension(), failure_message, params))
336 return false;
337 } else {
338 *failure_message =
339 "Found an unsupported extension '" +
340 parser.extension().name() +
341 "' in 'Sec-WebSocket-Extensions' header";
342 return false;
343 } 348 }
344 accepted_extensions.push_back(value);
345 } 349 }
346 *extensions = JoinString(accepted_extensions, ", "); 350 *accepted_extensions_descriptor = JoinString(header_values, ", ");
347 return true; 351 return true;
348 } 352 }
349 353
350 } // namespace 354 } // namespace
351 355
352 WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream( 356 WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream(
353 scoped_ptr<ClientSocketHandle> connection, 357 scoped_ptr<ClientSocketHandle> connection,
354 WebSocketStream::ConnectDelegate* connect_delegate, 358 WebSocketStream::ConnectDelegate* connect_delegate,
355 bool using_proxy, 359 bool using_proxy,
356 std::vector<std::string> requested_sub_protocols, 360 std::vector<std::string> requested_sub_protocols,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 std::string failure_message; 633 std::string failure_message;
630 if (ValidateUpgrade(headers, &failure_message) && 634 if (ValidateUpgrade(headers, &failure_message) &&
631 ValidateSecWebSocketAccept( 635 ValidateSecWebSocketAccept(
632 headers, handshake_challenge_response_, &failure_message) && 636 headers, handshake_challenge_response_, &failure_message) &&
633 ValidateConnection(headers, &failure_message) && 637 ValidateConnection(headers, &failure_message) &&
634 ValidateSubProtocol(headers, 638 ValidateSubProtocol(headers,
635 requested_sub_protocols_, 639 requested_sub_protocols_,
636 &sub_protocol_, 640 &sub_protocol_,
637 &failure_message) && 641 &failure_message) &&
638 ValidateExtensions(headers, 642 ValidateExtensions(headers,
639 requested_extensions_,
640 &extensions_, 643 &extensions_,
641 &failure_message, 644 &failure_message,
642 extension_params_.get())) { 645 extension_params_.get())) {
643 return OK; 646 return OK;
644 } 647 }
645 set_failure_message("Error during WebSocket handshake: " + failure_message); 648 set_failure_message("Error during WebSocket handshake: " + failure_message);
646 return ERR_INVALID_RESPONSE; 649 return ERR_INVALID_RESPONSE;
647 } 650 }
648 651
649 void WebSocketBasicHandshakeStream::set_failure_message( 652 void WebSocketBasicHandshakeStream::set_failure_message(
650 const std::string& failure_message) { 653 const std::string& failure_message) {
651 *failure_message_ = failure_message; 654 *failure_message_ = failure_message;
652 } 655 }
653 656
654 } // namespace net 657 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698