diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index a1757ae..95a88ae 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -5,4 +5,4 @@
-
\ No newline at end of file
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index bc8d0a3..e860487 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,4 +4,4 @@
-
\ No newline at end of file
+
diff --git a/build.gradle b/build.gradle
index c0f700e..8e2f5c4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -38,6 +38,8 @@ dependencies {
compile 'org.simpleframework:simple-xml:2.7.1'
compile 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'com.formdev:flatlaf:0.30'
+ implementation 'com.squareup.okhttp3:okhttp:4.7.2'
+ implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.7.2'
}
jar {
diff --git a/src/com/sheepit/client/Client.java b/src/com/sheepit/client/Client.java
index b66b5eb..c9812ae 100644
--- a/src/com/sheepit/client/Client.java
+++ b/src/com/sheepit/client/Client.java
@@ -685,6 +685,8 @@ import lombok.Data;
// must download the archive
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);
int attempts = 1;
diff --git a/src/com/sheepit/client/Server.java b/src/com/sheepit/client/Server.java
index 53ce7a7..8c9a8fe 100644
--- a/src/com/sheepit/client/Server.java
+++ b/src/com/sheepit/client/Server.java
@@ -19,45 +19,47 @@
package com.sheepit.client;
-import java.io.BufferedReader;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
-import java.net.ConnectException;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-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.net.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
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.FileMD5;
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.RequestEndPoint;
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.FermeExceptionBadResponseFromServer;
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.os.OS;
-public class Server extends Thread implements HostnameVerifier, X509TrustManager {
+
+public class Server extends Thread {
private String base_url;
+ private final OkHttpClient httpClient;
@Getter private ServerConfig serverConfig;
@@ -102,8 +101,10 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
this.lastRequestTime = 0;
this.keepmealive_duration = 15 * 60 * 1000; // default 15min
- CookieManager cookies = new CookieManager();
- CookieHandler.setDefault(cookies);
+ // 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
+ // 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() {
@@ -115,22 +116,28 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
long current_time = new Date().getTime();
if ((current_time - this.lastRequestTime) > this.keepmealive_duration) {
try {
- String args = "";
+ HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(this.getPage("keepmealive"))).newBuilder();
+
if (this.client != null && this.client.getRenderingJob() != null) {
- args = "?frame=" + this.client.getRenderingJob().getFrameNumber() + "&job=" + this.client.getRenderingJob().getId();
- if (this.client.getRenderingJob().getExtras() != null && this.client.getRenderingJob().getExtras().isEmpty() == false) {
- args += "&extras=" + this.client.getRenderingJob().getExtras();
+ Job job = this.client.getRenderingJob();
+
+ 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();
- args += "&remainingtime=" + this.client.getRenderingJob().getProcessRender().getRemainingDuration();
+
+ RenderProcess process = job.getProcessRender();
+ 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")) {
- DataInputStream in = new DataInputStream(connection.getInputStream());
+ if (response.code() == HttpURLConnection.HTTP_OK && response.body().contentType().toString().startsWith("text/xml")) {
+ String in = response.body().string();
+
try {
HeartBeatInfos heartBeartInfos = new Persister().read(HeartBeatInfos.class, in);
ServerCode serverCode = ServerCode.fromInt(heartBeartInfos.getStatus());
@@ -181,27 +188,33 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
public Error.Type getConfiguration() {
OS os = OS.getOS();
- HttpURLConnection connection = null;
String publickey = null;
try {
- String url_remote = this.base_url + "/server/config.php";
- String parameters = String
- .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",
- URLEncoder.encode(this.user_config.getLogin(), "UTF-8"), URLEncoder.encode(this.user_config.getPassword(), "UTF-8"),
- URLEncoder.encode(os.getCPU().family(), "UTF-8"), URLEncoder.encode(os.getCPU().model(), "UTF-8"),
- URLEncoder.encode(os.getCPU().name(), "UTF-8"),
- ((this.user_config.getNbCores() == -1) ? os.getCPU().cores() : this.user_config.getNbCores()),
- URLEncoder.encode(os.name(), "UTF-8"), os.getMemory(), URLEncoder.encode(os.getCPU().arch(), "UTF-8"),
- this.user_config.getJarVersion(), URLEncoder.encode(this.user_config.getHostname(), "UTF-8"),
- this.client.getGui().getClass().getSimpleName(), this.user_config.getExtras());
- this.log.debug("Server::getConfiguration url " + url_remote);
+ HttpUrl.Builder remoteURL = Objects.requireNonNull(HttpUrl.parse(this.base_url + "/server/config.php")).newBuilder();
+ FormBody formBody = new FormBody.Builder()
+ .add("login", user_config.getLogin())
+ .add("password", user_config.getPassword())
+ .add("cpu_family", os.getCPU().family())
+ .add("cpu_model", os.getCPU().model())
+ .add("cpu_model_name", os.getCPU().name())
+ .add("cpu_cores", String.valueOf(user_config.getNbCores() == -1 ? os.getCPU().cores() : user_config.getNbCores()))
+ .add("os", os.name())
+ .add("ram", String.valueOf(os.getMemory()))
+ .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);
- int r = connection.getResponseCode();
- String contentType = connection.getContentType();
+ this.log.debug("Server::getConfiguration url " + remoteURL.build().toString());
+
+ 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")) {
- DataInputStream in = new DataInputStream(connection.getInputStream());
+ String in = response.body().string();
serverConfig = new Persister().read(ServerConfig.class, in);
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);
return Error.Type.UNKNOWN;
}
- finally {
- if (connection != null) {
- connection.disconnect();
- }
- }
this.client.getGui().successfulAuthenticationEvent(publickey);
@@ -252,7 +260,6 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
this.log.debug("Server::requestJob");
String url_contents = "";
- HttpURLConnection connection = null;
try {
OS os = OS.getOS();
long maxMemory = this.user_config.getMaxMemory();
@@ -263,28 +270,26 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
else if (freeMemory > 0 && maxMemory > 0) {
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(),
- ((this.user_config.getNbCores() == -1) ? os.getCPU().cores() : this.user_config.getNbCores()), maxMemory,
- this.user_config.getMaxRenderTime());
- if (this.user_config.getComputeMethod() != ComputeType.CPU && this.user_config.getGPUDevice() != null) {
- String gpu_model = "";
- try {
- gpu_model = URLEncoder.encode(this.user_config.getGPUDevice().getModel(), "UTF-8");
- }
- catch (UnsupportedEncodingException e) {
- }
- url += "&gpu_model=" + gpu_model + "&gpu_ram=" + this.user_config.getGPUDevice().getMemory() + "&gpu_type=" + this.user_config.getGPUDevice()
- .getType();
+
+ HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(this.getPage("request-job"))).newBuilder()
+ .addQueryParameter("computemethod", String.valueOf(user_config.computeMethodToInt()))
+ .addQueryParameter("cpu_cores", String.valueOf(user_config.getNbCores() == -1 ? os.getCPU().cores() : user_config.getNbCores()))
+ .addQueryParameter("ram_max", String.valueOf(maxMemory))
+ .addQueryParameter("rendertime_max", String.valueOf(user_config.getMaxRenderTime()));
+
+ if (user_config.getComputeMethod() != ComputeType.CPU && user_config.getGPUDevice() != null) {
+ urlBuilder.addQueryParameter("gpu_model", user_config.getGPUDevice().getModel())
+ .addQueryParameter("gpu_ram", String.valueOf(user_config.getGPUDevice().getMemory()))
+ .addQueryParameter("gpu_type", 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 = connection.getResponseCode();
- String contentType = connection.getContentType();
+ int r = response.code();
+ String contentType = response.body().contentType().toString();
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);
@@ -358,13 +363,7 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
else if (r == HttpURLConnection.HTTP_OK && contentType.startsWith("text/html")) {
throw new FermeExceptionBadResponseFromServer();
}
- InputStream in = connection.getInputStream();
- String line;
- BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
- while ((line = reader.readLine()) != null) {
- System.out.print(line);
- }
- System.out.println("");
+ System.out.println(response.body().string());
}
}
catch (FermeException e) {
@@ -382,103 +381,87 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
e.printStackTrace(pw);
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");
}
- public HttpURLConnection HTTPRequest(String url_) throws IOException {
- return this.HTTPRequest(url_, null);
+ public Response HTTPRequest(String url) throws IOException {
+ HttpUrl.Builder httpUrlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
+ return this.HTTPRequest(httpUrlBuilder, null);
}
- public HttpURLConnection HTTPRequest(String url_, String data_) throws IOException {
- this.log.debug("Server::HTTPRequest url(" + url_ + ")");
- HttpURLConnection connection = null;
- URL url = new URL(url_);
+ public Response HTTPRequest(HttpUrl.Builder httpUrlBuilder) throws IOException {
+ return this.HTTPRequest(httpUrlBuilder, null);
+ }
+
+ 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();
- 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;
- }
- }
+ this.log.debug("Server::HTTPRequest url(" + url + ")");
if (data_ != null) {
- connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
- connection.setRequestMethod("POST");
- OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
- out.write(data_);
- out.flush();
- out.close();
+ builder.post(data_);
}
- // actually use the connection to, in case of timeout, generate an exception
- connection.getResponseCode();
+ Request request = builder.build();
+ Response response = null;
- this.lastRequestTime = new Date().getTime();
-
- return connection;
+ try {
+ response = httpClient.newCall(request).execute();
+
+ 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 {
// the destination_ parent directory must exist
try {
- HttpURLConnection httpCon = this.HTTPRequest(url_);
+ Response response = this.HTTPRequest(url_);
- InputStream inStrm = httpCon.getInputStream();
- if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) {
- this.log.error("Server::HTTPGetFile(" + url_ + ", ...) HTTP code is not " + HttpURLConnection.HTTP_OK + " it's " + httpCon.getResponseCode());
+ if (response.code() != HttpURLConnection.HTTP_OK) {
+ this.log.error("Server::HTTPGetFile(" + url_ + ", ...) HTTP code is not " + HttpURLConnection.HTTP_OK + " it's " + response.code());
return -1;
}
- int size = httpCon.getContentLength();
- long start = new Date().getTime();
- FileOutputStream fos = new FileOutputStream(destination_);
- byte[] ch = new byte[512 * 1024];
- int nb;
+ long start = new Date().getTime();
+ InputStream is = response.body().byteStream();
+ OutputStream output = new FileOutputStream(destination_);
+
+ long size = response.body().contentLength();
+ byte[] buffer = new byte[8 * 1024];
+ int len = 0;
long written = 0;
- long last_gui_update = 0; // size in byte
- while ((nb = inStrm.read(ch)) != -1) {
- fos.write(ch, 0, nb);
- written += nb;
- if ((written - last_gui_update) > 1000000) { // only update the gui every 1MB
+ long lastUpd = 0; // last GUI progress update
+
+ while ((len = is.read(buffer)) != -1) {
+ output.write(buffer, 0, len);
+ written += len;
+
+ if ((written - lastUpd) > 1000000) { // only update the gui every 1MB
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));
+
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.lastRequestTime = new Date().getTime();
+
return 0;
}
catch (Exception e) {
@@ -490,111 +473,62 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
e.printStackTrace(new PrintWriter(sw));
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;
}
public ServerCode HTTPSendFile(String surl, String 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 {
- FileInputStream fileInputStream = new FileInputStream(new File(exsistingFileName));
- URL url = new URL(urlString);
+ String fileMimeType = Files.probeContentType(Paths.get(file1));
- conn = (HttpURLConnection) url.openConnection();
- conn.setDoInput(true);
- conn.setDoOutput(true);
- conn.setInstanceFollowRedirects(true);
- conn.setUseCaches(false);
+ MediaType MEDIA_TYPE = MediaType.parse("image/" + fileMimeType); // e.g. "image/png"
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Connection", "Keep-Alive");
- conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
+ RequestBody uploadContent = new MultipartBody.Builder().setType(MultipartBody.FORM)
+ .addFormDataPart("file", new File(file1).getName(), RequestBody.create(MEDIA_TYPE, new File(file1))).build();
- 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 {
- SSLContext sc;
- sc = SSLContext.getInstance("SSL");
- 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) {
+ String in = response.body().string();
+ JobValidation jobValidation = new Persister().read(JobValidation.class, in);
- }
- return ServerCode.UNKNOWN;
- }
- catch (KeyManagementException e) {
- this.log.error("Server::HTTPSendFile, exception KeyManagementException " + e);
- try {
- fileInputStream.close();
- }
- catch (Exception e1) {
+ 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;
}
- 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;
}
catch (IOException e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
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;
}
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());
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() {
@@ -731,17 +603,58 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager
return "";
}
- @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
- }
-
- @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
- }
-
- @Override public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- @Override public boolean verify(String arg0, SSLSession arg1) {
- return true; // trust every ssl certificate
+ private OkHttpClient getOkHttpClient() {
+ try {
+ final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
+
+ @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ 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);
+ }
}
}