Skip to content

Commit b10bd22

Browse files
committed
Made my changes. Ready to merge 😄
1 parent a8447a0 commit b10bd22

File tree

7 files changed

+331
-40
lines changed

7 files changed

+331
-40
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# LightNodeStats
22

33
Simple app that shows the stats of the running light node service on ethOS
4+

app/src/main/java/org/ethereumphone/lightnodestats/MainActivity.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
66
import androidx.appcompat.app.AppCompatActivity
7+
import androidx.compose.foundation.ExperimentalFoundationApi
78
import androidx.compose.material.MaterialTheme
89
import androidx.compose.material.Surface
910
import androidx.compose.material.Text
@@ -14,13 +15,14 @@ import org.ethereumphone.lightnodestats.ui.MainStatsScreen
1415
import org.ethereumphone.lightnodestats.ui.theme.ethOSTheme
1516

1617
class MainActivity : AppCompatActivity() {
18+
@OptIn(ExperimentalFoundationApi::class)
1719
override fun onCreate(savedInstanceState: Bundle?) {
1820
super.onCreate(savedInstanceState)
1921
setContent {
2022
ethOSTheme() {
2123
// A surface container using the 'background' color from the theme
2224
Surface(color = MaterialTheme.colors.background) {
23-
//MainStatsScreen(context = applicationContext)
25+
MainStatsScreen(context = applicationContext)
2426
}
2527
}
2628
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
package org.ethereumphone.lightnodestats.data;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.BufferedReader;
5+
import java.io.ByteArrayInputStream;
6+
import java.io.IOException;
7+
import java.io.InputStream;
8+
import java.io.InputStreamReader;
9+
import java.nio.charset.StandardCharsets;
10+
import java.util.Arrays;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
import okhttp3.CipherSuite;
16+
import okhttp3.ConnectionSpec;
17+
import okhttp3.Headers;
18+
import okhttp3.MediaType;
19+
import okhttp3.OkHttpClient;
20+
import okhttp3.RequestBody;
21+
import okhttp3.ResponseBody;
22+
import okhttp3.logging.HttpLoggingInterceptor;
23+
import okio.Buffer;
24+
import okio.BufferedSource;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
import org.web3j.protocol.Service;
29+
import org.web3j.protocol.exceptions.ClientConnectionException;
30+
31+
import static okhttp3.ConnectionSpec.CLEARTEXT;
32+
33+
/** HTTP implementation of our services API. */
34+
public class EthHttpService extends Service {
35+
36+
/** Copied from {@link ConnectionSpec#APPROVED_CIPHER_SUITES}. */
37+
@SuppressWarnings("JavadocReference")
38+
private static final CipherSuite[] INFURA_CIPHER_SUITES =
39+
new CipherSuite[] {
40+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
41+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
42+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
43+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
44+
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
45+
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
46+
47+
// Note that the following cipher suites are all on HTTP/2's bad cipher suites list.
48+
// We'll
49+
// continue to include them until better suites are commonly available. For example,
50+
// none
51+
// of the better cipher suites listed above shipped with Android 4.4 or Java 7.
52+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
53+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
54+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
55+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
56+
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
57+
CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
58+
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
59+
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
60+
CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
61+
62+
// Additional INFURA CipherSuites
63+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
64+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
65+
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256,
66+
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256
67+
};
68+
69+
private static final ConnectionSpec INFURA_CIPHER_SUITE_SPEC =
70+
new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
71+
.cipherSuites(INFURA_CIPHER_SUITES)
72+
.build();
73+
74+
/** The list of {@link ConnectionSpec} instances used by the connection. */
75+
private static final List<ConnectionSpec> CONNECTION_SPEC_LIST =
76+
Arrays.asList(INFURA_CIPHER_SUITE_SPEC, CLEARTEXT);
77+
78+
public static final MediaType JSON_MEDIA_TYPE =
79+
MediaType.parse("application/json; charset=utf-8");
80+
81+
public static final String DEFAULT_URL = "http://localhost:8545/";
82+
83+
private static final Logger log = LoggerFactory.getLogger(org.web3j.protocol.http.HttpService.class);
84+
85+
private OkHttpClient httpClient;
86+
87+
private final String url;
88+
89+
private final boolean includeRawResponse;
90+
91+
private HashMap<String, String> headers = new HashMap<>();
92+
93+
public EthHttpService(String url, OkHttpClient httpClient, boolean includeRawResponses) {
94+
super(includeRawResponses);
95+
this.url = url;
96+
this.httpClient = httpClient;
97+
this.includeRawResponse = includeRawResponses;
98+
}
99+
100+
public EthHttpService(OkHttpClient httpClient, boolean includeRawResponses) {
101+
this(DEFAULT_URL, httpClient, includeRawResponses);
102+
}
103+
104+
public EthHttpService(String url, OkHttpClient httpClient) {
105+
this(url, httpClient, false);
106+
}
107+
108+
public EthHttpService(String url) {
109+
this(url, createOkHttpClient());
110+
}
111+
112+
public EthHttpService(String url, boolean includeRawResponse) {
113+
this(url, createOkHttpClient(), includeRawResponse);
114+
}
115+
116+
public EthHttpService(OkHttpClient httpClient) {
117+
this(DEFAULT_URL, httpClient);
118+
}
119+
120+
public EthHttpService(boolean includeRawResponse) {
121+
this(DEFAULT_URL, includeRawResponse);
122+
}
123+
124+
public EthHttpService() {
125+
this(DEFAULT_URL);
126+
}
127+
128+
private static OkHttpClient createOkHttpClient() {
129+
final OkHttpClient.Builder builder =
130+
new OkHttpClient.Builder().connectionSpecs(CONNECTION_SPEC_LIST);
131+
configureLogging(builder);
132+
return builder.build();
133+
}
134+
135+
private static void configureLogging(OkHttpClient.Builder builder) {
136+
if (log.isDebugEnabled()) {
137+
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(log::debug);
138+
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
139+
builder.addInterceptor(logging);
140+
}
141+
}
142+
143+
@Override
144+
protected InputStream performIO(String request) throws IOException {
145+
146+
RequestBody requestBody = RequestBody.create(request, JSON_MEDIA_TYPE);
147+
Headers headers = buildHeaders();
148+
149+
150+
//okhttp3.Request httpRequest =
151+
// new okhttp3.Request.Builder().url(url).headers(headers).post(requestBody).build();
152+
153+
String out = executeCommand("curl -X POST -H \"Content-Type: application/json\" --data '"+request+"' "+url);
154+
return new ByteArrayInputStream(out.getBytes(StandardCharsets.UTF_8));
155+
}
156+
157+
protected void processHeaders(Headers headers) {
158+
// Default implementation is empty
159+
}
160+
161+
public static String executeCommand(String command) {
162+
StringBuilder output = new StringBuilder();
163+
try {
164+
Process proc = Runtime.getRuntime().exec(new String[] { "sh", "-c", command });
165+
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
166+
167+
String line;
168+
while ((line = reader.readLine())!= null) {
169+
output.append(line + "\n");
170+
}
171+
proc.waitFor();
172+
} catch (Exception e) {
173+
e.printStackTrace();
174+
}
175+
176+
return output.toString();
177+
}
178+
179+
private InputStream buildInputStream(ResponseBody responseBody) throws IOException {
180+
InputStream inputStream = responseBody.byteStream();
181+
182+
if (includeRawResponse) {
183+
// we have to buffer the entire input payload, so that after processing
184+
// it can be re-read and used to populate the rawResponse field.
185+
186+
BufferedSource source = responseBody.source();
187+
source.request(Long.MAX_VALUE); // Buffer the entire body
188+
Buffer buffer = source.buffer();
189+
190+
long size = buffer.size();
191+
if (size > Integer.MAX_VALUE) {
192+
throw new UnsupportedOperationException(
193+
"Non-integer input buffer size specified: " + size);
194+
}
195+
196+
int bufferSize = (int) size;
197+
BufferedInputStream bufferedinputStream =
198+
new BufferedInputStream(inputStream, bufferSize);
199+
200+
bufferedinputStream.mark(inputStream.available());
201+
return bufferedinputStream;
202+
203+
} else {
204+
return inputStream;
205+
}
206+
}
207+
208+
private Headers buildHeaders() {
209+
return Headers.of(headers);
210+
}
211+
212+
public void addHeader(String key, String value) {
213+
headers.put(key, value);
214+
}
215+
216+
public void addHeaders(Map<String, String> headersToAdd) {
217+
headers.putAll(headersToAdd);
218+
}
219+
220+
public HashMap<String, String> getHeaders() {
221+
return headers;
222+
}
223+
224+
@Override
225+
public void close() throws IOException {}
226+
}

0 commit comments

Comments
 (0)