Replace standard Java HTTP libraries with okHTTP (#237)
* Replace standard Java HTTP libraries with okHTTP
This commit is contained in:
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -5,4 +5,4 @@
|
|||||||
<profile default="true" name="Default" enabled="true" />
|
<profile default="true" name="Default" enabled="true" />
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -4,4 +4,4 @@
|
|||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ dependencies {
|
|||||||
compile 'org.simpleframework:simple-xml:2.7.1'
|
compile 'org.simpleframework:simple-xml:2.7.1'
|
||||||
compile 'javax.xml.bind:jaxb-api:2.3.1'
|
compile 'javax.xml.bind:jaxb-api:2.3.1'
|
||||||
implementation 'com.formdev:flatlaf:0.30'
|
implementation 'com.formdev:flatlaf:0.30'
|
||||||
|
implementation 'com.squareup.okhttp3:okhttp:4.7.2'
|
||||||
|
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.7.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
|||||||
@@ -685,6 +685,8 @@ import lombok.Data;
|
|||||||
|
|
||||||
// must download the archive
|
// must download the archive
|
||||||
int ret = this.server.HTTPGetFile(url, local_path, this.gui, update_ui);
|
int ret = this.server.HTTPGetFile(url, local_path, this.gui, update_ui);
|
||||||
|
|
||||||
|
// Try to check the download file even if a download error has occurred (MD5 file check will delete the file if partially downloaded)
|
||||||
boolean md5_check = this.checkFile(ajob, local_path, md5_server);
|
boolean md5_check = this.checkFile(ajob, local_path, md5_server);
|
||||||
int attempts = 1;
|
int attempts = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -19,45 +19,47 @@
|
|||||||
|
|
||||||
package com.sheepit.client;
|
package com.sheepit.client;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.ConnectException;
|
import java.net.*;
|
||||||
import java.net.CookieHandler;
|
import java.nio.file.Files;
|
||||||
import java.net.CookieManager;
|
import java.nio.file.Paths;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.NoRouteToHostException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.security.KeyManagementException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.simpleframework.xml.core.Persister;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.FormBody;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.JavaNetCookieJar;
|
||||||
|
|
||||||
|
import com.sheepit.client.Configuration.ComputeType;
|
||||||
|
import com.sheepit.client.Error.ServerCode;
|
||||||
import com.sheepit.client.datamodel.CacheFileMD5;
|
import com.sheepit.client.datamodel.CacheFileMD5;
|
||||||
import com.sheepit.client.datamodel.FileMD5;
|
import com.sheepit.client.datamodel.FileMD5;
|
||||||
import com.sheepit.client.datamodel.HeartBeatInfos;
|
import com.sheepit.client.datamodel.HeartBeatInfos;
|
||||||
@@ -65,11 +67,6 @@ import com.sheepit.client.datamodel.JobInfos;
|
|||||||
import com.sheepit.client.datamodel.JobValidation;
|
import com.sheepit.client.datamodel.JobValidation;
|
||||||
import com.sheepit.client.datamodel.RequestEndPoint;
|
import com.sheepit.client.datamodel.RequestEndPoint;
|
||||||
import com.sheepit.client.datamodel.ServerConfig;
|
import com.sheepit.client.datamodel.ServerConfig;
|
||||||
import lombok.Getter;
|
|
||||||
import org.simpleframework.xml.core.Persister;
|
|
||||||
|
|
||||||
import com.sheepit.client.Configuration.ComputeType;
|
|
||||||
import com.sheepit.client.Error.ServerCode;
|
|
||||||
import com.sheepit.client.exception.FermeException;
|
import com.sheepit.client.exception.FermeException;
|
||||||
import com.sheepit.client.exception.FermeExceptionBadResponseFromServer;
|
import com.sheepit.client.exception.FermeExceptionBadResponseFromServer;
|
||||||
import com.sheepit.client.exception.FermeExceptionNoRendererAvailable;
|
import com.sheepit.client.exception.FermeExceptionNoRendererAvailable;
|
||||||
@@ -82,8 +79,10 @@ import com.sheepit.client.exception.FermeExceptionSessionDisabled;
|
|||||||
import com.sheepit.client.exception.FermeServerDown;
|
import com.sheepit.client.exception.FermeServerDown;
|
||||||
import com.sheepit.client.os.OS;
|
import com.sheepit.client.os.OS;
|
||||||
|
|
||||||
public class Server extends Thread implements HostnameVerifier, X509TrustManager {
|
|
||||||
|
public class Server extends Thread {
|
||||||
private String base_url;
|
private String base_url;
|
||||||
|
private final OkHttpClient httpClient;
|
||||||
|
|
||||||
@Getter private ServerConfig serverConfig;
|
@Getter private ServerConfig serverConfig;
|
||||||
|
|
||||||
@@ -102,8 +101,10 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
this.lastRequestTime = 0;
|
this.lastRequestTime = 0;
|
||||||
this.keepmealive_duration = 15 * 60 * 1000; // default 15min
|
this.keepmealive_duration = 15 * 60 * 1000; // default 15min
|
||||||
|
|
||||||
CookieManager cookies = new CookieManager();
|
// OkHttp performs best when we create a single OkHttpClient instance and reuse it for all of the HTTP calls. This is because each client holds its own
|
||||||
CookieHandler.setDefault(cookies);
|
// connection pool and thread pools.Reusing connections and threads reduces latency and saves memory. Conversely, creating a client for each request
|
||||||
|
// wastes resources on idle pools.
|
||||||
|
this.httpClient = getOkHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -115,22 +116,28 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
long current_time = new Date().getTime();
|
long current_time = new Date().getTime();
|
||||||
if ((current_time - this.lastRequestTime) > this.keepmealive_duration) {
|
if ((current_time - this.lastRequestTime) > this.keepmealive_duration) {
|
||||||
try {
|
try {
|
||||||
String args = "";
|
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(this.getPage("keepmealive"))).newBuilder();
|
||||||
|
|
||||||
if (this.client != null && this.client.getRenderingJob() != null) {
|
if (this.client != null && this.client.getRenderingJob() != null) {
|
||||||
args = "?frame=" + this.client.getRenderingJob().getFrameNumber() + "&job=" + this.client.getRenderingJob().getId();
|
Job job = this.client.getRenderingJob();
|
||||||
if (this.client.getRenderingJob().getExtras() != null && this.client.getRenderingJob().getExtras().isEmpty() == false) {
|
|
||||||
args += "&extras=" + this.client.getRenderingJob().getExtras();
|
urlBuilder.addQueryParameter("frame", job.getFrameNumber()).addQueryParameter("job", job.getId());
|
||||||
|
if (job.getExtras() != null && !job.getExtras().isEmpty()) {
|
||||||
|
urlBuilder.addQueryParameter("extras", job.getExtras());
|
||||||
}
|
}
|
||||||
if (this.client.getRenderingJob().getProcessRender() != null) {
|
|
||||||
args += "&rendertime=" + this.client.getRenderingJob().getProcessRender().getDuration();
|
RenderProcess process = job.getProcessRender();
|
||||||
args += "&remainingtime=" + this.client.getRenderingJob().getProcessRender().getRemainingDuration();
|
if (process != null) {
|
||||||
|
urlBuilder.addQueryParameter("rendertime", String.valueOf(process.getDuration()))
|
||||||
|
.addQueryParameter("remainingtime", String.valueOf(process.getRemainingDuration()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpURLConnection connection = this.HTTPRequest(this.getPage("keepmealive") + args);
|
Response response = this.HTTPRequest(urlBuilder);
|
||||||
|
|
||||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK && connection.getContentType().startsWith("text/xml")) {
|
if (response.code() == HttpURLConnection.HTTP_OK && response.body().contentType().toString().startsWith("text/xml")) {
|
||||||
DataInputStream in = new DataInputStream(connection.getInputStream());
|
String in = response.body().string();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HeartBeatInfos heartBeartInfos = new Persister().read(HeartBeatInfos.class, in);
|
HeartBeatInfos heartBeartInfos = new Persister().read(HeartBeatInfos.class, in);
|
||||||
ServerCode serverCode = ServerCode.fromInt(heartBeartInfos.getStatus());
|
ServerCode serverCode = ServerCode.fromInt(heartBeartInfos.getStatus());
|
||||||
@@ -181,27 +188,33 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
|
|
||||||
public Error.Type getConfiguration() {
|
public Error.Type getConfiguration() {
|
||||||
OS os = OS.getOS();
|
OS os = OS.getOS();
|
||||||
HttpURLConnection connection = null;
|
|
||||||
String publickey = null;
|
String publickey = null;
|
||||||
try {
|
try {
|
||||||
String url_remote = this.base_url + "/server/config.php";
|
HttpUrl.Builder remoteURL = Objects.requireNonNull(HttpUrl.parse(this.base_url + "/server/config.php")).newBuilder();
|
||||||
String parameters = String
|
FormBody formBody = new FormBody.Builder()
|
||||||
.format("login=%s&password=%s&cpu_family=%s&cpu_model=%s&cpu_model_name=%s&cpu_cores=%s&os=%s&ram=%s&bits=%s&version=%s&hostname=%s&ui=%s&extras=%s",
|
.add("login", user_config.getLogin())
|
||||||
URLEncoder.encode(this.user_config.getLogin(), "UTF-8"), URLEncoder.encode(this.user_config.getPassword(), "UTF-8"),
|
.add("password", user_config.getPassword())
|
||||||
URLEncoder.encode(os.getCPU().family(), "UTF-8"), URLEncoder.encode(os.getCPU().model(), "UTF-8"),
|
.add("cpu_family", os.getCPU().family())
|
||||||
URLEncoder.encode(os.getCPU().name(), "UTF-8"),
|
.add("cpu_model", os.getCPU().model())
|
||||||
((this.user_config.getNbCores() == -1) ? os.getCPU().cores() : this.user_config.getNbCores()),
|
.add("cpu_model_name", os.getCPU().name())
|
||||||
URLEncoder.encode(os.name(), "UTF-8"), os.getMemory(), URLEncoder.encode(os.getCPU().arch(), "UTF-8"),
|
.add("cpu_cores", String.valueOf(user_config.getNbCores() == -1 ? os.getCPU().cores() : user_config.getNbCores()))
|
||||||
this.user_config.getJarVersion(), URLEncoder.encode(this.user_config.getHostname(), "UTF-8"),
|
.add("os", os.name())
|
||||||
this.client.getGui().getClass().getSimpleName(), this.user_config.getExtras());
|
.add("ram", String.valueOf(os.getMemory()))
|
||||||
this.log.debug("Server::getConfiguration url " + url_remote);
|
.add("bits", os.getCPU().arch())
|
||||||
|
.add("version", user_config.getJarVersion())
|
||||||
|
.add("hostname", user_config.getHostname())
|
||||||
|
.add("ui", client.getGui().getClass().getSimpleName())
|
||||||
|
.add("extras", user_config.getExtras())
|
||||||
|
.build();
|
||||||
|
|
||||||
connection = this.HTTPRequest(url_remote, parameters);
|
this.log.debug("Server::getConfiguration url " + remoteURL.build().toString());
|
||||||
int r = connection.getResponseCode();
|
|
||||||
String contentType = connection.getContentType();
|
Response response = this.HTTPRequest(remoteURL, formBody);
|
||||||
|
int r = response.code();
|
||||||
|
String contentType = response.body().contentType().toString();
|
||||||
|
|
||||||
if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/xml")) {
|
if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/xml")) {
|
||||||
DataInputStream in = new DataInputStream(connection.getInputStream());
|
String in = response.body().string();
|
||||||
serverConfig = new Persister().read(ServerConfig.class, in);
|
serverConfig = new Persister().read(ServerConfig.class, in);
|
||||||
|
|
||||||
if (ServerCode.fromInt(serverConfig.getStatus()) != ServerCode.OK) {
|
if (ServerCode.fromInt(serverConfig.getStatus()) != ServerCode.OK) {
|
||||||
@@ -237,11 +250,6 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
this.log.error("Server::getConfiguration: exception Exception " + e);
|
this.log.error("Server::getConfiguration: exception Exception " + e);
|
||||||
return Error.Type.UNKNOWN;
|
return Error.Type.UNKNOWN;
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
if (connection != null) {
|
|
||||||
connection.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.client.getGui().successfulAuthenticationEvent(publickey);
|
this.client.getGui().successfulAuthenticationEvent(publickey);
|
||||||
|
|
||||||
@@ -252,7 +260,6 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
this.log.debug("Server::requestJob");
|
this.log.debug("Server::requestJob");
|
||||||
String url_contents = "";
|
String url_contents = "";
|
||||||
|
|
||||||
HttpURLConnection connection = null;
|
|
||||||
try {
|
try {
|
||||||
OS os = OS.getOS();
|
OS os = OS.getOS();
|
||||||
long maxMemory = this.user_config.getMaxMemory();
|
long maxMemory = this.user_config.getMaxMemory();
|
||||||
@@ -263,28 +270,26 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
else if (freeMemory > 0 && maxMemory > 0) {
|
else if (freeMemory > 0 && maxMemory > 0) {
|
||||||
maxMemory = Math.min(maxMemory, freeMemory);
|
maxMemory = Math.min(maxMemory, freeMemory);
|
||||||
}
|
}
|
||||||
String url = String
|
|
||||||
.format("%s?computemethod=%s&cpu_cores=%s&ram_max=%s&rendertime_max=%s", this.getPage("request-job"), this.user_config.computeMethodToInt(),
|
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(this.getPage("request-job"))).newBuilder()
|
||||||
((this.user_config.getNbCores() == -1) ? os.getCPU().cores() : this.user_config.getNbCores()), maxMemory,
|
.addQueryParameter("computemethod", String.valueOf(user_config.computeMethodToInt()))
|
||||||
this.user_config.getMaxRenderTime());
|
.addQueryParameter("cpu_cores", String.valueOf(user_config.getNbCores() == -1 ? os.getCPU().cores() : user_config.getNbCores()))
|
||||||
if (this.user_config.getComputeMethod() != ComputeType.CPU && this.user_config.getGPUDevice() != null) {
|
.addQueryParameter("ram_max", String.valueOf(maxMemory))
|
||||||
String gpu_model = "";
|
.addQueryParameter("rendertime_max", String.valueOf(user_config.getMaxRenderTime()));
|
||||||
try {
|
|
||||||
gpu_model = URLEncoder.encode(this.user_config.getGPUDevice().getModel(), "UTF-8");
|
if (user_config.getComputeMethod() != ComputeType.CPU && user_config.getGPUDevice() != null) {
|
||||||
}
|
urlBuilder.addQueryParameter("gpu_model", user_config.getGPUDevice().getModel())
|
||||||
catch (UnsupportedEncodingException e) {
|
.addQueryParameter("gpu_ram", String.valueOf(user_config.getGPUDevice().getMemory()))
|
||||||
}
|
.addQueryParameter("gpu_type", user_config.getGPUDevice().getType());
|
||||||
url += "&gpu_model=" + gpu_model + "&gpu_ram=" + this.user_config.getGPUDevice().getMemory() + "&gpu_type=" + this.user_config.getGPUDevice()
|
|
||||||
.getType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Response response = this.HTTPRequest(urlBuilder, RequestBody.create(MediaType.parse("application/xml"), this.generateXMLForMD5cache()));
|
||||||
|
|
||||||
connection = this.HTTPRequest(url, this.generateXMLForMD5cache());
|
int r = response.code();
|
||||||
|
String contentType = response.body().contentType().toString();
|
||||||
int r = connection.getResponseCode();
|
|
||||||
String contentType = connection.getContentType();
|
|
||||||
|
|
||||||
if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/xml")) {
|
if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/xml")) {
|
||||||
DataInputStream in = new DataInputStream(connection.getInputStream());
|
String in = response.body().string();
|
||||||
|
|
||||||
JobInfos jobData = new Persister().read(JobInfos.class, in);
|
JobInfos jobData = new Persister().read(JobInfos.class, in);
|
||||||
|
|
||||||
@@ -358,13 +363,7 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
else if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/html")) {
|
else if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/html")) {
|
||||||
throw new FermeExceptionBadResponseFromServer();
|
throw new FermeExceptionBadResponseFromServer();
|
||||||
}
|
}
|
||||||
InputStream in = connection.getInputStream();
|
System.out.println(response.body().string());
|
||||||
String line;
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
System.out.print(line);
|
|
||||||
}
|
|
||||||
System.out.println("");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (FermeException e) {
|
catch (FermeException e) {
|
||||||
@@ -382,103 +381,87 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
e.printStackTrace(pw);
|
e.printStackTrace(pw);
|
||||||
throw new FermeException("error requestJob: unknown exception " + e + " stacktrace: " + sw.toString());
|
throw new FermeException("error requestJob: unknown exception " + e + " stacktrace: " + sw.toString());
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
if (connection != null) {
|
|
||||||
connection.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new FermeException("error requestJob, end of function");
|
throw new FermeException("error requestJob, end of function");
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpURLConnection HTTPRequest(String url_) throws IOException {
|
public Response HTTPRequest(String url) throws IOException {
|
||||||
return this.HTTPRequest(url_, null);
|
HttpUrl.Builder httpUrlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
|
||||||
|
return this.HTTPRequest(httpUrlBuilder, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpURLConnection HTTPRequest(String url_, String data_) throws IOException {
|
public Response HTTPRequest(HttpUrl.Builder httpUrlBuilder) throws IOException {
|
||||||
this.log.debug("Server::HTTPRequest url(" + url_ + ")");
|
return this.HTTPRequest(httpUrlBuilder, null);
|
||||||
HttpURLConnection connection = null;
|
}
|
||||||
URL url = new URL(url_);
|
|
||||||
|
public Response HTTPRequest(HttpUrl.Builder httpUrlBuilder, RequestBody data_) throws IOException {
|
||||||
|
String url = httpUrlBuilder.build().toString();
|
||||||
|
Request.Builder builder = new Request.Builder();
|
||||||
|
builder.url(url);
|
||||||
|
|
||||||
connection = (HttpURLConnection) url.openConnection();
|
this.log.debug("Server::HTTPRequest url(" + url + ")");
|
||||||
connection.setDoInput(true);
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
connection.setInstanceFollowRedirects(true);
|
|
||||||
connection.setRequestMethod("GET");
|
|
||||||
|
|
||||||
if (url_.startsWith("https://")) {
|
|
||||||
try {
|
|
||||||
SSLContext sc;
|
|
||||||
sc = SSLContext.getInstance("SSL");
|
|
||||||
sc.init(null, new TrustManager[] { this }, null);
|
|
||||||
SSLSocketFactory factory = sc.getSocketFactory();
|
|
||||||
((HttpsURLConnection) connection).setSSLSocketFactory(factory);
|
|
||||||
((HttpsURLConnection) connection).setHostnameVerifier(this);
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException e) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
this.log.debug("Server::HTTPRequest NoSuchAlgorithmException " + e + " stacktrace: " + sw.toString());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (KeyManagementException e) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
this.log.debug("Server::HTTPRequest KeyManagementException " + e + " stacktrace: " + sw.toString());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_ != null) {
|
if (data_ != null) {
|
||||||
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
|
builder.post(data_);
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
|
|
||||||
out.write(data_);
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually use the connection to, in case of timeout, generate an exception
|
Request request = builder.build();
|
||||||
connection.getResponseCode();
|
Response response = null;
|
||||||
|
|
||||||
this.lastRequestTime = new Date().getTime();
|
try {
|
||||||
|
response = httpClient.newCall(request).execute();
|
||||||
return connection;
|
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
throw new IOException("Unexpected code " + response);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastRequestTime = new Date().getTime();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new IOException("Unexpected response from HTTP Stack" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int HTTPGetFile(String url_, String destination_, Gui gui_, String status_) throws FermeExceptionNoSpaceLeftOnDevice {
|
public int HTTPGetFile(String url_, String destination_, Gui gui_, String status_) throws FermeExceptionNoSpaceLeftOnDevice {
|
||||||
// the destination_ parent directory must exist
|
// the destination_ parent directory must exist
|
||||||
try {
|
try {
|
||||||
HttpURLConnection httpCon = this.HTTPRequest(url_);
|
Response response = this.HTTPRequest(url_);
|
||||||
|
|
||||||
InputStream inStrm = httpCon.getInputStream();
|
if (response.code() != HttpURLConnection.HTTP_OK) {
|
||||||
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
this.log.error("Server::HTTPGetFile(" + url_ + ", ...) HTTP code is not " + HttpURLConnection.HTTP_OK + " it's " + response.code());
|
||||||
this.log.error("Server::HTTPGetFile(" + url_ + ", ...) HTTP code is not " + HttpURLConnection.HTTP_OK + " it's " + httpCon.getResponseCode());
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int size = httpCon.getContentLength();
|
|
||||||
long start = new Date().getTime();
|
|
||||||
|
|
||||||
FileOutputStream fos = new FileOutputStream(destination_);
|
long start = new Date().getTime();
|
||||||
byte[] ch = new byte[512 * 1024];
|
InputStream is = response.body().byteStream();
|
||||||
int nb;
|
OutputStream output = new FileOutputStream(destination_);
|
||||||
|
|
||||||
|
long size = response.body().contentLength();
|
||||||
|
byte[] buffer = new byte[8 * 1024];
|
||||||
|
int len = 0;
|
||||||
long written = 0;
|
long written = 0;
|
||||||
long last_gui_update = 0; // size in byte
|
long lastUpd = 0; // last GUI progress update
|
||||||
while ((nb = inStrm.read(ch)) != -1) {
|
|
||||||
fos.write(ch, 0, nb);
|
while ((len = is.read(buffer)) != -1) {
|
||||||
written += nb;
|
output.write(buffer, 0, len);
|
||||||
if ((written - last_gui_update) > 1000000) { // only update the gui every 1MB
|
written += len;
|
||||||
|
|
||||||
|
if ((written - lastUpd) > 1000000) { // only update the gui every 1MB
|
||||||
gui_.status(String.format(status_, (int) (100.0 * written / size)));
|
gui_.status(String.format(status_, (int) (100.0 * written / size)));
|
||||||
last_gui_update = written;
|
lastUpd = written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fos.close();
|
|
||||||
inStrm.close();
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
is.close();
|
||||||
|
|
||||||
gui_.status(String.format(status_, 100));
|
gui_.status(String.format(status_, 100));
|
||||||
|
|
||||||
long end = new Date().getTime();
|
long end = new Date().getTime();
|
||||||
this.log.debug(String.format("File downloaded at %.1f kB/s, written %d B", ((float) (size / 1000)) / ((float) (end - start) / 1000), written));
|
this.log.debug(String.format("File downloaded at %.1f kB/s, written %d B", ((float) (size / 1000)) / ((float) (end - start) / 1000), written));
|
||||||
this.lastRequestTime = new Date().getTime();
|
this.lastRequestTime = new Date().getTime();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
@@ -490,111 +473,62 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
e.printStackTrace(new PrintWriter(sw));
|
e.printStackTrace(new PrintWriter(sw));
|
||||||
this.log.error("Server::HTTPGetFile Exception " + e + " stacktrace " + sw.toString());
|
this.log.error("Server::HTTPGetFile Exception " + e + " stacktrace " + sw.toString());
|
||||||
}
|
}
|
||||||
this.log.debug("Server::HTTPGetFile(" + url_ + ", ...) will failed (end of function)");
|
this.log.debug(String.format("Server::HTTPGetFile(%s) did fail", url_));
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerCode HTTPSendFile(String surl, String file1) {
|
public ServerCode HTTPSendFile(String surl, String file1) {
|
||||||
this.log.debug("Server::HTTPSendFile(" + surl + "," + file1 + ")");
|
this.log.debug("Server::HTTPSendFile(" + surl + "," + file1 + ")");
|
||||||
|
|
||||||
HttpURLConnection conn = null;
|
|
||||||
DataOutputStream dos = null;
|
|
||||||
BufferedReader inStream = null;
|
|
||||||
|
|
||||||
String exsistingFileName = file1;
|
|
||||||
File fFile2Snd = new File(exsistingFileName);
|
|
||||||
|
|
||||||
String lineEnd = "\r\n";
|
|
||||||
String twoHyphens = "--";
|
|
||||||
String boundary = "***232404jkg4220957934FW**";
|
|
||||||
|
|
||||||
int bytesRead, bytesAvailable, bufferSize;
|
|
||||||
byte[] buffer;
|
|
||||||
int maxBufferSize = 1 * 1024 * 1024;
|
|
||||||
|
|
||||||
String urlString = surl;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileInputStream fileInputStream = new FileInputStream(new File(exsistingFileName));
|
String fileMimeType = Files.probeContentType(Paths.get(file1));
|
||||||
URL url = new URL(urlString);
|
|
||||||
|
|
||||||
conn = (HttpURLConnection) url.openConnection();
|
MediaType MEDIA_TYPE = MediaType.parse("image/" + fileMimeType); // e.g. "image/png"
|
||||||
conn.setDoInput(true);
|
|
||||||
conn.setDoOutput(true);
|
|
||||||
conn.setInstanceFollowRedirects(true);
|
|
||||||
conn.setUseCaches(false);
|
|
||||||
|
|
||||||
conn.setRequestMethod("POST");
|
RequestBody uploadContent = new MultipartBody.Builder().setType(MultipartBody.FORM)
|
||||||
conn.setRequestProperty("Connection", "Keep-Alive");
|
.addFormDataPart("file", new File(file1).getName(), RequestBody.create(MEDIA_TYPE, new File(file1))).build();
|
||||||
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
|
|
||||||
|
|
||||||
if (urlString.startsWith("https://")) {
|
Request request = new Request.Builder().url(surl).post(uploadContent).build();
|
||||||
|
|
||||||
|
Call call = httpClient.newCall(request);
|
||||||
|
Response response = call.execute();
|
||||||
|
|
||||||
|
int r = response.code();
|
||||||
|
String contentType = response.body().contentType().toString();
|
||||||
|
|
||||||
|
if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/xml")) {
|
||||||
try {
|
try {
|
||||||
SSLContext sc;
|
String in = response.body().string();
|
||||||
sc = SSLContext.getInstance("SSL");
|
JobValidation jobValidation = new Persister().read(JobValidation.class, in);
|
||||||
sc.init(null, new TrustManager[] { this }, null);
|
|
||||||
SSLSocketFactory factory = sc.getSocketFactory();
|
|
||||||
((HttpsURLConnection) conn).setSSLSocketFactory(factory);
|
|
||||||
((HttpsURLConnection) conn).setHostnameVerifier(this);
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException e) {
|
|
||||||
this.log.error("Server::HTTPSendFile, exception NoSuchAlgorithmException " + e);
|
|
||||||
try {
|
|
||||||
fileInputStream.close();
|
|
||||||
}
|
|
||||||
catch (Exception e1) {
|
|
||||||
|
|
||||||
}
|
this.lastRequestTime = new Date().getTime();
|
||||||
return ServerCode.UNKNOWN;
|
|
||||||
}
|
|
||||||
catch (KeyManagementException e) {
|
|
||||||
this.log.error("Server::HTTPSendFile, exception KeyManagementException " + e);
|
|
||||||
try {
|
|
||||||
fileInputStream.close();
|
|
||||||
}
|
|
||||||
catch (Exception e1) {
|
|
||||||
|
|
||||||
|
ServerCode serverCode = ServerCode.fromInt(jobValidation.getStatus());
|
||||||
|
if (serverCode != ServerCode.OK) {
|
||||||
|
this.log.error("Server::HTTPSendFile wrong status (is " + serverCode + ")");
|
||||||
|
return serverCode;
|
||||||
}
|
}
|
||||||
return ServerCode.UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
catch (Exception e) { // for the .read
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServerCode.OK;
|
||||||
|
}
|
||||||
|
else if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/html")) {
|
||||||
|
return ServerCode.ERROR_BAD_RESPONSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.println(response.body().string());
|
||||||
}
|
}
|
||||||
|
|
||||||
dos = new DataOutputStream(conn.getOutputStream());
|
|
||||||
dos.writeBytes(twoHyphens + boundary + lineEnd);
|
|
||||||
dos.writeBytes("Content-Disposition: form-data; name=\"file\";" + " filename=\"" + fFile2Snd.getName() + "\"" + lineEnd);
|
|
||||||
dos.writeBytes(lineEnd);
|
|
||||||
|
|
||||||
bytesAvailable = fileInputStream.available();
|
|
||||||
bufferSize = Math.min(bytesAvailable, maxBufferSize);
|
|
||||||
buffer = new byte[bufferSize];
|
|
||||||
|
|
||||||
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
|
|
||||||
|
|
||||||
while (bytesRead > 0) {
|
|
||||||
dos.write(buffer, 0, bufferSize);
|
|
||||||
bytesAvailable = fileInputStream.available();
|
|
||||||
bufferSize = Math.min(bytesAvailable, maxBufferSize);
|
|
||||||
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
dos.writeBytes(lineEnd);
|
|
||||||
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
|
|
||||||
fileInputStream.close();
|
|
||||||
dos.flush();
|
|
||||||
dos.close();
|
|
||||||
}
|
|
||||||
catch (MalformedURLException e) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
this.log.error("Server::HTTPSendFile, MalformedURLException " + e + " stacktrace " + sw.toString());
|
|
||||||
return ServerCode.UNKNOWN;
|
return ServerCode.UNKNOWN;
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
e.printStackTrace(pw);
|
e.printStackTrace(pw);
|
||||||
this.log.error("Server::HTTPSendFile, IOException " + e + " stacktrace " + sw.toString());
|
this.log.error(String.format("Server::HTTPSendFile Error in upload process. Exception %s stacktrace ", e.getMessage(), sw.toString()));
|
||||||
return ServerCode.UNKNOWN;
|
return ServerCode.UNKNOWN;
|
||||||
}
|
}
|
||||||
catch (OutOfMemoryError e) {
|
catch (OutOfMemoryError e) {
|
||||||
@@ -611,68 +545,6 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
this.log.error("Server::HTTPSendFile, Exception " + e + " stacktrace " + sw.toString());
|
this.log.error("Server::HTTPSendFile, Exception " + e + " stacktrace " + sw.toString());
|
||||||
return ServerCode.UNKNOWN;
|
return ServerCode.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r;
|
|
||||||
try {
|
|
||||||
r = conn.getResponseCode();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
this.log.debug("Server::HTTPSendFile IOException " + e + " stacktrace: " + sw.toString());
|
|
||||||
return ServerCode.UNKNOWN;
|
|
||||||
}
|
|
||||||
String contentType = conn.getContentType();
|
|
||||||
|
|
||||||
if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/xml")) {
|
|
||||||
DataInputStream in;
|
|
||||||
try {
|
|
||||||
in = new DataInputStream(conn.getInputStream());
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
this.log.debug("Server::HTTPSendFile IOException " + e + " stacktrace: " + sw.toString());
|
|
||||||
return ServerCode.UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
JobValidation jobValidation = new Persister().read(JobValidation.class, in);
|
|
||||||
|
|
||||||
this.lastRequestTime = new Date().getTime();
|
|
||||||
|
|
||||||
ServerCode serverCode = ServerCode.fromInt(jobValidation.getStatus());
|
|
||||||
if (serverCode != ServerCode.OK) {
|
|
||||||
this.log.error("Server::HTTPSendFile wrong status (is " + serverCode + ")");
|
|
||||||
return serverCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) { // for the .read
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ServerCode.OK;
|
|
||||||
}
|
|
||||||
else if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/html")) {
|
|
||||||
return ServerCode.ERROR_BAD_RESPONSE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
inStream = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
||||||
|
|
||||||
String str;
|
|
||||||
while ((str = inStream.readLine()) != null) {
|
|
||||||
System.out.println(str);
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
inStream.close();
|
|
||||||
}
|
|
||||||
catch (IOException ioex) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ServerCode.UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateXMLForMD5cache() {
|
private String generateXMLForMD5cache() {
|
||||||
@@ -731,17 +603,58 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
|
private OkHttpClient getOkHttpClient() {
|
||||||
}
|
try {
|
||||||
|
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
|
||||||
@Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
|
|
||||||
}
|
@Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
}
|
||||||
@Override public X509Certificate[] getAcceptedIssuers() {
|
|
||||||
return null;
|
@Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean verify(String arg0, SSLSession arg1) {
|
@Override public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||||
return true; // trust every ssl certificate
|
return new java.security.cert.X509Certificate[] {};
|
||||||
|
}
|
||||||
|
} };
|
||||||
|
|
||||||
|
final SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||||
|
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||||
|
|
||||||
|
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
|
||||||
|
|
||||||
|
CookieManager cookieManager = new CookieManager();
|
||||||
|
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
|
||||||
|
builder.cookieJar(new JavaNetCookieJar(cookieManager)); // Cookie store to maintain the session across calls
|
||||||
|
|
||||||
|
builder.connectTimeout(30, TimeUnit.SECONDS); // Cancel the HTTP Request if the connection to server takes more than 10 seconds
|
||||||
|
builder.writeTimeout(60, TimeUnit.SECONDS); // Cancel the upload if the client cannot send any byte in 60 seconds
|
||||||
|
|
||||||
|
// If the user has selected a proxy, then we must increase the download timeout. Reason being the way proxies work. To download a large file (i.e.
|
||||||
|
// a 500MB job), the proxy must first download the file to the proxy cache and then the information is sent fast to the SheepIt client. From a client
|
||||||
|
// viewpoint, the HTTP connection will make the CONNECT step really fast but then the time until the fist byte is received (the time measured by
|
||||||
|
// readTimeout) will be really long (minutes). Without a proxy in the middle, a connection that does receive nothing in 60 seconds might be
|
||||||
|
// considered a dead connection.
|
||||||
|
if (this.user_config.getProxy() != null) {
|
||||||
|
builder.readTimeout(10, TimeUnit.MINUTES); // Proxy enabled - 10 minutes
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.readTimeout(1, TimeUnit.MINUTES); // No proxy - 60 seconds max
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.hostnameVerifier(new HostnameVerifier() {
|
||||||
|
@Override public boolean verify(String hostname, SSLSession session) {
|
||||||
|
return true; // Accept all certificates
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user