tharak-android 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -0
- package/build.gradle +45 -0
- package/consumer-rules.pro +0 -0
- package/libs/vital-sdk.aar +0 -0
- package/package.json +22 -0
- package/proguard-rules.pro +21 -0
- package/src/androidTest/androidTest.iml +11 -0
- package/src/androidTest/java/org/tharak/core/ExampleInstrumentedTest.java +27 -0
- package/src/androidTest/java/org/thiragatisoft/core/ExampleInstrumentedTest.java +26 -0
- package/src/main/AndroidManifest.xml +5 -0
- package/src/main/java/org/thiragatisoft/core/AppUtils.java +31 -0
- package/src/main/java/org/thiragatisoft/core/FileSelector.java +162 -0
- package/src/main/java/org/thiragatisoft/core/MainActivity.java +27 -0
- package/src/main/java/org/thiragatisoft/core/RestClient.java +298 -0
- package/src/main/java/org/thiragatisoft/core/VitalActivity.java +612 -0
- package/src/main/java/org/thiragatisoft/core/VitalsPlugin.java +15 -0
- package/src/main/java/org/thiragatisoft/core/VolleyMultipartRequest.java +218 -0
- package/src/main/java/org/thiragatisoft/core/http/CapacitorCookieManager.java +175 -0
- package/src/main/java/org/thiragatisoft/core/http/CapacitorHttpUrlConnection.java +408 -0
- package/src/main/java/org/thiragatisoft/core/http/FilesystemUtils.java +65 -0
- package/src/main/java/org/thiragatisoft/core/http/FormUploader.java +219 -0
- package/src/main/java/org/thiragatisoft/core/http/Http.java +275 -0
- package/src/main/java/org/thiragatisoft/core/http/HttpRequestHandler.java +515 -0
- package/src/main/java/org/thiragatisoft/core/http/ICapacitorHttpUrlConnection.java +15 -0
- package/src/main/java/org/thiragatisoft/core/http/JSValue.java +68 -0
- package/src/main/java/org/thiragatisoft/core/http/MimeType.java +17 -0
- package/src/main/main.iml +12 -0
- package/src/test/java/org/tharak/ExampleUnitTest.java +17 -0
- package/src/test/java/org/tharak/JSObjectTest.java +209 -0
- package/src/test/java/org/tharak/PluginMethodHandleTest.java +44 -0
- package/src/test/java/org/tharak/util/HostMaskTest.java +70 -0
- package/src/test/java/org/thiragatisoft/core/ExampleUnitTest.java +17 -0
- package/src/test/test.iml +11 -0
@@ -0,0 +1,218 @@
|
|
1
|
+
package org.thiragatisoft.core;
|
2
|
+
|
3
|
+
import com.android.volley.AuthFailureError;
|
4
|
+
import com.android.volley.NetworkResponse;
|
5
|
+
import com.android.volley.ParseError;
|
6
|
+
import com.android.volley.Request;
|
7
|
+
import com.android.volley.Response;
|
8
|
+
import com.android.volley.VolleyError;
|
9
|
+
import com.android.volley.toolbox.HttpHeaderParser;
|
10
|
+
|
11
|
+
import java.io.ByteArrayInputStream;
|
12
|
+
import java.io.ByteArrayOutputStream;
|
13
|
+
import java.io.DataOutputStream;
|
14
|
+
import java.io.IOException;
|
15
|
+
import java.io.UnsupportedEncodingException;
|
16
|
+
import java.util.Map;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Tharak
|
20
|
+
*/
|
21
|
+
|
22
|
+
public class VolleyMultipartRequest extends Request<NetworkResponse> {
|
23
|
+
|
24
|
+
private final String twoHyphens = "--";
|
25
|
+
private final String lineEnd = "\r\n";
|
26
|
+
private final String boundary = "apiclient-" + System.currentTimeMillis();
|
27
|
+
|
28
|
+
private Response.Listener<NetworkResponse> mListener;
|
29
|
+
private Response.ErrorListener mErrorListener;
|
30
|
+
private Map<String, String> mHeaders;
|
31
|
+
|
32
|
+
|
33
|
+
public VolleyMultipartRequest(int method, String url,
|
34
|
+
Response.Listener<NetworkResponse> listener,
|
35
|
+
Response.ErrorListener errorListener) {
|
36
|
+
super(method, url, errorListener);
|
37
|
+
this.mListener = listener;
|
38
|
+
this.mErrorListener = errorListener;
|
39
|
+
}
|
40
|
+
|
41
|
+
@Override
|
42
|
+
public Map<String, String> getHeaders() throws AuthFailureError {
|
43
|
+
return (mHeaders != null) ? mHeaders : super.getHeaders();
|
44
|
+
}
|
45
|
+
|
46
|
+
@Override
|
47
|
+
public String getBodyContentType() {
|
48
|
+
return "multipart/form-data;boundary=" + boundary;
|
49
|
+
}
|
50
|
+
|
51
|
+
@Override
|
52
|
+
public byte[] getBody() throws AuthFailureError {
|
53
|
+
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
54
|
+
DataOutputStream dos = new DataOutputStream(bos);
|
55
|
+
|
56
|
+
try {
|
57
|
+
// populate text payload
|
58
|
+
Map<String, String> params = getParams();
|
59
|
+
if (params != null && params.size() > 0) {
|
60
|
+
textParse(dos, params, getParamsEncoding());
|
61
|
+
}
|
62
|
+
|
63
|
+
// populate data byte payload
|
64
|
+
Map<String, DataPart> data = getByteData();
|
65
|
+
if (data != null && data.size() > 0) {
|
66
|
+
dataParse(dos, data);
|
67
|
+
}
|
68
|
+
|
69
|
+
// close multipart form data after text and file data
|
70
|
+
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
|
71
|
+
|
72
|
+
return bos.toByteArray();
|
73
|
+
} catch (IOException e) {
|
74
|
+
e.printStackTrace();
|
75
|
+
}
|
76
|
+
return null;
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Custom method handle data payload.
|
81
|
+
*
|
82
|
+
* @return Map data part label with data byte
|
83
|
+
* @throws AuthFailureError
|
84
|
+
*/
|
85
|
+
protected Map<String, DataPart> getByteData() throws AuthFailureError {
|
86
|
+
return null;
|
87
|
+
}
|
88
|
+
|
89
|
+
@Override
|
90
|
+
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
|
91
|
+
try {
|
92
|
+
return Response.success(
|
93
|
+
response,
|
94
|
+
HttpHeaderParser.parseCacheHeaders(response));
|
95
|
+
} catch (Exception e) {
|
96
|
+
return Response.error(new ParseError(e));
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
@Override
|
101
|
+
protected void deliverResponse(NetworkResponse response) {
|
102
|
+
mListener.onResponse(response);
|
103
|
+
}
|
104
|
+
|
105
|
+
@Override
|
106
|
+
public void deliverError(VolleyError error) {
|
107
|
+
mErrorListener.onErrorResponse(error);
|
108
|
+
}
|
109
|
+
|
110
|
+
/**
|
111
|
+
* Parse string map into data output stream by key and value.
|
112
|
+
*
|
113
|
+
* @param dataOutputStream data output stream handle string parsing
|
114
|
+
* @param params string inputs collection
|
115
|
+
* @param encoding encode the inputs, default UTF-8
|
116
|
+
* @throws IOException
|
117
|
+
*/
|
118
|
+
private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
|
119
|
+
try {
|
120
|
+
for (Map.Entry<String, String> entry : params.entrySet()) {
|
121
|
+
buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
|
122
|
+
}
|
123
|
+
} catch (UnsupportedEncodingException uee) {
|
124
|
+
throw new RuntimeException("Encoding not supported: " + encoding, uee);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
/**
|
129
|
+
* Parse data into data output stream.
|
130
|
+
*
|
131
|
+
* @param dataOutputStream data output stream handle file attachment
|
132
|
+
* @param data loop through data
|
133
|
+
* @throws IOException
|
134
|
+
*/
|
135
|
+
private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
|
136
|
+
for (Map.Entry<String, DataPart> entry : data.entrySet()) {
|
137
|
+
buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Write string data into header and data output stream.
|
143
|
+
*
|
144
|
+
* @param dataOutputStream data output stream handle string parsing
|
145
|
+
* @param parameterName name of input
|
146
|
+
* @param parameterValue value of input
|
147
|
+
* @throws IOException
|
148
|
+
*/
|
149
|
+
private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
|
150
|
+
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
|
151
|
+
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
|
152
|
+
dataOutputStream.writeBytes(lineEnd);
|
153
|
+
dataOutputStream.writeBytes(parameterValue + lineEnd);
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Write data file into header and data output stream.
|
158
|
+
*
|
159
|
+
* @param dataOutputStream data output stream handle data parsing
|
160
|
+
* @param dataFile data byte as DataPart from collection
|
161
|
+
* @param inputName name of data input
|
162
|
+
* @throws IOException
|
163
|
+
*/
|
164
|
+
private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
|
165
|
+
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
|
166
|
+
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
|
167
|
+
inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
|
168
|
+
if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
|
169
|
+
dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
|
170
|
+
}
|
171
|
+
dataOutputStream.writeBytes(lineEnd);
|
172
|
+
|
173
|
+
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
|
174
|
+
int bytesAvailable = fileInputStream.available();
|
175
|
+
|
176
|
+
int maxBufferSize = 1024 * 1024;
|
177
|
+
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
|
178
|
+
byte[] buffer = new byte[bufferSize];
|
179
|
+
|
180
|
+
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
|
181
|
+
|
182
|
+
while (bytesRead > 0) {
|
183
|
+
dataOutputStream.write(buffer, 0, bufferSize);
|
184
|
+
bytesAvailable = fileInputStream.available();
|
185
|
+
bufferSize = Math.min(bytesAvailable, maxBufferSize);
|
186
|
+
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
|
187
|
+
}
|
188
|
+
|
189
|
+
dataOutputStream.writeBytes(lineEnd);
|
190
|
+
}
|
191
|
+
|
192
|
+
class DataPart {
|
193
|
+
private String fileName;
|
194
|
+
private byte[] content;
|
195
|
+
private String type;
|
196
|
+
|
197
|
+
public DataPart() {
|
198
|
+
}
|
199
|
+
|
200
|
+
DataPart(String name, byte[] data) {
|
201
|
+
fileName = name;
|
202
|
+
content = data;
|
203
|
+
}
|
204
|
+
|
205
|
+
String getFileName() {
|
206
|
+
return fileName;
|
207
|
+
}
|
208
|
+
|
209
|
+
byte[] getContent() {
|
210
|
+
return content;
|
211
|
+
}
|
212
|
+
|
213
|
+
String getType() {
|
214
|
+
return type;
|
215
|
+
}
|
216
|
+
|
217
|
+
}
|
218
|
+
}
|
@@ -0,0 +1,175 @@
|
|
1
|
+
package org.thiragatisoft.core.http;
|
2
|
+
|
3
|
+
|
4
|
+
import java.net.CookieManager;
|
5
|
+
import java.net.CookiePolicy;
|
6
|
+
import java.net.CookieStore;
|
7
|
+
import java.net.HttpCookie;
|
8
|
+
import java.net.URI;
|
9
|
+
import java.util.ArrayList;
|
10
|
+
import java.util.Collections;
|
11
|
+
import java.util.HashMap;
|
12
|
+
import java.util.List;
|
13
|
+
import java.util.Map;
|
14
|
+
import java.util.Objects;
|
15
|
+
|
16
|
+
public class CapacitorCookieManager extends CookieManager {
|
17
|
+
|
18
|
+
private final android.webkit.CookieManager webkitCookieManager;
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Create a new cookie manager for use with @capacitor-community/http with the default cookie
|
22
|
+
* store and policy
|
23
|
+
*/
|
24
|
+
public CapacitorCookieManager() {
|
25
|
+
this(null, null);
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Create a new cookie manager for use with @capacitor-community/http with specified cookie
|
30
|
+
* store and cookie policy.
|
31
|
+
* @param store a {@code CookieStore} to be used by cookiemanager. if {@code null}, cookie
|
32
|
+
* manager will use a default one, which is an in-memory CookieStore implementation.
|
33
|
+
* @param policy a {@code CookiePolicy} instance to be used by cookie manager as policy
|
34
|
+
* callback. if {@code null}, ACCEPT_ORIGINAL_SERVER will be used.
|
35
|
+
*/
|
36
|
+
public CapacitorCookieManager(CookieStore store, CookiePolicy policy) {
|
37
|
+
super(store, policy);
|
38
|
+
webkitCookieManager = android.webkit.CookieManager.getInstance();
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Gets the cookies for the given URL.
|
43
|
+
* @param url the URL for which the cookies are requested
|
44
|
+
* @return value the cookies as a string, using the format of the 'Cookie' HTTP request header
|
45
|
+
*/
|
46
|
+
public String getCookieString(String url) {
|
47
|
+
return webkitCookieManager.getCookie(url);
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Gets a cookie value for the given URL and key.
|
52
|
+
* @param url the URL for which the cookies are requested
|
53
|
+
* @param key the key of the cookie to search for
|
54
|
+
* @return the {@code HttpCookie} value of the cookie at the key,
|
55
|
+
* otherwise it will return a new empty {@code HttpCookie}
|
56
|
+
*/
|
57
|
+
public HttpCookie getCookie(String url, String key) {
|
58
|
+
HttpCookie[] cookies = getCookies(url);
|
59
|
+
for (HttpCookie cookie : cookies) {
|
60
|
+
if (cookie.getName().equals(key)) {
|
61
|
+
return cookie;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
return null;
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Gets an array of {@code HttpCookie} given a URL.
|
70
|
+
* @param url the URL for which the cookies are requested
|
71
|
+
* @return an {@code HttpCookie} array of non-expired cookies
|
72
|
+
*/
|
73
|
+
public HttpCookie[] getCookies(String url) {
|
74
|
+
try {
|
75
|
+
ArrayList<HttpCookie> cookieList = new ArrayList<>();
|
76
|
+
String cookieString = getCookieString(url);
|
77
|
+
if (cookieString != null) {
|
78
|
+
String[] singleCookie = cookieString.split(";");
|
79
|
+
for (String c : singleCookie) {
|
80
|
+
HttpCookie parsed = HttpCookie.parse(c).get(0);
|
81
|
+
parsed.setValue(parsed.getValue());
|
82
|
+
cookieList.add(parsed);
|
83
|
+
}
|
84
|
+
}
|
85
|
+
HttpCookie[] cookies = new HttpCookie[cookieList.size()];
|
86
|
+
return cookieList.toArray(cookies);
|
87
|
+
} catch (Exception ex) {
|
88
|
+
return new HttpCookie[0];
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Sets a cookie for the given URL. Any existing cookie with the same host, path and name will
|
94
|
+
* be replaced with the new cookie. The cookie being set will be ignored if it is expired.
|
95
|
+
* @param url the URL for which the cookie is to be set
|
96
|
+
* @param value the cookie as a string, using the format of the 'Set-Cookie' HTTP response header
|
97
|
+
*/
|
98
|
+
public void setCookie(String url, String value) {
|
99
|
+
webkitCookieManager.setCookie(url, value);
|
100
|
+
flush();
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Sets a cookie for the given URL. Any existing cookie with the same host, path and name will
|
105
|
+
* be replaced with the new cookie. The cookie being set will be ignored if it is expired.
|
106
|
+
* @param url the URL for which the cookie is to be set
|
107
|
+
* @param key the {@code HttpCookie} name to use for lookup
|
108
|
+
* @param value the value of the {@code HttpCookie} given a key
|
109
|
+
*/
|
110
|
+
public void setCookie(String url, String key, String value) {
|
111
|
+
String cookieValue = key + "=" + value;
|
112
|
+
setCookie(url, cookieValue);
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Removes all cookies. This method is asynchronous.
|
117
|
+
*/
|
118
|
+
public void removeAllCookies() {
|
119
|
+
webkitCookieManager.removeAllCookies(null);
|
120
|
+
flush();
|
121
|
+
}
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Ensures all cookies currently accessible through the getCookie API are written to persistent
|
125
|
+
* storage. This call will block the caller until it is done and may perform I/O.
|
126
|
+
*/
|
127
|
+
public void flush() {
|
128
|
+
webkitCookieManager.flush();
|
129
|
+
}
|
130
|
+
|
131
|
+
@Override
|
132
|
+
public void put(URI uri, Map<String, List<String>> responseHeaders) {
|
133
|
+
// make sure our args are valid
|
134
|
+
if ((uri == null) || (responseHeaders == null)) return;
|
135
|
+
|
136
|
+
// save our url once
|
137
|
+
String url = uri.toString();
|
138
|
+
|
139
|
+
// go over the headers
|
140
|
+
for (String headerKey : responseHeaders.keySet()) {
|
141
|
+
// ignore headers which aren't cookie related
|
142
|
+
if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
|
143
|
+
|
144
|
+
// process each of the headers
|
145
|
+
for (String headerValue : Objects.requireNonNull(responseHeaders.get(headerKey))) {
|
146
|
+
setCookie(url, headerValue);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
@Override
|
152
|
+
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) {
|
153
|
+
// make sure our args are valid
|
154
|
+
if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
|
155
|
+
|
156
|
+
// save our url once
|
157
|
+
String url = uri.toString();
|
158
|
+
|
159
|
+
// prepare our response
|
160
|
+
Map<String, List<String>> res = new HashMap<>();
|
161
|
+
|
162
|
+
// get the cookie
|
163
|
+
String cookie = getCookieString(url);
|
164
|
+
|
165
|
+
// return it
|
166
|
+
if (cookie != null) res.put("Cookie", Collections.singletonList(cookie));
|
167
|
+
return res;
|
168
|
+
}
|
169
|
+
|
170
|
+
@Override
|
171
|
+
public CookieStore getCookieStore() {
|
172
|
+
// we don't want anyone to work with this cookie store directly
|
173
|
+
throw new UnsupportedOperationException();
|
174
|
+
}
|
175
|
+
}
|