Add support for NetErrorDetails to Cronet's BidirectionalStream
This plumbs the quic error information through to Cronet's
BidirectionalStream::OnError
Bug: 624942
Cq-Include-Trybots: master.tryserver.chromium.android:android_cronet_tester
Change-Id: I7debf4c530cc9fba4a8fe5c62808afa582e6428e
Reviewed-on: https://chromium-review.googlesource.com/567282
Reviewed-by: Misha Efimov <[email protected]>
Commit-Queue: Brad Lassey <[email protected]>
Cr-Commit-Position: refs/heads/master@{#487690}
diff --git a/components/cronet/android/cronet_bidirectional_stream_adapter.cc b/components/cronet/android/cronet_bidirectional_stream_adapter.cc
index 104cb43..74e7d84c 100644
--- a/components/cronet/android/cronet_bidirectional_stream_adapter.cc
+++ b/components/cronet/android/cronet_bidirectional_stream_adapter.cc
@@ -322,10 +322,11 @@
DCHECK(context_->IsOnNetworkThread());
stream_failed_ = true;
JNIEnv* env = base::android::AttachCurrentThread();
- // TODO(mgersh): Add support for NetErrorDetails (http://crbug.com/624942)
+ net::NetErrorDetails net_error_details;
+ bidi_stream_->PopulateNetErrorDetails(&net_error_details);
cronet::Java_CronetBidirectionalStream_onError(
env, owner_.obj(), NetErrorToUrlRequestError(error), error,
- net::QUIC_NO_ERROR,
+ net_error_details.quic_connection_error,
ConvertUTF8ToJavaString(env, net::ErrorToString(error)).obj(),
bidi_stream_->GetTotalReceivedBytes());
}
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java
index 28f6612..5ff68b4 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java
@@ -334,6 +334,11 @@
NetworkException networkError = (NetworkException) callback.mError;
assertTrue(NetError.ERR_QUIC_PROTOCOL_ERROR == networkError.getCronetInternalErrorCode()
|| NetError.ERR_CONNECTION_REFUSED == networkError.getCronetInternalErrorCode());
+ if (NetError.ERR_CONNECTION_REFUSED == networkError.getCronetInternalErrorCode()) return;
+ assertTrue(callback.mError instanceof QuicException);
+ QuicException quicException = (QuicException) callback.mError;
+ // 16 is QUIC_PEER_GOING_AWAY
+ assertEquals(16, quicException.getQuicDetailedErrorCode());
}
@SmallTest
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc
index dbd25301..176f140 100644
--- a/net/http/bidirectional_stream.cc
+++ b/net/http/bidirectional_stream.cc
@@ -213,6 +213,12 @@
*load_timing_info = load_timing_info_;
}
+void BidirectionalStream::PopulateNetErrorDetails(NetErrorDetails* details) {
+ DCHECK(details);
+ if (stream_impl_)
+ stream_impl_->PopulateNetErrorDetails(details);
+}
+
void BidirectionalStream::OnStreamReady(bool request_headers_sent) {
request_headers_sent_ = request_headers_sent;
if (net_log_.IsCapturing()) {
diff --git a/net/http/bidirectional_stream.h b/net/http/bidirectional_stream.h
index e72e7fe4..043ce80b 100644
--- a/net/http/bidirectional_stream.h
+++ b/net/http/bidirectional_stream.h
@@ -31,6 +31,7 @@
class ProxyInfo;
class SpdyHeaderBlock;
struct BidirectionalStreamRequestInfo;
+struct NetErrorDetails;
struct SSLConfig;
// A class to do HTTP/2 bidirectional streaming. Note that at most one each of
@@ -170,6 +171,11 @@
// Gets LoadTimingInfo of this stream.
void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
+ // Get the network error details this stream is encountering.
+ // Fills in |details| if it is available; leaves |details| unchanged if it
+ // is unavailable.
+ void PopulateNetErrorDetails(NetErrorDetails* details);
+
private:
// BidirectionalStreamImpl::Delegate implementation:
void OnStreamReady(bool request_headers_sent) override;
diff --git a/net/http/bidirectional_stream_impl.h b/net/http/bidirectional_stream_impl.h
index 9b5ffab7..b5228f25 100644
--- a/net/http/bidirectional_stream_impl.h
+++ b/net/http/bidirectional_stream_impl.h
@@ -26,6 +26,7 @@
class NetLogWithSource;
class SpdyHeaderBlock;
struct BidirectionalStreamRequestInfo;
+struct NetErrorDetails;
// Exposes an interface to do HTTP/2 bidirectional streaming.
// Note that only one ReadData or SendData should be in flight until the
@@ -152,6 +153,11 @@
// and false otherwise.
virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const = 0;
+ // Get the network error details this stream is encountering.
+ // Fills in |details| if it is available; leaves |details| unchanged if it
+ // is unavailable.
+ virtual void PopulateNetErrorDetails(NetErrorDetails* details) = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(BidirectionalStreamImpl);
};
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl.cc b/net/quic/chromium/bidirectional_stream_quic_impl.cc
index c10720d5..648056a 100644
--- a/net/quic/chromium/bidirectional_stream_quic_impl.cc
+++ b/net/quic/chromium/bidirectional_stream_quic_impl.cc
@@ -17,6 +17,7 @@
#include "net/socket/next_proto.h"
#include "net/spdy/chromium/spdy_http_utils.h"
#include "net/spdy/core/spdy_header_block.h"
+#include "quic_http_stream.h"
namespace net {
namespace {
@@ -226,6 +227,16 @@
return true;
}
+void BidirectionalStreamQuicImpl::PopulateNetErrorDetails(
+ NetErrorDetails* details) {
+ DCHECK(details);
+ details->connection_info =
+ QuicHttpStream::ConnectionInfoFromQuicVersion(session_->GetQuicVersion());
+ session_->PopulateNetErrorDetails(details);
+ if (session_->IsCryptoHandshakeConfirmed() && stream_)
+ details->quic_connection_error = stream_->connection_error();
+}
+
void BidirectionalStreamQuicImpl::OnStreamReady(int rv) {
DCHECK_NE(ERR_IO_PENDING, rv);
DCHECK(!stream_);
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl.h b/net/quic/chromium/bidirectional_stream_quic_impl.h
index 8ec93aee..8b63600bd 100644
--- a/net/quic/chromium/bidirectional_stream_quic_impl.h
+++ b/net/quic/chromium/bidirectional_stream_quic_impl.h
@@ -51,6 +51,7 @@
int64_t GetTotalReceivedBytes() const override;
int64_t GetTotalSentBytes() const override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
private:
int WriteHeaders();
diff --git a/net/spdy/chromium/bidirectional_stream_spdy_impl.cc b/net/spdy/chromium/bidirectional_stream_spdy_impl.cc
index fa223bb4..616f1673 100644
--- a/net/spdy/chromium/bidirectional_stream_spdy_impl.cc
+++ b/net/spdy/chromium/bidirectional_stream_spdy_impl.cc
@@ -193,6 +193,9 @@
return stream_->GetLoadTimingInfo(load_timing_info);
}
+void BidirectionalStreamSpdyImpl::PopulateNetErrorDetails(
+ NetErrorDetails* details) {}
+
void BidirectionalStreamSpdyImpl::OnHeadersSent() {
DCHECK(stream_);
diff --git a/net/spdy/chromium/bidirectional_stream_spdy_impl.h b/net/spdy/chromium/bidirectional_stream_spdy_impl.h
index 61e00e0..c4c11ed 100644
--- a/net/spdy/chromium/bidirectional_stream_spdy_impl.h
+++ b/net/spdy/chromium/bidirectional_stream_spdy_impl.h
@@ -57,6 +57,7 @@
int64_t GetTotalReceivedBytes() const override;
int64_t GetTotalSentBytes() const override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
+ void PopulateNetErrorDetails(NetErrorDetails* details) override;
// SpdyStream::Delegate implementation:
void OnHeadersSent() override;