OLD | NEW |
1 // Copyright (c) 2011 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/socket/web_socket_server_socket.h" | 5 #include "net/socket/web_socket_server_socket.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <limits> | 9 #include <limits> |
10 #include <map> | 10 #include <map> |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 DCHECK(transport_socket); | 128 DCHECK(transport_socket); |
129 DCHECK(delegate); | 129 DCHECK(delegate); |
130 } | 130 } |
131 | 131 |
132 virtual ~WebSocketServerSocketImpl() { | 132 virtual ~WebSocketServerSocketImpl() { |
133 std::deque<PendingReq>::iterator it = GetPendingReq(PendingReq::TYPE_READ); | 133 std::deque<PendingReq>::iterator it = GetPendingReq(PendingReq::TYPE_READ); |
134 if (it != pending_reqs_.end() && | 134 if (it != pending_reqs_.end() && |
135 it->type == PendingReq::TYPE_READ && | 135 it->type == PendingReq::TYPE_READ && |
136 it->io_buf != NULL && | 136 it->io_buf != NULL && |
137 it->io_buf->data() != NULL && | 137 it->io_buf->data() != NULL && |
138 it->callback != 0) { | 138 (it->old_callback || !it->callback.is_null())) { |
139 it->callback->Run(0); // Report EOF. | 139 if (it->old_callback) |
| 140 it->old_callback->Run(0); // Report EOF. |
| 141 else |
| 142 it->callback.Run(0); |
140 } | 143 } |
141 } | 144 } |
142 | 145 |
143 private: | 146 private: |
144 enum Phase { | 147 enum Phase { |
145 // Before Accept() is called. | 148 // Before Accept() is called. |
146 PHASE_NYMPH, | 149 PHASE_NYMPH, |
147 | 150 |
148 // After Accept() is called and until handshake success/fail. | 151 // After Accept() is called and until handshake success/fail. |
149 PHASE_HANDSHAKE, | 152 PHASE_HANDSHAKE, |
(...skipping 18 matching lines...) Expand all Loading... |
168 TYPE_WRITE = 1 << 2, | 171 TYPE_WRITE = 1 << 2, |
169 | 172 |
170 TYPE_READ_METADATA = TYPE_READ | TYPE_METADATA, | 173 TYPE_READ_METADATA = TYPE_READ | TYPE_METADATA, |
171 TYPE_WRITE_METADATA = TYPE_WRITE | TYPE_METADATA | 174 TYPE_WRITE_METADATA = TYPE_WRITE | TYPE_METADATA |
172 }; | 175 }; |
173 | 176 |
174 PendingReq(Type type, net::DrainableIOBuffer* io_buf, | 177 PendingReq(Type type, net::DrainableIOBuffer* io_buf, |
175 net::OldCompletionCallback* callback) | 178 net::OldCompletionCallback* callback) |
176 : type(type), | 179 : type(type), |
177 io_buf(io_buf), | 180 io_buf(io_buf), |
| 181 old_callback(callback) { |
| 182 switch (type) { |
| 183 case PendingReq::TYPE_READ: |
| 184 case PendingReq::TYPE_WRITE: |
| 185 case PendingReq::TYPE_READ_METADATA: |
| 186 case PendingReq::TYPE_WRITE_METADATA: { |
| 187 DCHECK(io_buf); |
| 188 break; |
| 189 } |
| 190 default: { |
| 191 NOTREACHED(); |
| 192 break; |
| 193 } |
| 194 } |
| 195 } |
| 196 PendingReq(Type type, net::DrainableIOBuffer* io_buf, |
| 197 const net::CompletionCallback& callback) |
| 198 : type(type), |
| 199 io_buf(io_buf), |
| 200 old_callback(NULL), |
178 callback(callback) { | 201 callback(callback) { |
179 switch (type) { | 202 switch (type) { |
180 case PendingReq::TYPE_READ: | 203 case PendingReq::TYPE_READ: |
181 case PendingReq::TYPE_WRITE: | 204 case PendingReq::TYPE_WRITE: |
182 case PendingReq::TYPE_READ_METADATA: | 205 case PendingReq::TYPE_READ_METADATA: |
183 case PendingReq::TYPE_WRITE_METADATA: { | 206 case PendingReq::TYPE_WRITE_METADATA: { |
184 DCHECK(io_buf); | 207 DCHECK(io_buf); |
185 break; | 208 break; |
186 } | 209 } |
187 default: { | 210 default: { |
188 NOTREACHED(); | 211 NOTREACHED(); |
189 break; | 212 break; |
190 } | 213 } |
191 } | 214 } |
192 } | 215 } |
193 | 216 |
194 Type type; | 217 Type type; |
195 scoped_refptr<net::DrainableIOBuffer> io_buf; | 218 scoped_refptr<net::DrainableIOBuffer> io_buf; |
196 net::OldCompletionCallback* callback; | 219 net::OldCompletionCallback* old_callback; |
| 220 net::CompletionCallback callback; |
197 }; | 221 }; |
198 | 222 |
199 // Socket implementation. | 223 // Socket implementation. |
200 virtual int Read(net::IOBuffer* buf, int buf_len, | 224 virtual int Read(net::IOBuffer* buf, int buf_len, |
201 net::OldCompletionCallback* callback) OVERRIDE { | 225 net::OldCompletionCallback* callback) OVERRIDE { |
202 if (buf_len == 0) | 226 if (buf_len == 0) |
203 return 0; | 227 return 0; |
204 if (buf == NULL || buf_len < 0) { | 228 if (buf == NULL || buf_len < 0) { |
205 NOTREACHED(); | 229 NOTREACHED(); |
206 return net::ERR_INVALID_ARGUMENT; | 230 return net::ERR_INVALID_ARGUMENT; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 } | 278 } |
255 case PHASE_NYMPH: | 279 case PHASE_NYMPH: |
256 case PHASE_HANDSHAKE: | 280 case PHASE_HANDSHAKE: |
257 default: { | 281 default: { |
258 NOTREACHED(); | 282 NOTREACHED(); |
259 return net::ERR_UNEXPECTED; | 283 return net::ERR_UNEXPECTED; |
260 } | 284 } |
261 } | 285 } |
262 return net::ERR_IO_PENDING; | 286 return net::ERR_IO_PENDING; |
263 } | 287 } |
| 288 virtual int Read(net::IOBuffer* buf, int buf_len, |
| 289 const net::CompletionCallback& callback) OVERRIDE { |
| 290 if (buf_len == 0) |
| 291 return 0; |
| 292 if (buf == NULL || buf_len < 0) { |
| 293 NOTREACHED(); |
| 294 return net::ERR_INVALID_ARGUMENT; |
| 295 } |
| 296 while (int bytes_remaining = fill_handshake_buf_->BytesConsumed() - |
| 297 process_handshake_buf_->BytesConsumed()) { |
| 298 DCHECK(!is_transport_read_pending_); |
| 299 DCHECK(GetPendingReq(PendingReq::TYPE_READ) == pending_reqs_.end()); |
| 300 switch (phase_) { |
| 301 case PHASE_FRAME_OUTSIDE: |
| 302 case PHASE_FRAME_INSIDE: |
| 303 case PHASE_FRAME_LENGTH: |
| 304 case PHASE_FRAME_SKIP: { |
| 305 int n = std::min(bytes_remaining, buf_len); |
| 306 int rv = ProcessDataFrames( |
| 307 process_handshake_buf_->data(), n, buf->data(), buf_len); |
| 308 process_handshake_buf_->DidConsume(n); |
| 309 if (rv == 0) { |
| 310 // ProcessDataFrames may return zero for non-empty buffer if it |
| 311 // contains only frame delimiters without real data. In this case: |
| 312 // try again and do not just return zero (zero stands for EOF). |
| 313 continue; |
| 314 } |
| 315 return rv; |
| 316 } |
| 317 case PHASE_SHUT: { |
| 318 return 0; |
| 319 } |
| 320 case PHASE_NYMPH: |
| 321 case PHASE_HANDSHAKE: |
| 322 default: { |
| 323 NOTREACHED(); |
| 324 return net::ERR_UNEXPECTED; |
| 325 } |
| 326 } |
| 327 } |
| 328 switch (phase_) { |
| 329 case PHASE_FRAME_OUTSIDE: |
| 330 case PHASE_FRAME_INSIDE: |
| 331 case PHASE_FRAME_LENGTH: |
| 332 case PHASE_FRAME_SKIP: { |
| 333 pending_reqs_.push_back(PendingReq( |
| 334 PendingReq::TYPE_READ, |
| 335 new net::DrainableIOBuffer(buf, buf_len), |
| 336 callback)); |
| 337 ConsiderTransportRead(); |
| 338 break; |
| 339 } |
| 340 case PHASE_SHUT: { |
| 341 return 0; |
| 342 } |
| 343 case PHASE_NYMPH: |
| 344 case PHASE_HANDSHAKE: |
| 345 default: { |
| 346 NOTREACHED(); |
| 347 return net::ERR_UNEXPECTED; |
| 348 } |
| 349 } |
| 350 return net::ERR_IO_PENDING; |
| 351 } |
264 | 352 |
265 virtual int Write(net::IOBuffer* buf, int buf_len, | 353 virtual int Write(net::IOBuffer* buf, int buf_len, |
266 net::OldCompletionCallback* callback) OVERRIDE { | 354 net::OldCompletionCallback* callback) OVERRIDE { |
267 if (buf_len == 0) | 355 if (buf_len == 0) |
268 return 0; | 356 return 0; |
269 if (buf == NULL || buf_len < 0) { | 357 if (buf == NULL || buf_len < 0) { |
270 NOTREACHED(); | 358 NOTREACHED(); |
271 return net::ERR_INVALID_ARGUMENT; | 359 return net::ERR_INVALID_ARGUMENT; |
272 } | 360 } |
273 DCHECK_EQ(std::find(buf->data(), buf->data() + buf_len, '\xff'), | 361 DCHECK_EQ(std::find(buf->data(), buf->data() + buf_len, '\xff'), |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 &WebSocketServerSocketImpl::OnWrite, rv)); | 478 &WebSocketServerSocketImpl::OnWrite, rv)); |
391 } | 479 } |
392 } | 480 } |
393 | 481 |
394 void Shut(int result) { | 482 void Shut(int result) { |
395 if (result > 0 || result == net::ERR_IO_PENDING) | 483 if (result > 0 || result == net::ERR_IO_PENDING) |
396 result = net::ERR_UNEXPECTED; | 484 result = net::ERR_UNEXPECTED; |
397 if (result != 0) { | 485 if (result != 0) { |
398 while (!pending_reqs_.empty()) { | 486 while (!pending_reqs_.empty()) { |
399 PendingReq& req = pending_reqs_.front(); | 487 PendingReq& req = pending_reqs_.front(); |
400 if (req.callback) | 488 if (req.old_callback) |
401 req.callback->Run(result); | 489 req.old_callback->Run(result); |
| 490 else if (!req.callback.is_null()) |
| 491 req.callback.Run(result); |
402 pending_reqs_.pop_front(); | 492 pending_reqs_.pop_front(); |
403 } | 493 } |
404 transport_socket_.reset(); // terminate underlying connection. | 494 transport_socket_.reset(); // terminate underlying connection. |
405 } | 495 } |
406 phase_ = PHASE_SHUT; | 496 phase_ = PHASE_SHUT; |
407 } | 497 } |
408 | 498 |
409 // Callbacks for transport socket. | 499 // Callbacks for transport socket. |
410 void OnRead(int result) { | 500 void OnRead(int result) { |
411 if (!is_transport_read_pending_) { | 501 if (!is_transport_read_pending_) { |
(...skipping 28 matching lines...) Expand all Loading... |
440 NOTREACHED(); | 530 NOTREACHED(); |
441 Shut(net::ERR_UNEXPECTED); | 531 Shut(net::ERR_UNEXPECTED); |
442 return; | 532 return; |
443 } | 533 } |
444 fill_handshake_buf_->DidConsume(result); | 534 fill_handshake_buf_->DidConsume(result); |
445 // ProcessHandshake invalidates iterators for |pending_reqs_| | 535 // ProcessHandshake invalidates iterators for |pending_reqs_| |
446 int rv = ProcessHandshake(); | 536 int rv = ProcessHandshake(); |
447 if (rv > 0) { | 537 if (rv > 0) { |
448 process_handshake_buf_->DidConsume(rv); | 538 process_handshake_buf_->DidConsume(rv); |
449 phase_ = PHASE_FRAME_OUTSIDE; | 539 phase_ = PHASE_FRAME_OUTSIDE; |
450 net::OldCompletionCallback* cb = pending_reqs_.front().callback; | 540 net::OldCompletionCallback* old_cb = |
| 541 pending_reqs_.front().old_callback; |
| 542 net::CompletionCallback cb = pending_reqs_.front().callback; |
451 pending_reqs_.pop_front(); | 543 pending_reqs_.pop_front(); |
452 ConsiderTransportWrite(); // Schedule answer handshake. | 544 ConsiderTransportWrite(); // Schedule answer handshake. |
453 if (cb) | 545 if (old_cb) |
454 cb->Run(0); | 546 old_cb->Run(0); |
| 547 else if (!cb.is_null()) |
| 548 cb.Run(0); |
455 } else if (rv == net::ERR_IO_PENDING) { | 549 } else if (rv == net::ERR_IO_PENDING) { |
456 if (fill_handshake_buf_->BytesRemaining() < 1) | 550 if (fill_handshake_buf_->BytesRemaining() < 1) |
457 Shut(net::ERR_LIMIT_VIOLATION); | 551 Shut(net::ERR_LIMIT_VIOLATION); |
458 } else if (rv < 0) { | 552 } else if (rv < 0) { |
459 Shut(rv); | 553 Shut(rv); |
460 } else { | 554 } else { |
461 Shut(net::ERR_UNEXPECTED); | 555 Shut(net::ERR_UNEXPECTED); |
462 } | 556 } |
463 break; | 557 break; |
464 } | 558 } |
465 case PHASE_FRAME_OUTSIDE: | 559 case PHASE_FRAME_OUTSIDE: |
466 case PHASE_FRAME_INSIDE: | 560 case PHASE_FRAME_INSIDE: |
467 case PHASE_FRAME_LENGTH: | 561 case PHASE_FRAME_LENGTH: |
468 case PHASE_FRAME_SKIP: { | 562 case PHASE_FRAME_SKIP: { |
469 int rv = ProcessDataFrames( | 563 int rv = ProcessDataFrames( |
470 it->io_buf->data(), result, | 564 it->io_buf->data(), result, |
471 it->io_buf->data(), it->io_buf->BytesRemaining()); | 565 it->io_buf->data(), it->io_buf->BytesRemaining()); |
472 if (rv < 0) { | 566 if (rv < 0) { |
473 Shut(rv); | 567 Shut(rv); |
474 return; | 568 return; |
475 } | 569 } |
476 if (rv > 0 || phase_ == PHASE_SHUT) { | 570 if (rv > 0 || phase_ == PHASE_SHUT) { |
477 net::OldCompletionCallback* cb = it->callback; | 571 net::OldCompletionCallback* old_cb = it->old_callback; |
| 572 net::CompletionCallback cb = it->callback; |
478 pending_reqs_.erase(it); | 573 pending_reqs_.erase(it); |
479 if (cb) | 574 if (old_cb) |
480 cb->Run(rv); | 575 old_cb->Run(rv); |
| 576 else if (!cb.is_null()) |
| 577 cb.Run(rv); |
481 } | 578 } |
482 break; | 579 break; |
483 } | 580 } |
484 case PHASE_NYMPH: | 581 case PHASE_NYMPH: |
485 default: { | 582 default: { |
486 NOTREACHED(); | 583 NOTREACHED(); |
487 Shut(net::ERR_UNEXPECTED); | 584 Shut(net::ERR_UNEXPECTED); |
488 break; | 585 break; |
489 } | 586 } |
490 } | 587 } |
(...skipping 17 matching lines...) Expand all Loading... |
508 if (it == pending_reqs_.end() || | 605 if (it == pending_reqs_.end() || |
509 it->io_buf == NULL || | 606 it->io_buf == NULL || |
510 it->io_buf->data() == NULL) { | 607 it->io_buf->data() == NULL) { |
511 NOTREACHED(); | 608 NOTREACHED(); |
512 Shut(net::ERR_UNEXPECTED); | 609 Shut(net::ERR_UNEXPECTED); |
513 return; | 610 return; |
514 } | 611 } |
515 DCHECK_LE(result, it->io_buf->BytesRemaining()); | 612 DCHECK_LE(result, it->io_buf->BytesRemaining()); |
516 it->io_buf->DidConsume(result); | 613 it->io_buf->DidConsume(result); |
517 if (it->io_buf->BytesRemaining() == 0) { | 614 if (it->io_buf->BytesRemaining() == 0) { |
518 net::OldCompletionCallback* cb = it->callback; | 615 net::OldCompletionCallback* old_cb = it->old_callback; |
| 616 net::CompletionCallback cb = it->callback; |
519 int bytes_written = it->io_buf->BytesConsumed(); | 617 int bytes_written = it->io_buf->BytesConsumed(); |
520 DCHECK_GT(bytes_written, 0); | 618 DCHECK_GT(bytes_written, 0); |
521 pending_reqs_.erase(it); | 619 pending_reqs_.erase(it); |
522 if (cb) | 620 if (old_cb) |
523 cb->Run(bytes_written); | 621 old_cb->Run(bytes_written); |
| 622 else if (!cb.is_null()) |
| 623 cb.Run(bytes_written); |
524 } | 624 } |
525 ConsiderTransportWrite(); | 625 ConsiderTransportWrite(); |
526 } | 626 } |
527 | 627 |
528 // Returns (positive) number of consumed bytes on success. | 628 // Returns (positive) number of consumed bytes on success. |
529 // Returns ERR_IO_PENDING in case of incomplete input. | 629 // Returns ERR_IO_PENDING in case of incomplete input. |
530 // Returns ERR_WS_PROTOCOL_ERROR or ERR_LIMIT_VIOLATION in case of failure to | 630 // Returns ERR_WS_PROTOCOL_ERROR or ERR_LIMIT_VIOLATION in case of failure to |
531 // reasonably parse input. | 631 // reasonably parse input. |
532 int ProcessHandshake() { | 632 int ProcessHandshake() { |
533 static const char kGetPrefix[] = "GET "; | 633 static const char kGetPrefix[] = "GET "; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 | 996 |
897 WebSocketServerSocket* CreateWebSocketServerSocket( | 997 WebSocketServerSocket* CreateWebSocketServerSocket( |
898 Socket* transport_socket, WebSocketServerSocket::Delegate* delegate) { | 998 Socket* transport_socket, WebSocketServerSocket::Delegate* delegate) { |
899 return new WebSocketServerSocketImpl(transport_socket, delegate); | 999 return new WebSocketServerSocketImpl(transport_socket, delegate); |
900 } | 1000 } |
901 | 1001 |
902 WebSocketServerSocket::~WebSocketServerSocket() { | 1002 WebSocketServerSocket::~WebSocketServerSocket() { |
903 } | 1003 } |
904 | 1004 |
905 } // namespace net; | 1005 } // namespace net; |
OLD | NEW |