Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1936)

Unified Diff: net/spdy/spdy_http_stream.cc

Issue 2832973003: Split net/spdy into core and chromium subdirectories. (Closed)
Patch Set: Fix some more build rules. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_http_stream.h ('k') | net/spdy/spdy_http_stream_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_http_stream.cc
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
deleted file mode 100644
index 0e07de38cd49f8fc19bde6ea66422d1614e72470..0000000000000000000000000000000000000000
--- a/net/spdy/spdy_http_stream.cc
+++ /dev/null
@@ -1,595 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/spdy/spdy_http_stream.h"
-
-#include <algorithm>
-#include <list>
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/values.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/upload_data_stream.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_response_info.h"
-#include "net/log/net_log_event_type.h"
-#include "net/log/net_log_with_source.h"
-#include "net/spdy/platform/api/spdy_string.h"
-#include "net/spdy/spdy_header_block.h"
-#include "net/spdy/spdy_http_utils.h"
-#include "net/spdy/spdy_protocol.h"
-#include "net/spdy/spdy_session.h"
-
-namespace net {
-
-const size_t SpdyHttpStream::kRequestBodyBufferSize = 1 << 14; // 16KB
-
-SpdyHttpStream::SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session,
- bool direct,
- NetLogSource source_dependency)
- : MultiplexedHttpStream(MultiplexedSessionHandle(spdy_session)),
- spdy_session_(spdy_session),
- is_reused_(spdy_session_->IsReused()),
- source_dependency_(source_dependency),
- stream_(nullptr),
- stream_closed_(false),
- closed_stream_status_(ERR_FAILED),
- closed_stream_id_(0),
- closed_stream_received_bytes_(0),
- closed_stream_sent_bytes_(0),
- request_info_(NULL),
- response_info_(NULL),
- response_headers_complete_(false),
- user_buffer_len_(0),
- request_body_buf_size_(0),
- buffered_read_callback_pending_(false),
- more_read_data_pending_(false),
- direct_(direct),
- was_alpn_negotiated_(false),
- weak_factory_(this) {
- DCHECK(spdy_session_.get());
-}
-
-SpdyHttpStream::~SpdyHttpStream() {
- if (stream_) {
- stream_->DetachDelegate();
- DCHECK(!stream_);
- }
-}
-
-int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
- RequestPriority priority,
- const NetLogWithSource& stream_net_log,
- const CompletionCallback& callback) {
- DCHECK(!stream_);
- if (!spdy_session_)
- return ERR_CONNECTION_CLOSED;
-
- request_info_ = request_info;
- if (request_info_->method == "GET") {
- int error = spdy_session_->GetPushStream(request_info_->url, priority,
- &stream_, stream_net_log);
- if (error != OK)
- return error;
-
- // |stream_| may be NULL even if OK was returned.
- if (stream_) {
- DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM);
- InitializeStreamHelper();
- return OK;
- }
- }
-
- int rv = stream_request_.StartRequest(
- SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url,
- priority, stream_net_log,
- base::Bind(&SpdyHttpStream::OnStreamCreated,
- weak_factory_.GetWeakPtr(), callback));
-
- if (rv == OK) {
- stream_ = stream_request_.ReleaseStream().get();
- InitializeStreamHelper();
- }
-
- return rv;
-}
-
-int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
- CHECK(!callback.is_null());
- if (stream_closed_)
- return closed_stream_status_;
-
- CHECK(stream_);
-
- // Check if we already have the response headers. If so, return synchronously.
- if (response_headers_complete_) {
- CHECK(!stream_->IsIdle());
- return OK;
- }
-
- // Still waiting for the response, return IO_PENDING.
- CHECK(response_callback_.is_null());
- response_callback_ = callback;
- return ERR_IO_PENDING;
-}
-
-int SpdyHttpStream::ReadResponseBody(
- IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
- // Invalidate HttpRequestInfo pointer. This is to allow the stream to be
- // shared across multiple transactions which might require this
- // stream to outlive the request_'s owner.
- // Only allowed when Reading of response body starts. It is safe to reset it
- // at this point since request_->upload_data_stream is also not needed
- // anymore.
- request_info_ = nullptr;
-
- if (stream_)
- CHECK(!stream_->IsIdle());
-
- CHECK(buf);
- CHECK(buf_len);
- CHECK(!callback.is_null());
-
- // If we have data buffered, complete the IO immediately.
- if (!response_body_queue_.IsEmpty()) {
- return response_body_queue_.Dequeue(buf->data(), buf_len);
- } else if (stream_closed_) {
- return closed_stream_status_;
- }
-
- CHECK(response_callback_.is_null());
- CHECK(!user_buffer_.get());
- CHECK_EQ(0, user_buffer_len_);
-
- response_callback_ = callback;
- user_buffer_ = buf;
- user_buffer_len_ = buf_len;
- return ERR_IO_PENDING;
-}
-
-void SpdyHttpStream::Close(bool not_reusable) {
- // Note: the not_reusable flag has no meaning for SPDY streams.
-
- Cancel();
- DCHECK(!stream_);
-}
-
-bool SpdyHttpStream::IsResponseBodyComplete() const {
- return stream_closed_;
-}
-
-bool SpdyHttpStream::IsConnectionReused() const {
- return is_reused_;
-}
-
-int64_t SpdyHttpStream::GetTotalReceivedBytes() const {
- if (stream_closed_)
- return closed_stream_received_bytes_;
-
- if (!stream_)
- return 0;
-
- return stream_->raw_received_bytes();
-}
-
-int64_t SpdyHttpStream::GetTotalSentBytes() const {
- if (stream_closed_)
- return closed_stream_sent_bytes_;
-
- if (!stream_)
- return 0;
-
- return stream_->raw_sent_bytes();
-}
-
-bool SpdyHttpStream::GetAlternativeService(
- AlternativeService* alternative_service) const {
- return false;
-}
-
-bool SpdyHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
- if (stream_closed_) {
- if (!closed_stream_has_load_timing_info_)
- return false;
- *load_timing_info = closed_stream_load_timing_info_;
- return true;
- }
-
- // If |stream_| has yet to be created, or does not yet have an ID, fail.
- // The reused flag can only be correctly set once a stream has an ID. Streams
- // get their IDs once the request has been successfully sent, so this does not
- // behave that differently from other stream types.
- if (!stream_ || stream_->stream_id() == 0)
- return false;
-
- return stream_->GetLoadTimingInfo(load_timing_info);
-}
-
-int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
- HttpResponseInfo* response,
- const CompletionCallback& callback) {
- if (stream_closed_) {
- return closed_stream_status_;
- }
-
- base::Time request_time = base::Time::Now();
- CHECK(stream_);
-
- stream_->SetRequestTime(request_time);
- // This should only get called in the case of a request occurring
- // during server push that has already begun but hasn't finished,
- // so we set the response's request time to be the actual one
- if (response_info_)
- response_info_->request_time = request_time;
-
- CHECK(!request_body_buf_.get());
- if (HasUploadData()) {
- request_body_buf_ = new IOBufferWithSize(kRequestBodyBufferSize);
- // The request body buffer is empty at first.
- request_body_buf_size_ = 0;
- }
-
- CHECK(!callback.is_null());
- CHECK(response);
-
- // SendRequest can be called in two cases.
- //
- // a) A client initiated request. In this case, |response_info_| should be
- // NULL to start with.
- // b) A client request which matches a response that the server has already
- // pushed.
- if (push_response_info_.get()) {
- *response = *(push_response_info_.get());
- push_response_info_.reset();
- } else {
- DCHECK_EQ(static_cast<HttpResponseInfo*>(NULL), response_info_);
- }
-
- response_info_ = response;
-
- // Put the peer's IP address and port into the response.
- IPEndPoint address;
- int result = stream_->GetPeerAddress(&address);
- if (result != OK)
- return result;
- response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
-
- if (stream_->type() == SPDY_PUSH_STREAM) {
- // Pushed streams do not send any data, and should always be
- // idle. However, we still want to return ERR_IO_PENDING to mimic
- // non-push behavior. The callback will be called when the
- // response is received.
- CHECK(response_callback_.is_null());
- response_callback_ = callback;
- return ERR_IO_PENDING;
- }
-
- SpdyHeaderBlock headers;
- CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, direct_,
- &headers);
- stream_->net_log().AddEvent(
- NetLogEventType::HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS,
- base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
- result = stream_->SendRequestHeaders(
- std::move(headers),
- HasUploadData() ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND);
-
- if (result == ERR_IO_PENDING) {
- CHECK(request_callback_.is_null());
- request_callback_ = callback;
- }
- return result;
-}
-
-void SpdyHttpStream::Cancel() {
- request_callback_.Reset();
- response_callback_.Reset();
- if (stream_) {
- stream_->Cancel();
- DCHECK(!stream_);
- }
-}
-
-void SpdyHttpStream::OnHeadersSent() {
- if (HasUploadData()) {
- ReadAndSendRequestBodyData();
- } else {
- MaybePostRequestCallback(OK);
- }
-}
-
-void SpdyHttpStream::OnHeadersReceived(
- const SpdyHeaderBlock& response_headers) {
- DCHECK(!response_headers_complete_);
- response_headers_complete_ = true;
-
- if (!response_info_) {
- DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM);
- push_response_info_.reset(new HttpResponseInfo);
- response_info_ = push_response_info_.get();
- }
-
- const bool headers_valid =
- SpdyHeadersToHttpResponse(response_headers, response_info_);
- DCHECK(headers_valid);
-
- response_info_->response_time = stream_->response_time();
- // Don't store the SSLInfo in the response here, HttpNetworkTransaction
- // will take care of that part.
- response_info_->was_alpn_negotiated = was_alpn_negotiated_;
- response_info_->request_time = stream_->GetRequestTime();
- response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP2;
- response_info_->alpn_negotiated_protocol =
- HttpResponseInfo::ConnectionInfoToString(response_info_->connection_info);
- response_info_->vary_data
- .Init(*request_info_, *response_info_->headers.get());
-
- if (!response_callback_.is_null()) {
- DoResponseCallback(OK);
- }
-}
-
-void SpdyHttpStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) {
- DCHECK(response_headers_complete_);
-
- // Note that data may be received for a SpdyStream prior to the user calling
- // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often
- // happen for server initiated streams.
- DCHECK(stream_);
- DCHECK(!stream_->IsClosed() || stream_->type() == SPDY_PUSH_STREAM);
- if (buffer) {
- response_body_queue_.Enqueue(std::move(buffer));
-
- if (user_buffer_.get()) {
- // Handing small chunks of data to the caller creates measurable overhead.
- // We buffer data in short time-spans and send a single read notification.
- ScheduleBufferedReadCallback();
- }
- }
-}
-
-void SpdyHttpStream::OnDataSent() {
- request_body_buf_size_ = 0;
- ReadAndSendRequestBodyData();
-}
-
-// TODO(xunjieli): Maybe do something with the trailers. crbug.com/422958.
-void SpdyHttpStream::OnTrailers(const SpdyHeaderBlock& trailers) {}
-
-void SpdyHttpStream::OnClose(int status) {
- // Cancel any pending reads from the upload data stream.
- if (request_info_ && request_info_->upload_data_stream)
- request_info_->upload_data_stream->Reset();
-
- if (stream_) {
- stream_closed_ = true;
- closed_stream_status_ = status;
- closed_stream_id_ = stream_->stream_id();
- closed_stream_has_load_timing_info_ =
- stream_->GetLoadTimingInfo(&closed_stream_load_timing_info_);
- closed_stream_received_bytes_ = stream_->raw_received_bytes();
- closed_stream_sent_bytes_ = stream_->raw_sent_bytes();
- }
- stream_ = nullptr;
-
- // Callbacks might destroy |this|.
- base::WeakPtr<SpdyHttpStream> self = weak_factory_.GetWeakPtr();
-
- if (!request_callback_.is_null()) {
- DoRequestCallback(status);
- if (!self)
- return;
- }
-
- if (status == OK) {
- // We need to complete any pending buffered read now.
- DoBufferedReadCallback();
- if (!self)
- return;
- }
-
- if (!response_callback_.is_null()) {
- DoResponseCallback(status);
- }
-}
-
-NetLogSource SpdyHttpStream::source_dependency() const {
- return source_dependency_;
-}
-
-bool SpdyHttpStream::HasUploadData() const {
- CHECK(request_info_);
- return
- request_info_->upload_data_stream &&
- ((request_info_->upload_data_stream->size() > 0) ||
- request_info_->upload_data_stream->is_chunked());
-}
-
-void SpdyHttpStream::OnStreamCreated(
- const CompletionCallback& callback,
- int rv) {
- if (rv == OK) {
- stream_ = stream_request_.ReleaseStream().get();
- InitializeStreamHelper();
- }
- callback.Run(rv);
-}
-
-void SpdyHttpStream::ReadAndSendRequestBodyData() {
- CHECK(HasUploadData());
- CHECK_EQ(request_body_buf_size_, 0);
- if (request_info_->upload_data_stream->IsEOF()) {
- MaybePostRequestCallback(OK);
- return;
- }
-
- // Read the data from the request body stream.
- const int rv = request_info_->upload_data_stream
- ->Read(request_body_buf_.get(),
- request_body_buf_->size(),
- base::Bind(&SpdyHttpStream::OnRequestBodyReadCompleted,
- weak_factory_.GetWeakPtr()));
-
- if (rv != ERR_IO_PENDING)
- OnRequestBodyReadCompleted(rv);
-}
-
-void SpdyHttpStream::InitializeStreamHelper() {
- stream_->SetDelegate(this);
- was_alpn_negotiated_ = stream_->WasAlpnNegotiated();
-}
-
-void SpdyHttpStream::ResetStreamInternal() {
- spdy_session_->ResetStream(stream()->stream_id(), ERROR_CODE_INTERNAL_ERROR,
- SpdyString());
-}
-
-void SpdyHttpStream::OnRequestBodyReadCompleted(int status) {
- if (status < 0) {
- DCHECK_NE(ERR_IO_PENDING, status);
- // Post |request_callback_| with received error. This should be posted
- // before ResetStreamInternal, because the latter would call
- // |request_callback_| via OnClose with an error code potentially different
- // from |status|.
- MaybePostRequestCallback(status);
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&SpdyHttpStream::ResetStreamInternal,
- weak_factory_.GetWeakPtr()));
-
- return;
- }
-
- CHECK_GE(status, 0);
- request_body_buf_size_ = status;
- const bool eof = request_info_->upload_data_stream->IsEOF();
- // Only the final frame may have a length of 0.
- if (eof) {
- CHECK_GE(request_body_buf_size_, 0);
- } else {
- CHECK_GT(request_body_buf_size_, 0);
- }
- stream_->SendData(request_body_buf_.get(),
- request_body_buf_size_,
- eof ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND);
-}
-
-void SpdyHttpStream::ScheduleBufferedReadCallback() {
- // If there is already a scheduled DoBufferedReadCallback, don't issue
- // another one. Mark that we have received more data and return.
- if (buffered_read_callback_pending_) {
- more_read_data_pending_ = true;
- return;
- }
-
- more_read_data_pending_ = false;
- buffered_read_callback_pending_ = true;
- const base::TimeDelta kBufferTime = base::TimeDelta::FromMilliseconds(1);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&SpdyHttpStream::DoBufferedReadCallback,
- weak_factory_.GetWeakPtr()),
- kBufferTime);
-}
-
-// Checks to see if we should wait for more buffered data before notifying
-// the caller. Returns true if we should wait, false otherwise.
-bool SpdyHttpStream::ShouldWaitForMoreBufferedData() const {
- // If the response is complete, there is no point in waiting.
- if (stream_closed_)
- return false;
-
- DCHECK_GT(user_buffer_len_, 0);
- return response_body_queue_.GetTotalSize() <
- static_cast<size_t>(user_buffer_len_);
-}
-
-void SpdyHttpStream::DoBufferedReadCallback() {
- buffered_read_callback_pending_ = false;
-
- // If the transaction is cancelled or errored out, we don't need to complete
- // the read.
- if (!stream_ && !stream_closed_)
- return;
-
- int stream_status =
- stream_closed_ ? closed_stream_status_ : stream_->response_status();
- if (stream_status != OK)
- return;
-
- // When more_read_data_pending_ is true, it means that more data has
- // arrived since we started waiting. Wait a little longer and continue
- // to buffer.
- if (more_read_data_pending_ && ShouldWaitForMoreBufferedData()) {
- ScheduleBufferedReadCallback();
- return;
- }
-
- int rv = 0;
- if (user_buffer_.get()) {
- rv = ReadResponseBody(user_buffer_.get(), user_buffer_len_,
- response_callback_);
- CHECK_NE(rv, ERR_IO_PENDING);
- user_buffer_ = NULL;
- user_buffer_len_ = 0;
- DoResponseCallback(rv);
- }
-}
-
-void SpdyHttpStream::DoRequestCallback(int rv) {
- CHECK_NE(rv, ERR_IO_PENDING);
- CHECK(!request_callback_.is_null());
- // Since Run may result in being called back, reset request_callback_ in
- // advance.
- base::ResetAndReturn(&request_callback_).Run(rv);
-}
-
-void SpdyHttpStream::MaybeDoRequestCallback(int rv) {
- CHECK_NE(ERR_IO_PENDING, rv);
- if (request_callback_)
- base::ResetAndReturn(&request_callback_).Run(rv);
-}
-
-void SpdyHttpStream::MaybePostRequestCallback(int rv) {
- CHECK_NE(ERR_IO_PENDING, rv);
- if (request_callback_)
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&SpdyHttpStream::MaybeDoRequestCallback,
- weak_factory_.GetWeakPtr(), rv));
-}
-
-void SpdyHttpStream::DoResponseCallback(int rv) {
- CHECK_NE(rv, ERR_IO_PENDING);
- CHECK(!response_callback_.is_null());
-
- // Since Run may result in being called back, reset response_callback_ in
- // advance.
- base::ResetAndReturn(&response_callback_).Run(rv);
-}
-
-bool SpdyHttpStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
- if (!spdy_session_)
- return false;
-
- return spdy_session_->GetPeerAddress(endpoint) == OK;
-}
-
-void SpdyHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) {
- details->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP2;
- return;
-}
-
-void SpdyHttpStream::SetPriority(RequestPriority priority) {
- // TODO(akalin): Plumb this through to |stream_request_| and
- // |stream_|.
-}
-
-} // namespace net
« no previous file with comments | « net/spdy/spdy_http_stream.h ('k') | net/spdy/spdy_http_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698