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/spdy/spdy_http_stream.h" | 5 #include "net/spdy/spdy_http_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <list> | 8 #include <list> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 spdy_session_(spdy_session), | 31 spdy_session_(spdy_session), |
32 stream_closed_(false), | 32 stream_closed_(false), |
33 closed_stream_pushed_(false), | 33 closed_stream_pushed_(false), |
34 closed_stream_status_(ERR_FAILED), | 34 closed_stream_status_(ERR_FAILED), |
35 closed_stream_id_(0), | 35 closed_stream_id_(0), |
36 request_info_(NULL), | 36 request_info_(NULL), |
37 has_upload_data_(false), | 37 has_upload_data_(false), |
38 response_info_(NULL), | 38 response_info_(NULL), |
39 response_headers_received_(false), | 39 response_headers_received_(false), |
40 user_buffer_len_(0), | 40 user_buffer_len_(0), |
| 41 raw_request_body_buf_size_(0), |
41 buffered_read_callback_pending_(false), | 42 buffered_read_callback_pending_(false), |
42 more_read_data_pending_(false), | 43 more_read_data_pending_(false), |
43 direct_(direct) {} | 44 direct_(direct) {} |
44 | 45 |
45 void SpdyHttpStream::InitializeWithExistingStream( | 46 void SpdyHttpStream::InitializeWithExistingStream( |
46 const base::WeakPtr<SpdyStream>& spdy_stream) { | 47 const base::WeakPtr<SpdyStream>& spdy_stream) { |
47 stream_ = spdy_stream; | 48 stream_ = spdy_stream; |
48 stream_->SetDelegate(this); | 49 stream_->SetDelegate(this); |
49 response_headers_received_ = true; | 50 response_headers_received_ = true; |
50 } | 51 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 | 230 |
230 CHECK(!has_upload_data_); | 231 CHECK(!has_upload_data_); |
231 has_upload_data_ = request_info_->upload_data_stream && | 232 has_upload_data_ = request_info_->upload_data_stream && |
232 (request_info_->upload_data_stream->size() || | 233 (request_info_->upload_data_stream->size() || |
233 request_info_->upload_data_stream->is_chunked()); | 234 request_info_->upload_data_stream->is_chunked()); |
234 if (has_upload_data_) { | 235 if (has_upload_data_) { |
235 // Use kMaxSpdyFrameChunkSize as the buffer size, since the request | 236 // Use kMaxSpdyFrameChunkSize as the buffer size, since the request |
236 // body data is written with this size at a time. | 237 // body data is written with this size at a time. |
237 raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); | 238 raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); |
238 // The request body buffer is empty at first. | 239 // The request body buffer is empty at first. |
239 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, 0); | 240 raw_request_body_buf_size_ = 0; |
240 } | 241 } |
241 | 242 |
242 CHECK(!callback.is_null()); | 243 CHECK(!callback.is_null()); |
243 CHECK(response); | 244 CHECK(response); |
244 | 245 |
245 // SendRequest can be called in two cases. | 246 // SendRequest can be called in two cases. |
246 // | 247 // |
247 // a) A client initiated request. In this case, |response_info_| should be | 248 // a) A client initiated request. In this case, |response_info_| should be |
248 // NULL to start with. | 249 // NULL to start with. |
249 // b) A client request which matches a response that the server has already | 250 // b) A client request which matches a response that the server has already |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 } | 282 } |
282 | 283 |
283 SpdySendStatus SpdyHttpStream::OnSendHeadersComplete() { | 284 SpdySendStatus SpdyHttpStream::OnSendHeadersComplete() { |
284 if (!callback_.is_null()) | 285 if (!callback_.is_null()) |
285 DoCallback(OK); | 286 DoCallback(OK); |
286 return has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND; | 287 return has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND; |
287 } | 288 } |
288 | 289 |
289 void SpdyHttpStream::OnSendBody() { | 290 void SpdyHttpStream::OnSendBody() { |
290 CHECK(request_info_ && request_info_->upload_data_stream); | 291 CHECK(request_info_ && request_info_->upload_data_stream); |
291 if (request_body_buf_->BytesRemaining() > 0) { | 292 if (raw_request_body_buf_size_ > 0) { |
292 SendRequestBodyData(); | 293 SendRequestBodyData(); |
293 } else { | 294 } else { |
294 // We shouldn't be called if there's no more data to read. | 295 // We shouldn't be called if there's no more data to read. |
295 CHECK(!request_info_->upload_data_stream->IsEOF()); | 296 CHECK(!request_info_->upload_data_stream->IsEOF()); |
296 ReadAndSendRequestBodyData(); | 297 ReadAndSendRequestBodyData(); |
297 } | 298 } |
298 } | 299 } |
299 | 300 |
300 SpdySendStatus SpdyHttpStream::OnSendBodyComplete(size_t bytes_sent) { | 301 SpdySendStatus SpdyHttpStream::OnSendBodyComplete() { |
301 // |status| is the number of bytes written to the SPDY stream. | 302 // |status| is the number of bytes written to the SPDY stream. |
302 CHECK(request_info_ && request_info_->upload_data_stream); | 303 CHECK(request_info_ && request_info_->upload_data_stream); |
303 DCHECK_GE(static_cast<int>(bytes_sent), 0); | 304 raw_request_body_buf_size_ = 0; |
304 DCHECK_LE(static_cast<int>(bytes_sent), request_body_buf_->BytesRemaining()); | |
305 | |
306 request_body_buf_->DidConsume(static_cast<int>(bytes_sent)); | |
307 | 305 |
308 // Check for more data to send. | 306 // Check for more data to send. |
309 if (!request_info_->upload_data_stream->IsEOF() || | 307 return request_info_->upload_data_stream->IsEOF() ? |
310 (request_body_buf_->BytesRemaining() > 0)) | 308 NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND; |
311 return MORE_DATA_TO_SEND; | |
312 | |
313 return NO_MORE_DATA_TO_SEND; | |
314 } | 309 } |
315 | 310 |
316 int SpdyHttpStream::OnResponseReceived(const SpdyHeaderBlock& response, | 311 int SpdyHttpStream::OnResponseReceived(const SpdyHeaderBlock& response, |
317 base::Time response_time, | 312 base::Time response_time, |
318 int status) { | 313 int status) { |
319 if (!response_info_) { | 314 if (!response_info_) { |
320 DCHECK(stream_->pushed()); | 315 DCHECK(stream_->pushed()); |
321 push_response_info_.reset(new HttpResponseInfo); | 316 push_response_info_.reset(new HttpResponseInfo); |
322 response_info_ = push_response_info_.get(); | 317 response_info_ = push_response_info_.get(); |
323 } | 318 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 390 |
396 if (user_buffer_) { | 391 if (user_buffer_) { |
397 // Handing small chunks of data to the caller creates measurable overhead. | 392 // Handing small chunks of data to the caller creates measurable overhead. |
398 // We buffer data in short time-spans and send a single read notification. | 393 // We buffer data in short time-spans and send a single read notification. |
399 ScheduleBufferedReadCallback(); | 394 ScheduleBufferedReadCallback(); |
400 } | 395 } |
401 } | 396 } |
402 return OK; | 397 return OK; |
403 } | 398 } |
404 | 399 |
405 void SpdyHttpStream::OnDataSent(size_t /*bytes_sent*/) { | 400 void SpdyHttpStream::OnDataSent() { |
406 // For HTTP streams, no data is sent from the client while in the OPEN state, | 401 // For HTTP streams, no data is sent from the client while in the OPEN state, |
407 // so it is never called. | 402 // so it is never called. |
408 NOTREACHED(); | 403 CHECK(false); |
409 } | 404 } |
410 | 405 |
411 void SpdyHttpStream::OnClose(int status) { | 406 void SpdyHttpStream::OnClose(int status) { |
412 if (stream_) { | 407 if (stream_) { |
413 stream_closed_ = true; | 408 stream_closed_ = true; |
414 closed_stream_pushed_ = stream_->pushed(); | 409 closed_stream_pushed_ = stream_->pushed(); |
415 closed_stream_status_ = status; | 410 closed_stream_status_ = status; |
416 closed_stream_id_ = stream_->stream_id(); | 411 closed_stream_id_ = stream_->stream_id(); |
417 } | 412 } |
418 stream_.reset(); | 413 stream_.reset(); |
(...skipping 11 matching lines...) Expand all Loading... |
430 int rv) { | 425 int rv) { |
431 if (rv == OK) { | 426 if (rv == OK) { |
432 stream_ = stream_request_.ReleaseStream(); | 427 stream_ = stream_request_.ReleaseStream(); |
433 stream_->SetDelegate(this); | 428 stream_->SetDelegate(this); |
434 } | 429 } |
435 callback.Run(rv); | 430 callback.Run(rv); |
436 } | 431 } |
437 | 432 |
438 void SpdyHttpStream::ReadAndSendRequestBodyData() { | 433 void SpdyHttpStream::ReadAndSendRequestBodyData() { |
439 CHECK(request_info_ && request_info_->upload_data_stream); | 434 CHECK(request_info_ && request_info_->upload_data_stream); |
440 CHECK_EQ(0, request_body_buf_->BytesRemaining()); | 435 CHECK_EQ(raw_request_body_buf_size_, 0); |
441 | 436 |
442 // Read the data from the request body stream. | 437 // Read the data from the request body stream. |
443 const int rv = request_info_->upload_data_stream->Read( | 438 const int rv = request_info_->upload_data_stream->Read( |
444 raw_request_body_buf_, raw_request_body_buf_->size(), | 439 raw_request_body_buf_, raw_request_body_buf_->size(), |
445 base::Bind( | 440 base::Bind( |
446 &SpdyHttpStream::OnRequestBodyReadCompleted, | 441 &SpdyHttpStream::OnRequestBodyReadCompleted, |
447 weak_factory_.GetWeakPtr())); | 442 weak_factory_.GetWeakPtr())); |
448 | 443 |
449 if (rv != ERR_IO_PENDING) { | 444 if (rv != ERR_IO_PENDING) { |
450 // ERR_IO_PENDING is the only possible error. | 445 // ERR_IO_PENDING is the only possible error. |
451 CHECK_GE(rv, 0); | 446 CHECK_GE(rv, 0); |
452 OnRequestBodyReadCompleted(rv); | 447 OnRequestBodyReadCompleted(rv); |
453 } | 448 } |
454 } | 449 } |
455 | 450 |
456 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { | 451 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { |
457 CHECK_GE(status, 0); | 452 CHECK_GE(status, 0); |
458 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, status); | 453 raw_request_body_buf_size_ = status; |
459 SendRequestBodyData(); | 454 SendRequestBodyData(); |
460 } | 455 } |
461 | 456 |
462 void SpdyHttpStream::SendRequestBodyData() { | 457 void SpdyHttpStream::SendRequestBodyData() { |
463 const bool eof = request_info_->upload_data_stream->IsEOF(); | 458 const bool eof = request_info_->upload_data_stream->IsEOF(); |
464 if (eof) { | 459 if (eof) { |
465 CHECK_GE(request_body_buf_->BytesRemaining(), 0); | 460 CHECK_GE(raw_request_body_buf_size_, 0); |
466 } else { | 461 } else { |
467 CHECK_GT(request_body_buf_->BytesRemaining(), 0); | 462 CHECK_GT(raw_request_body_buf_size_, 0); |
468 } | 463 } |
469 stream_->QueueStreamData(request_body_buf_, | 464 stream_->SendStreamData(raw_request_body_buf_, |
470 request_body_buf_->BytesRemaining(), | 465 raw_request_body_buf_size_, |
471 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); | 466 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); |
472 } | 467 } |
473 | 468 |
474 void SpdyHttpStream::ScheduleBufferedReadCallback() { | 469 void SpdyHttpStream::ScheduleBufferedReadCallback() { |
475 // If there is already a scheduled DoBufferedReadCallback, don't issue | 470 // If there is already a scheduled DoBufferedReadCallback, don't issue |
476 // another one. Mark that we have received more data and return. | 471 // another one. Mark that we have received more data and return. |
477 if (buffered_read_callback_pending_) { | 472 if (buffered_read_callback_pending_) { |
478 more_read_data_pending_ = true; | 473 more_read_data_pending_ = true; |
479 return; | 474 return; |
480 } | 475 } |
481 | 476 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 bool SpdyHttpStream::IsSpdyHttpStream() const { | 555 bool SpdyHttpStream::IsSpdyHttpStream() const { |
561 return true; | 556 return true; |
562 } | 557 } |
563 | 558 |
564 void SpdyHttpStream::Drain(HttpNetworkSession* session) { | 559 void SpdyHttpStream::Drain(HttpNetworkSession* session) { |
565 Close(false); | 560 Close(false); |
566 delete this; | 561 delete this; |
567 } | 562 } |
568 | 563 |
569 } // namespace net | 564 } // namespace net |
OLD | NEW |