fedilab-Android-App/app/src/main/java/app/fedilab/android/client/HttpsConnection.java

1068 lines
46 KiB
Java
Raw Normal View History

2019-05-18 11:10:30 +02:00
package app.fedilab.android.client;
2017-11-18 08:27:25 +01:00
/* Copyright 2017 Thomas Schneider
*
2019-05-18 11:10:30 +02:00
* This file is a part of Fedilab
2017-11-18 08:27:25 +01:00
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
2019-05-18 11:10:30 +02:00
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
2017-11-18 08:27:25 +01:00
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
2019-05-18 11:10:30 +02:00
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
2017-11-18 08:27:25 +01:00
* see <http://www.gnu.org/licenses>. */
2018-12-29 19:21:39 +01:00
2017-11-18 09:30:58 +01:00
import android.content.Context;
2017-11-18 11:25:04 +01:00
import android.content.SharedPreferences;
2017-11-18 09:30:58 +01:00
import android.os.Build;
import android.text.Html;
import android.text.SpannableString;
2018-09-05 10:19:07 +02:00
2019-03-24 16:38:12 +01:00
import com.google.gson.JsonObject;
2018-12-29 19:21:39 +01:00
import net.gotev.uploadservice.MultipartUploadRequest;
import net.gotev.uploadservice.ServerResponse;
import net.gotev.uploadservice.UploadInfo;
import net.gotev.uploadservice.UploadNotificationConfig;
import net.gotev.uploadservice.UploadStatusDelegate;
import org.apache.poi.util.IOUtils;
2017-11-18 09:44:54 +01:00
import org.json.JSONObject;
2018-12-29 19:21:39 +01:00
2017-11-18 09:30:58 +01:00
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
2017-11-18 08:27:25 +01:00
import java.io.IOException;
2017-11-18 09:30:58 +01:00
import java.io.InputStream;
2018-04-22 18:02:00 +02:00
import java.io.OutputStream;
2018-01-19 18:59:30 +01:00
import java.net.Authenticator;
2017-11-18 12:22:41 +01:00
import java.net.HttpURLConnection;
2018-01-19 18:59:30 +01:00
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
2018-01-19 18:59:30 +01:00
import java.net.PasswordAuthentication;
import java.net.Proxy;
2017-11-18 08:27:25 +01:00
import java.net.URL;
2019-11-15 16:32:25 +01:00
import java.nio.charset.StandardCharsets;
2017-11-18 08:27:25 +01:00
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
2018-08-17 18:55:38 +02:00
import java.util.Scanner;
2017-11-18 08:27:25 +01:00
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2020-04-08 12:42:15 +02:00
2017-11-18 08:27:25 +01:00
import javax.net.ssl.HttpsURLConnection;
2018-12-29 19:21:39 +01:00
2019-05-18 11:10:30 +02:00
import app.fedilab.android.R;
2021-01-26 18:47:15 +01:00
import app.fedilab.android.activities.MainActivity;
2019-10-12 16:12:23 +02:00
import app.fedilab.android.activities.SlideMediaActivity;
2019-05-18 11:10:30 +02:00
import app.fedilab.android.activities.TootActivity;
2021-01-26 18:47:15 +01:00
import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask;
2019-05-18 11:10:30 +02:00
import app.fedilab.android.client.Entities.Error;
import app.fedilab.android.helper.FileNameCleaner;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnDownloadInterface;
2017-11-18 09:30:58 +01:00
2019-11-29 15:26:49 +01:00
import static app.fedilab.android.helper.Helper.urlPattern;
2017-11-18 08:27:25 +01:00
/**
* Created by Thomas on 17/11/2017.
* Manage http queries
*/
public class HttpsConnection {
2018-01-24 15:56:33 +01:00
private HttpURLConnection httpURLConnection;
2017-11-18 08:27:25 +01:00
private String since_id, max_id;
2021-01-19 17:43:51 +01:00
private final Context context;
private final int CHUNK_SIZE = 4096;
private final SharedPreferences sharedpreferences;
2018-01-19 18:59:30 +01:00
private Proxy proxy;
2021-01-19 17:43:51 +01:00
private final String instance;
private final String USER_AGENT;
2020-02-01 10:48:03 +01:00
2017-11-18 09:30:58 +01:00
2019-09-06 17:55:14 +02:00
public HttpsConnection(Context context, String instance) {
this.instance = instance;
2017-11-18 09:30:58 +01:00
this.context = context;
2018-01-19 18:59:30 +01:00
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean proxyEnabled = sharedpreferences.getBoolean(Helper.SET_PROXY_ENABLED, false);
2018-01-20 09:46:28 +01:00
int type = sharedpreferences.getInt(Helper.SET_PROXY_TYPE, 0);
2018-01-19 18:59:30 +01:00
proxy = null;
2019-11-29 18:02:49 +01:00
USER_AGENT = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT);
2019-09-06 17:55:14 +02:00
if (proxyEnabled) {
2018-08-30 17:48:32 +02:00
try {
String host = sharedpreferences.getString(Helper.SET_PROXY_HOST, "127.0.0.1");
int port = sharedpreferences.getInt(Helper.SET_PROXY_PORT, 8118);
2019-09-06 17:55:14 +02:00
if (type == 0)
2018-08-30 17:48:32 +02:00
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
else
proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(host, port));
final String login = sharedpreferences.getString(Helper.SET_PROXY_LOGIN, null);
final String pwd = sharedpreferences.getString(Helper.SET_PROXY_PASSWORD, null);
2019-09-06 17:55:14 +02:00
if (login != null) {
2018-08-30 17:48:32 +02:00
Authenticator authenticator = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
assert pwd != null;
return (new PasswordAuthentication(login,
pwd.toCharArray()));
}
};
Authenticator.setDefault(authenticator);
}
2019-09-06 17:55:14 +02:00
} catch (Exception e) {
2018-08-30 17:48:32 +02:00
proxy = null;
2018-01-19 18:59:30 +01:00
}
2018-08-30 17:48:32 +02:00
2018-01-19 18:59:30 +01:00
}
2019-05-24 15:13:28 +02:00
2019-09-06 17:55:14 +02:00
if (instance != null && instance.endsWith(".onion")) {
2020-03-08 11:28:51 +01:00
HttpsURLConnection.setDefaultHostnameVerifier((arg0, arg1) -> true);
2019-05-24 15:13:28 +02:00
}
2017-11-18 09:30:58 +01:00
}
2017-11-18 08:27:25 +01:00
2017-12-10 18:37:58 +01:00
2021-01-26 18:47:15 +01:00
private void setToken(MultipartUploadRequest multipartUploadRequest, String token) {
if (token != null) {
if (token.startsWith("Basic "))
multipartUploadRequest.addHeader("Authorization", token);
else if (token.startsWith("X-XSRF-TOKEN")) {
String cookie = token.split("\\|")[1];
multipartUploadRequest.addHeader("cookie", cookie);
String[] tokens = token.split("\\|")[0].split(";");
multipartUploadRequest.addHeader("x-xsrf-token", tokens[0].replace("X-XSRF-TOKEN= ", ""));
multipartUploadRequest.addHeader("x-csrf-token", tokens[1].replace("X-CSRF-TOKEN= ", ""));
} else
multipartUploadRequest.addHeader("Authorization", "Bearer " + token);
}
}
2021-01-24 16:05:51 +01:00
private void setToken(String token) {
2021-01-24 19:16:02 +01:00
2021-01-24 16:05:51 +01:00
if (token != null) {
if (token.startsWith("Basic "))
httpURLConnection.setRequestProperty("Authorization", token);
2021-01-24 19:16:02 +01:00
else if (token.startsWith("X-XSRF-TOKEN")) {
String cookie = token.split("\\|")[1];
httpURLConnection.setRequestProperty("cookie", cookie);
String[] tokens = token.split("\\|")[0].split(";");
httpURLConnection.setRequestProperty("x-xsrf-token", tokens[0].replace("X-XSRF-TOKEN= ", ""));
httpURLConnection.setRequestProperty("x-csrf-token", tokens[1].replace("X-CSRF-TOKEN= ", ""));
} else
2021-01-24 16:05:51 +01:00
httpURLConnection.setRequestProperty("Authorization", "Bearer " + token);
}
}
2019-11-27 15:05:54 +01:00
/**
* Get calls
2020-03-08 10:29:06 +01:00
*
2019-11-27 15:05:54 +01:00
* @param urlConnection String url
2020-03-08 10:29:06 +01:00
* @param timeout int timeout
* @param paramaters HashMap<String, String> paramaters
* @param token String token
2019-11-27 15:05:54 +01:00
* @return String
2020-04-08 12:42:15 +02:00
* @throws IOException IOException
2020-03-08 11:28:51 +01:00
* @throws NoSuchAlgorithmException NoSuchAlgorithmException
2020-04-08 12:42:15 +02:00
* @throws KeyManagementException KeyManagementException
2020-03-08 11:28:51 +01:00
* @throws HttpsConnectionException HttpsConnectionException
2019-11-27 15:05:54 +01:00
*/
2017-11-18 08:27:25 +01:00
public String get(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2019-11-28 07:21:28 +01:00
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
2020-06-19 17:17:17 +02:00
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
2019-11-28 07:21:28 +01:00
while (it.hasNext()) {
2020-06-19 17:17:17 +02:00
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
2019-11-28 07:21:28 +01:00
it.remove();
}
}
StringBuilder postData = new StringBuilder();
2019-12-08 17:49:13 +01:00
URL url;
2020-03-08 10:29:06 +01:00
if (params.size() > 0) {
2019-12-08 17:49:13 +01:00
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
url = new URL(urlConnection + "?" + postData);
2020-03-08 10:29:06 +01:00
} else {
2019-12-08 17:49:13 +01:00
url = new URL(urlConnection);
2019-11-28 07:21:28 +01:00
}
2020-02-01 10:48:03 +01:00
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
2020-02-01 10:48:03 +01:00
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(timeout * 1000);
httpURLConnection.setRequestProperty("http.keepAlive", "false");
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Accept", "application/json");
httpURLConnection.setUseCaches(true);
httpURLConnection.setDefaultUseCaches(true);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
2021-01-24 16:05:51 +01:00
setToken(token);
httpURLConnection.setRequestMethod("GET");
2020-02-01 10:48:03 +01:00
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
response = converToString(httpURLConnection.getInputStream());
2020-02-01 10:48:03 +01:00
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
2020-02-01 10:48:03 +01:00
if (stream == null) {
stream = httpURLConnection.getInputStream();
2019-11-27 15:05:54 +01:00
}
2020-02-01 10:48:03 +01:00
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
2019-12-15 17:33:15 +01:00
}
2020-02-01 10:48:03 +01:00
} catch (Exception e) {
e.printStackTrace();
2019-12-15 17:33:15 +01:00
}
2019-11-27 15:05:54 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
2020-02-01 10:48:03 +01:00
try {
httpURLConnection.getInputStream().close();
2020-02-01 10:48:03 +01:00
} catch (Exception ignored) {
}
2020-02-01 10:48:03 +01:00
throw new HttpsConnectionException(responseCode, error);
2017-11-18 08:27:25 +01:00
}
2020-02-01 10:48:03 +01:00
getSinceMaxId();
httpURLConnection.getInputStream().close();
2020-02-01 10:48:03 +01:00
return response;
2017-11-18 08:27:25 +01:00
}
2019-11-29 15:53:46 +01:00
/**
* Will check if the current url is redirecting
2020-03-08 10:29:06 +01:00
*
2019-11-29 15:53:46 +01:00
* @param urlConnection String the url to check
* @return String null|string url redirection
*/
2020-03-08 10:29:06 +01:00
public String checkUrl(String urlConnection) {
2019-11-29 15:26:49 +01:00
URL url;
String redirect = null;
try {
url = new URL(urlConnection);
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
2019-11-29 15:26:49 +01:00
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("http.keepAlive", "false");
httpURLConnection.setInstanceFollowRedirects(false);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestMethod("HEAD");
if (httpURLConnection.getResponseCode() == 301 || httpURLConnection.getResponseCode() == 302) {
Map<String, List<String>> map = httpURLConnection.getHeaderFields();
2019-11-29 15:26:49 +01:00
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
2019-11-29 15:53:46 +01:00
if (entry.toString().toLowerCase().startsWith("location")) {
2019-11-29 15:26:49 +01:00
Matcher matcher = urlPattern.matcher(entry.toString());
if (matcher.find()) {
redirect = matcher.group(1);
}
}
}
}
httpURLConnection.getInputStream().close();
2020-03-08 10:29:06 +01:00
if (redirect != null && redirect.compareTo(urlConnection) != 0) {
2019-12-04 11:39:49 +01:00
URL redirectURL = new URL(redirect);
String host = redirectURL.getHost();
String protocol = redirectURL.getProtocol();
2020-03-08 10:29:06 +01:00
if (protocol == null || host == null) {
2019-12-04 11:39:49 +01:00
redirect = null;
}
}
return redirect;
2019-11-29 15:26:49 +01:00
} catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return null;
}
2017-12-10 18:37:58 +01:00
public String get(String urlConnection) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2019-11-27 15:05:54 +01:00
2020-02-01 10:48:03 +01:00
URL url = new URL(urlConnection);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(30 * 1000);
httpURLConnection.setRequestProperty("http.keepAlive", "false");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Accept", "application/json");
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setDefaultUseCaches(true);
httpURLConnection.setUseCaches(true);
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
2020-03-27 18:31:46 +01:00
getSinceMaxId();
response = converToString(httpURLConnection.getInputStream());
2020-04-08 12:42:15 +02:00
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
2020-03-27 18:31:46 +01:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
2020-03-27 18:31:46 +01:00
}
2020-02-01 10:48:03 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
throw new HttpsConnectionException(responseCode, error);
2017-12-10 18:37:58 +01:00
}
getSinceMaxId();
httpURLConnection.getInputStream().close();
return response;
2017-12-10 18:37:58 +01:00
}
2017-11-18 08:27:25 +01:00
public String post(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2020-06-19 17:17:17 +02:00
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
2018-01-24 15:56:33 +01:00
}
2020-06-19 17:17:17 +02:00
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setConnectTimeout(timeout * 1000);
httpURLConnection.setDoOutput(true);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestMethod("POST");
2021-01-24 16:05:51 +01:00
setToken(token);
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpURLConnection.getOutputStream().write(postDataBytes);
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
getSinceMaxId();
response = converToString(httpURLConnection.getInputStream());
2019-09-06 17:55:14 +02:00
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
2019-03-24 16:38:12 +01:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2019-03-24 16:38:12 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
throw new HttpsConnectionException(responseCode, error);
2019-03-24 16:38:12 +01:00
}
getSinceMaxId();
httpURLConnection.getInputStream().close();
return response;
2019-03-24 16:38:12 +01:00
}
2020-03-08 11:28:51 +01:00
String postJson(String urlConnection, int timeout, JsonObject jsonObject, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2020-06-19 17:17:17 +02:00
URL url = new URL(urlConnection);
byte[] postDataBytes;
postDataBytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setConnectTimeout(timeout * 1000);
httpURLConnection.setDoOutput(true);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Accept", "application/json");
2021-02-21 17:18:37 +01:00
httpURLConnection.setRequestMethod("POST");
setToken(token);
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpURLConnection.getOutputStream().write(postDataBytes);
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
getSinceMaxId();
response = converToString(httpURLConnection.getInputStream());
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
int responseCode = httpURLConnection.getResponseCode();
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
throw new HttpsConnectionException(responseCode, error);
}
getSinceMaxId();
httpURLConnection.getInputStream().close();
return response;
}
String postJson(String urlConnection, int timeout, JSONObject jsonObject, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
URL url = new URL(urlConnection);
byte[] postDataBytes;
postDataBytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setConnectTimeout(timeout * 1000);
httpURLConnection.setDoOutput(true);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Accept", "application/json");
httpURLConnection.setRequestMethod("POST");
2021-01-24 16:05:51 +01:00
setToken(token);
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
2020-06-19 17:17:17 +02:00
httpURLConnection.getOutputStream().write(postDataBytes);
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
2019-03-24 16:38:12 +01:00
getSinceMaxId();
response = converToString(httpURLConnection.getInputStream());
2019-09-06 17:55:14 +02:00
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
2018-08-17 18:55:38 +02:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2018-01-24 15:56:33 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
throw new HttpsConnectionException(responseCode, error);
}
getSinceMaxId();
httpURLConnection.getInputStream().close();
return response;
2017-11-18 08:27:25 +01:00
}
2020-03-08 11:28:51 +01:00
@SuppressWarnings("SameParameterValue")
String postMisskey(String urlConnection, int timeout, JSONObject paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2018-12-29 19:21:39 +01:00
URL url = new URL(urlConnection);
2019-11-15 16:32:25 +01:00
byte[] postDataBytes = paramaters.toString().getBytes(StandardCharsets.UTF_8);
2018-12-29 19:21:39 +01:00
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
2018-12-29 19:21:39 +01:00
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setConnectTimeout(timeout * 1000);
httpURLConnection.setDoOutput(true);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestMethod("POST");
2021-01-24 16:05:51 +01:00
setToken(token);
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
2018-12-29 19:21:39 +01:00
httpURLConnection.getOutputStream().write(postDataBytes);
2018-12-29 19:21:39 +01:00
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
2018-12-29 19:21:39 +01:00
getSinceMaxId();
response = converToString(httpURLConnection.getInputStream());
2018-12-29 19:21:39 +01:00
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
2018-12-29 19:21:39 +01:00
if (stream == null) {
stream = httpURLConnection.getInputStream();
2018-12-29 19:21:39 +01:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
2019-09-06 17:55:14 +02:00
if (scanner.hasNext()) {
2019-08-17 17:10:24 +02:00
error = scanner.next();
}
2019-09-06 17:55:14 +02:00
} catch (Exception e) {
e.printStackTrace();
}
2018-12-29 19:21:39 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
2019-08-17 11:10:31 +02:00
try {
httpURLConnection.getInputStream().close();
2019-09-06 17:55:14 +02:00
} catch (Exception ignored) {
}
2018-12-29 19:21:39 +01:00
throw new HttpsConnectionException(responseCode, error);
}
getSinceMaxId();
httpURLConnection.getInputStream().close();
2018-12-29 19:21:39 +01:00
return response;
}
2017-12-27 08:57:07 +01:00
/***
* Download method which works for http and https connections
* @param downloadUrl String download url
* @param listener OnDownloadInterface, listener which manages progress
*/
2017-11-18 12:22:41 +01:00
public void download(final String downloadUrl, final OnDownloadInterface listener) {
2020-03-08 11:28:51 +01:00
new Thread(() -> {
URL url;
try {
url = new URL(downloadUrl);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = httpURLConnection.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpURLConnection.getHeaderField("Content-Disposition");
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
2017-11-18 12:22:41 +01:00
}
2020-03-08 11:28:51 +01:00
} else {
// extracts file name from URL
fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1
);
2017-12-27 08:36:55 +01:00
}
fileName = FileNameCleaner.cleanFileName(fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpURLConnection.getInputStream();
File saveDir = context.getCacheDir();
final String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead;
byte[] buffer = new byte[CHUNK_SIZE];
int contentSize = httpURLConnection.getContentLength();
int downloadedFileSize = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
downloadedFileSize += bytesRead;
if (context instanceof SlideMediaActivity) {
final int currentProgress = (downloadedFileSize * 100) / contentSize;
((SlideMediaActivity) context).runOnUiThread(() -> listener.onUpdateProgress(currentProgress > 0 ? currentProgress : 101));
2020-03-08 11:28:51 +01:00
}
}
outputStream.close();
inputStream.close();
if (context instanceof TootActivity)
((TootActivity) context).runOnUiThread(() -> listener.onDownloaded(saveFilePath, downloadUrl, null));
if (context instanceof SlideMediaActivity)
((SlideMediaActivity) context).runOnUiThread(() -> listener.onDownloaded(saveFilePath, downloadUrl, null));
} else {
final Error error = new Error();
error.setError(String.valueOf(responseCode));
if (context instanceof TootActivity)
((TootActivity) context).runOnUiThread(() -> listener.onDownloaded(null, downloadUrl, error));
if (context instanceof SlideMediaActivity)
((SlideMediaActivity) context).runOnUiThread(() -> listener.onDownloaded(null, downloadUrl, error));
2020-03-08 11:28:51 +01:00
}
} catch (IOException e) {
Error error = new Error();
error.setError(context.getString(R.string.toast_error));
2017-11-18 12:22:41 +01:00
}
2017-11-18 12:22:41 +01:00
}).start();
2017-11-26 19:10:42 +01:00
}
2017-12-13 11:09:58 +01:00
public InputStream getPicture(final String downloadUrl) {
2020-06-19 17:17:17 +02:00
URL url;
try {
url = new URL(downloadUrl);
} catch (MalformedURLException e) {
return null;
}
try {
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
2020-03-08 10:29:06 +01:00
}
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
2021-01-27 15:59:07 +01:00
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) {
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
String cookie = token.split("\\|")[1];
httpURLConnection.setRequestProperty("Cookie", cookie);
}
int responseCode = httpURLConnection.getResponseCode();
// always check HTTP response code first
if (responseCode >= 200 && responseCode < 400) {
// opens input stream from the HTTP connection
return httpURLConnection.getInputStream();
}
httpURLConnection.getInputStream().close();
} catch (IOException | NoSuchAlgorithmException | KeyManagementException ignored) {
}
if (httpURLConnection != null)
2018-01-24 15:56:33 +01:00
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
2018-01-24 15:56:33 +01:00
}
2020-06-19 17:17:17 +02:00
return null;
2017-12-13 11:09:58 +01:00
}
2019-09-06 17:55:14 +02:00
private void uploadMedia(String urlConnection, InputStream avatar, InputStream header, String filename) {
UploadNotificationConfig uploadConfig = new UploadNotificationConfig();
uploadConfig.getCompleted().autoClear = true;
File file = new File(context.getCacheDir() + "/" + filename);
OutputStream outputStream;
try {
outputStream = new FileOutputStream(file);
2019-09-06 17:55:14 +02:00
if (avatar != null) {
IOUtils.copy(avatar, outputStream);
2019-09-06 17:55:14 +02:00
} else {
IOUtils.copy(header, outputStream);
2018-04-22 18:02:00 +02:00
}
} catch (IOException e) {
e.printStackTrace();
}
2018-04-22 18:02:00 +02:00
try {
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
MultipartUploadRequest m = new MultipartUploadRequest(context, urlConnection)
.setMethod("PATCH");
2019-09-06 17:55:14 +02:00
if (avatar != null) {
m.addFileToUpload(file.getPath(), "avatar");
} else {
m.addFileToUpload(file.getPath(), "header");
}
2021-01-26 18:47:15 +01:00
MultipartUploadRequest multipartUploadRequest = m.addParameter("name", filename);
setToken(multipartUploadRequest, token);
multipartUploadRequest.setNotificationConfig(uploadConfig)
.setDelegate(new UploadStatusDelegate() {
@Override
public void onProgress(Context context, UploadInfo uploadInfo) {
// your code here
2018-04-23 13:42:21 +02:00
}
2018-05-10 09:50:19 +02:00
@Override
public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse,
Exception exception) {
2020-03-08 11:28:51 +01:00
//noinspection ResultOfMethodCallIgnored
file.delete();
}
2018-04-23 13:42:21 +02:00
@Override
public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) {
2020-03-08 11:28:51 +01:00
//noinspection ResultOfMethodCallIgnored
file.delete();
}
2018-05-10 09:50:19 +02:00
@Override
public void onCancelled(Context context, UploadInfo uploadInfo) {
2020-03-08 11:28:51 +01:00
//noinspection ResultOfMethodCallIgnored
file.delete();
}
})
.startUpload();
2020-03-08 11:28:51 +01:00
} catch (MalformedURLException | FileNotFoundException e) {
e.printStackTrace();
2018-05-10 09:50:19 +02:00
}
}
2019-09-06 17:55:14 +02:00
@SuppressWarnings("SameParameterValue")
public String patch(String urlConnection, int timeout, HashMap<String, String> paramaters, InputStream avatar, String avatarName, InputStream header, String headerName, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2018-05-10 09:50:19 +02:00
2020-06-19 17:17:17 +02:00
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = (postData.toString()).getBytes(StandardCharsets.UTF_8);
2018-05-10 09:50:19 +02:00
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setConnectTimeout(timeout * 1000);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
httpURLConnection.setRequestMethod("PATCH");
2021-01-26 18:47:15 +01:00
setToken(token);
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpURLConnection.setDoOutput(true);
String response;
OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(postDataBytes);
if (avatar != null) {
uploadMedia(urlConnection, avatar, null, avatarName);
}
if (header != null) {
uploadMedia(urlConnection, null, header, headerName);
}
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
response = converToString(httpURLConnection.getInputStream());
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
2019-09-06 17:55:14 +02:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2018-05-10 09:50:19 +02:00
}
int responseCode = httpURLConnection.getResponseCode();
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
2018-04-22 18:02:00 +02:00
}
throw new HttpsConnectionException(responseCode, error);
2018-04-22 18:02:00 +02:00
}
httpURLConnection.getInputStream().close();
return response;
2018-04-22 18:02:00 +02:00
}
2017-11-18 08:27:25 +01:00
public String put(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2020-06-19 17:17:17 +02:00
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
2018-01-24 15:56:33 +01:00
}
2020-06-19 17:17:17 +02:00
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
2017-11-18 08:27:25 +01:00
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setConnectTimeout(timeout * 1000);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
2021-01-26 18:47:15 +01:00
setToken(token);
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpURLConnection.setRequestMethod("PUT");
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.getOutputStream().write(postDataBytes);
String response;
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
getSinceMaxId();
response = converToString(httpURLConnection.getInputStream());
2019-09-06 17:55:14 +02:00
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
2018-08-17 18:55:38 +02:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2018-01-24 15:56:33 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
try {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
throw new HttpsConnectionException(responseCode, error);
}
getSinceMaxId();
httpURLConnection.getInputStream().close();
return response;
2017-11-18 08:27:25 +01:00
}
2017-11-18 08:27:25 +01:00
public int delete(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
2020-06-19 17:17:17 +02:00
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
2018-01-24 15:56:33 +01:00
}
2020-06-19 17:17:17 +02:00
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
2017-11-18 08:27:25 +01:00
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
httpURLConnection = (HttpsURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
if (httpURLConnection instanceof HttpsURLConnection) {
((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(new TLSSocketFactory(this.instance));
}
2021-01-26 18:47:15 +01:00
setToken(token);
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setRequestMethod("DELETE");
httpURLConnection.setConnectTimeout(timeout * 1000);
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpURLConnection.getOutputStream().write(postDataBytes);
if (httpURLConnection.getResponseCode() >= 200 && httpURLConnection.getResponseCode() < 400) {
getSinceMaxId();
httpURLConnection.getInputStream().close();
return httpURLConnection.getResponseCode();
} else {
String error = null;
if (httpURLConnection.getErrorStream() != null) {
InputStream stream = httpURLConnection.getErrorStream();
if (stream == null) {
stream = httpURLConnection.getInputStream();
2018-08-17 18:55:38 +02:00
}
try (Scanner scanner = new Scanner(stream)) {
scanner.useDelimiter("\\Z");
if (scanner.hasNext()) {
error = scanner.next();
}
} catch (Exception e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2018-01-24 15:56:33 +01:00
}
int responseCode = httpURLConnection.getResponseCode();
try {
2018-01-24 15:56:33 +01:00
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
2018-01-24 15:56:33 +01:00
}
throw new HttpsConnectionException(responseCode, error);
2017-11-18 08:27:25 +01:00
}
}
public String getSince_id() {
return since_id;
}
public String getMax_id() {
return max_id;
}
2019-11-29 07:30:11 +01:00
2019-09-06 17:55:14 +02:00
private void getSinceMaxId() {
if (Helper.getLiveInstanceWithProtocol(context) == null)
2018-01-14 19:03:20 +01:00
return;
if (httpURLConnection == null)
return;
Map<String, List<String>> map = httpURLConnection.getHeaderFields();
2021-01-26 18:47:15 +01:00
if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) {
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if (entry.toString().startsWith("Link") || entry.toString().startsWith("link")) {
Pattern patternMaxId = Pattern.compile("max_id=([0-9a-zA-Z]+).*");
Matcher matcherMaxId = patternMaxId.matcher(entry.toString());
if (matcherMaxId.find()) {
max_id = matcherMaxId.group(1);
2017-11-18 08:27:25 +01:00
}
2021-01-26 18:47:15 +01:00
if (entry.toString().startsWith("Link")) {
Pattern patternSinceId = Pattern.compile("since_id=([0-9a-zA-Z]+).*");
Matcher matcherSinceId = patternSinceId.matcher(entry.toString());
if (matcherSinceId.find()) {
since_id = matcherSinceId.group(1);
}
2017-11-19 07:25:43 +01:00
2021-01-26 18:47:15 +01:00
}
} else if (entry.toString().startsWith("Min-Id") || entry.toString().startsWith("min-id")) {
Pattern patternMaxId = Pattern.compile("min-id=\\[([0-9a-zA-Z]+).*]");
Matcher matcherMaxId = patternMaxId.matcher(entry.toString());
if (matcherMaxId.find()) {
max_id = matcherMaxId.group(1);
}
2017-11-18 08:27:25 +01:00
}
}
}
}
2020-03-08 11:28:51 +01:00
private String converToString(InputStream inputStream) {
2018-09-15 14:05:21 +02:00
java.util.Scanner s = new java.util.Scanner(inputStream).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
2017-12-02 14:54:25 +01:00
int getActionCode() {
try {
return httpURLConnection.getResponseCode();
} catch (IOException e) {
return -1;
2017-11-18 14:10:53 +01:00
}
2017-11-18 09:30:58 +01:00
}
2019-11-15 16:32:25 +01:00
2017-11-18 08:27:25 +01:00
public class HttpsConnectionException extends Exception {
2021-01-19 17:43:51 +01:00
private final int statusCode;
private final String message;
2019-09-06 17:55:14 +02:00
2017-11-18 08:27:25 +01:00
HttpsConnectionException(int statusCode, String message) {
this.statusCode = statusCode;
SpannableString spannableString;
2019-09-06 17:55:14 +02:00
if (message != null) {
2018-08-24 15:47:16 +02:00
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableString = new SpannableString(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
else
spannableString = new SpannableString(Html.fromHtml(message));
2019-09-06 17:55:14 +02:00
} else {
2018-08-24 15:47:16 +02:00
spannableString = new SpannableString(context.getString(R.string.toast_error));
}
this.message = spannableString.toString();
2017-11-18 08:27:25 +01:00
}
public int getStatusCode() {
return statusCode;
}
@Override
public String getMessage() {
return message;
}
2017-11-18 08:27:25 +01:00
}
}