| 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 |