2525import java .security .cert .CertificateException ;
2626import java .util .ArrayList ;
2727import java .util .Base64 ;
28+ import java .util .HashMap ;
2829import java .util .LinkedList ;
2930import java .util .List ;
3031import java .util .Locale ;
32+ import java .util .Map ;
3133import java .util .concurrent .TimeUnit ;
3234
3335import javax .net .ssl .HostnameVerifier ;
5456import okhttp3 .Call ;
5557import okhttp3 .Connection ;
5658import okhttp3 .Credentials ;
59+ import okhttp3 .EventListener ;
5760import okhttp3 .Headers ;
5861import okhttp3 .Interceptor ;
5962import okhttp3 .MediaType ;
6568import okhttp3 .Response ;
6669import okhttp3 .ResponseBody ;
6770import okhttp3 .Route ;
71+ import okhttp3 .EventListener .Factory ;
6872import okio .BufferedSource ;
6973
7074public class HttpProtocol extends AbstractHttpProtocol {
@@ -86,6 +90,9 @@ public class HttpProtocol extends AbstractHttpProtocol {
8690
8791 private final List <String []> customRequestHeaders = new LinkedList <>();
8892
93+ // track the time spent for each URL in DNS resolution
94+ private final Map <String , Long > DNStimes = new HashMap <>();
95+
8996 private static final TrustManager [] trustAllCerts = new TrustManager [] { new X509TrustManager () {
9097 @ Override
9198 public void checkClientTrusted (
@@ -237,6 +244,13 @@ public boolean verify(String hostname, SSLSession session) {
237244 });
238245 }
239246
247+ builder .eventListenerFactory (new Factory () {
248+ @ Override
249+ public EventListener create (Call call ) {
250+ return new DNSResolutionListener (DNStimes );
251+ }
252+ });
253+
240254 client = builder .build ();
241255 }
242256
@@ -332,7 +346,13 @@ public ProtocolResponse getProtocolOutput(String url, final Metadata metadata) t
332346 trimmed .getValue ().toString ().toLowerCase (Locale .ROOT ));
333347 LOG .warn ("HTTP content trimmed to {}" , bytes .length );
334348 }
335-
349+
350+ Long DNSResolution = DNStimes .remove (call .toString ());
351+ if (DNSResolution != null ) {
352+ responsemetadata .setValue ("metrics.dns.resolution.msec" ,
353+ DNSResolution .toString ());
354+ }
355+
336356 return new ProtocolResponse (bytes , response .code (), responsemetadata );
337357 }
338358 }
@@ -358,7 +378,7 @@ private final byte[] toByteArray(final ResponseBody responseBody,
358378 int bytesRequested = 0 ;
359379 int bufferGrowStepBytes = 8192 ;
360380
361- while (source .buffer ().size () <= maxContentBytes ) {
381+ while (source .getBuffer ().size () <= maxContentBytes ) {
362382 bytesRequested += Math .min (bufferGrowStepBytes ,
363383 /*
364384 * request one byte more than required to reliably detect truncated
@@ -371,7 +391,7 @@ private final byte[] toByteArray(final ResponseBody responseBody,
371391 success = source .request (bytesRequested );
372392 } catch (IOException e ) {
373393 // requesting more content failed, e.g. by a socket timeout
374- if (partialContentAsTrimmed && source .buffer ().size () > 0 ) {
394+ if (partialContentAsTrimmed && source .getBuffer ().size () > 0 ) {
375395 // treat already fetched content as trimmed
376396 trimmed .setValue (TrimmedContentReason .DISCONNECT );
377397 LOG .debug ("Exception while fetching {}" , e );
@@ -392,17 +412,17 @@ private final byte[] toByteArray(final ResponseBody responseBody,
392412
393413 // okhttp may fetch more content than requested, quickly "increment"
394414 // bytes
395- bytesRequested = (int ) source .buffer ().size ();
415+ bytesRequested = (int ) source .getBuffer ().size ();
396416 }
397- int bytesBuffered = (int ) source .buffer ().size ();
417+ int bytesBuffered = (int ) source .getBuffer ().size ();
398418 int bytesToCopy = bytesBuffered ;
399419 if (maxContent != -1 && bytesToCopy > maxContent ) {
400420 // okhttp's internal buffer is larger than maxContent
401421 trimmed .setValue (TrimmedContentReason .LENGTH );
402422 bytesToCopy = maxContentBytes ;
403423 }
404424 byte [] arr = new byte [bytesToCopy ];
405- source .buffer ().readFully (arr );
425+ source .getBuffer ().readFully (arr );
406426 return arr ;
407427 }
408428
0 commit comments