5
5
6
6
package io .opentelemetry .contrib .aws .resource ;
7
7
8
+ import java .io .ByteArrayOutputStream ;
8
9
import java .io .FileInputStream ;
9
10
import java .io .IOException ;
11
+ import java .io .InputStream ;
12
+ import java .net .HttpURLConnection ;
13
+ import java .net .URL ;
14
+ import java .nio .charset .StandardCharsets ;
10
15
import java .security .KeyStore ;
11
16
import java .security .cert .Certificate ;
12
17
import java .security .cert .CertificateFactory ;
13
18
import java .time .Duration ;
14
19
import java .util .Collection ;
15
20
import java .util .Map ;
21
+ import java .util .Objects ;
16
22
import java .util .logging .Level ;
17
23
import java .util .logging .Logger ;
18
24
import javax .annotation .Nullable ;
25
+ import javax .net .ssl .HttpsURLConnection ;
19
26
import javax .net .ssl .SSLContext ;
20
27
import javax .net .ssl .SSLSocketFactory ;
21
28
import javax .net .ssl .TrustManager ;
22
29
import javax .net .ssl .TrustManagerFactory ;
23
30
import javax .net .ssl .X509TrustManager ;
24
- import okhttp3 .OkHttpClient ;
25
- import okhttp3 .Request ;
26
- import okhttp3 .RequestBody ;
27
- import okhttp3 .Response ;
28
- import okhttp3 .ResponseBody ;
29
31
30
32
/** A simple HTTP client based on OkHttp. Not meant for high throughput. */
31
33
final class SimpleHttpClient {
@@ -34,42 +36,50 @@ final class SimpleHttpClient {
34
36
35
37
private static final Duration TIMEOUT = Duration .ofSeconds (2 );
36
38
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 ;
56
43
}
57
44
58
- OkHttpClient client = clientBuilder .build ();
45
+ KeyStore keyStore = getKeystoreForTrustedCert (certPath );
46
+ X509TrustManager trustManager = buildTrustManager (keyStore );
47
+ return buildSslSocketFactory (trustManager );
48
+ }
59
49
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 ;
65
63
}
66
- Request .Builder requestBuilder =
67
- new Request .Builder ().url (urlStr ).method (httpMethod , requestBody );
64
+ }
68
65
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 ());
70
82
71
- try (Response response = client .newCall (requestBuilder .build ()).execute ()) {
72
- int responseCode = response .code ();
73
83
if (responseCode != 200 ) {
74
84
logger .log (
75
85
Level .FINE ,
@@ -78,12 +88,11 @@ public String fetchString(
78
88
+ " code ("
79
89
+ responseCode
80
90
+ ") text "
81
- + response . message () );
91
+ + responseBody );
82
92
return "" ;
83
93
}
84
- ResponseBody body = response .body ();
85
- return body != null ? body .string () : "" ;
86
- } catch (IOException e ) {
94
+ return responseBody ;
95
+ } catch (Exception e ) {
87
96
logger .log (Level .FINE , "SimpleHttpClient fetch string failed." , e );
88
97
}
89
98
@@ -142,4 +151,14 @@ private static KeyStore getKeystoreForTrustedCert(String certPath) {
142
151
return null ;
143
152
}
144
153
}
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
+ }
145
164
}
0 commit comments