Replace standard Java HTTP libraries with okHTTP (#237)

* Replace standard Java HTTP libraries with okHTTP
This commit is contained in:
Luis Uguina
2020-06-01 19:15:44 +10:00
committed by GitHub
parent cdf552f708
commit 4cf51013e6
5 changed files with 230 additions and 313 deletions

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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 (response.code() == HttpURLConnection.HTTP_OK && response.body().contentType().toString().startsWith("text/xml")) {
String in = response.body().string();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK && connection.getContentType().startsWith("text/xml")) {
DataInputStream in = new DataInputStream(connection.getInputStream());
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());
}
connection = this.HTTPRequest(url, this.generateXMLForMD5cache());
Response response = this.HTTPRequest(urlBuilder, RequestBody.create(MediaType.parse("application/xml"), 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);
}
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(true);
connection.setRequestMethod("GET");
public Response HTTPRequest(HttpUrl.Builder httpUrlBuilder, RequestBody data_) throws IOException {
String url = httpUrlBuilder.build().toString();
Request.Builder builder = new Request.Builder();
builder.url(url);
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();
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 {
// 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 {
}
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) {
return true; // trust every ssl certificate
@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);
}
}
}