| Index: net/http/http_network_transaction.cc
|
| ===================================================================
|
| --- net/http/http_network_transaction.cc (revision 54789)
|
| +++ net/http/http_network_transaction.cc (working copy)
|
| @@ -298,7 +298,7 @@
|
| // update in DoSSLConnectComplete if |result| is OK?
|
| if (using_spdy_) {
|
| // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620
|
| - next_state_ = STATE_SPDY_GET_STREAM;
|
| + next_state_ = STATE_INIT_STREAM;
|
| } else {
|
| next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
|
| }
|
| @@ -370,10 +370,10 @@
|
| // Even if the server says the connection is keep-alive, we have to be
|
| // able to find the end of each response in order to reuse the connection.
|
| if (GetResponseHeaders()->IsKeepAlive() &&
|
| - http_stream_->CanFindEndOfResponse()) {
|
| + stream_->CanFindEndOfResponse()) {
|
| // If the response body hasn't been completely read, we need to drain
|
| // it first.
|
| - if (!http_stream_->IsResponseBodyComplete()) {
|
| + if (!stream_->IsResponseBodyComplete()) {
|
| next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
|
| read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket.
|
| read_buf_len_ = kDrainBodyBufferSize;
|
| @@ -430,16 +430,10 @@
|
| }
|
|
|
| // Are we using SPDY or HTTP?
|
| - if (using_spdy_) {
|
| - DCHECK(!http_stream_.get());
|
| - DCHECK(spdy_http_stream_->GetResponseInfo()->headers);
|
| - next_state = STATE_SPDY_READ_BODY;
|
| - } else {
|
| - DCHECK(!spdy_http_stream_.get());
|
| - next_state = STATE_READ_BODY;
|
| -
|
| - if (!connection_->is_initialized())
|
| - return 0; // |*connection_| has been reset. Treat like EOF.
|
| + next_state = STATE_READ_BODY;
|
| + DCHECK(stream_->GetResponseInfo()->headers);
|
| + if (!using_spdy_ && !connection_->is_initialized()) {
|
| + return 0; // |*connection_| has been reset. Treat like EOF.
|
| }
|
|
|
| read_buf_ = buf;
|
| @@ -468,14 +462,11 @@
|
| case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
|
| case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
|
| case STATE_SEND_REQUEST_COMPLETE:
|
| - case STATE_SPDY_GET_STREAM:
|
| - case STATE_SPDY_SEND_REQUEST_COMPLETE:
|
| + case STATE_INIT_STREAM_COMPLETE:
|
| return LOAD_STATE_SENDING_REQUEST;
|
| case STATE_READ_HEADERS_COMPLETE:
|
| - case STATE_SPDY_READ_HEADERS_COMPLETE:
|
| return LOAD_STATE_WAITING_FOR_RESPONSE;
|
| case STATE_READ_BODY_COMPLETE:
|
| - case STATE_SPDY_READ_BODY_COMPLETE:
|
| return LOAD_STATE_READING_RESPONSE;
|
| default:
|
| return LOAD_STATE_IDLE;
|
| @@ -483,10 +474,10 @@
|
| }
|
|
|
| uint64 HttpNetworkTransaction::GetUploadProgress() const {
|
| - if (!http_stream_.get())
|
| + if (!stream_.get())
|
| return 0;
|
|
|
| - return http_stream_->GetUploadProgress();
|
| + return stream_->GetUploadProgress();
|
| }
|
|
|
| HttpNetworkTransaction::~HttpNetworkTransaction() {
|
| @@ -497,9 +488,10 @@
|
| // The STATE_NONE check guarantees there are no pending socket IOs that
|
| // could try to call this object back after it is deleted.
|
| bool keep_alive = next_state_ == STATE_NONE &&
|
| - http_stream_.get() &&
|
| - http_stream_->IsResponseBodyComplete() &&
|
| - http_stream_->CanFindEndOfResponse() &&
|
| + !using_spdy_ &&
|
| + stream_.get() &&
|
| + stream_->IsResponseBodyComplete() &&
|
| + stream_->CanFindEndOfResponse() &&
|
| GetResponseHeaders()->IsKeepAlive();
|
| if (!keep_alive)
|
| connection_->socket()->Disconnect();
|
| @@ -508,8 +500,8 @@
|
| if (pac_request_)
|
| session_->proxy_service()->CancelPacRequest(pac_request_);
|
|
|
| - if (spdy_http_stream_.get())
|
| - spdy_http_stream_->Cancel();
|
| + if (using_spdy_ && stream_.get())
|
| + static_cast<SpdyHttpStream*>(stream_.get())->Cancel();
|
| }
|
|
|
| void HttpNetworkTransaction::DoCallback(int rv) {
|
| @@ -550,6 +542,13 @@
|
| case STATE_INIT_CONNECTION_COMPLETE:
|
| rv = DoInitConnectionComplete(rv);
|
| break;
|
| + case STATE_INIT_STREAM:
|
| + DCHECK_EQ(OK, rv);
|
| + rv = DoInitStream();
|
| + break;
|
| + case STATE_INIT_STREAM_COMPLETE:
|
| + rv = DoInitStreamComplete(rv);
|
| + break;
|
| case STATE_RESTART_TUNNEL_AUTH:
|
| DCHECK_EQ(OK, rv);
|
| rv = DoRestartTunnelAuth();
|
| @@ -609,40 +608,6 @@
|
| net_log_.EndEvent(
|
| NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, NULL);
|
| break;
|
| - case STATE_SPDY_GET_STREAM:
|
| - DCHECK_EQ(OK, rv);
|
| - rv = DoSpdyGetStream();
|
| - break;
|
| - case STATE_SPDY_GET_STREAM_COMPLETE:
|
| - rv = DoSpdyGetStreamComplete(rv);
|
| - break;
|
| - case STATE_SPDY_SEND_REQUEST:
|
| - DCHECK_EQ(OK, rv);
|
| - net_log_.BeginEvent(NetLog::TYPE_SPDY_TRANSACTION_SEND_REQUEST, NULL);
|
| - rv = DoSpdySendRequest();
|
| - break;
|
| - case STATE_SPDY_SEND_REQUEST_COMPLETE:
|
| - rv = DoSpdySendRequestComplete(rv);
|
| - net_log_.EndEvent(NetLog::TYPE_SPDY_TRANSACTION_SEND_REQUEST, NULL);
|
| - break;
|
| - case STATE_SPDY_READ_HEADERS:
|
| - DCHECK_EQ(OK, rv);
|
| - net_log_.BeginEvent(NetLog::TYPE_SPDY_TRANSACTION_READ_HEADERS, NULL);
|
| - rv = DoSpdyReadHeaders();
|
| - break;
|
| - case STATE_SPDY_READ_HEADERS_COMPLETE:
|
| - rv = DoSpdyReadHeadersComplete(rv);
|
| - net_log_.EndEvent(NetLog::TYPE_SPDY_TRANSACTION_READ_HEADERS, NULL);
|
| - break;
|
| - case STATE_SPDY_READ_BODY:
|
| - DCHECK_EQ(OK, rv);
|
| - net_log_.BeginEvent(NetLog::TYPE_SPDY_TRANSACTION_READ_BODY, NULL);
|
| - rv = DoSpdyReadBody();
|
| - break;
|
| - case STATE_SPDY_READ_BODY_COMPLETE:
|
| - rv = DoSpdyReadBodyComplete(rv);
|
| - net_log_.EndEvent(NetLog::TYPE_SPDY_TRANSACTION_READ_BODY, NULL);
|
| - break;
|
| default:
|
| NOTREACHED() << "bad state";
|
| rv = ERR_FAILED;
|
| @@ -748,7 +713,9 @@
|
| if (session_->spdy_session_pool()->HasSession(pair)) {
|
| using_spdy_ = true;
|
| reused_socket_ = true;
|
| - next_state_ = STATE_SPDY_GET_STREAM;
|
| + next_state_ = STATE_INIT_STREAM;
|
| + spdy_session_ =
|
| + session_->spdy_session_pool()->Get(pair, session_, net_log_);
|
| return OK;
|
| }
|
|
|
| @@ -950,7 +917,7 @@
|
| if (!using_ssl_) {
|
| DCHECK_EQ(OK, result);
|
| if (using_spdy_)
|
| - next_state_ = STATE_SPDY_GET_STREAM;
|
| + next_state_ = STATE_INIT_STREAM;
|
| else
|
| next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
|
| return result;
|
| @@ -987,13 +954,56 @@
|
| if (using_spdy_) {
|
| UpdateConnectionTypeHistograms(CONNECTION_SPDY);
|
| // TODO(cbentzel): Add auth support to spdy. See http://crbug.com/46620
|
| - next_state_ = STATE_SPDY_GET_STREAM;
|
| + next_state_ = STATE_INIT_STREAM;
|
| } else {
|
| next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
|
| }
|
| return OK;
|
| }
|
|
|
| +int HttpNetworkTransaction::DoInitStream() {
|
| + next_state_ = STATE_INIT_STREAM_COMPLETE;
|
| +
|
| + if (!using_spdy_) {
|
| + stream_.reset(new HttpBasicStream(connection_.get()));
|
| + return stream_->InitializeStream(request_, net_log_, &io_callback_);
|
| + }
|
| +
|
| + CHECK(!stream_.get());
|
| +
|
| + const scoped_refptr<SpdySessionPool> spdy_pool =
|
| + session_->spdy_session_pool();
|
| +
|
| + HostPortProxyPair pair(endpoint_, proxy_info_.ToPacString());
|
| + if (!spdy_session_.get()) {
|
| + // SPDY can be negotiated using the TLS next protocol negotiation (NPN)
|
| + // extension, or just directly using SSL. Either way, |connection_| must
|
| + // contain an SSLClientSocket.
|
| + CHECK(connection_->socket());
|
| + int error = spdy_pool->GetSpdySessionFromSocket(
|
| + pair, session_, connection_.release(), net_log_,
|
| + spdy_certificate_error_, &spdy_session_, using_ssl_);
|
| + if (error != OK)
|
| + return error;
|
| + }
|
| + CHECK(spdy_session_.get());
|
| + if (spdy_session_->IsClosed())
|
| + return ERR_CONNECTION_CLOSED;
|
| +
|
| + headers_valid_ = false;
|
| +
|
| + stream_.reset(new SpdyHttpStream(spdy_session_.release()));
|
| + return stream_->InitializeStream(request_, net_log_, &io_callback_);
|
| +}
|
| +
|
| +int HttpNetworkTransaction::DoInitStreamComplete(int result) {
|
| + if (result < 0)
|
| + return result;
|
| +
|
| + next_state_ = STATE_SEND_REQUEST;
|
| + return OK;
|
| +}
|
| +
|
| int HttpNetworkTransaction::DoRestartTunnelAuth() {
|
| next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE;
|
| HttpProxyClientSocket* http_proxy_socket =
|
| @@ -1057,7 +1067,7 @@
|
| int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
|
| DCHECK_NE(ERR_IO_PENDING, rv);
|
| if (rv == OK)
|
| - next_state_ = STATE_SEND_REQUEST;
|
| + next_state_ = STATE_INIT_STREAM;
|
| return rv;
|
| }
|
|
|
| @@ -1074,7 +1084,7 @@
|
|
|
| // This is constructed lazily (instead of within our Start method), so that
|
| // we have proxy info available.
|
| - if (request_headers_.empty()) {
|
| + if (request_headers_.empty() && !using_spdy_) {
|
| // Figure out if we can/should add Proxy-Authentication & Authentication
|
| // headers.
|
| HttpRequestHeaders authorization_headers;
|
| @@ -1107,10 +1117,8 @@
|
| }
|
|
|
| headers_valid_ = false;
|
| - http_stream_.reset(new HttpBasicStream(connection_.get()));
|
| - http_stream_->InitializeStream(request_, net_log_, NULL);
|
| - return http_stream_->SendRequest(request_headers_, request_body, &response_,
|
| - &io_callback_);
|
| + return stream_->SendRequest(request_headers_, request_body, &response_,
|
| + &io_callback_);
|
| }
|
|
|
| int HttpNetworkTransaction::DoSendRequestComplete(int result) {
|
| @@ -1122,7 +1130,7 @@
|
|
|
| int HttpNetworkTransaction::DoReadHeaders() {
|
| next_state_ = STATE_READ_HEADERS_COMPLETE;
|
| - return http_stream_->ReadResponseHeaders(&io_callback_);
|
| + return stream_->ReadResponseHeaders(&io_callback_);
|
| }
|
|
|
| int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() {
|
| @@ -1136,6 +1144,18 @@
|
| }
|
|
|
| int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
|
| + if (using_spdy_) {
|
| + // TODO(willchan): Flesh out the support for HTTP authentication here.
|
| + if (result < 0)
|
| + return HandleIOError(result);
|
| +
|
| + if (result == OK)
|
| + headers_valid_ = true;
|
| +
|
| + LogTransactionConnectedMetrics();
|
| + return result;
|
| + }
|
| +
|
| // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here
|
| // due to SSL renegotiation.
|
| if (using_ssl_) {
|
| @@ -1241,32 +1261,37 @@
|
| int HttpNetworkTransaction::DoReadBody() {
|
| DCHECK(read_buf_);
|
| DCHECK_GT(read_buf_len_, 0);
|
| - DCHECK(connection_->is_initialized());
|
| + if (!using_spdy_)
|
| + DCHECK(connection_->is_initialized());
|
|
|
| next_state_ = STATE_READ_BODY_COMPLETE;
|
| - return http_stream_->ReadResponseBody(read_buf_, read_buf_len_,
|
| - &io_callback_);
|
| + return stream_->ReadResponseBody(read_buf_, read_buf_len_, &io_callback_);
|
| }
|
|
|
| int HttpNetworkTransaction::DoReadBodyComplete(int result) {
|
| - // We are done with the Read call.
|
| - bool done = false, keep_alive = false;
|
| - if (result <= 0)
|
| - done = true;
|
| + if (!using_spdy_) {
|
| + // We are done with the Read call.
|
| + bool done = false, keep_alive = false;
|
| + if (result <= 0)
|
| + done = true;
|
|
|
| - if (http_stream_->IsResponseBodyComplete()) {
|
| - done = true;
|
| - if (http_stream_->CanFindEndOfResponse())
|
| - keep_alive = GetResponseHeaders()->IsKeepAlive();
|
| - }
|
| + if (stream_->IsResponseBodyComplete()) {
|
| + done = true;
|
| + if (stream_->CanFindEndOfResponse())
|
| + keep_alive = GetResponseHeaders()->IsKeepAlive();
|
| + }
|
|
|
| - // Clean up connection_->if we are done.
|
| - if (done) {
|
| - LogTransactionMetrics();
|
| - if (!keep_alive)
|
| - connection_->socket()->Disconnect();
|
| - connection_->Reset();
|
| - // The next Read call will return 0 (EOF).
|
| + // Clean up connection_->if we are done.
|
| + if (done) {
|
| + LogTransactionMetrics();
|
| + if (!keep_alive)
|
| + connection_->socket()->Disconnect();
|
| + connection_->Reset();
|
| + // The next Read call will return 0 (EOF).
|
| + }
|
| + } else {
|
| + if (result <= 0)
|
| + stream_.reset();
|
| }
|
|
|
| // Clear these to avoid leaving around old state.
|
| @@ -1296,7 +1321,7 @@
|
| // Error or closed connection while reading the socket.
|
| done = true;
|
| keep_alive = false;
|
| - } else if (http_stream_->IsResponseBodyComplete()) {
|
| + } else if (stream_->IsResponseBodyComplete()) {
|
| done = true;
|
| }
|
|
|
| @@ -1310,118 +1335,6 @@
|
| return OK;
|
| }
|
|
|
| -int HttpNetworkTransaction::DoSpdyGetStream() {
|
| - next_state_ = STATE_SPDY_GET_STREAM_COMPLETE;
|
| - CHECK(!spdy_http_stream_.get());
|
| -
|
| - // First we get a SPDY session. Theoretically, we've just negotiated one, but
|
| - // if one already exists, then screw it, use the existing one! Otherwise,
|
| - // use the existing TCP socket.
|
| -
|
| - const scoped_refptr<SpdySessionPool> spdy_pool =
|
| - session_->spdy_session_pool();
|
| - scoped_refptr<SpdySession> spdy_session;
|
| -
|
| - HostPortProxyPair pair(endpoint_, proxy_info_.ToPacString());
|
| - if (spdy_pool->HasSession(pair)) {
|
| - spdy_session = spdy_pool->Get(pair, session_, net_log_);
|
| - } else {
|
| - if(using_ssl_) {
|
| - // SPDY can be negotiated using the TLS next protocol negotiation (NPN)
|
| - // extension, or just directly using SSL. Either way, |connection_| must
|
| - // contain an SSLClientSocket.
|
| - CHECK(connection_->socket());
|
| - int error = spdy_pool->GetSpdySessionFromSocket(
|
| - pair, session_, connection_.release(), net_log_,
|
| - spdy_certificate_error_, &spdy_session, true);
|
| - if (error != OK)
|
| - return error;
|
| - }
|
| - else {
|
| - // We may want SPDY without SSL
|
| - int error = spdy_pool->GetSpdySessionFromSocket(
|
| - pair, session_, connection_.release(), net_log_,
|
| - spdy_certificate_error_, &spdy_session, false);
|
| - if (error != OK)
|
| - return error;
|
| - }
|
| - }
|
| -
|
| - CHECK(spdy_session.get());
|
| - if (spdy_session->IsClosed())
|
| - return ERR_CONNECTION_CLOSED;
|
| -
|
| - headers_valid_ = false;
|
| -
|
| - spdy_http_stream_.reset(new SpdyHttpStream(spdy_session));
|
| - return spdy_http_stream_->InitializeStream(request_, net_log_, &io_callback_);
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdyGetStreamComplete(int result) {
|
| - if (result < 0)
|
| - return result;
|
| -
|
| - next_state_ = STATE_SPDY_SEND_REQUEST;
|
| - return OK;
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdySendRequest() {
|
| - next_state_ = STATE_SPDY_SEND_REQUEST_COMPLETE;
|
| -
|
| - UploadDataStream* upload_data_stream = NULL;
|
| - if (request_->upload_data) {
|
| - int error_code = OK;
|
| - upload_data_stream = UploadDataStream::Create(request_->upload_data,
|
| - &error_code);
|
| - if (!upload_data_stream)
|
| - return error_code;
|
| - }
|
| - return spdy_http_stream_->SendRequest(request_headers_, upload_data_stream,
|
| - &response_, &io_callback_);
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdySendRequestComplete(int result) {
|
| - if (result < 0)
|
| - return HandleIOError(result);
|
| -
|
| - next_state_ = STATE_SPDY_READ_HEADERS;
|
| - return OK;
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdyReadHeaders() {
|
| - next_state_ = STATE_SPDY_READ_HEADERS_COMPLETE;
|
| - return spdy_http_stream_->ReadResponseHeaders(&io_callback_);
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdyReadHeadersComplete(int result) {
|
| - // TODO(willchan): Flesh out the support for HTTP authentication here.
|
| - if (result < 0)
|
| - return HandleIOError(result);
|
| -
|
| - if (result == OK)
|
| - headers_valid_ = true;
|
| -
|
| - LogTransactionConnectedMetrics();
|
| - return result;
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdyReadBody() {
|
| - next_state_ = STATE_SPDY_READ_BODY_COMPLETE;
|
| -
|
| - return spdy_http_stream_->ReadResponseBody(
|
| - read_buf_, read_buf_len_, &io_callback_);
|
| -}
|
| -
|
| -int HttpNetworkTransaction::DoSpdyReadBodyComplete(int result) {
|
| - read_buf_ = NULL;
|
| - read_buf_len_ = 0;
|
| -
|
| - if (result <= 0)
|
| - spdy_http_stream_.reset();
|
| -
|
| - return result;
|
| -}
|
| -
|
| void HttpNetworkTransaction::LogHttpConnectedMetrics(
|
| const ClientSocketHandle& handle) {
|
| UMA_HISTOGRAM_ENUMERATION("Net.HttpSocketType", handle.reuse_type(),
|
| @@ -1700,7 +1613,7 @@
|
| pending_auth_target_ = HttpAuth::AUTH_NONE;
|
| read_buf_ = NULL;
|
| read_buf_len_ = 0;
|
| - http_stream_.reset();
|
| + stream_.reset();
|
| headers_valid_ = false;
|
| request_headers_.clear();
|
| response_ = HttpResponseInfo();
|
| @@ -1711,8 +1624,9 @@
|
| }
|
|
|
| bool HttpNetworkTransaction::ShouldResendRequest(int error) const {
|
| - if (using_spdy_ && spdy_http_stream_ != NULL)
|
| - return spdy_http_stream_->ShouldResendFailedRequest(error);
|
| + if (using_spdy_ && stream_ != NULL)
|
| + return static_cast<SpdyHttpStream *>(stream_.get())->
|
| + ShouldResendFailedRequest(error);
|
|
|
| // NOTE: we resend a request only if we reused a keep-alive connection.
|
| // This automatically prevents an infinite resend loop because we'll run
|
| @@ -1739,7 +1653,7 @@
|
| // headers, but we may need to resend the CONNECT request first to recreate
|
| // the SSL tunnel.
|
|
|
| - spdy_http_stream_.reset(NULL);
|
| + stream_.reset(NULL);
|
|
|
| request_headers_.clear();
|
| next_state_ = STATE_INIT_CONNECTION; // Resend the request.
|
| @@ -1888,6 +1802,8 @@
|
| STATE_CASE(STATE_RESOLVE_PROXY_COMPLETE);
|
| STATE_CASE(STATE_INIT_CONNECTION);
|
| STATE_CASE(STATE_INIT_CONNECTION_COMPLETE);
|
| + STATE_CASE(STATE_INIT_STREAM);
|
| + STATE_CASE(STATE_INIT_STREAM_COMPLETE);
|
| STATE_CASE(STATE_GENERATE_PROXY_AUTH_TOKEN);
|
| STATE_CASE(STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE);
|
| STATE_CASE(STATE_GENERATE_SERVER_AUTH_TOKEN);
|
| @@ -1900,14 +1816,6 @@
|
| STATE_CASE(STATE_READ_BODY_COMPLETE);
|
| STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART);
|
| STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE);
|
| - STATE_CASE(STATE_SPDY_GET_STREAM);
|
| - STATE_CASE(STATE_SPDY_GET_STREAM_COMPLETE);
|
| - STATE_CASE(STATE_SPDY_SEND_REQUEST);
|
| - STATE_CASE(STATE_SPDY_SEND_REQUEST_COMPLETE);
|
| - STATE_CASE(STATE_SPDY_READ_HEADERS);
|
| - STATE_CASE(STATE_SPDY_READ_HEADERS_COMPLETE);
|
| - STATE_CASE(STATE_SPDY_READ_BODY);
|
| - STATE_CASE(STATE_SPDY_READ_BODY_COMPLETE);
|
| STATE_CASE(STATE_NONE);
|
| default:
|
| description = StringPrintf("Unknown state 0x%08X (%u)", state, state);
|
|
|