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 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 more_read_data_pending_(false), | 43 more_read_data_pending_(false), |
44 direct_(direct) { } | 44 direct_(direct) { } |
45 | 45 |
46 void SpdyHttpStream::InitializeWithExistingStream(SpdyStream* spdy_stream) { | 46 void SpdyHttpStream::InitializeWithExistingStream(SpdyStream* spdy_stream) { |
47 stream_ = spdy_stream; | 47 stream_ = spdy_stream; |
48 stream_->SetDelegate(this); | 48 stream_->SetDelegate(this); |
49 response_headers_received_ = true; | 49 response_headers_received_ = true; |
50 } | 50 } |
51 | 51 |
52 SpdyHttpStream::~SpdyHttpStream() { | 52 SpdyHttpStream::~SpdyHttpStream() { |
53 if (stream_) | 53 if (stream_.get()) |
54 stream_->DetachDelegate(); | 54 stream_->DetachDelegate(); |
55 } | 55 } |
56 | 56 |
57 int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, | 57 int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, |
58 const BoundNetLog& stream_net_log, | 58 const BoundNetLog& stream_net_log, |
59 const CompletionCallback& callback) { | 59 const CompletionCallback& callback) { |
60 DCHECK(!stream_.get()); | 60 DCHECK(!stream_.get()); |
61 if (spdy_session_->IsClosed()) | 61 if (spdy_session_->IsClosed()) |
62 return ERR_CONNECTION_CLOSED; | 62 return ERR_CONNECTION_CLOSED; |
63 | 63 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 } | 135 } |
136 bytes_read += bytes_to_copy; | 136 bytes_read += bytes_to_copy; |
137 } | 137 } |
138 stream_->IncreaseRecvWindowSize(bytes_read); | 138 stream_->IncreaseRecvWindowSize(bytes_read); |
139 return bytes_read; | 139 return bytes_read; |
140 } else if (stream_->closed()) { | 140 } else if (stream_->closed()) { |
141 return stream_->response_status(); | 141 return stream_->response_status(); |
142 } | 142 } |
143 | 143 |
144 CHECK(callback_.is_null()); | 144 CHECK(callback_.is_null()); |
145 CHECK(!user_buffer_); | 145 CHECK(!user_buffer_.get()); |
146 CHECK_EQ(0, user_buffer_len_); | 146 CHECK_EQ(0, user_buffer_len_); |
147 | 147 |
148 callback_ = callback; | 148 callback_ = callback; |
149 user_buffer_ = buf; | 149 user_buffer_ = buf; |
150 user_buffer_len_ = buf_len; | 150 user_buffer_len_ = buf_len; |
151 return ERR_IO_PENDING; | 151 return ERR_IO_PENDING; |
152 } | 152 } |
153 | 153 |
154 void SpdyHttpStream::Close(bool not_reusable) { | 154 void SpdyHttpStream::Close(bool not_reusable) { |
155 // Note: the not_reusable flag has no meaning for SPDY streams. | 155 // Note: the not_reusable flag has no meaning for SPDY streams. |
156 | 156 |
157 Cancel(); | 157 Cancel(); |
158 } | 158 } |
159 | 159 |
160 HttpStream* SpdyHttpStream::RenewStreamForAuth() { | 160 HttpStream* SpdyHttpStream::RenewStreamForAuth() { |
161 return NULL; | 161 return NULL; |
162 } | 162 } |
163 | 163 |
164 bool SpdyHttpStream::IsResponseBodyComplete() const { | 164 bool SpdyHttpStream::IsResponseBodyComplete() const { |
165 if (!stream_) | 165 if (!stream_.get()) |
166 return false; | 166 return false; |
167 return stream_->closed(); | 167 return stream_->closed(); |
168 } | 168 } |
169 | 169 |
170 bool SpdyHttpStream::CanFindEndOfResponse() const { | 170 bool SpdyHttpStream::CanFindEndOfResponse() const { |
171 return true; | 171 return true; |
172 } | 172 } |
173 | 173 |
174 bool SpdyHttpStream::IsMoreDataBuffered() const { | 174 bool SpdyHttpStream::IsMoreDataBuffered() const { |
175 return false; | 175 return false; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 response_info_->request_time = request_time; | 214 response_info_->request_time = request_time; |
215 | 215 |
216 CHECK(!request_body_stream_.get()); | 216 CHECK(!request_body_stream_.get()); |
217 if (request_body != NULL) { | 217 if (request_body != NULL) { |
218 if (request_body->size() || request_body->is_chunked()) { | 218 if (request_body->size() || request_body->is_chunked()) { |
219 request_body_stream_.reset(request_body.release()); | 219 request_body_stream_.reset(request_body.release()); |
220 // Use kMaxSpdyFrameChunkSize as the buffer size, since the request | 220 // Use kMaxSpdyFrameChunkSize as the buffer size, since the request |
221 // body data is written with this size at a time. | 221 // body data is written with this size at a time. |
222 raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); | 222 raw_request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); |
223 // The request body buffer is empty at first. | 223 // The request body buffer is empty at first. |
224 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, 0); | 224 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), 0); |
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 CHECK(!callback.is_null()); | 228 CHECK(!callback.is_null()); |
229 CHECK(!stream_->cancelled()); | 229 CHECK(!stream_->cancelled()); |
230 CHECK(response); | 230 CHECK(response); |
231 | 231 |
232 if (!stream_->pushed() && stream_->closed()) { | 232 if (!stream_->pushed() && stream_->closed()) { |
233 if (stream_->response_status() == OK) | 233 if (stream_->response_status() == OK) |
234 return ERR_FAILED; | 234 return ERR_FAILED; |
(...skipping 26 matching lines...) Expand all Loading... |
261 bool has_upload_data = request_body_stream_.get() != NULL; | 261 bool has_upload_data = request_body_stream_.get() != NULL; |
262 result = stream_->SendRequest(has_upload_data); | 262 result = stream_->SendRequest(has_upload_data); |
263 if (result == ERR_IO_PENDING) { | 263 if (result == ERR_IO_PENDING) { |
264 CHECK(callback_.is_null()); | 264 CHECK(callback_.is_null()); |
265 callback_ = callback; | 265 callback_ = callback; |
266 } | 266 } |
267 return result; | 267 return result; |
268 } | 268 } |
269 | 269 |
270 void SpdyHttpStream::Cancel() { | 270 void SpdyHttpStream::Cancel() { |
271 if (spdy_session_) | 271 if (spdy_session_.get()) |
272 spdy_session_->CancelPendingCreateStreams(&stream_); | 272 spdy_session_->CancelPendingCreateStreams(&stream_); |
273 callback_.Reset(); | 273 callback_.Reset(); |
274 if (stream_) | 274 if (stream_.get()) |
275 stream_->Cancel(); | 275 stream_->Cancel(); |
276 } | 276 } |
277 | 277 |
278 int SpdyHttpStream::SendData() { | 278 int SpdyHttpStream::SendData() { |
279 CHECK(request_body_stream_.get()); | 279 CHECK(request_body_stream_.get()); |
280 CHECK_EQ(0, request_body_buf_->BytesRemaining()); | 280 CHECK_EQ(0, request_body_buf_->BytesRemaining()); |
281 | 281 |
282 // Read the data from the request body stream. | 282 // Read the data from the request body stream. |
283 const int bytes_read = request_body_stream_->Read( | 283 const int bytes_read = request_body_stream_->Read( |
284 raw_request_body_buf_, raw_request_body_buf_->size(), | 284 raw_request_body_buf_.get(), raw_request_body_buf_->size(), |
285 base::Bind( | 285 base::Bind( |
286 base::IgnoreResult(&SpdyHttpStream::OnRequestBodyReadCompleted), | 286 base::IgnoreResult(&SpdyHttpStream::OnRequestBodyReadCompleted), |
287 weak_factory_.GetWeakPtr())); | 287 weak_factory_.GetWeakPtr())); |
288 | 288 |
289 if (bytes_read == ERR_IO_PENDING) | 289 if (bytes_read == ERR_IO_PENDING) |
290 return ERR_IO_PENDING; | 290 return ERR_IO_PENDING; |
291 // ERR_IO_PENDING is the only possible error. | 291 // ERR_IO_PENDING is the only possible error. |
292 DCHECK_GE(bytes_read, 0); | 292 DCHECK_GE(bytes_read, 0); |
293 return OnRequestBodyReadCompleted(bytes_read); | 293 return OnRequestBodyReadCompleted(bytes_read); |
294 } | 294 } |
295 | 295 |
296 bool SpdyHttpStream::OnSendHeadersComplete(int status) { | 296 bool SpdyHttpStream::OnSendHeadersComplete(int status) { |
297 if (!callback_.is_null()) | 297 if (!callback_.is_null()) |
298 DoCallback(status); | 298 DoCallback(status); |
299 return request_body_stream_.get() == NULL; | 299 return request_body_stream_.get() == NULL; |
300 } | 300 } |
301 | 301 |
302 int SpdyHttpStream::OnSendBody() { | 302 int SpdyHttpStream::OnSendBody() { |
303 CHECK(request_body_stream_.get()); | 303 CHECK(request_body_stream_.get()); |
304 const bool eof = request_body_stream_->IsEOF(); | 304 const bool eof = request_body_stream_->IsEOF(); |
305 if (request_body_buf_->BytesRemaining() > 0) { | 305 if (request_body_buf_->BytesRemaining() > 0) { |
306 return stream_->WriteStreamData( | 306 return stream_->WriteStreamData( |
307 request_body_buf_, | 307 request_body_buf_.get(), |
308 request_body_buf_->BytesRemaining(), | 308 request_body_buf_->BytesRemaining(), |
309 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); | 309 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); |
310 } | 310 } |
311 | 311 |
312 // The entire body data has been sent. | 312 // The entire body data has been sent. |
313 if (eof) | 313 if (eof) |
314 return OK; | 314 return OK; |
315 | 315 |
316 return SendData(); | 316 return SendData(); |
317 } | 317 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 // Don't store the SSLInfo in the response here, HttpNetworkTransaction | 364 // Don't store the SSLInfo in the response here, HttpNetworkTransaction |
365 // will take care of that part. | 365 // will take care of that part. |
366 SSLInfo ssl_info; | 366 SSLInfo ssl_info; |
367 NextProto protocol_negotiated = kProtoUnknown; | 367 NextProto protocol_negotiated = kProtoUnknown; |
368 stream_->GetSSLInfo(&ssl_info, | 368 stream_->GetSSLInfo(&ssl_info, |
369 &response_info_->was_npn_negotiated, | 369 &response_info_->was_npn_negotiated, |
370 &protocol_negotiated); | 370 &protocol_negotiated); |
371 response_info_->npn_negotiated_protocol = | 371 response_info_->npn_negotiated_protocol = |
372 SSLClientSocket::NextProtoToString(protocol_negotiated); | 372 SSLClientSocket::NextProtoToString(protocol_negotiated); |
373 response_info_->request_time = stream_->GetRequestTime(); | 373 response_info_->request_time = stream_->GetRequestTime(); |
374 response_info_->vary_data.Init(*request_info_, *response_info_->headers); | 374 response_info_-> |
| 375 vary_data.Init(*request_info_, *response_info_->headers.get()); |
375 // TODO(ahendrickson): This is recorded after the entire SYN_STREAM control | 376 // TODO(ahendrickson): This is recorded after the entire SYN_STREAM control |
376 // frame has been received and processed. Move to framer? | 377 // frame has been received and processed. Move to framer? |
377 response_info_->response_time = response_time; | 378 response_info_->response_time = response_time; |
378 | 379 |
379 if (!callback_.is_null()) | 380 if (!callback_.is_null()) |
380 DoCallback(status); | 381 DoCallback(status); |
381 | 382 |
382 return status; | 383 return status; |
383 } | 384 } |
384 | 385 |
(...skipping 12 matching lines...) Expand all Loading... |
397 // Note that data may be received for a SpdyStream prior to the user calling | 398 // Note that data may be received for a SpdyStream prior to the user calling |
398 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often | 399 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often |
399 // happen for server initiated streams. | 400 // happen for server initiated streams. |
400 DCHECK(!stream_->closed() || stream_->pushed()); | 401 DCHECK(!stream_->closed() || stream_->pushed()); |
401 if (length > 0) { | 402 if (length > 0) { |
402 // Save the received data. | 403 // Save the received data. |
403 IOBufferWithSize* io_buffer = new IOBufferWithSize(length); | 404 IOBufferWithSize* io_buffer = new IOBufferWithSize(length); |
404 memcpy(io_buffer->data(), data, length); | 405 memcpy(io_buffer->data(), data, length); |
405 response_body_.push_back(make_scoped_refptr(io_buffer)); | 406 response_body_.push_back(make_scoped_refptr(io_buffer)); |
406 | 407 |
407 if (user_buffer_) { | 408 if (user_buffer_.get()) { |
408 // Handing small chunks of data to the caller creates measurable overhead. | 409 // Handing small chunks of data to the caller creates measurable overhead. |
409 // We buffer data in short time-spans and send a single read notification. | 410 // We buffer data in short time-spans and send a single read notification. |
410 ScheduleBufferedReadCallback(); | 411 ScheduleBufferedReadCallback(); |
411 } | 412 } |
412 } | 413 } |
413 return OK; | 414 return OK; |
414 } | 415 } |
415 | 416 |
416 void SpdyHttpStream::OnDataSent(int length) { | 417 void SpdyHttpStream::OnDataSent(int length) { |
417 // For HTTP streams, no data is sent from the client while in the OPEN state, | 418 // For HTTP streams, no data is sent from the client while in the OPEN state, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 | 464 |
464 return bytes_buffered < user_buffer_len_; | 465 return bytes_buffered < user_buffer_len_; |
465 } | 466 } |
466 | 467 |
467 bool SpdyHttpStream::DoBufferedReadCallback() { | 468 bool SpdyHttpStream::DoBufferedReadCallback() { |
468 weak_factory_.InvalidateWeakPtrs(); | 469 weak_factory_.InvalidateWeakPtrs(); |
469 buffered_read_callback_pending_ = false; | 470 buffered_read_callback_pending_ = false; |
470 | 471 |
471 // If the transaction is cancelled or errored out, we don't need to complete | 472 // If the transaction is cancelled or errored out, we don't need to complete |
472 // the read. | 473 // the read. |
473 if (!stream_ || stream_->response_status() != OK || stream_->cancelled()) | 474 if ( |
| 475 !stream_.get() || stream_->response_status() != OK || stream_-> |
| 476 cancelled()) |
474 return false; | 477 return false; |
475 | 478 |
476 // When more_read_data_pending_ is true, it means that more data has | 479 // When more_read_data_pending_ is true, it means that more data has |
477 // arrived since we started waiting. Wait a little longer and continue | 480 // arrived since we started waiting. Wait a little longer and continue |
478 // to buffer. | 481 // to buffer. |
479 if (more_read_data_pending_ && ShouldWaitForMoreBufferedData()) { | 482 if (more_read_data_pending_ && ShouldWaitForMoreBufferedData()) { |
480 ScheduleBufferedReadCallback(); | 483 ScheduleBufferedReadCallback(); |
481 return false; | 484 return false; |
482 } | 485 } |
483 | 486 |
484 int rv = 0; | 487 int rv = 0; |
485 if (user_buffer_) { | 488 if (user_buffer_.get()) { |
486 rv = ReadResponseBody(user_buffer_, user_buffer_len_, callback_); | 489 rv = ReadResponseBody(user_buffer_.get(), user_buffer_len_, callback_); |
487 CHECK_NE(rv, ERR_IO_PENDING); | 490 CHECK_NE(rv, ERR_IO_PENDING); |
488 user_buffer_ = NULL; | 491 user_buffer_ = NULL; |
489 user_buffer_len_ = 0; | 492 user_buffer_len_ = 0; |
490 DoCallback(rv); | 493 DoCallback(rv); |
491 return true; | 494 return true; |
492 } | 495 } |
493 return false; | 496 return false; |
494 } | 497 } |
495 | 498 |
496 void SpdyHttpStream::DoCallback(int rv) { | 499 void SpdyHttpStream::DoCallback(int rv) { |
497 CHECK_NE(rv, ERR_IO_PENDING); | 500 CHECK_NE(rv, ERR_IO_PENDING); |
498 CHECK(!callback_.is_null()); | 501 CHECK(!callback_.is_null()); |
499 | 502 |
500 // Since Run may result in being called back, clear user_callback_ in advance. | 503 // Since Run may result in being called back, clear user_callback_ in advance. |
501 CompletionCallback c = callback_; | 504 CompletionCallback c = callback_; |
502 callback_.Reset(); | 505 callback_.Reset(); |
503 c.Run(rv); | 506 c.Run(rv); |
504 } | 507 } |
505 | 508 |
506 int SpdyHttpStream::OnRequestBodyReadCompleted(int status) { | 509 int SpdyHttpStream::OnRequestBodyReadCompleted(int status) { |
507 DCHECK_GE(status, 0); | 510 DCHECK_GE(status, 0); |
508 | 511 |
509 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_, status); | 512 request_body_buf_ = |
| 513 new DrainableIOBuffer(raw_request_body_buf_.get(), status); |
510 | 514 |
511 const bool eof = request_body_stream_->IsEOF(); | 515 const bool eof = request_body_stream_->IsEOF(); |
512 return stream_->WriteStreamData(request_body_buf_, | 516 return stream_->WriteStreamData(request_body_buf_.get(), |
513 request_body_buf_->BytesRemaining(), | 517 request_body_buf_->BytesRemaining(), |
514 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); | 518 eof ? DATA_FLAG_FIN : DATA_FLAG_NONE); |
515 } | 519 } |
516 | 520 |
517 void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) { | 521 void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) { |
518 DCHECK(stream_); | 522 DCHECK(stream_); |
519 bool using_npn; | 523 bool using_npn; |
520 NextProto protocol_negotiated = kProtoUnknown; | 524 NextProto protocol_negotiated = kProtoUnknown; |
521 stream_->GetSSLInfo(ssl_info, &using_npn, &protocol_negotiated); | 525 stream_->GetSSLInfo(ssl_info, &using_npn, &protocol_negotiated); |
522 } | 526 } |
523 | 527 |
524 void SpdyHttpStream::GetSSLCertRequestInfo( | 528 void SpdyHttpStream::GetSSLCertRequestInfo( |
525 SSLCertRequestInfo* cert_request_info) { | 529 SSLCertRequestInfo* cert_request_info) { |
526 DCHECK(stream_); | 530 DCHECK(stream_); |
527 stream_->GetSSLCertRequestInfo(cert_request_info); | 531 stream_->GetSSLCertRequestInfo(cert_request_info); |
528 } | 532 } |
529 | 533 |
530 bool SpdyHttpStream::IsSpdyHttpStream() const { | 534 bool SpdyHttpStream::IsSpdyHttpStream() const { |
531 return true; | 535 return true; |
532 } | 536 } |
533 | 537 |
534 void SpdyHttpStream::Drain(HttpNetworkSession* session) { | 538 void SpdyHttpStream::Drain(HttpNetworkSession* session) { |
535 Close(false); | 539 Close(false); |
536 delete this; | 540 delete this; |
537 } | 541 } |
538 | 542 |
539 } // namespace net | 543 } // namespace net |
OLD | NEW |