OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "googleurl/src/gurl.h" | 7 #include "googleurl/src/gurl.h" |
8 #include "net/base/net_errors.h" | 8 #include "net/base/net_errors.h" |
9 #include "net/base/cookie_policy.h" | 9 #include "net/base/cookie_policy.h" |
10 #include "net/base/cookie_store.h" | 10 #include "net/base/cookie_store.h" |
11 #include "net/http/http_util.h" | 11 #include "net/http/http_util.h" |
12 #include "net/url_request/url_request_context.h" | 12 #include "net/url_request/url_request_context.h" |
| 13 #include "net/websockets/websocket_throttle.h" |
| 14 |
| 15 namespace { |
| 16 |
| 17 class CompletionCallbackRunner |
| 18 : public base::RefCountedThreadSafe<CompletionCallbackRunner> { |
| 19 public: |
| 20 explicit CompletionCallbackRunner(net::CompletionCallback* callback) |
| 21 : callback_(callback) { |
| 22 DCHECK(callback_); |
| 23 } |
| 24 void Run() { |
| 25 callback_->Run(net::OK); |
| 26 } |
| 27 private: |
| 28 friend class base::RefCountedThreadSafe<CompletionCallbackRunner>; |
| 29 |
| 30 virtual ~CompletionCallbackRunner() {} |
| 31 |
| 32 net::CompletionCallback* callback_; |
| 33 |
| 34 DISALLOW_COPY_AND_ASSIGN(CompletionCallbackRunner); |
| 35 }; |
| 36 |
| 37 } |
13 | 38 |
14 namespace net { | 39 namespace net { |
15 | 40 |
16 // lower-case header names. | 41 // lower-case header names. |
17 static const char* const kCookieHeaders[] = { | 42 static const char* const kCookieHeaders[] = { |
18 "cookie", "cookie2" | 43 "cookie", "cookie2" |
19 }; | 44 }; |
20 static const char* const kSetCookieHeaders[] = { | 45 static const char* const kSetCookieHeaders[] = { |
21 "set-cookie", "set-cookie2" | 46 "set-cookie", "set-cookie2" |
22 }; | 47 }; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 } | 93 } |
69 | 94 |
70 // static | 95 // static |
71 void WebSocketJob::EnsureInit() { | 96 void WebSocketJob::EnsureInit() { |
72 Singleton<WebSocketJobInitSingleton>::get(); | 97 Singleton<WebSocketJobInitSingleton>::get(); |
73 } | 98 } |
74 | 99 |
75 WebSocketJob::WebSocketJob(SocketStream::Delegate* delegate) | 100 WebSocketJob::WebSocketJob(SocketStream::Delegate* delegate) |
76 : delegate_(delegate), | 101 : delegate_(delegate), |
77 state_(INITIALIZED), | 102 state_(INITIALIZED), |
| 103 waiting_(false), |
| 104 callback_(NULL), |
78 handshake_request_sent_(0), | 105 handshake_request_sent_(0), |
79 handshake_response_header_length_(0), | 106 handshake_response_header_length_(0), |
80 response_cookies_save_index_(0), | 107 response_cookies_save_index_(0), |
81 ALLOW_THIS_IN_INITIALIZER_LIST(can_get_cookies_callback_( | 108 ALLOW_THIS_IN_INITIALIZER_LIST(can_get_cookies_callback_( |
82 this, &WebSocketJob::OnCanGetCookiesCompleted)), | 109 this, &WebSocketJob::OnCanGetCookiesCompleted)), |
83 ALLOW_THIS_IN_INITIALIZER_LIST(can_set_cookie_callback_( | 110 ALLOW_THIS_IN_INITIALIZER_LIST(can_set_cookie_callback_( |
84 this, &WebSocketJob::OnCanSetCookieCompleted)) { | 111 this, &WebSocketJob::OnCanSetCookieCompleted)) { |
85 } | 112 } |
86 | 113 |
87 WebSocketJob::~WebSocketJob() { | 114 WebSocketJob::~WebSocketJob() { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 148 |
122 void WebSocketJob::RestartWithAuth( | 149 void WebSocketJob::RestartWithAuth( |
123 const std::wstring& username, | 150 const std::wstring& username, |
124 const std::wstring& password) { | 151 const std::wstring& password) { |
125 state_ = CONNECTING; | 152 state_ = CONNECTING; |
126 socket_->RestartWithAuth(username, password); | 153 socket_->RestartWithAuth(username, password); |
127 } | 154 } |
128 | 155 |
129 void WebSocketJob::DetachDelegate() { | 156 void WebSocketJob::DetachDelegate() { |
130 state_ = CLOSED; | 157 state_ = CLOSED; |
| 158 Singleton<WebSocketThrottle>::get()->RemoveFromQueue(this); |
| 159 Singleton<WebSocketThrottle>::get()->WakeupSocketIfNecessary(); |
| 160 |
131 delegate_ = NULL; | 161 delegate_ = NULL; |
132 if (socket_) | 162 if (socket_) |
133 socket_->DetachDelegate(); | 163 socket_->DetachDelegate(); |
134 socket_ = NULL; | 164 socket_ = NULL; |
135 } | 165 } |
136 | 166 |
| 167 int WebSocketJob::OnStartOpenConnection( |
| 168 SocketStream* socket, CompletionCallback* callback) { |
| 169 DCHECK(!callback_); |
| 170 state_ = CONNECTING; |
| 171 addresses_.Copy(socket->address_list().head(), true); |
| 172 Singleton<WebSocketThrottle>::get()->PutInQueue(this); |
| 173 if (!waiting_) |
| 174 return OK; |
| 175 callback_ = callback; |
| 176 return ERR_IO_PENDING; |
| 177 } |
| 178 |
137 void WebSocketJob::OnConnected( | 179 void WebSocketJob::OnConnected( |
138 SocketStream* socket, int max_pending_send_allowed) { | 180 SocketStream* socket, int max_pending_send_allowed) { |
139 if (delegate_) | 181 if (delegate_) |
140 delegate_->OnConnected(socket, max_pending_send_allowed); | 182 delegate_->OnConnected(socket, max_pending_send_allowed); |
141 } | 183 } |
142 | 184 |
143 void WebSocketJob::OnSentData(SocketStream* socket, int amount_sent) { | 185 void WebSocketJob::OnSentData(SocketStream* socket, int amount_sent) { |
144 if (state_ == CONNECTING) { | 186 if (state_ == CONNECTING) { |
145 OnSentHandshakeRequest(socket, amount_sent); | 187 OnSentHandshakeRequest(socket, amount_sent); |
146 return; | 188 return; |
147 } | 189 } |
148 if (delegate_) | 190 if (delegate_) |
149 delegate_->OnSentData(socket, amount_sent); | 191 delegate_->OnSentData(socket, amount_sent); |
150 } | 192 } |
151 | 193 |
152 void WebSocketJob::OnReceivedData( | 194 void WebSocketJob::OnReceivedData( |
153 SocketStream* socket, const char* data, int len) { | 195 SocketStream* socket, const char* data, int len) { |
154 if (state_ == CONNECTING) { | 196 if (state_ == CONNECTING) { |
155 OnReceivedHandshakeResponse(socket, data, len); | 197 OnReceivedHandshakeResponse(socket, data, len); |
156 return; | 198 return; |
157 } | 199 } |
158 if (delegate_) | 200 if (delegate_) |
159 delegate_->OnReceivedData(socket, data, len); | 201 delegate_->OnReceivedData(socket, data, len); |
160 } | 202 } |
161 | 203 |
162 void WebSocketJob::OnClose(SocketStream* socket) { | 204 void WebSocketJob::OnClose(SocketStream* socket) { |
163 state_ = CLOSED; | 205 state_ = CLOSED; |
| 206 Singleton<WebSocketThrottle>::get()->RemoveFromQueue(this); |
| 207 Singleton<WebSocketThrottle>::get()->WakeupSocketIfNecessary(); |
| 208 |
164 SocketStream::Delegate* delegate = delegate_; | 209 SocketStream::Delegate* delegate = delegate_; |
165 delegate_ = NULL; | 210 delegate_ = NULL; |
166 socket_ = NULL; | 211 socket_ = NULL; |
167 if (delegate) | 212 if (delegate) |
168 delegate->OnClose(socket); | 213 delegate->OnClose(socket); |
169 } | 214 } |
170 | 215 |
171 void WebSocketJob::OnAuthRequired( | 216 void WebSocketJob::OnAuthRequired( |
172 SocketStream* socket, AuthChallengeInfo* auth_info) { | 217 SocketStream* socket, AuthChallengeInfo* auth_info) { |
173 if (delegate_) | 218 if (delegate_) |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 std::string(handshake_response_.data() + | 363 std::string(handshake_response_.data() + |
319 handshake_response_header_length_, | 364 handshake_response_header_length_, |
320 handshake_response_.size() - | 365 handshake_response_.size() - |
321 handshake_response_header_length_); | 366 handshake_response_header_length_); |
322 std::string received_data = | 367 std::string received_data = |
323 handshake_response_status_line + | 368 handshake_response_status_line + |
324 filtered_handshake_response_header + | 369 filtered_handshake_response_header + |
325 "\r\n" + | 370 "\r\n" + |
326 remaining_data; | 371 remaining_data; |
327 state_ = OPEN; | 372 state_ = OPEN; |
| 373 Singleton<WebSocketThrottle>::get()->RemoveFromQueue(this); |
| 374 Singleton<WebSocketThrottle>::get()->WakeupSocketIfNecessary(); |
| 375 |
328 if (delegate_) | 376 if (delegate_) |
329 delegate_->OnReceivedData(socket_, | 377 delegate_->OnReceivedData(socket_, |
330 received_data.data(), received_data.size()); | 378 received_data.data(), received_data.size()); |
331 return; | 379 return; |
332 } | 380 } |
333 | 381 |
334 AddRef(); // Balanced in OnCanSetCookieCompleted | 382 AddRef(); // Balanced in OnCanSetCookieCompleted |
335 | 383 |
336 int policy = OK; | 384 int policy = OK; |
337 if (socket_->context()->cookie_policy()) { | 385 if (socket_->context()->cookie_policy()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 417 |
370 GURL WebSocketJob::GetURLForCookies() const { | 418 GURL WebSocketJob::GetURLForCookies() const { |
371 GURL url = socket_->url(); | 419 GURL url = socket_->url(); |
372 std::string scheme = socket_->is_secure() ? "https" : "http"; | 420 std::string scheme = socket_->is_secure() ? "https" : "http"; |
373 url_canon::Replacements<char> replacements; | 421 url_canon::Replacements<char> replacements; |
374 replacements.SetScheme(scheme.c_str(), | 422 replacements.SetScheme(scheme.c_str(), |
375 url_parse::Component(0, scheme.length())); | 423 url_parse::Component(0, scheme.length())); |
376 return url.ReplaceComponents(replacements); | 424 return url.ReplaceComponents(replacements); |
377 } | 425 } |
378 | 426 |
| 427 const AddressList& WebSocketJob::address_list() const { |
| 428 return addresses_; |
| 429 } |
| 430 |
| 431 void WebSocketJob::SetWaiting() { |
| 432 waiting_ = true; |
| 433 } |
| 434 |
| 435 bool WebSocketJob::IsWaiting() const { |
| 436 return waiting_; |
| 437 } |
| 438 |
| 439 void WebSocketJob::Wakeup() { |
| 440 waiting_ = false; |
| 441 DCHECK(callback_); |
| 442 // We wrap |callback_| to keep this alive while this is released. |
| 443 scoped_refptr<CompletionCallbackRunner> runner = |
| 444 new CompletionCallbackRunner(callback_); |
| 445 callback_ = NULL; |
| 446 MessageLoopForIO::current()->PostTask( |
| 447 FROM_HERE, |
| 448 NewRunnableMethod(runner.get(), |
| 449 &CompletionCallbackRunner::Run)); |
| 450 } |
| 451 |
379 } // namespace net | 452 } // namespace net |
OLD | NEW |