55
66package io .opentelemetry .contrib .aws .resource ;
77
8+ import java .io .ByteArrayOutputStream ;
89import java .io .FileInputStream ;
910import java .io .IOException ;
11+ import java .io .InputStream ;
12+ import java .net .HttpURLConnection ;
13+ import java .net .URL ;
14+ import java .nio .charset .StandardCharsets ;
1015import java .security .KeyStore ;
1116import java .security .cert .Certificate ;
1217import java .security .cert .CertificateFactory ;
1318import java .time .Duration ;
1419import java .util .Collection ;
1520import java .util .Map ;
21+ import java .util .Objects ;
1622import java .util .logging .Level ;
1723import java .util .logging .Logger ;
1824import javax .annotation .Nullable ;
25+ import javax .net .ssl .HttpsURLConnection ;
1926import javax .net .ssl .SSLContext ;
2027import javax .net .ssl .SSLSocketFactory ;
2128import javax .net .ssl .TrustManager ;
2229import javax .net .ssl .TrustManagerFactory ;
2330import javax .net .ssl .X509TrustManager ;
24- import okhttp3 .OkHttpClient ;
25- import okhttp3 .Request ;
26- import okhttp3 .RequestBody ;
27- import okhttp3 .Response ;
28- import okhttp3 .ResponseBody ;
2931
3032/** A simple HTTP client based on OkHttp. Not meant for high throughput. */
3133final class SimpleHttpClient {
@@ -34,56 +36,57 @@ final class SimpleHttpClient {
3436
3537 private static final Duration TIMEOUT = Duration .ofSeconds (2 );
3638
37- private static final RequestBody EMPTY_BODY = RequestBody .create (new byte [0 ]);
39+ @ Nullable
40+ private static SSLSocketFactory getSslSocketFactoryForCertPath (@ Nullable String certPath ) {
41+ if (Objects .isNull (certPath )) {
42+ return null ;
43+ }
44+
45+ KeyStore keyStore = getKeystoreForTrustedCert (certPath );
46+ X509TrustManager trustManager = buildTrustManager (keyStore );
47+ return buildSslSocketFactory (trustManager );
48+ }
49+
50+ private static HttpURLConnection setupUrlConnection (
51+ String urlStr , String httpMethod , Map <String , String > headers ) throws Exception {
52+ try {
53+ HttpURLConnection urlConnection = (HttpURLConnection ) new URL (urlStr ).openConnection ();
54+ urlConnection .setRequestMethod (httpMethod );
55+ headers .forEach (urlConnection ::setRequestProperty );
56+ urlConnection .setConnectTimeout ((int ) TIMEOUT .toMillis ());
57+ urlConnection .setReadTimeout ((int ) TIMEOUT .toMillis ());
58+ urlConnection .setDoInput (true );
59+ urlConnection .setDoOutput (false );
60+ return urlConnection ;
61+ } catch (IOException e ) {
62+ logger .log (Level .WARNING , "Cannot open connection to " + urlStr , e );
63+ throw e ;
64+ }
65+ }
3866
3967 /** Fetch a string from a remote server. */
4068 public String fetchString (
4169 String httpMethod , String urlStr , Map <String , String > headers , @ Nullable String certPath ) {
4270
43- OkHttpClient .Builder clientBuilder =
44- new OkHttpClient .Builder ()
45- .callTimeout (TIMEOUT )
46- .connectTimeout (TIMEOUT )
47- .readTimeout (TIMEOUT );
48-
49- if (urlStr .startsWith ("https" ) && certPath != null ) {
50- KeyStore keyStore = getKeystoreForTrustedCert (certPath );
51- X509TrustManager trustManager = buildTrustManager (keyStore );
52- SSLSocketFactory socketFactory = buildSslSocketFactory (trustManager );
53- if (socketFactory != null ) {
54- clientBuilder .sslSocketFactory (socketFactory , trustManager );
71+ try {
72+ HttpURLConnection httpUrlConnection = setupUrlConnection (urlStr , httpMethod , headers );
73+ if (urlStr .startsWith ("https" )) {
74+ HttpsURLConnection urlConnection = (HttpsURLConnection ) httpUrlConnection ;
75+ SSLSocketFactory sslSocketFactory = getSslSocketFactoryForCertPath (certPath );
76+ urlConnection .setSSLSocketFactory (sslSocketFactory );
5577 }
56- }
57-
58- OkHttpClient client = clientBuilder .build ();
59-
60- // AWS incorrectly uses PUT despite having no request body, OkHttp will only allow us to send
61- // GET with null body or PUT with empty string body
62- RequestBody requestBody = null ;
63- if (httpMethod .equals ("PUT" )) {
64- requestBody = EMPTY_BODY ;
65- }
66- Request .Builder requestBuilder =
67- new Request .Builder ().url (urlStr ).method (httpMethod , requestBody );
6878
69- headers .forEach (requestBuilder ::addHeader );
79+ int responseCode = httpUrlConnection .getResponseCode ();
80+ String responseBody = convert (httpUrlConnection .getInputStream ());
7081
71- try (Response response = client .newCall (requestBuilder .build ()).execute ()) {
72- int responseCode = response .code ();
7382 if (responseCode != 200 ) {
7483 logger .log (
7584 Level .FINE ,
76- "Error response from "
77- + urlStr
78- + " code ("
79- + responseCode
80- + ") text "
81- + response .message ());
85+ "Error response from " + urlStr + " code (" + responseCode + ") text " + responseBody );
8286 return "" ;
8387 }
84- ResponseBody body = response .body ();
85- return body != null ? body .string () : "" ;
86- } catch (IOException e ) {
88+ return responseBody ;
89+ } catch (Exception e ) {
8790 logger .log (Level .FINE , "SimpleHttpClient fetch string failed." , e );
8891 }
8992
@@ -142,4 +145,14 @@ private static KeyStore getKeystoreForTrustedCert(String certPath) {
142145 return null ;
143146 }
144147 }
148+
149+ public static String convert (InputStream inputStream ) throws IOException {
150+ ByteArrayOutputStream result = new ByteArrayOutputStream ();
151+ byte [] buffer = new byte [1024 ];
152+ int length ;
153+ while ((length = inputStream .read (buffer )) != -1 ) {
154+ result .write (buffer , 0 , length );
155+ }
156+ return result .toString (StandardCharsets .UTF_8 .name ());
157+ }
145158}
0 commit comments