| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, | 55 int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, |
| 56 RequestPriority priority, | 56 RequestPriority priority, |
| 57 const BoundNetLog& stream_net_log, | 57 const BoundNetLog& stream_net_log, |
| 58 const CompletionCallback& callback) { | 58 const CompletionCallback& callback) { |
| 59 DCHECK(!stream_); | 59 DCHECK(!stream_); |
| 60 if (!spdy_session_) | 60 if (!spdy_session_) |
| 61 return ERR_CONNECTION_CLOSED; | 61 return ERR_CONNECTION_CLOSED; |
| 62 | 62 |
| 63 request_info_ = request_info; | 63 request_info_ = request_info; |
| 64 if (request_info_->method == "GET") { | 64 if (request_info_->method == "GET") { |
| 65 int error = spdy_session_->GetPushStream(request_info_->url, &stream_, | 65 int error = spdy_session_->GetPushStream( |
| 66 stream_net_log); | 66 request_info_->url, &stream_, stream_net_log); |
| 67 if (error != OK) | 67 if (error != OK) |
| 68 return error; | 68 return error; |
| 69 | 69 |
| 70 // |stream_| may be NULL even if OK was returned. | 70 // |stream_| may be NULL even if OK was returned. |
| 71 if (stream_.get()) { | 71 if (stream_.get()) { |
| 72 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM); | 72 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM); |
| 73 stream_->SetDelegate(this); | 73 stream_->SetDelegate(this); |
| 74 return OK; | 74 return OK; |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 | 77 |
| 78 int rv = stream_request_.StartRequest( | 78 int rv = |
| 79 SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url, | 79 stream_request_.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, |
| 80 priority, stream_net_log, | 80 spdy_session_, |
| 81 base::Bind(&SpdyHttpStream::OnStreamCreated, | 81 request_info_->url, |
| 82 weak_factory_.GetWeakPtr(), callback)); | 82 priority, |
| 83 stream_net_log, |
| 84 base::Bind(&SpdyHttpStream::OnStreamCreated, |
| 85 weak_factory_.GetWeakPtr(), |
| 86 callback)); |
| 83 | 87 |
| 84 if (rv == OK) { | 88 if (rv == OK) { |
| 85 stream_ = stream_request_.ReleaseStream(); | 89 stream_ = stream_request_.ReleaseStream(); |
| 86 stream_->SetDelegate(this); | 90 stream_->SetDelegate(this); |
| 87 } | 91 } |
| 88 | 92 |
| 89 return rv; | 93 return rv; |
| 90 } | 94 } |
| 91 | 95 |
| 92 const HttpResponseInfo* SpdyHttpStream::GetResponseInfo() const { | 96 const HttpResponseInfo* SpdyHttpStream::GetResponseInfo() const { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 113 CHECK(!stream_->IsIdle()); | 117 CHECK(!stream_->IsIdle()); |
| 114 return OK; | 118 return OK; |
| 115 } | 119 } |
| 116 | 120 |
| 117 // Still waiting for the response, return IO_PENDING. | 121 // Still waiting for the response, return IO_PENDING. |
| 118 CHECK(callback_.is_null()); | 122 CHECK(callback_.is_null()); |
| 119 callback_ = callback; | 123 callback_ = callback; |
| 120 return ERR_IO_PENDING; | 124 return ERR_IO_PENDING; |
| 121 } | 125 } |
| 122 | 126 |
| 123 int SpdyHttpStream::ReadResponseBody( | 127 int SpdyHttpStream::ReadResponseBody(IOBuffer* buf, |
| 124 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | 128 int buf_len, |
| 129 const CompletionCallback& callback) { |
| 125 if (stream_.get()) | 130 if (stream_.get()) |
| 126 CHECK(!stream_->IsIdle()); | 131 CHECK(!stream_->IsIdle()); |
| 127 | 132 |
| 128 CHECK(buf); | 133 CHECK(buf); |
| 129 CHECK(buf_len); | 134 CHECK(buf_len); |
| 130 CHECK(!callback.is_null()); | 135 CHECK(!callback.is_null()); |
| 131 | 136 |
| 132 // If we have data buffered, complete the IO immediately. | 137 // If we have data buffered, complete the IO immediately. |
| 133 if (!response_body_queue_.IsEmpty()) { | 138 if (!response_body_queue_.IsEmpty()) { |
| 134 return response_body_queue_.Dequeue(buf->data(), buf_len); | 139 return response_body_queue_.Dequeue(buf->data(), buf_len); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 response_info_->socket_address = HostPortPair::FromIPEndPoint(address); | 263 response_info_->socket_address = HostPortPair::FromIPEndPoint(address); |
| 259 | 264 |
| 260 if (stream_->type() == SPDY_PUSH_STREAM) { | 265 if (stream_->type() == SPDY_PUSH_STREAM) { |
| 261 // Pushed streams do not send any data, and should always be | 266 // Pushed streams do not send any data, and should always be |
| 262 // idle. However, we still want to return ERR_IO_PENDING to mimic | 267 // idle. However, we still want to return ERR_IO_PENDING to mimic |
| 263 // non-push behavior. The callback will be called when the | 268 // non-push behavior. The callback will be called when the |
| 264 // response is received. | 269 // response is received. |
| 265 result = ERR_IO_PENDING; | 270 result = ERR_IO_PENDING; |
| 266 } else { | 271 } else { |
| 267 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); | 272 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| 268 CreateSpdyHeadersFromHttpRequest( | 273 CreateSpdyHeadersFromHttpRequest(*request_info_, |
| 269 *request_info_, request_headers, | 274 request_headers, |
| 270 headers.get(), stream_->GetProtocolVersion(), | 275 headers.get(), |
| 271 direct_); | 276 stream_->GetProtocolVersion(), |
| 277 direct_); |
| 272 stream_->net_log().AddEvent( | 278 stream_->net_log().AddEvent( |
| 273 NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS, | 279 NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS, |
| 274 base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get())); | 280 base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get())); |
| 275 result = | 281 result = stream_->SendRequestHeaders( |
| 276 stream_->SendRequestHeaders( | 282 headers.Pass(), |
| 277 headers.Pass(), | 283 HasUploadData() ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND); |
| 278 HasUploadData() ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND); | |
| 279 } | 284 } |
| 280 | 285 |
| 281 if (result == ERR_IO_PENDING) { | 286 if (result == ERR_IO_PENDING) { |
| 282 CHECK(callback_.is_null()); | 287 CHECK(callback_.is_null()); |
| 283 callback_ = callback; | 288 callback_ = callback; |
| 284 } | 289 } |
| 285 return result; | 290 return result; |
| 286 } | 291 } |
| 287 | 292 |
| 288 void SpdyHttpStream::Cancel() { | 293 void SpdyHttpStream::Cancel() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 318 // We do not have complete headers yet. | 323 // We do not have complete headers yet. |
| 319 return RESPONSE_HEADERS_ARE_INCOMPLETE; | 324 return RESPONSE_HEADERS_ARE_INCOMPLETE; |
| 320 } | 325 } |
| 321 | 326 |
| 322 response_info_->response_time = stream_->response_time(); | 327 response_info_->response_time = stream_->response_time(); |
| 323 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE; | 328 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE; |
| 324 // Don't store the SSLInfo in the response here, HttpNetworkTransaction | 329 // Don't store the SSLInfo in the response here, HttpNetworkTransaction |
| 325 // will take care of that part. | 330 // will take care of that part. |
| 326 SSLInfo ssl_info; | 331 SSLInfo ssl_info; |
| 327 NextProto protocol_negotiated = kProtoUnknown; | 332 NextProto protocol_negotiated = kProtoUnknown; |
| 328 stream_->GetSSLInfo(&ssl_info, | 333 stream_->GetSSLInfo( |
| 329 &response_info_->was_npn_negotiated, | 334 &ssl_info, &response_info_->was_npn_negotiated, &protocol_negotiated); |
| 330 &protocol_negotiated); | |
| 331 response_info_->npn_negotiated_protocol = | 335 response_info_->npn_negotiated_protocol = |
| 332 SSLClientSocket::NextProtoToString(protocol_negotiated); | 336 SSLClientSocket::NextProtoToString(protocol_negotiated); |
| 333 response_info_->request_time = stream_->GetRequestTime(); | 337 response_info_->request_time = stream_->GetRequestTime(); |
| 334 response_info_->connection_info = | 338 response_info_->connection_info = |
| 335 HttpResponseInfo::ConnectionInfoFromNextProto(stream_->GetProtocol()); | 339 HttpResponseInfo::ConnectionInfoFromNextProto(stream_->GetProtocol()); |
| 336 response_info_->vary_data | 340 response_info_->vary_data.Init(*request_info_, |
| 337 .Init(*request_info_, *response_info_->headers.get()); | 341 *response_info_->headers.get()); |
| 338 | 342 |
| 339 if (!callback_.is_null()) | 343 if (!callback_.is_null()) |
| 340 DoCallback(OK); | 344 DoCallback(OK); |
| 341 | 345 |
| 342 return RESPONSE_HEADERS_ARE_COMPLETE; | 346 return RESPONSE_HEADERS_ARE_COMPLETE; |
| 343 } | 347 } |
| 344 | 348 |
| 345 void SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { | 349 void SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
| 346 CHECK_EQ(response_headers_status_, RESPONSE_HEADERS_ARE_COMPLETE); | 350 CHECK_EQ(response_headers_status_, RESPONSE_HEADERS_ARE_COMPLETE); |
| 347 | 351 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 if (status == net::OK) { | 384 if (status == net::OK) { |
| 381 // We need to complete any pending buffered read now. | 385 // We need to complete any pending buffered read now. |
| 382 invoked_callback = DoBufferedReadCallback(); | 386 invoked_callback = DoBufferedReadCallback(); |
| 383 } | 387 } |
| 384 if (!invoked_callback && !callback_.is_null()) | 388 if (!invoked_callback && !callback_.is_null()) |
| 385 DoCallback(status); | 389 DoCallback(status); |
| 386 } | 390 } |
| 387 | 391 |
| 388 bool SpdyHttpStream::HasUploadData() const { | 392 bool SpdyHttpStream::HasUploadData() const { |
| 389 CHECK(request_info_); | 393 CHECK(request_info_); |
| 390 return | 394 return request_info_->upload_data_stream && |
| 391 request_info_->upload_data_stream && | 395 ((request_info_->upload_data_stream->size() > 0) || |
| 392 ((request_info_->upload_data_stream->size() > 0) || | 396 request_info_->upload_data_stream->is_chunked()); |
| 393 request_info_->upload_data_stream->is_chunked()); | |
| 394 } | 397 } |
| 395 | 398 |
| 396 void SpdyHttpStream::OnStreamCreated( | 399 void SpdyHttpStream::OnStreamCreated(const CompletionCallback& callback, |
| 397 const CompletionCallback& callback, | 400 int rv) { |
| 398 int rv) { | |
| 399 if (rv == OK) { | 401 if (rv == OK) { |
| 400 stream_ = stream_request_.ReleaseStream(); | 402 stream_ = stream_request_.ReleaseStream(); |
| 401 stream_->SetDelegate(this); | 403 stream_->SetDelegate(this); |
| 402 } | 404 } |
| 403 callback.Run(rv); | 405 callback.Run(rv); |
| 404 } | 406 } |
| 405 | 407 |
| 406 void SpdyHttpStream::ReadAndSendRequestBodyData() { | 408 void SpdyHttpStream::ReadAndSendRequestBodyData() { |
| 407 CHECK(HasUploadData()); | 409 CHECK(HasUploadData()); |
| 408 CHECK_EQ(request_body_buf_size_, 0); | 410 CHECK_EQ(request_body_buf_size_, 0); |
| 409 | 411 |
| 410 if (request_info_->upload_data_stream->IsEOF()) | 412 if (request_info_->upload_data_stream->IsEOF()) |
| 411 return; | 413 return; |
| 412 | 414 |
| 413 // Read the data from the request body stream. | 415 // Read the data from the request body stream. |
| 414 const int rv = request_info_->upload_data_stream | 416 const int rv = request_info_->upload_data_stream->Read( |
| 415 ->Read(request_body_buf_.get(), | 417 request_body_buf_.get(), |
| 416 request_body_buf_->size(), | 418 request_body_buf_->size(), |
| 417 base::Bind(&SpdyHttpStream::OnRequestBodyReadCompleted, | 419 base::Bind(&SpdyHttpStream::OnRequestBodyReadCompleted, |
| 418 weak_factory_.GetWeakPtr())); | 420 weak_factory_.GetWeakPtr())); |
| 419 | 421 |
| 420 if (rv != ERR_IO_PENDING) { | 422 if (rv != ERR_IO_PENDING) { |
| 421 // ERR_IO_PENDING is the only possible error. | 423 // ERR_IO_PENDING is the only possible error. |
| 422 CHECK_GE(rv, 0); | 424 CHECK_GE(rv, 0); |
| 423 OnRequestBodyReadCompleted(rv); | 425 OnRequestBodyReadCompleted(rv); |
| 424 } | 426 } |
| 425 } | 427 } |
| 426 | 428 |
| 427 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { | 429 void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { |
| 428 CHECK_GE(status, 0); | 430 CHECK_GE(status, 0); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 458 | 460 |
| 459 // Checks to see if we should wait for more buffered data before notifying | 461 // Checks to see if we should wait for more buffered data before notifying |
| 460 // the caller. Returns true if we should wait, false otherwise. | 462 // the caller. Returns true if we should wait, false otherwise. |
| 461 bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const { | 463 bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const { |
| 462 // If the response is complete, there is no point in waiting. | 464 // If the response is complete, there is no point in waiting. |
| 463 if (stream_closed_) | 465 if (stream_closed_) |
| 464 return false; | 466 return false; |
| 465 | 467 |
| 466 DCHECK_GT(user_buffer_len_, 0); | 468 DCHECK_GT(user_buffer_len_, 0); |
| 467 return response_body_queue_.GetTotalSize() < | 469 return response_body_queue_.GetTotalSize() < |
| 468 static_cast<size_t>(user_buffer_len_); | 470 static_cast<size_t>(user_buffer_len_); |
| 469 } | 471 } |
| 470 | 472 |
| 471 bool SpdyHttpStream::DoBufferedReadCallback() { | 473 bool SpdyHttpStream::DoBufferedReadCallback() { |
| 472 buffered_read_callback_pending_ = false; | 474 buffered_read_callback_pending_ = false; |
| 473 | 475 |
| 474 // If the transaction is cancelled or errored out, we don't need to complete | 476 // If the transaction is cancelled or errored out, we don't need to complete |
| 475 // the read. | 477 // the read. |
| 476 if (!stream_.get() && !stream_closed_) | 478 if (!stream_.get() && !stream_closed_) |
| 477 return false; | 479 return false; |
| 478 | 480 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 Close(false); | 534 Close(false); |
| 533 delete this; | 535 delete this; |
| 534 } | 536 } |
| 535 | 537 |
| 536 void SpdyHttpStream::SetPriority(RequestPriority priority) { | 538 void SpdyHttpStream::SetPriority(RequestPriority priority) { |
| 537 // TODO(akalin): Plumb this through to |stream_request_| and | 539 // TODO(akalin): Plumb this through to |stream_request_| and |
| 538 // |stream_|. | 540 // |stream_|. |
| 539 } | 541 } |
| 540 | 542 |
| 541 } // namespace net | 543 } // namespace net |
| OLD | NEW |