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

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

Issue 6823075: Accept new WebSocket handshake format (hybi-04 and later). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revise comments. Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_handshake_handler.h" 5 #include "net/websockets/websocket_handshake_handler.h"
6 6
7 #include "base/base64.h"
7 #include "base/md5.h" 8 #include "base/md5.h"
9 #include "base/sha1.h"
8 #include "base/string_piece.h" 10 #include "base/string_piece.h"
9 #include "base/string_util.h" 11 #include "base/string_util.h"
10 #include "googleurl/src/gurl.h" 12 #include "googleurl/src/gurl.h"
11 #include "net/http/http_response_headers.h" 13 #include "net/http/http_response_headers.h"
12 #include "net/http/http_util.h" 14 #include "net/http/http_util.h"
13 15
14 namespace { 16 namespace {
15 17
16 const size_t kRequestKey3Size = 8U; 18 const size_t kRequestKey3Size = 8U;
17 const size_t kResponseKeySize = 16U; 19 const size_t kResponseKeySize = 16U;
20 const char* const kWebSocketGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
18 21
19 void ParseHandshakeHeader( 22 void ParseHandshakeHeader(
20 const char* handshake_message, int len, 23 const char* handshake_message, int len,
21 std::string* status_line, 24 std::string* status_line,
22 std::string* headers) { 25 std::string* headers) {
23 size_t i = base::StringPiece(handshake_message, len).find_first_of("\r\n"); 26 size_t i = base::StringPiece(handshake_message, len).find_first_of("\r\n");
24 if (i == base::StringPiece::npos) { 27 if (i == base::StringPiece::npos) {
25 *status_line = std::string(handshake_message, len); 28 *status_line = std::string(handshake_message, len);
26 *headers = ""; 29 *headers = "";
27 return; 30 return;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 key_number /= spaces; 126 key_number /= spaces;
124 127
125 char part[4]; 128 char part[4];
126 for (int i = 0; i < 4; i++) { 129 for (int i = 0; i < 4; i++) {
127 part[3 - i] = key_number & 0xFF; 130 part[3 - i] = key_number & 0xFF;
128 key_number >>= 8; 131 key_number >>= 8;
129 } 132 }
130 challenge->append(part, 4); 133 challenge->append(part, 4);
131 } 134 }
132 135
136 // Hybi-04 and later drafts require clients to send Sec-WebSocket-Key header,
137 // thus we can detect request format by looking at the presence of this header.
138 bool IsHybi04HandshakeRequest(const std::string& request_headers) {
139 std::vector<std::string> values;
140 const char* const headers_to_get[1] = { "sec-websocket-key" };
141 FetchHeaders(request_headers, headers_to_get, 1, &values);
142 return !values.empty();
143 }
144
133 } // anonymous namespace 145 } // anonymous namespace
134 146
135 namespace net { 147 namespace net {
136 148
137 WebSocketHandshakeRequestHandler::WebSocketHandshakeRequestHandler() 149 WebSocketHandshakeRequestHandler::WebSocketHandshakeRequestHandler()
138 : original_length_(0), 150 : original_length_(0),
139 raw_length_(0) {} 151 raw_length_(0),
152 is_hybi04_handshake_(false) {}
140 153
141 bool WebSocketHandshakeRequestHandler::ParseRequest( 154 bool WebSocketHandshakeRequestHandler::ParseRequest(
142 const char* data, int length) { 155 const char* data, int length) {
143 DCHECK_GT(length, 0); 156 DCHECK_GT(length, 0);
144 std::string input(data, length); 157 std::string input(data, length);
145 int input_header_length = 158 int input_header_length =
146 HttpUtil::LocateEndOfHeaders(input.data(), input.size(), 0); 159 HttpUtil::LocateEndOfHeaders(input.data(), input.size(), 0);
147 if (input_header_length <= 0 || 160 if (input_header_length <= 0)
148 input_header_length + kRequestKey3Size > input.size())
149 return false; 161 return false;
150 162
151 ParseHandshakeHeader(input.data(), 163 ParseHandshakeHeader(input.data(),
152 input_header_length, 164 input_header_length,
153 &status_line_, 165 &status_line_,
154 &headers_); 166 &headers_);
155 167
156 // draft-hixie-thewebsocketprotocol-76 or later will send /key3/ 168 // WebSocket protocol drafts hixie-76 (hybi-00), hybi-01, 02 and 03 require
157 // after handshake request header. 169 // the clients to send key3 after the handshake request header fields.
170 // Hybi-04 and later drafts, on the other hand, no longer have key3
171 // in the handshake format.
172 if (IsHybi04HandshakeRequest(headers_)) {
173 key3_ = "";
174 is_hybi04_handshake_ = true;
175 original_length_ = input_header_length;
176 return true;
177 }
178
179 if (input_header_length + kRequestKey3Size > input.size())
180 return false;
181
158 // Assumes WebKit doesn't send any data after handshake request message 182 // Assumes WebKit doesn't send any data after handshake request message
159 // until handshake is finished. 183 // until handshake is finished.
160 // Thus, |key3_| is part of handshake message, and not in part 184 // Thus, |key3_| is part of handshake message, and not in part
161 // of WebSocket frame stream. 185 // of WebSocket frame stream.
162 DCHECK_EQ(kRequestKey3Size, 186 DCHECK_EQ(kRequestKey3Size, input.size() - input_header_length);
163 input.size() -
164 input_header_length);
165 key3_ = std::string(input.data() + input_header_length, 187 key3_ = std::string(input.data() + input_header_length,
166 input.size() - input_header_length); 188 input.size() - input_header_length);
189 is_hybi04_handshake_ = false;
167 original_length_ = input.size(); 190 original_length_ = input.size();
168 return true; 191 return true;
169 } 192 }
170 193
171 size_t WebSocketHandshakeRequestHandler::original_length() const { 194 size_t WebSocketHandshakeRequestHandler::original_length() const {
172 return original_length_; 195 return original_length_;
173 } 196 }
174 197
175 void WebSocketHandshakeRequestHandler::AppendHeaderIfMissing( 198 void WebSocketHandshakeRequestHandler::AppendHeaderIfMissing(
176 const std::string& name, const std::string& value) { 199 const std::string& name, const std::string& value) {
(...skipping 18 matching lines...) Expand all
195 status_line_.data(), status_line_.size()).find_first_of(" "); 218 status_line_.data(), status_line_.size()).find_first_of(" ");
196 if (method_end != base::StringPiece::npos) 219 if (method_end != base::StringPiece::npos)
197 request_info.method = std::string(status_line_.data(), method_end); 220 request_info.method = std::string(status_line_.data(), method_end);
198 221
199 request_info.extra_headers.Clear(); 222 request_info.extra_headers.Clear();
200 request_info.extra_headers.AddHeadersFromString(headers_); 223 request_info.extra_headers.AddHeadersFromString(headers_);
201 224
202 request_info.extra_headers.RemoveHeader("Upgrade"); 225 request_info.extra_headers.RemoveHeader("Upgrade");
203 request_info.extra_headers.RemoveHeader("Connection"); 226 request_info.extra_headers.RemoveHeader("Connection");
204 227
205 challenge->clear(); 228 if (is_hybi04_handshake_) {
206 std::string key; 229 std::string key;
207 request_info.extra_headers.GetHeader("Sec-WebSocket-Key1", &key); 230 request_info.extra_headers.GetHeader("Sec-WebSocket-Key", &key);
208 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key1"); 231 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key");
209 GetKeyNumber(key, challenge); 232 *challenge = key;
233 } else {
234 challenge->clear();
235 std::string key;
236 request_info.extra_headers.GetHeader("Sec-WebSocket-Key1", &key);
237 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key1");
238 GetKeyNumber(key, challenge);
210 239
211 request_info.extra_headers.GetHeader("Sec-WebSocket-Key2", &key); 240 request_info.extra_headers.GetHeader("Sec-WebSocket-Key2", &key);
212 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key2"); 241 request_info.extra_headers.RemoveHeader("Sec-WebSocket-Key2");
213 GetKeyNumber(key, challenge); 242 GetKeyNumber(key, challenge);
214 243
215 challenge->append(key3_); 244 challenge->append(key3_);
245 }
216 246
217 return request_info; 247 return request_info;
218 } 248 }
219 249
220 bool WebSocketHandshakeRequestHandler::GetRequestHeaderBlock( 250 bool WebSocketHandshakeRequestHandler::GetRequestHeaderBlock(
221 const GURL& url, spdy::SpdyHeaderBlock* headers, std::string* challenge) { 251 const GURL& url, spdy::SpdyHeaderBlock* headers, std::string* challenge) {
222 // We don't set "method" and "version". These are fixed value in WebSocket 252 // We don't set "method" and "version". These are fixed value in WebSocket
223 // protocol. 253 // protocol.
224 (*headers)["url"] = url.spec(); 254 (*headers)["url"] = url.spec();
225 255
226 std::string key1; 256 std::string new_key; // For protocols hybi-04 and newer.
227 std::string key2; 257 std::string old_key1; // For protocols hybi-03 and older.
258 std::string old_key2; // Ditto.
228 HttpUtil::HeadersIterator iter(headers_.begin(), headers_.end(), "\r\n"); 259 HttpUtil::HeadersIterator iter(headers_.begin(), headers_.end(), "\r\n");
229 while (iter.GetNext()) { 260 while (iter.GetNext()) {
230 if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 261 if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
231 "connection")) { 262 "connection")) {
232 // Ignore "Connection" header. 263 // Ignore "Connection" header.
233 continue; 264 continue;
234 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 265 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
235 "upgrade")) { 266 "upgrade")) {
236 // Ignore "Upgrade" header. 267 // Ignore "Upgrade" header.
237 continue; 268 continue;
238 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 269 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
239 "sec-websocket-key1")) { 270 "sec-websocket-key1")) {
240 // Use only for generating challenge. 271 // Only used for generating challenge.
241 key1 = iter.values(); 272 old_key1 = iter.values();
242 continue; 273 continue;
243 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(), 274 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
244 "sec-websocket-key2")) { 275 "sec-websocket-key2")) {
245 // Use only for generating challenge. 276 // Only used for generating challenge.
246 key2 = iter.values(); 277 old_key2 = iter.values();
278 continue;
279 } else if (LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
280 "sec-websocket-key")) {
281 // Only used for generating challenge.
282 new_key = iter.values();
247 continue; 283 continue;
248 } 284 }
249 // Others should be sent out to |headers|. 285 // Others should be sent out to |headers|.
250 std::string name = StringToLowerASCII(iter.name()); 286 std::string name = StringToLowerASCII(iter.name());
251 spdy::SpdyHeaderBlock::iterator found = headers->find(name); 287 spdy::SpdyHeaderBlock::iterator found = headers->find(name);
252 if (found == headers->end()) { 288 if (found == headers->end()) {
253 (*headers)[name] = iter.values(); 289 (*headers)[name] = iter.values();
254 } else { 290 } else {
255 // For now, websocket doesn't use multiple headers, but follows to http. 291 // For now, websocket doesn't use multiple headers, but follows to http.
256 found->second.append(1, '\0'); // +=() doesn't append 0's 292 found->second.append(1, '\0'); // +=() doesn't append 0's
257 found->second.append(iter.values()); 293 found->second.append(iter.values());
258 } 294 }
259 } 295 }
260 296
261 challenge->clear(); 297 if (is_hybi04_handshake_) {
262 GetKeyNumber(key1, challenge); 298 DCHECK(old_key1.empty());
263 GetKeyNumber(key2, challenge); 299 DCHECK(old_key2.empty());
264 challenge->append(key3_); 300 *challenge = new_key;
301 } else {
302 DCHECK(new_key.empty());
303 challenge->clear();
304 GetKeyNumber(old_key1, challenge);
305 GetKeyNumber(old_key2, challenge);
306 challenge->append(key3_);
307 }
265 308
266 return true; 309 return true;
267 } 310 }
268 311
269 std::string WebSocketHandshakeRequestHandler::GetRawRequest() { 312 std::string WebSocketHandshakeRequestHandler::GetRawRequest() {
270 DCHECK(!status_line_.empty()); 313 DCHECK(!status_line_.empty());
271 DCHECK(!headers_.empty()); 314 DCHECK(!headers_.empty());
272 DCHECK_EQ(kRequestKey3Size, key3_.size()); 315 // The following works on both hybi-04 and older handshake,
316 // because |key3_| is guaranteed to be empty if the handshake was hybi-04's.
273 std::string raw_request = status_line_ + headers_ + "\r\n" + key3_; 317 std::string raw_request = status_line_ + headers_ + "\r\n" + key3_;
274 raw_length_ = raw_request.size(); 318 raw_length_ = raw_request.size();
275 return raw_request; 319 return raw_request;
276 } 320 }
277 321
278 size_t WebSocketHandshakeRequestHandler::raw_length() const { 322 size_t WebSocketHandshakeRequestHandler::raw_length() const {
279 DCHECK_GT(raw_length_, 0); 323 DCHECK_GT(raw_length_, 0);
280 return raw_length_; 324 return raw_length_;
281 } 325 }
282 326
327 bool WebSocketHandshakeRequestHandler::is_hybi04_handshake() const {
328 return is_hybi04_handshake_;
329 }
330
283 WebSocketHandshakeResponseHandler::WebSocketHandshakeResponseHandler() 331 WebSocketHandshakeResponseHandler::WebSocketHandshakeResponseHandler()
284 : original_header_length_(0) { 332 : original_header_length_(0),
333 expect_hybi04_handshake_(false) {
285 } 334 }
286 335
287 WebSocketHandshakeResponseHandler::~WebSocketHandshakeResponseHandler() {} 336 WebSocketHandshakeResponseHandler::~WebSocketHandshakeResponseHandler() {}
288 337
338 bool WebSocketHandshakeResponseHandler::expect_hybi04_handshake() const {
339 return expect_hybi04_handshake_;
340 }
341
342 void WebSocketHandshakeResponseHandler::set_expect_hybi04_handshake(
343 bool expect_hybi04_handshake) {
344 expect_hybi04_handshake_ = expect_hybi04_handshake;
345 }
346
289 size_t WebSocketHandshakeResponseHandler::ParseRawResponse( 347 size_t WebSocketHandshakeResponseHandler::ParseRawResponse(
290 const char* data, int length) { 348 const char* data, int length) {
291 DCHECK_GT(length, 0); 349 DCHECK_GT(length, 0);
292 if (HasResponse()) { 350 if (HasResponse()) {
293 DCHECK(!status_line_.empty()); 351 DCHECK(!status_line_.empty());
294 DCHECK(!headers_.empty()); 352 DCHECK(!headers_.empty());
295 DCHECK_EQ(kResponseKeySize, key_.size()); 353 DCHECK_EQ(GetResponseKeySize(), key_.size());
296 return 0; 354 return 0;
297 } 355 }
298 356
299 size_t old_original_length = original_.size(); 357 size_t old_original_length = original_.size();
300 358
301 original_.append(data, length); 359 original_.append(data, length);
302 // TODO(ukai): fail fast when response gives wrong status code. 360 // TODO(ukai): fail fast when response gives wrong status code.
303 original_header_length_ = HttpUtil::LocateEndOfHeaders( 361 original_header_length_ = HttpUtil::LocateEndOfHeaders(
304 original_.data(), original_.size(), 0); 362 original_.data(), original_.size(), 0);
305 if (!HasResponse()) 363 if (!HasResponse())
306 return length; 364 return length;
307 365
308 ParseHandshakeHeader(original_.data(), 366 ParseHandshakeHeader(original_.data(),
309 original_header_length_, 367 original_header_length_,
310 &status_line_, 368 &status_line_,
311 &headers_); 369 &headers_);
312 int header_size = status_line_.size() + headers_.size(); 370 int header_size = status_line_.size() + headers_.size();
313 DCHECK_GE(original_header_length_, header_size); 371 DCHECK_GE(original_header_length_, header_size);
314 header_separator_ = std::string(original_.data() + header_size, 372 header_separator_ = std::string(original_.data() + header_size,
315 original_header_length_ - header_size); 373 original_header_length_ - header_size);
316 key_ = std::string(original_.data() + original_header_length_, 374 key_ = std::string(original_.data() + original_header_length_,
317 kResponseKeySize); 375 GetResponseKeySize());
318 376 return original_header_length_ + GetResponseKeySize() - old_original_length;
319 return original_header_length_ + kResponseKeySize - old_original_length;
320 } 377 }
321 378
322 bool WebSocketHandshakeResponseHandler::HasResponse() const { 379 bool WebSocketHandshakeResponseHandler::HasResponse() const {
323 return original_header_length_ > 0 && 380 return original_header_length_ > 0 &&
324 original_header_length_ + kResponseKeySize <= original_.size(); 381 original_header_length_ + GetResponseKeySize() <= original_.size();
325 } 382 }
326 383
327 bool WebSocketHandshakeResponseHandler::ParseResponseInfo( 384 bool WebSocketHandshakeResponseHandler::ParseResponseInfo(
328 const HttpResponseInfo& response_info, 385 const HttpResponseInfo& response_info,
329 const std::string& challenge) { 386 const std::string& challenge) {
330 if (!response_info.headers.get()) 387 if (!response_info.headers.get())
331 return false; 388 return false;
332 389
333 std::string response_message; 390 std::string response_message;
334 response_message = response_info.headers->GetStatusLine(); 391 response_message = response_info.headers->GetStatusLine();
335 response_message += "\r\n"; 392 response_message += "\r\n";
336 response_message += "Upgrade: WebSocket\r\n"; 393 if (expect_hybi04_handshake_)
394 response_message += "Upgrade: websocket\r\n";
395 else
396 response_message += "Upgrade: WebSocket\r\n";
337 response_message += "Connection: Upgrade\r\n"; 397 response_message += "Connection: Upgrade\r\n";
398
399 if (expect_hybi04_handshake_) {
400 std::string hash = base::SHA1HashString(challenge + kWebSocketGuid);
401 std::string websocket_accept;
402 DCHECK(base::Base64Encode(hash, &websocket_accept));
Yuta Kitamura 2011/04/13 09:57:52 Call to Base64Encode should not be inside DCHECK.
Yuta Kitamura 2011/04/13 11:23:50 Done.
403 response_message += "Sec-WebSocket-Accept: " + websocket_accept + "\r\n";
404 }
405
338 void* iter = NULL; 406 void* iter = NULL;
339 std::string name; 407 std::string name;
340 std::string value; 408 std::string value;
341 while (response_info.headers->EnumerateHeaderLines(&iter, &name, &value)) { 409 while (response_info.headers->EnumerateHeaderLines(&iter, &name, &value)) {
342 response_message += name + ": " + value + "\r\n"; 410 response_message += name + ": " + value + "\r\n";
343 } 411 }
344 response_message += "\r\n"; 412 response_message += "\r\n";
345 413
346 MD5Digest digest; 414 if (!expect_hybi04_handshake_) {
347 MD5Sum(challenge.data(), challenge.size(), &digest); 415 MD5Digest digest;
416 MD5Sum(challenge.data(), challenge.size(), &digest);
348 417
349 const char* digest_data = reinterpret_cast<char*>(digest.a); 418 const char* digest_data = reinterpret_cast<char*>(digest.a);
350 response_message.append(digest_data, sizeof(digest.a)); 419 response_message.append(digest_data, sizeof(digest.a));
420 }
351 421
352 return ParseRawResponse(response_message.data(), 422 return ParseRawResponse(response_message.data(),
353 response_message.size()) == response_message.size(); 423 response_message.size()) == response_message.size();
354 } 424 }
355 425
356 bool WebSocketHandshakeResponseHandler::ParseResponseHeaderBlock( 426 bool WebSocketHandshakeResponseHandler::ParseResponseHeaderBlock(
357 const spdy::SpdyHeaderBlock& headers, 427 const spdy::SpdyHeaderBlock& headers,
358 const std::string& challenge) { 428 const std::string& challenge) {
359 std::string response_message; 429 std::string response_message;
360 response_message = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"; 430 if (expect_hybi04_handshake_) {
361 response_message += "Upgrade: WebSocket\r\n"; 431 response_message = "HTTP/1.1 101 Switching Protocols\r\n";
432 response_message += "Upgrade: websocket\r\n";
433 } else {
434 response_message = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
435 response_message += "Upgrade: WebSocket\r\n";
436 }
362 response_message += "Connection: Upgrade\r\n"; 437 response_message += "Connection: Upgrade\r\n";
438
439 if (expect_hybi04_handshake_) {
440 std::string hash = base::SHA1HashString(challenge + kWebSocketGuid);
441 std::string websocket_accept;
442 DCHECK(base::Base64Encode(hash, &websocket_accept));
Yuta Kitamura 2011/04/13 11:23:50 Fixed here, too.
443 response_message += "Sec-WebSocket-Accept: " + websocket_accept + "\r\n";
444 }
445
363 for (spdy::SpdyHeaderBlock::const_iterator iter = headers.begin(); 446 for (spdy::SpdyHeaderBlock::const_iterator iter = headers.begin();
364 iter != headers.end(); 447 iter != headers.end();
365 ++iter) { 448 ++iter) {
366 // For each value, if the server sends a NUL-separated list of values, 449 // For each value, if the server sends a NUL-separated list of values,
367 // we separate that back out into individual headers for each value 450 // we separate that back out into individual headers for each value
368 // in the list. 451 // in the list.
369 const std::string& value = iter->second; 452 const std::string& value = iter->second;
370 size_t start = 0; 453 size_t start = 0;
371 size_t end = 0; 454 size_t end = 0;
372 do { 455 do {
373 end = value.find('\0', start); 456 end = value.find('\0', start);
374 std::string tval; 457 std::string tval;
375 if (end != std::string::npos) 458 if (end != std::string::npos)
376 tval = value.substr(start, (end - start)); 459 tval = value.substr(start, (end - start));
377 else 460 else
378 tval = value.substr(start); 461 tval = value.substr(start);
379 response_message += iter->first + ": " + tval + "\r\n"; 462 response_message += iter->first + ": " + tval + "\r\n";
380 start = end + 1; 463 start = end + 1;
381 } while (end != std::string::npos); 464 } while (end != std::string::npos);
382 } 465 }
383 response_message += "\r\n"; 466 response_message += "\r\n";
384 467
385 MD5Digest digest; 468 if (!expect_hybi04_handshake_) {
386 MD5Sum(challenge.data(), challenge.size(), &digest); 469 MD5Digest digest;
470 MD5Sum(challenge.data(), challenge.size(), &digest);
387 471
388 const char* digest_data = reinterpret_cast<char*>(digest.a); 472 const char* digest_data = reinterpret_cast<char*>(digest.a);
389 response_message.append(digest_data, sizeof(digest.a)); 473 response_message.append(digest_data, sizeof(digest.a));
474 }
390 475
391 return ParseRawResponse(response_message.data(), 476 return ParseRawResponse(response_message.data(),
392 response_message.size()) == response_message.size(); 477 response_message.size()) == response_message.size();
393 } 478 }
394 479
395 void WebSocketHandshakeResponseHandler::GetHeaders( 480 void WebSocketHandshakeResponseHandler::GetHeaders(
396 const char* const headers_to_get[], 481 const char* const headers_to_get[],
397 size_t headers_to_get_len, 482 size_t headers_to_get_len,
398 std::vector<std::string>* values) { 483 std::vector<std::string>* values) {
399 DCHECK(HasResponse()); 484 DCHECK(HasResponse());
400 DCHECK(!status_line_.empty()); 485 DCHECK(!status_line_.empty());
401 DCHECK(!headers_.empty()); 486 DCHECK(!headers_.empty());
402 DCHECK_EQ(kResponseKeySize, key_.size()); 487 DCHECK_EQ(GetResponseKeySize(), key_.size());
403 488
404 FetchHeaders(headers_, headers_to_get, headers_to_get_len, values); 489 FetchHeaders(headers_, headers_to_get, headers_to_get_len, values);
405 } 490 }
406 491
407 void WebSocketHandshakeResponseHandler::RemoveHeaders( 492 void WebSocketHandshakeResponseHandler::RemoveHeaders(
408 const char* const headers_to_remove[], 493 const char* const headers_to_remove[],
409 size_t headers_to_remove_len) { 494 size_t headers_to_remove_len) {
410 DCHECK(HasResponse()); 495 DCHECK(HasResponse());
411 DCHECK(!status_line_.empty()); 496 DCHECK(!status_line_.empty());
412 DCHECK(!headers_.empty()); 497 DCHECK(!headers_.empty());
413 DCHECK_EQ(kResponseKeySize, key_.size()); 498 DCHECK_EQ(GetResponseKeySize(), key_.size());
414 499
415 headers_ = FilterHeaders(headers_, headers_to_remove, headers_to_remove_len); 500 headers_ = FilterHeaders(headers_, headers_to_remove, headers_to_remove_len);
416 } 501 }
417 502
418 std::string WebSocketHandshakeResponseHandler::GetRawResponse() const { 503 std::string WebSocketHandshakeResponseHandler::GetRawResponse() const {
419 DCHECK(HasResponse()); 504 DCHECK(HasResponse());
420 return std::string(original_.data(), 505 return std::string(original_.data(),
421 original_header_length_ + kResponseKeySize); 506 original_header_length_ + GetResponseKeySize());
422 } 507 }
423 508
424 std::string WebSocketHandshakeResponseHandler::GetResponse() { 509 std::string WebSocketHandshakeResponseHandler::GetResponse() {
425 DCHECK(HasResponse()); 510 DCHECK(HasResponse());
426 DCHECK(!status_line_.empty()); 511 DCHECK(!status_line_.empty());
427 // headers_ might be empty for wrong response from server. 512 // headers_ might be empty for wrong response from server.
428 DCHECK_EQ(kResponseKeySize, key_.size()); 513 DCHECK_EQ(GetResponseKeySize(), key_.size());
429 514
430 return status_line_ + headers_ + header_separator_ + key_; 515 return status_line_ + headers_ + header_separator_ + key_;
431 } 516 }
432 517
518 size_t WebSocketHandshakeResponseHandler::GetResponseKeySize() const {
519 return expect_hybi04_handshake_ ? 0 : kResponseKeySize;
520 }
521
433 } // namespace net 522 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698