fedilab-Android-App/app/src/main/java/fr/gouv/etalab/mastodon/client/HttpsConnection.java

473 lines
21 KiB
Java
Raw Normal View History

2017-11-18 08:27:25 +01:00
package fr.gouv.etalab.mastodon.client;
/* Copyright 2017 Thomas Schneider
*
* This file is a part of Mastalab
*
* 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.
*
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
* see <http://www.gnu.org/licenses>. */
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;
2017-11-18 09:44:54 +01:00
import org.json.JSONObject;
2017-11-18 09:30:58 +01:00
import java.io.BufferedInputStream;
2017-11-18 08:27:25 +01:00
import java.io.BufferedReader;
2017-11-18 09:30:58 +01:00
import java.io.ByteArrayOutputStream;
2017-11-18 08:27:25 +01:00
import java.io.DataOutputStream;
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;
2017-11-18 08:27:25 +01:00
import java.io.InputStreamReader;
2017-11-18 09:30:58 +01:00
import java.io.OutputStream;
2017-11-18 08:27:25 +01:00
import java.io.Reader;
import java.net.URL;
import java.net.URLEncoder;
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;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.HttpsURLConnection;
2017-11-18 09:44:54 +01:00
import fr.gouv.etalab.mastodon.client.Entities.Attachment;
2017-11-18 11:25:04 +01:00
import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.helper.Helper;
2017-11-18 09:30:58 +01:00
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
2017-11-18 08:27:25 +01:00
/**
* Created by Thomas on 17/11/2017.
* Manage http queries
*/
public class HttpsConnection {
private HttpsURLConnection httpsURLConnection;
private String since_id, max_id;
2017-11-18 09:30:58 +01:00
private int actionCode;
private Context context;
public HttpsConnection(){}
2017-11-18 11:25:04 +01:00
public HttpsConnection(Context context){
2017-11-18 09:30:58 +01:00
this.context = context;
}
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 {
Map<String,Object> params = new LinkedHashMap<>();
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
URL url = new URL(urlConnection + "?" + postData);
httpsURLConnection = (HttpsURLConnection)url.openConnection();
2017-11-18 09:30:58 +01:00
httpsURLConnection.setConnectTimeout(timeout * 1000);
2017-11-18 08:27:25 +01:00
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
if( token != null)
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
httpsURLConnection.setRequestMethod("GET");
getSinceMaxId();
2017-11-18 09:30:58 +01:00
actionCode = httpsURLConnection.getResponseCode();
if (actionCode >= 200 && actionCode < 400) {
2017-11-18 08:27:25 +01:00
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
httpsURLConnection.disconnect();
in.close();
return sb.toString();
}else {
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
2017-11-18 09:30:58 +01:00
throw new HttpsConnectionException(actionCode, sb.toString());
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 {
URL url = new URL(urlConnection);
Map<String,Object> params = new LinkedHashMap<>();
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
httpsURLConnection = (HttpsURLConnection)url.openConnection();
2017-11-18 09:30:58 +01:00
httpsURLConnection.setConnectTimeout(timeout * 1000);
2017-11-18 08:27:25 +01:00
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
httpsURLConnection.setRequestMethod("POST");
if( token != null)
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
2017-11-18 09:30:58 +01:00
actionCode = httpsURLConnection.getResponseCode();
2017-11-18 08:27:25 +01:00
getSinceMaxId();
httpsURLConnection.setDoOutput(true);
2017-11-18 09:30:58 +01:00
if (actionCode >= 200 && actionCode < 400) {
2017-11-18 08:27:25 +01:00
httpsURLConnection.getOutputStream().write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
httpsURLConnection.disconnect();
in.close();
return sb.toString();
}else {
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
2017-11-18 09:30:58 +01:00
throw new HttpsConnectionException(actionCode, sb.toString());
2017-11-18 08:27:25 +01:00
}
}
2017-11-18 11:25:04 +01:00
public void upload(final InputStream inputStream, final OnRetrieveAttachmentInterface listener) {
2017-11-18 09:30:58 +01:00
new Thread(new Runnable() {
@Override
public void run() {
try {
2017-11-18 11:25:04 +01:00
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
final URL url = new URL("https://"+Helper.getLiveInstance(context)+"/api/v1/media");
2017-11-18 09:30:58 +01:00
ByteArrayOutputStream ous = null;
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
ous = new ByteArrayOutputStream();
int read;
while ((read = inputStream.read(buffer)) != -1) {
ous.write(buffer, 0, read);
}
ous.flush();
} finally {
if (ous != null)
ous.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte[] pixels = ous.toByteArray();
httpsURLConnection = (HttpsURLConnection) url.openConnection();
2017-11-18 11:25:04 +01:00
httpsURLConnection.setConnectTimeout(240 * 1000);
2017-11-18 09:30:58 +01:00
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
httpsURLConnection.setDoInput(true);
httpsURLConnection.setDoOutput(true);
httpsURLConnection.setUseCaches(false);
if (token != null)
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
httpsURLConnection.setRequestMethod("POST");
httpsURLConnection.setRequestProperty("Content-Type", "multipart/form-data");
httpsURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpsURLConnection.setRequestProperty("Cache-Control", "no-cache");
httpsURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=*****");
DataOutputStream request = new DataOutputStream(httpsURLConnection.getOutputStream());
request.writeBytes("--*****\r\n");
request.writeBytes("Content-Disposition: form-data; name=\"picture\";filename=\"picture.png\"\r\n");
request.writeBytes("\r\n");
request.write(pixels);
2017-11-18 09:44:54 +01:00
int totalSize = pixels.length;
int bytesTransferred = 0;
int chunkSize = 2000;
while (bytesTransferred < totalSize) {
int nextChunkSize = totalSize - bytesTransferred;
if (nextChunkSize > chunkSize) {
nextChunkSize = chunkSize;
}
request.write(pixels, bytesTransferred, nextChunkSize);
bytesTransferred += nextChunkSize;
int progress = 100 * bytesTransferred / totalSize;
listener.onUpdateProgress(progress);
}
2017-11-18 09:30:58 +01:00
request.writeBytes("\r\n");
request.writeBytes("--*****\r\n");
request.flush();
request.close();
InputStream responseStream = new BufferedInputStream(httpsURLConnection.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
2017-11-18 09:44:54 +01:00
listener.onUpdateProgress(101);
2017-11-18 09:30:58 +01:00
responseStreamReader.close();
String response = stringBuilder.toString();
2017-11-18 09:44:54 +01:00
Attachment attachment = API.parseAttachmentResponse(new JSONObject(response));
listener.onRetrieveAttachment(attachment, null);
2017-11-18 09:30:58 +01:00
}catch (Exception e) {
2017-11-18 09:44:54 +01:00
listener.onUpdateProgress(101);
2017-11-18 11:25:04 +01:00
Error error = new Error();
2017-11-18 09:44:54 +01:00
error.setError(e.getMessage());
listener.onRetrieveAttachment(null, error);
2017-11-18 09:30:58 +01:00
}
}
}).start();
}
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 {
URL url = new URL(urlConnection);
Map<String,Object> params = new LinkedHashMap<>();
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
httpsURLConnection = (HttpsURLConnection)url.openConnection();
2017-11-18 09:30:58 +01:00
httpsURLConnection.setConnectTimeout(timeout * 1000);
2017-11-18 08:27:25 +01:00
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
if( token != null)
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
getSinceMaxId();
httpsURLConnection.setRequestMethod("PUT");
httpsURLConnection.setDoInput(true);
httpsURLConnection.setDoOutput(true);
2017-11-18 09:30:58 +01:00
actionCode = httpsURLConnection.getResponseCode();
if (actionCode >= 200 && actionCode < 400) {
2017-11-18 08:27:25 +01:00
DataOutputStream dataOutputStream = new DataOutputStream(httpsURLConnection.getOutputStream());
dataOutputStream.write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
httpsURLConnection.disconnect();
in.close();
return sb.toString();
}else {
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
2017-11-18 09:30:58 +01:00
throw new HttpsConnectionException(actionCode, sb.toString());
2017-11-18 08:27:25 +01:00
}
}
public String patch(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
URL url = new URL(urlConnection);
Map<String,Object> params = new LinkedHashMap<>();
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
httpsURLConnection = (HttpsURLConnection)url.openConnection();
2017-11-18 09:30:58 +01:00
httpsURLConnection.setConnectTimeout(timeout * 1000);
2017-11-18 08:27:25 +01:00
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
httpsURLConnection.setRequestMethod("PATCH");
if( token != null)
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpsURLConnection.setDoOutput(true);
getSinceMaxId();
2017-11-18 09:30:58 +01:00
actionCode = httpsURLConnection.getResponseCode();
if (actionCode >= 200 && actionCode < 400) {
2017-11-18 08:27:25 +01:00
httpsURLConnection.getOutputStream().write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
httpsURLConnection.disconnect();
in.close();
return sb.toString();
}else {
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
2017-11-18 09:30:58 +01:00
throw new HttpsConnectionException(actionCode, sb.toString());
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 {
URL url = new URL(urlConnection);
Map<String,Object> params = new LinkedHashMap<>();
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
httpsURLConnection = (HttpsURLConnection)url.openConnection();
2017-11-18 09:30:58 +01:00
httpsURLConnection.setConnectTimeout(timeout * 1000);
2017-11-18 08:27:25 +01:00
getSinceMaxId();
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
if( token != null)
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
httpsURLConnection.setRequestMethod("DELETE");
2017-11-18 09:30:58 +01:00
actionCode = httpsURLConnection.getResponseCode();
if (actionCode >= 200 && actionCode < 400) {
2017-11-18 08:27:25 +01:00
httpsURLConnection.disconnect();
2017-11-18 09:30:58 +01:00
return actionCode;
2017-11-18 08:27:25 +01:00
}else {
Reader in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
2017-11-18 09:30:58 +01:00
throw new HttpsConnectionException(actionCode, sb.toString());
2017-11-18 08:27:25 +01:00
}
}
public String getSince_id() {
return since_id;
}
public String getMax_id() {
return max_id;
}
private void getSinceMaxId(){
Map<String, List<String>> map = httpsURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if( entry.toString().startsWith("Link: ")){
Pattern patternMaxId = Pattern.compile("max_id=([0-9]{1,}).*");
Matcher matcherMaxId = patternMaxId.matcher(entry.toString());
if (matcherMaxId.find()) {
max_id = matcherMaxId.group(1);
}
if( entry.toString().startsWith("Link: ")){
Pattern patternSinceId = Pattern.compile("since_id=([0-9]{1,}).*");
Matcher matcherSinceId = patternSinceId.matcher(entry.toString());
if (matcherSinceId.find()) {
since_id = matcherSinceId.group(1);
}
}
}
}
}
2017-11-18 09:30:58 +01:00
public int getActionCode() {
return actionCode;
}
2017-11-18 08:27:25 +01:00
public class HttpsConnectionException extends Exception {
private int statusCode;
private String message;
HttpsConnectionException(int statusCode, String message) {
this.statusCode = statusCode;
this.message = message;
}
public int getStatusCode() {
return statusCode;
}
@Override
public String getMessage() {
return message;
}
}
}