Skip to content

Commit 84c2246

Browse files
authored
Merge pull request #215 from chrisws/master
Tidy up request implementation
2 parents 2aed92b + 02a01e5 commit 84c2246

File tree

4 files changed

+122
-54
lines changed

4 files changed

+122
-54
lines changed

src/platform/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ android {
99
applicationId 'net.sourceforge.smallbasic'
1010
minSdkVersion 19
1111
targetSdkVersion 34
12-
versionCode 61
12+
versionCode 63
1313
versionName '12.27'
1414
resourceConfigurations += ['en']
1515
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package net.sourceforge.smallbasic;
2+
3+
import androidx.annotation.NonNull;
4+
5+
import java.io.BufferedReader;
6+
import java.io.IOException;
7+
import java.io.InputStream;
8+
import java.io.InputStreamReader;
9+
import java.io.OutputStream;
10+
import java.net.HttpURLConnection;
11+
import java.net.URL;
12+
import java.nio.charset.StandardCharsets;
13+
import java.util.concurrent.CountDownLatch;
14+
import java.util.concurrent.TimeUnit;
15+
16+
public class HttpConnection implements Runnable {
17+
private static final int TIMEOUT_MILLIS = 30000;
18+
private static final String ERROR_PREFIX = "error: [";
19+
private static final String ERROR_POSTFIX = "]";
20+
21+
private final String endPoint;
22+
private final String data;
23+
private final String apiKey;
24+
private final CountDownLatch latch;
25+
private String result;
26+
27+
public HttpConnection(String endPoint, String data, String apiKey) {
28+
this.endPoint = endPoint;
29+
this.data = data;
30+
this.apiKey = apiKey;
31+
this.latch = new CountDownLatch(1);
32+
}
33+
34+
public String invoke() {
35+
new Thread(this).start();
36+
try {
37+
if (!latch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) {
38+
result = buildError("timeout");
39+
}
40+
} catch (InterruptedException e) {
41+
result = buildError(e.toString());
42+
}
43+
return result;
44+
}
45+
46+
@Override
47+
public void run() {
48+
HttpURLConnection conn = null;
49+
try {
50+
conn = getHttpURLConnection(endPoint, (data == null || data.isEmpty()) ? "GET" : "POST", apiKey);
51+
if (data != null && !data.isEmpty()) {
52+
conn.setRequestProperty("Content-Length", "" + data.getBytes().length);
53+
conn.setDoInput(true);
54+
OutputStream os = conn.getOutputStream();
55+
os.write(data.getBytes(StandardCharsets.UTF_8));
56+
os.flush();
57+
os.close();
58+
}
59+
int responseCode = conn.getResponseCode();
60+
if (responseCode == HttpURLConnection.HTTP_OK) {
61+
result = getText(conn.getInputStream());
62+
} else if (responseCode >= HttpURLConnection.HTTP_BAD_REQUEST && responseCode < HttpURLConnection.HTTP_INTERNAL_ERROR) {
63+
result = buildError(getText(conn.getErrorStream()));
64+
} else {
65+
result = buildError(String.valueOf(responseCode));
66+
}
67+
} catch (Exception e) {
68+
result = buildError(e.toString());
69+
} finally {
70+
if (conn != null) {
71+
conn.disconnect();
72+
}
73+
}
74+
latch.countDown();
75+
}
76+
77+
@NonNull
78+
private static String buildError(String message) {
79+
return ERROR_PREFIX + message + ERROR_POSTFIX;
80+
}
81+
82+
@NonNull
83+
private HttpURLConnection getHttpURLConnection(String endPoint, String method, String apiKey) throws IOException {
84+
URL url = new URL(endPoint);
85+
HttpURLConnection result = (HttpURLConnection) url.openConnection();
86+
result.setRequestMethod(method);
87+
result.setRequestProperty("User-Agent", "SmallBASIC");
88+
result.setConnectTimeout(TIMEOUT_MILLIS);
89+
result.setInstanceFollowRedirects(true);
90+
if (apiKey != null && !apiKey.isEmpty()) {
91+
result.setRequestProperty("Accept", "application/json");
92+
result.setRequestProperty("Content-Type", "application/json");
93+
result.setRequestProperty("Authorization", "Bearer " + apiKey);
94+
} else {
95+
result.setRequestProperty("Accept", "*/*");
96+
}
97+
return result;
98+
}
99+
100+
private String getText(InputStream stream) throws IOException {
101+
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
102+
String inputLine;
103+
StringBuilder response = new StringBuilder();
104+
while ((inputLine = in.readLine()) != null) {
105+
response.append(inputLine);
106+
}
107+
in.close();
108+
return response.toString();
109+
}
110+
}

src/platform/android/app/src/main/java/net/sourceforge/smallbasic/MainActivity.java

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import android.view.inputmethod.InputMethodManager;
3939
import android.widget.Toast;
4040

41-
import androidx.annotation.NonNull;
4241
import androidx.core.app.ActivityCompat;
4342
import androidx.core.content.ContextCompat;
4443
import androidx.core.content.FileProvider;
@@ -59,14 +58,11 @@
5958
import java.io.InputStreamReader;
6059
import java.io.OutputStream;
6160
import java.io.UnsupportedEncodingException;
62-
import java.net.HttpURLConnection;
6361
import java.net.Inet4Address;
6462
import java.net.InetAddress;
6563
import java.net.NetworkInterface;
6664
import java.net.SocketException;
67-
import java.net.URL;
6865
import java.net.URLDecoder;
69-
import java.nio.charset.StandardCharsets;
7066
import java.util.ArrayList;
7167
import java.util.Collection;
7268
import java.util.Date;
@@ -103,7 +99,6 @@ public class MainActivity extends NativeActivity {
10399
private static final String FOLDER_NAME = "SmallBASIC";
104100
private static final int COPY_BUFFER_SIZE = 1024;
105101
private static final String[] SAMPLES = {"welcome.bas"};
106-
private static final int TIMEOUT_MILLIS = 5000;
107102
private String _startupBas = null;
108103
private boolean _untrusted = false;
109104
private final ExecutorService _audioExecutor = Executors.newSingleThreadExecutor();
@@ -510,33 +505,8 @@ public boolean removeLocationUpdates() {
510505
}
511506

512507
public String request(String endPoint, String data, String apiKey) throws IOException {
513-
String result;
514-
try {
515-
HttpURLConnection conn = getHttpURLConnection(endPoint, (data == null || data.isEmpty()) ? "GET" : "POST", apiKey);
516-
if (data != null && !data.isEmpty()) {
517-
conn.setRequestProperty("Content-Length", "" + data.getBytes().length);
518-
OutputStream os = conn.getOutputStream();
519-
os.write(data.getBytes(StandardCharsets.UTF_8));
520-
os.flush();
521-
os.close();
522-
}
523-
int responseCode = conn.getResponseCode();
524-
if (responseCode == HttpURLConnection.HTTP_OK) {
525-
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
526-
String inputLine;
527-
StringBuilder response = new StringBuilder();
528-
while ((inputLine = in.readLine()) != null) {
529-
response.append(inputLine);
530-
}
531-
in.close();
532-
result = response.toString();
533-
} else {
534-
result = "error: [" + responseCode + "]";
535-
}
536-
} catch (Exception e) {
537-
result = "error: [" + e + "]";
538-
}
539-
return result;
508+
HttpConnection connection = new HttpConnection(endPoint, data, apiKey);
509+
return connection.invoke();
540510
}
541511

542512
public boolean requestLocationUpdates() {
@@ -798,23 +768,6 @@ private void execStream(InputStream inputStream) throws IOException {
798768
runFile(outputFile.getAbsolutePath());
799769
}
800770

801-
@NonNull
802-
private HttpURLConnection getHttpURLConnection(String endPoint, String method, String apiKey) throws IOException {
803-
URL url = new URL(endPoint);
804-
HttpURLConnection result = (HttpURLConnection) url.openConnection();
805-
result.setConnectTimeout(TIMEOUT_MILLIS);
806-
result.setRequestProperty("User-Agent", "SmallBASIC");
807-
result.setRequestMethod(method);
808-
result.setInstanceFollowRedirects(true);
809-
if (apiKey != null && !apiKey.isEmpty()) {
810-
result.setRequestProperty("Accept", "application/json");
811-
result.setRequestProperty("Content-Type", "application/json");
812-
result.setRequestProperty("Authorization", "Bearer " + apiKey);
813-
}
814-
result.setDoOutput(true);
815-
return result;
816-
}
817-
818771
private Uri getSharedFile(File file) {
819772
Uri result;
820773
try {

src/platform/android/jni/runtime.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,8 +977,15 @@ int Runtime::getFontId() {
977977

978978
int Runtime::invokeRequest(int argc, slib_par_t *params, var_t *retval) {
979979
int result = 0;
980-
if ((argc >= 1 && argc <= 3 && v_is_type(params[0].var_p, V_STR)) &&
981-
(argc < 3 || v_is_type(params[2].var_p, V_STR))) {
980+
if (argc != 1 && argc != 3) {
981+
v_setstr(retval, "Expected 1 or 3 arguments");
982+
} else if (!v_is_type(params[0].var_p, V_STR)) {
983+
v_setstr(retval, "invalid endPoint");
984+
} else if (argc == 3 && !v_is_type(params[1].var_p, V_STR) && !v_is_type(params[1].var_p, V_MAP)) {
985+
v_setstr(retval, "invalid postData");
986+
} else if (argc == 3 && !v_is_type(params[2].var_p, V_STR)) {
987+
v_setstr(retval, "invalid apiKey");
988+
} else {
982989
_output->redraw();
983990

984991
JNIEnv *env;
@@ -1002,8 +1009,6 @@ int Runtime::invokeRequest(int argc, slib_par_t *params, var_t *retval) {
10021009
env->DeleteLocalRef(apiKey);
10031010

10041011
_app->activity->vm->DetachCurrentThread();
1005-
} else {
1006-
v_setstr(retval, "Invalid request arguments");
10071012
}
10081013
return result;
10091014
}

0 commit comments

Comments
 (0)