OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_job.h" | 5 #include "net/websockets/websocket_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "net/websockets/websocket_handshake_handler.h" | 21 #include "net/websockets/websocket_handshake_handler.h" |
22 #include "net/websockets/websocket_net_log_params.h" | 22 #include "net/websockets/websocket_net_log_params.h" |
23 #include "net/websockets/websocket_throttle.h" | 23 #include "net/websockets/websocket_throttle.h" |
24 #include "url/gurl.h" | 24 #include "url/gurl.h" |
25 | 25 |
26 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. | 26 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 // lower-case header names. | 30 // lower-case header names. |
31 const char* const kCookieHeaders[] = { | 31 const char* const kCookieHeaders[] = {"cookie", "cookie2"}; |
32 "cookie", "cookie2" | 32 const char* const kSetCookieHeaders[] = {"set-cookie", "set-cookie2"}; |
33 }; | |
34 const char* const kSetCookieHeaders[] = { | |
35 "set-cookie", "set-cookie2" | |
36 }; | |
37 | 33 |
38 net::SocketStreamJob* WebSocketJobFactory( | 34 net::SocketStreamJob* WebSocketJobFactory(const GURL& url, |
39 const GURL& url, net::SocketStream::Delegate* delegate, | 35 net::SocketStream::Delegate* delegate, |
40 net::URLRequestContext* context, net::CookieStore* cookie_store) { | 36 net::URLRequestContext* context, |
| 37 net::CookieStore* cookie_store) { |
41 net::WebSocketJob* job = new net::WebSocketJob(delegate); | 38 net::WebSocketJob* job = new net::WebSocketJob(delegate); |
42 job->InitSocketStream(new net::SocketStream(url, job, context, cookie_store)); | 39 job->InitSocketStream(new net::SocketStream(url, job, context, cookie_store)); |
43 return job; | 40 return job; |
44 } | 41 } |
45 | 42 |
46 class WebSocketJobInitSingleton { | 43 class WebSocketJobInitSingleton { |
47 private: | 44 private: |
48 friend struct base::DefaultLazyInstanceTraits<WebSocketJobInitSingleton>; | 45 friend struct base::DefaultLazyInstanceTraits<WebSocketJobInitSingleton>; |
49 WebSocketJobInitSingleton() { | 46 WebSocketJobInitSingleton() { |
50 net::SocketStreamJob::RegisterProtocolFactory("ws", WebSocketJobFactory); | 47 net::SocketStreamJob::RegisterProtocolFactory("ws", WebSocketJobFactory); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } | 98 } |
102 | 99 |
103 bool WebSocketJob::SendData(const char* data, int len) { | 100 bool WebSocketJob::SendData(const char* data, int len) { |
104 switch (state_) { | 101 switch (state_) { |
105 case INITIALIZED: | 102 case INITIALIZED: |
106 return false; | 103 return false; |
107 | 104 |
108 case CONNECTING: | 105 case CONNECTING: |
109 return SendHandshakeRequest(data, len); | 106 return SendHandshakeRequest(data, len); |
110 | 107 |
111 case OPEN: | 108 case OPEN: { |
112 { | 109 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(len); |
113 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(len); | 110 memcpy(buffer->data(), data, len); |
114 memcpy(buffer->data(), data, len); | 111 if (current_send_buffer_.get() || !send_buffer_queue_.empty()) { |
115 if (current_send_buffer_.get() || !send_buffer_queue_.empty()) { | 112 send_buffer_queue_.push_back(buffer); |
116 send_buffer_queue_.push_back(buffer); | 113 return true; |
117 return true; | |
118 } | |
119 current_send_buffer_ = new DrainableIOBuffer(buffer.get(), len); | |
120 return SendDataInternal(current_send_buffer_->data(), | |
121 current_send_buffer_->BytesRemaining()); | |
122 } | 114 } |
| 115 current_send_buffer_ = new DrainableIOBuffer(buffer.get(), len); |
| 116 return SendDataInternal(current_send_buffer_->data(), |
| 117 current_send_buffer_->BytesRemaining()); |
| 118 } |
123 | 119 |
124 case CLOSING: | 120 case CLOSING: |
125 case CLOSED: | 121 case CLOSED: |
126 return false; | 122 return false; |
127 } | 123 } |
128 return false; | 124 return false; |
129 } | 125 } |
130 | 126 |
131 void WebSocketJob::Close() { | 127 void WebSocketJob::Close() { |
132 if (state_ == CLOSED) | 128 if (state_ == CLOSED) |
(...skipping 25 matching lines...) Expand all Loading... |
158 if (socket_.get()) | 154 if (socket_.get()) |
159 socket_->DetachDelegate(); | 155 socket_->DetachDelegate(); |
160 socket_ = NULL; | 156 socket_ = NULL; |
161 if (!callback_.is_null()) { | 157 if (!callback_.is_null()) { |
162 waiting_ = false; | 158 waiting_ = false; |
163 callback_.Reset(); | 159 callback_.Reset(); |
164 Release(); // Balanced with OnStartOpenConnection(). | 160 Release(); // Balanced with OnStartOpenConnection(). |
165 } | 161 } |
166 } | 162 } |
167 | 163 |
168 int WebSocketJob::OnStartOpenConnection( | 164 int WebSocketJob::OnStartOpenConnection(SocketStream* socket, |
169 SocketStream* socket, const CompletionCallback& callback) { | 165 const CompletionCallback& callback) { |
170 DCHECK(callback_.is_null()); | 166 DCHECK(callback_.is_null()); |
171 state_ = CONNECTING; | 167 state_ = CONNECTING; |
172 | 168 |
173 addresses_ = socket->address_list(); | 169 addresses_ = socket->address_list(); |
174 if (!WebSocketThrottle::GetInstance()->PutInQueue(this)) { | 170 if (!WebSocketThrottle::GetInstance()->PutInQueue(this)) { |
175 return ERR_WS_THROTTLE_QUEUE_TOO_LARGE; | 171 return ERR_WS_THROTTLE_QUEUE_TOO_LARGE; |
176 } | 172 } |
177 | 173 |
178 if (delegate_) { | 174 if (delegate_) { |
179 int result = delegate_->OnStartOpenConnection(socket, callback); | 175 int result = delegate_->OnStartOpenConnection(socket, callback); |
180 DCHECK_EQ(OK, result); | 176 DCHECK_EQ(OK, result); |
181 } | 177 } |
182 if (waiting_) { | 178 if (waiting_) { |
183 // PutInQueue() may set |waiting_| true for throttling. In this case, | 179 // PutInQueue() may set |waiting_| true for throttling. In this case, |
184 // Wakeup() will be called later. | 180 // Wakeup() will be called later. |
185 callback_ = callback; | 181 callback_ = callback; |
186 AddRef(); // Balanced when callback_ is cleared. | 182 AddRef(); // Balanced when callback_ is cleared. |
187 return ERR_IO_PENDING; | 183 return ERR_IO_PENDING; |
188 } | 184 } |
189 return TrySpdyStream(); | 185 return TrySpdyStream(); |
190 } | 186 } |
191 | 187 |
192 void WebSocketJob::OnConnected( | 188 void WebSocketJob::OnConnected(SocketStream* socket, |
193 SocketStream* socket, int max_pending_send_allowed) { | 189 int max_pending_send_allowed) { |
194 if (state_ == CLOSED) | 190 if (state_ == CLOSED) |
195 return; | 191 return; |
196 DCHECK_EQ(CONNECTING, state_); | 192 DCHECK_EQ(CONNECTING, state_); |
197 if (delegate_) | 193 if (delegate_) |
198 delegate_->OnConnected(socket, max_pending_send_allowed); | 194 delegate_->OnConnected(socket, max_pending_send_allowed); |
199 } | 195 } |
200 | 196 |
201 void WebSocketJob::OnSentData(SocketStream* socket, int amount_sent) { | 197 void WebSocketJob::OnSentData(SocketStream* socket, int amount_sent) { |
202 DCHECK_NE(INITIALIZED, state_); | 198 DCHECK_NE(INITIALIZED, state_); |
203 DCHECK_GT(amount_sent, 0); | 199 DCHECK_GT(amount_sent, 0); |
204 if (state_ == CLOSED) | 200 if (state_ == CLOSED) |
205 return; | 201 return; |
206 if (state_ == CONNECTING) { | 202 if (state_ == CONNECTING) { |
207 OnSentHandshakeRequest(socket, amount_sent); | 203 OnSentHandshakeRequest(socket, amount_sent); |
208 return; | 204 return; |
209 } | 205 } |
210 if (delegate_) { | 206 if (delegate_) { |
211 DCHECK(state_ == OPEN || state_ == CLOSING); | 207 DCHECK(state_ == OPEN || state_ == CLOSING); |
212 if (!current_send_buffer_.get()) { | 208 if (!current_send_buffer_.get()) { |
213 VLOG(1) | 209 VLOG(1) << "OnSentData current_send_buffer=NULL amount_sent=" |
214 << "OnSentData current_send_buffer=NULL amount_sent=" << amount_sent; | 210 << amount_sent; |
215 return; | 211 return; |
216 } | 212 } |
217 current_send_buffer_->DidConsume(amount_sent); | 213 current_send_buffer_->DidConsume(amount_sent); |
218 if (current_send_buffer_->BytesRemaining() > 0) | 214 if (current_send_buffer_->BytesRemaining() > 0) |
219 return; | 215 return; |
220 | 216 |
221 // We need to report amount_sent of original buffer size, instead of | 217 // We need to report amount_sent of original buffer size, instead of |
222 // amount sent to |socket|. | 218 // amount sent to |socket|. |
223 amount_sent = current_send_buffer_->size(); | 219 amount_sent = current_send_buffer_->size(); |
224 DCHECK_GT(amount_sent, 0); | 220 DCHECK_GT(amount_sent, 0); |
225 current_send_buffer_ = NULL; | 221 current_send_buffer_ = NULL; |
226 if (!weak_ptr_factory_for_send_pending_.HasWeakPtrs()) { | 222 if (!weak_ptr_factory_for_send_pending_.HasWeakPtrs()) { |
227 base::MessageLoopForIO::current()->PostTask( | 223 base::MessageLoopForIO::current()->PostTask( |
228 FROM_HERE, | 224 FROM_HERE, |
229 base::Bind(&WebSocketJob::SendPending, | 225 base::Bind(&WebSocketJob::SendPending, |
230 weak_ptr_factory_for_send_pending_.GetWeakPtr())); | 226 weak_ptr_factory_for_send_pending_.GetWeakPtr())); |
231 } | 227 } |
232 delegate_->OnSentData(socket, amount_sent); | 228 delegate_->OnSentData(socket, amount_sent); |
233 } | 229 } |
234 } | 230 } |
235 | 231 |
236 void WebSocketJob::OnReceivedData( | 232 void WebSocketJob::OnReceivedData(SocketStream* socket, |
237 SocketStream* socket, const char* data, int len) { | 233 const char* data, |
| 234 int len) { |
238 DCHECK_NE(INITIALIZED, state_); | 235 DCHECK_NE(INITIALIZED, state_); |
239 if (state_ == CLOSED) | 236 if (state_ == CLOSED) |
240 return; | 237 return; |
241 if (state_ == CONNECTING) { | 238 if (state_ == CONNECTING) { |
242 OnReceivedHandshakeResponse(socket, data, len); | 239 OnReceivedHandshakeResponse(socket, data, len); |
243 return; | 240 return; |
244 } | 241 } |
245 DCHECK(state_ == OPEN || state_ == CLOSING); | 242 DCHECK(state_ == OPEN || state_ == CLOSING); |
246 if (delegate_ && len > 0) | 243 if (delegate_ && len > 0) |
247 delegate_->OnReceivedData(socket, data, len); | 244 delegate_->OnReceivedData(socket, data, len); |
(...skipping 11 matching lines...) Expand all Loading... |
259 socket_ = NULL; | 256 socket_ = NULL; |
260 if (!callback_.is_null()) { | 257 if (!callback_.is_null()) { |
261 waiting_ = false; | 258 waiting_ = false; |
262 callback_.Reset(); | 259 callback_.Reset(); |
263 Release(); // Balanced with OnStartOpenConnection(). | 260 Release(); // Balanced with OnStartOpenConnection(). |
264 } | 261 } |
265 if (delegate) | 262 if (delegate) |
266 delegate->OnClose(socket); | 263 delegate->OnClose(socket); |
267 } | 264 } |
268 | 265 |
269 void WebSocketJob::OnAuthRequired( | 266 void WebSocketJob::OnAuthRequired(SocketStream* socket, |
270 SocketStream* socket, AuthChallengeInfo* auth_info) { | 267 AuthChallengeInfo* auth_info) { |
271 if (delegate_) | 268 if (delegate_) |
272 delegate_->OnAuthRequired(socket, auth_info); | 269 delegate_->OnAuthRequired(socket, auth_info); |
273 } | 270 } |
274 | 271 |
275 void WebSocketJob::OnSSLCertificateError( | 272 void WebSocketJob::OnSSLCertificateError(SocketStream* socket, |
276 SocketStream* socket, const SSLInfo& ssl_info, bool fatal) { | 273 const SSLInfo& ssl_info, |
| 274 bool fatal) { |
277 if (delegate_) | 275 if (delegate_) |
278 delegate_->OnSSLCertificateError(socket, ssl_info, fatal); | 276 delegate_->OnSSLCertificateError(socket, ssl_info, fatal); |
279 } | 277 } |
280 | 278 |
281 void WebSocketJob::OnError(const SocketStream* socket, int error) { | 279 void WebSocketJob::OnError(const SocketStream* socket, int error) { |
282 if (delegate_ && error != ERR_PROTOCOL_SWITCHED) | 280 if (delegate_ && error != ERR_PROTOCOL_SWITCHED) |
283 delegate_->OnError(socket, error); | 281 delegate_->OnError(socket, error); |
284 } | 282 } |
285 | 283 |
286 void WebSocketJob::OnCreatedSpdyStream(int result) { | 284 void WebSocketJob::OnCreatedSpdyStream(int result) { |
(...skipping 22 matching lines...) Expand all Loading... |
309 if (delegate_) | 307 if (delegate_) |
310 delegate_->OnSentData(socket_.get(), original_length); | 308 delegate_->OnSentData(socket_.get(), original_length); |
311 } | 309 } |
312 | 310 |
313 void WebSocketJob::OnSpdyResponseHeadersUpdated( | 311 void WebSocketJob::OnSpdyResponseHeadersUpdated( |
314 const SpdyHeaderBlock& response_headers) { | 312 const SpdyHeaderBlock& response_headers) { |
315 DCHECK_NE(INITIALIZED, state_); | 313 DCHECK_NE(INITIALIZED, state_); |
316 if (state_ != CONNECTING) | 314 if (state_ != CONNECTING) |
317 return; | 315 return; |
318 // TODO(toyoshim): Fallback to non-spdy connection? | 316 // TODO(toyoshim): Fallback to non-spdy connection? |
319 handshake_response_->ParseResponseHeaderBlock(response_headers, | 317 handshake_response_->ParseResponseHeaderBlock( |
320 challenge_, | 318 response_headers, challenge_, spdy_protocol_version_); |
321 spdy_protocol_version_); | |
322 | 319 |
323 SaveCookiesAndNotifyHeadersComplete(); | 320 SaveCookiesAndNotifyHeadersComplete(); |
324 } | 321 } |
325 | 322 |
326 void WebSocketJob::OnSentSpdyData(size_t bytes_sent) { | 323 void WebSocketJob::OnSentSpdyData(size_t bytes_sent) { |
327 DCHECK_NE(INITIALIZED, state_); | 324 DCHECK_NE(INITIALIZED, state_); |
328 DCHECK_NE(CONNECTING, state_); | 325 DCHECK_NE(CONNECTING, state_); |
329 if (state_ == CLOSED) | 326 if (state_ == CLOSED) |
330 return; | 327 return; |
331 if (!spdy_websocket_stream_.get()) | 328 if (!spdy_websocket_stream_.get()) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 allow = false; | 367 allow = false; |
371 | 368 |
372 if (socket_.get() && delegate_ && state_ == CONNECTING) { | 369 if (socket_.get() && delegate_ && state_ == CONNECTING) { |
373 handshake_request_->RemoveHeaders(kCookieHeaders, | 370 handshake_request_->RemoveHeaders(kCookieHeaders, |
374 arraysize(kCookieHeaders)); | 371 arraysize(kCookieHeaders)); |
375 if (allow && socket_->cookie_store()) { | 372 if (allow && socket_->cookie_store()) { |
376 // Add cookies, including HttpOnly cookies. | 373 // Add cookies, including HttpOnly cookies. |
377 CookieOptions cookie_options; | 374 CookieOptions cookie_options; |
378 cookie_options.set_include_httponly(); | 375 cookie_options.set_include_httponly(); |
379 socket_->cookie_store()->GetCookiesWithOptionsAsync( | 376 socket_->cookie_store()->GetCookiesWithOptionsAsync( |
380 GetURLForCookies(), cookie_options, | 377 GetURLForCookies(), |
| 378 cookie_options, |
381 base::Bind(&WebSocketJob::LoadCookieCallback, | 379 base::Bind(&WebSocketJob::LoadCookieCallback, |
382 weak_ptr_factory_.GetWeakPtr())); | 380 weak_ptr_factory_.GetWeakPtr())); |
383 } else { | 381 } else { |
384 DoSendData(); | 382 DoSendData(); |
385 } | 383 } |
386 } | 384 } |
387 } | 385 } |
388 | 386 |
389 void WebSocketJob::LoadCookieCallback(const std::string& cookie) { | 387 void WebSocketJob::LoadCookieCallback(const std::string& cookie) { |
390 if (!cookie.empty()) | 388 if (!cookie.empty()) |
391 // TODO(tyoshino): Sending cookie means that connection doesn't need | 389 // TODO(tyoshino): Sending cookie means that connection doesn't need |
392 // PRIVACY_MODE_ENABLED as cookies may be server-bound and channel id | 390 // PRIVACY_MODE_ENABLED as cookies may be server-bound and channel id |
393 // wouldn't negatively affect privacy anyway. Need to restart connection | 391 // wouldn't negatively affect privacy anyway. Need to restart connection |
394 // or refactor to determine cookie status prior to connecting. | 392 // or refactor to determine cookie status prior to connecting. |
395 handshake_request_->AppendHeaderIfMissing("Cookie", cookie); | 393 handshake_request_->AppendHeaderIfMissing("Cookie", cookie); |
396 DoSendData(); | 394 DoSendData(); |
397 } | 395 } |
398 | 396 |
399 void WebSocketJob::DoSendData() { | 397 void WebSocketJob::DoSendData() { |
400 if (spdy_websocket_stream_.get()) { | 398 if (spdy_websocket_stream_.get()) { |
401 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); | 399 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
402 handshake_request_->GetRequestHeaderBlock( | 400 handshake_request_->GetRequestHeaderBlock( |
403 socket_->url(), headers.get(), &challenge_, spdy_protocol_version_); | 401 socket_->url(), headers.get(), &challenge_, spdy_protocol_version_); |
404 spdy_websocket_stream_->SendRequest(headers.Pass()); | 402 spdy_websocket_stream_->SendRequest(headers.Pass()); |
405 } else { | 403 } else { |
406 const std::string& handshake_request = | 404 const std::string& handshake_request = handshake_request_->GetRawRequest(); |
407 handshake_request_->GetRawRequest(); | |
408 handshake_request_sent_ = 0; | 405 handshake_request_sent_ = 0; |
409 socket_->net_log()->AddEvent( | 406 socket_->net_log()->AddEvent( |
410 NetLog::TYPE_WEB_SOCKET_SEND_REQUEST_HEADERS, | 407 NetLog::TYPE_WEB_SOCKET_SEND_REQUEST_HEADERS, |
411 base::Bind(&NetLogWebSocketHandshakeCallback, &handshake_request)); | 408 base::Bind(&NetLogWebSocketHandshakeCallback, &handshake_request)); |
412 socket_->SendData(handshake_request.data(), | 409 socket_->SendData(handshake_request.data(), handshake_request.size()); |
413 handshake_request.size()); | |
414 } | 410 } |
415 // Just buffered in |handshake_request_|. | 411 // Just buffered in |handshake_request_|. |
416 started_to_send_handshake_request_ = true; | 412 started_to_send_handshake_request_ = true; |
417 } | 413 } |
418 | 414 |
419 void WebSocketJob::OnSentHandshakeRequest( | 415 void WebSocketJob::OnSentHandshakeRequest(SocketStream* socket, |
420 SocketStream* socket, int amount_sent) { | 416 int amount_sent) { |
421 DCHECK_EQ(state_, CONNECTING); | 417 DCHECK_EQ(state_, CONNECTING); |
422 handshake_request_sent_ += amount_sent; | 418 handshake_request_sent_ += amount_sent; |
423 DCHECK_LE(handshake_request_sent_, handshake_request_->raw_length()); | 419 DCHECK_LE(handshake_request_sent_, handshake_request_->raw_length()); |
424 if (handshake_request_sent_ >= handshake_request_->raw_length()) { | 420 if (handshake_request_sent_ >= handshake_request_->raw_length()) { |
425 // handshake request has been sent. | 421 // handshake request has been sent. |
426 // notify original size of handshake request to delegate. | 422 // notify original size of handshake request to delegate. |
427 // Reset the handshake_request_ first in case this object is deleted by the | 423 // Reset the handshake_request_ first in case this object is deleted by the |
428 // delegate. | 424 // delegate. |
429 size_t original_length = handshake_request_->original_length(); | 425 size_t original_length = handshake_request_->original_length(); |
430 handshake_request_.reset(); | 426 handshake_request_.reset(); |
431 if (delegate_) | 427 if (delegate_) |
432 delegate_->OnSentData(socket, original_length); | 428 delegate_->OnSentData(socket, original_length); |
433 } | 429 } |
434 } | 430 } |
435 | 431 |
436 void WebSocketJob::OnReceivedHandshakeResponse( | 432 void WebSocketJob::OnReceivedHandshakeResponse(SocketStream* socket, |
437 SocketStream* socket, const char* data, int len) { | 433 const char* data, |
| 434 int len) { |
438 DCHECK_EQ(state_, CONNECTING); | 435 DCHECK_EQ(state_, CONNECTING); |
439 if (handshake_response_->HasResponse()) { | 436 if (handshake_response_->HasResponse()) { |
440 // If we already has handshake response, received data should be frame | 437 // If we already has handshake response, received data should be frame |
441 // data, not handshake message. | 438 // data, not handshake message. |
442 received_data_after_handshake_.insert( | 439 received_data_after_handshake_.insert( |
443 received_data_after_handshake_.end(), data, data + len); | 440 received_data_after_handshake_.end(), data, data + len); |
444 return; | 441 return; |
445 } | 442 } |
446 | 443 |
447 size_t response_length = handshake_response_->ParseRawResponse(data, len); | 444 size_t response_length = handshake_response_->ParseRawResponse(data, len); |
(...skipping 25 matching lines...) Expand all Loading... |
473 handshake_response_->GetHeaders( | 470 handshake_response_->GetHeaders( |
474 kSetCookieHeaders, arraysize(kSetCookieHeaders), &response_cookies_); | 471 kSetCookieHeaders, arraysize(kSetCookieHeaders), &response_cookies_); |
475 | 472 |
476 // Now, loop over the response cookies, and attempt to persist each. | 473 // Now, loop over the response cookies, and attempt to persist each. |
477 SaveNextCookie(); | 474 SaveNextCookie(); |
478 } | 475 } |
479 | 476 |
480 void WebSocketJob::NotifyHeadersComplete() { | 477 void WebSocketJob::NotifyHeadersComplete() { |
481 // Remove cookie headers, with malformed headers preserved. | 478 // Remove cookie headers, with malformed headers preserved. |
482 // Actual handshake should be done in Blink. | 479 // Actual handshake should be done in Blink. |
483 handshake_response_->RemoveHeaders( | 480 handshake_response_->RemoveHeaders(kSetCookieHeaders, |
484 kSetCookieHeaders, arraysize(kSetCookieHeaders)); | 481 arraysize(kSetCookieHeaders)); |
485 std::string handshake_response = handshake_response_->GetResponse(); | 482 std::string handshake_response = handshake_response_->GetResponse(); |
486 handshake_response_.reset(); | 483 handshake_response_.reset(); |
487 std::vector<char> received_data(handshake_response.begin(), | 484 std::vector<char> received_data(handshake_response.begin(), |
488 handshake_response.end()); | 485 handshake_response.end()); |
489 received_data.insert(received_data.end(), | 486 received_data.insert(received_data.end(), |
490 received_data_after_handshake_.begin(), | 487 received_data_after_handshake_.begin(), |
491 received_data_after_handshake_.end()); | 488 received_data_after_handshake_.end()); |
492 received_data_after_handshake_.clear(); | 489 received_data_after_handshake_.clear(); |
493 | 490 |
494 state_ = OPEN; | 491 state_ = OPEN; |
(...skipping 28 matching lines...) Expand all Loading... |
523 response_cookies_save_index_ < response_cookies_.size()) { | 520 response_cookies_save_index_ < response_cookies_.size()) { |
524 std::string cookie = response_cookies_[response_cookies_save_index_]; | 521 std::string cookie = response_cookies_[response_cookies_save_index_]; |
525 response_cookies_save_index_++; | 522 response_cookies_save_index_++; |
526 | 523 |
527 if (!delegate_->CanSetCookie( | 524 if (!delegate_->CanSetCookie( |
528 socket_.get(), url_for_cookies, cookie, &options)) | 525 socket_.get(), url_for_cookies, cookie, &options)) |
529 continue; | 526 continue; |
530 | 527 |
531 callback_pending_ = true; | 528 callback_pending_ = true; |
532 socket_->cookie_store()->SetCookieWithOptionsAsync( | 529 socket_->cookie_store()->SetCookieWithOptionsAsync( |
533 url_for_cookies, cookie, options, | 530 url_for_cookies, |
| 531 cookie, |
| 532 options, |
534 base::Bind(&WebSocketJob::OnCookieSaved, | 533 base::Bind(&WebSocketJob::OnCookieSaved, |
535 weak_ptr_factory_.GetWeakPtr())); | 534 weak_ptr_factory_.GetWeakPtr())); |
536 } | 535 } |
537 } | 536 } |
538 | 537 |
539 save_next_cookie_running_ = false; | 538 save_next_cookie_running_ = false; |
540 | 539 |
541 if (callback_pending_) | 540 if (callback_pending_) |
542 return; | 541 return; |
543 | 542 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 HttpTransactionFactory* factory = | 585 HttpTransactionFactory* factory = |
587 socket_->context()->http_transaction_factory(); | 586 socket_->context()->http_transaction_factory(); |
588 if (!factory) | 587 if (!factory) |
589 return OK; | 588 return OK; |
590 scoped_refptr<HttpNetworkSession> session = factory->GetSession(); | 589 scoped_refptr<HttpNetworkSession> session = factory->GetSession(); |
591 if (!session.get()) | 590 if (!session.get()) |
592 return OK; | 591 return OK; |
593 SpdySessionPool* spdy_pool = session->spdy_session_pool(); | 592 SpdySessionPool* spdy_pool = session->spdy_session_pool(); |
594 PrivacyMode privacy_mode = socket_->privacy_mode(); | 593 PrivacyMode privacy_mode = socket_->privacy_mode(); |
595 const SpdySessionKey key(HostPortPair::FromURL(socket_->url()), | 594 const SpdySessionKey key(HostPortPair::FromURL(socket_->url()), |
596 socket_->proxy_server(), privacy_mode); | 595 socket_->proxy_server(), |
| 596 privacy_mode); |
597 // Forbid wss downgrade to SPDY without SSL. | 597 // Forbid wss downgrade to SPDY without SSL. |
598 // TODO(toyoshim): Does it realize the same policy with HTTP? | 598 // TODO(toyoshim): Does it realize the same policy with HTTP? |
599 base::WeakPtr<SpdySession> spdy_session = | 599 base::WeakPtr<SpdySession> spdy_session = |
600 spdy_pool->FindAvailableSession(key, *socket_->net_log()); | 600 spdy_pool->FindAvailableSession(key, *socket_->net_log()); |
601 if (!spdy_session) | 601 if (!spdy_session) |
602 return OK; | 602 return OK; |
603 | 603 |
604 SSLInfo ssl_info; | 604 SSLInfo ssl_info; |
605 bool was_npn_negotiated; | 605 bool was_npn_negotiated; |
606 NextProto protocol_negotiated = kProtoUnknown; | 606 NextProto protocol_negotiated = kProtoUnknown; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 | 694 |
695 scoped_refptr<IOBufferWithSize> next_buffer = send_buffer_queue_.front(); | 695 scoped_refptr<IOBufferWithSize> next_buffer = send_buffer_queue_.front(); |
696 send_buffer_queue_.pop_front(); | 696 send_buffer_queue_.pop_front(); |
697 current_send_buffer_ = | 697 current_send_buffer_ = |
698 new DrainableIOBuffer(next_buffer.get(), next_buffer->size()); | 698 new DrainableIOBuffer(next_buffer.get(), next_buffer->size()); |
699 SendDataInternal(current_send_buffer_->data(), | 699 SendDataInternal(current_send_buffer_->data(), |
700 current_send_buffer_->BytesRemaining()); | 700 current_send_buffer_->BytesRemaining()); |
701 } | 701 } |
702 | 702 |
703 } // namespace net | 703 } // namespace net |
OLD | NEW |