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,42 +36,50 @@ 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 ]);
38-
39- /** Fetch a string from a remote server. */
40- public String fetchString (
41- String httpMethod , String urlStr , Map <String , String > headers , @ Nullable String certPath ) {
42-
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 );
55- }
39+ @ Nullable
40+ private static SSLSocketFactory getSslSocketFactoryForCertPath (@ Nullable String certPath ) {
41+ if (Objects .isNull (certPath )) {
42+ return null ;
5643 }
5744
58- OkHttpClient client = clientBuilder .build ();
45+ KeyStore keyStore = getKeystoreForTrustedCert (certPath );
46+ X509TrustManager trustManager = buildTrustManager (keyStore );
47+ return buildSslSocketFactory (trustManager );
48+ }
5949
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 ;
50+ private static HttpURLConnection setupUrlConnection (String urlStr , String httpMethod , Map <String , String > headers ) throws Exception {
51+ try {
52+ HttpURLConnection urlConnection = (HttpURLConnection ) new URL (urlStr ).openConnection ();
53+ urlConnection .setRequestMethod (httpMethod );
54+ headers .forEach (urlConnection ::setRequestProperty );
55+ urlConnection .setConnectTimeout ((int ) TIMEOUT .toMillis ());
56+ urlConnection .setReadTimeout ((int ) TIMEOUT .toMillis ());
57+ urlConnection .setDoInput (true );
58+ urlConnection .setDoOutput (false );
59+ return urlConnection ;
60+ } catch (IOException e ) {
61+ logger .log (Level .WARNING , "Cannot open connection to " + urlStr , e );
62+ throw e ;
6563 }
66- Request .Builder requestBuilder =
67- new Request .Builder ().url (urlStr ).method (httpMethod , requestBody );
64+ }
6865
69- headers .forEach (requestBuilder ::addHeader );
66+ /** Fetch a string from a remote server. */
67+ public String fetchString (String httpMethod ,
68+ String urlStr ,
69+ Map <String , String > headers ,
70+ @ Nullable String certPath ) {
71+
72+ try {
73+ HttpURLConnection httpUrlConnection = setupUrlConnection (urlStr , httpMethod , headers );
74+ if (urlStr .startsWith ("https" )) {
75+ HttpsURLConnection urlConnection = (HttpsURLConnection ) httpUrlConnection ;
76+ SSLSocketFactory sslSocketFactory = getSslSocketFactoryForCertPath (certPath );
77+ urlConnection .setSSLSocketFactory (sslSocketFactory );
78+ }
79+
80+ int responseCode = httpUrlConnection .getResponseCode ();
81+ String responseBody = convert (httpUrlConnection .getInputStream ());
7082
71- try (Response response = client .newCall (requestBuilder .build ()).execute ()) {
72- int responseCode = response .code ();
7383 if (responseCode != 200 ) {
7484 logger .log (
7585 Level .FINE ,
@@ -78,12 +88,11 @@ public String fetchString(
7888 + " code ("
7989 + responseCode
8090 + ") text "
81- + response . message () );
91+ + responseBody );
8292 return "" ;
8393 }
84- ResponseBody body = response .body ();
85- return body != null ? body .string () : "" ;
86- } catch (IOException e ) {
94+ return responseBody ;
95+ } catch (Exception e ) {
8796 logger .log (Level .FINE , "SimpleHttpClient fetch string failed." , e );
8897 }
8998
@@ -142,4 +151,14 @@ private static KeyStore getKeystoreForTrustedCert(String certPath) {
142151 return null ;
143152 }
144153 }
154+
155+ public static String convert (InputStream inputStream ) throws IOException {
156+ ByteArrayOutputStream result = new ByteArrayOutputStream ();
157+ byte [] buffer = new byte [1024 ];
158+ int length ;
159+ while ((length = inputStream .read (buffer )) != -1 ) {
160+ result .write (buffer , 0 , length );
161+ }
162+ return result .toString (StandardCharsets .UTF_8 .name ());
163+ }
145164}
0 commit comments