package art.servers.controller;
|
|
import art.library.interop.InteropParameter;
|
import art.library.interop.InteropParameters;
|
import art.library.interop.InteropResponse;
|
import art.library.interop.serialization.Serialization;
|
import art.library.interop.serialization.SerializationException;
|
import art.library.utils.licence.Licence;
|
import art.servers.ServerException;
|
import art.servers.Shared;
|
import art.servers.configuration.ConfigurationListenerHttp;
|
import art.servers.types.HttpAuthentication;
|
import com.sun.net.httpserver.BasicAuthenticator;
|
import com.sun.net.httpserver.HttpContext;
|
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpHandler;
|
import com.sun.net.httpserver.HttpServer;
|
import java.io.ByteArrayOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.PrintWriter;
|
import java.io.StringWriter;
|
import java.net.InetSocketAddress;
|
import java.net.URLDecoder;
|
import java.nio.charset.StandardCharsets;
|
import java.util.concurrent.Executors;
|
|
|
|
public class ControllerListenerHttp extends Controller
|
{
|
protected String name = null;
|
protected HttpServer server = null;
|
protected ConfigurationListenerHttp configuration = null;
|
protected ListenerImplementation implementation = null;
|
|
|
public ControllerListenerHttp(ConfigurationListenerHttp configuration)
|
{
|
this.name = Shared.getMessage("Listener http");
|
this.setName(this.getClass().getName() + " : " + name);
|
this.configuration = configuration;
|
start();
|
}
|
|
|
public ListenerImplementation getListenerImplementation()
|
{
|
if (implementation != null) return implementation;
|
return Shared.controllerListener.getListenerImplementation();
|
}
|
|
|
public void setListenerImplementation(ListenerImplementation implementation)
|
{
|
this.implementation = implementation;
|
}
|
|
|
|
public void run()
|
{
|
Shared.traceInformation(name, "Starting");
|
|
while ((isInterrupted() == false) && (exit == false))
|
{
|
try
|
{
|
if (server == null)
|
{
|
connect();
|
}
|
|
sleep(1000);
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
Shared.traceInformation(name, "Finishing");
|
}
|
|
|
|
|
|
|
protected void connect()
|
{
|
try
|
{
|
server = HttpServer.create(new InetSocketAddress(configuration.port), 0);
|
contexts();
|
server.setExecutor(Executors.newCachedThreadPool());
|
server.start();
|
Shared.traceInformation(name, "Disconnecting", Shared.getMessage("Port") + " = " + configuration.port);
|
return;
|
|
}
|
catch (Exception exception)
|
{
|
Shared.traceError(name, "Disconnecting", Shared.getMessage("Port") + " = " + configuration.port, exception);
|
}
|
|
}
|
|
|
protected void contexts()
|
{
|
HttpContext context1 = server.createContext("/login", new login());
|
HttpContext context2 = server.createContext("/art", new artic());
|
HttpContext context3 = server.createContext("/get", new get());
|
HttpContext context4 = server.createContext("/set", new set());
|
HttpContext context5 = server.createContext("/session", new session());
|
HttpContext context6 = server.createContext("/gis", new gis());
|
HttpContext context7 = server.createContext("/saml", new saml());
|
HttpContext context8 = server.createContext("/logout", new logout());
|
|
if (configuration.readUser != null)
|
{
|
context3.setAuthenticator(new BasicAuthenticator(configuration.readUser)
|
{
|
public boolean checkCredentials(String user, String pwd)
|
{
|
return user.equals(configuration.readUser) && pwd.equals(configuration.readPassword);
|
}
|
});
|
}
|
|
if (configuration.writeUser != null)
|
{
|
context4.setAuthenticator(new BasicAuthenticator(configuration.writeUser)
|
{
|
public boolean checkCredentials(String user, String pwd)
|
{
|
return user.equals(configuration.writeUser) && pwd.equals(configuration.writePassword);
|
}
|
});
|
}
|
}
|
|
|
|
|
|
|
protected class login implements HttpHandler
|
{
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
String language = null;
|
|
try
|
{
|
InteropParameters parameters = new InteropParameters(httpExchange.getRequestURI().getRawQuery());
|
language = (parameters.hasParameter("language") == true) ? (String)parameters.getParameterValue("language") : "";
|
String type = (parameters.hasParameter("type") == true) ? (String)parameters.getParameterValue("type") : "text";
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
InteropResponse response = getListenerImplementation().login(parameters, type, httpExchange.getRemoteAddress().getHostName());
|
result(httpExchange, response);
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
result(httpExchange, 400, language, e);
|
}
|
}
|
}
|
|
|
|
|
|
|
protected class logout implements HttpHandler
|
{
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
String language = null;
|
|
try
|
{
|
InteropParameters parameters = new InteropParameters(httpExchange.getRequestURI().getRawQuery());
|
language = (parameters.hasParameter("language") == true) ? (String)parameters.getParameterValue("language") : "";
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
InteropResponse response = getListenerImplementation().logout(parameters, httpExchange.getRemoteAddress().getHostName());
|
result(httpExchange, response);
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
result(httpExchange, 400, language, e);
|
}
|
}
|
}
|
|
|
|
|
protected class artic implements HttpHandler
|
{
|
String language = null;
|
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
try
|
{
|
InteropParameters parameters = new InteropParameters(httpExchange.getRequestURI().getRawQuery());
|
language = (parameters.hasParameter("language") == true) ? (String)parameters.getParameterValue("language") : "";
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
|
int tokenStatus = checkToken(parameters, httpExchange.getRemoteAddress().getHostName());
|
|
if (tokenStatus != 200)
|
{
|
result(httpExchange, tokenStatus, "Invalid authentication or invalid token");
|
}
|
|
InteropResponse response = getListenerImplementation().artic(parameters);
|
result(httpExchange, response);
|
}
|
catch (Exception exception)
|
{
|
Shared.println(Shared.getMessage("Model"), exception);
|
exception.printStackTrace();
|
result(httpExchange, 400, language, exception);
|
}
|
}
|
}
|
|
|
|
|
protected class gis implements HttpHandler
|
{
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
try
|
{
|
String uri = httpExchange.getRequestURI().getRawQuery();
|
InteropResponse response = getListenerImplementation().gis(uri);
|
result(httpExchange, response);
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
result(httpExchange, 400, "", exception);
|
}
|
}
|
}
|
|
|
|
|
protected class saml implements HttpHandler
|
{
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
try
|
{
|
InteropParameters parameters = new InteropParameters();
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
InteropResponse response = getListenerImplementation().saml(parameters);
|
result(httpExchange, response);
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
result(httpExchange, 400, "", exception);
|
}
|
}
|
}
|
|
|
private int checkToken(InteropParameters parameters, String remoteAddress)
|
{
|
try
|
{
|
HttpAuthentication authentication = Serialization.deserialize(HttpAuthentication.class, Licence.decrypt((String)parameters.getParameterValue("token")));
|
|
if (authentication.isTokenValid(remoteAddress) == false)
|
{
|
return 401; // Page expired
|
}
|
|
parameters.addParameter("username", authentication.username);
|
parameters.addParameter("computer", authentication.address);
|
|
authentication.lastRequestTimestamp = System.currentTimeMillis();
|
return 200;
|
}
|
catch (Exception e)
|
{
|
}
|
|
try
|
{
|
String[] login = ((String)parameters.getParameterValue("token")).split(",");
|
String username = login[0];
|
String password = login[1];
|
|
HttpAuthentication authentication = getListenerImplementation().login(username, password, remoteAddress);
|
String token = URLDecoder.decode(authentication.getHttpToken().token, StandardCharsets.UTF_8.toString());
|
parameters.setParameter("token", token);
|
authentication.lastRequestTimestamp = System.currentTimeMillis();
|
parameters.addParameter("username", authentication.username);
|
parameters.addParameter("computer", authentication.address);
|
return 200;
|
}
|
catch (Exception exception)
|
{
|
Shared.println(Shared.getMessage("Model"), exception);
|
}
|
|
return 401; // Invalid token, unauthorized
|
}
|
|
|
|
|
|
|
|
|
protected class get implements HttpHandler
|
{
|
String language = null;
|
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
try
|
{
|
InteropParameters parameters = new InteropParameters(httpExchange.getRequestURI().getRawQuery());
|
language = (parameters.hasParameter("language") == true) ? (String)parameters.getParameterValue("language") : "";
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
InteropResponse response = getListenerImplementation().get(parameters);
|
result(httpExchange, response);
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
result(httpExchange, 400, language, exception);
|
}
|
}
|
}
|
|
|
|
|
protected class set implements HttpHandler
|
{
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
String language = null;
|
|
try
|
{
|
InteropParameters parameters = new InteropParameters(httpExchange.getRequestURI().getRawQuery());
|
language = (parameters.hasParameter("language") == true) ? (String)parameters.getParameterValue("language") : "";
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
InteropResponse response = getListenerImplementation().set(parameters);
|
result(httpExchange, response);
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
result(httpExchange, 400, language, exception);
|
}
|
}
|
}
|
|
|
|
|
|
protected class session implements HttpHandler
|
{
|
public void handle(HttpExchange httpExchange) throws IOException
|
{
|
String language = null;
|
|
try
|
{
|
InteropParameters parameters = new InteropParameters(httpExchange.getRequestURI().getRawQuery());
|
language = (parameters.hasParameter("language") == true) ? (String)parameters.getParameterValue("language") : "";
|
String token = (parameters.hasParameter("token") == true) ? (String)parameters.getParameterValue("token") : "";
|
|
if (checkToken(language, token) == false)
|
{
|
throw new SerializationException(Shared.getMessage(language, "Invalid session"));
|
}
|
|
parameters.addParameter(new InteropParameter("body-content", getRequestBody(httpExchange)));
|
InteropResponse response = getListenerImplementation().session(parameters);
|
result(httpExchange, response);
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
result(httpExchange, 400, language, exception);
|
}
|
}
|
}
|
|
|
|
private boolean checkToken(String language, String token)
|
{
|
try
|
{
|
InteropParameters parameters = new InteropParameters();
|
parameters.addParameter(new InteropParameter("service", "transactions"));
|
parameters.addParameter(new InteropParameter("operation", "checkToken"));
|
parameters.addParameter(new InteropParameter("language", language));
|
parameters.addParameter(new InteropParameter("token", token));
|
InteropResponse response = Shared.controllerTransactions.set(parameters);
|
boolean result = (Boolean)response.getValue()[0];
|
if (result == true) return true;
|
}
|
catch (Exception e)
|
{
|
}
|
|
return false;
|
}
|
|
|
|
|
|
|
|
// <editor-fold defaultstate="collapsed" desc="Request body">
|
|
|
|
private byte[] getRequestBody(HttpExchange httpExchange) throws Exception
|
{
|
ByteArrayOutputStream bos = null;
|
|
try
|
{
|
InputStream input = httpExchange.getRequestBody();
|
bos = new ByteArrayOutputStream();
|
byte[] buffer = new byte[8196];
|
int length;
|
|
while ((length = input.read(buffer)) != -1)
|
{
|
bos.write(buffer, 0, length);
|
}
|
return bos.toByteArray();
|
}
|
catch (Exception exception)
|
{
|
Shared.println(Shared.getMessage("Model"), exception);
|
throw exception;
|
}
|
finally
|
{
|
try { bos.close(); } catch (Exception ex) {};
|
httpExchange.getRequestBody().close();
|
}
|
}
|
|
|
|
// </editor-fold>
|
|
|
|
// <editor-fold defaultstate="collapsed" desc="Response">
|
|
|
protected void result(HttpExchange httpExchange, int httpErrorCode, byte[] data) throws Exception
|
{
|
try
|
{
|
httpExchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*");
|
httpExchange.getResponseHeaders().set("Accept", "*/*");
|
httpExchange.sendResponseHeaders(httpErrorCode, data.length);
|
httpExchange.getResponseBody().write(data);
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
finally
|
{
|
httpExchange.getResponseBody().close();
|
}
|
}
|
|
|
|
protected void result(HttpExchange httpExchange, InteropResponse response)
|
{
|
// https://www.sitepoint.com/mime-types-complete-list/
|
// httpExchange.getResponseHeaders().set("Content-Type", "text/html; charset=" + StandardCharsets.UTF_8);
|
// httpExchange.getResponseHeaders().set("Content-Type", "application/pdf"; charset=" + StandardCharsets.UTF_8);
|
// httpExchange.getResponseHeaders().set("Content-Type", "application/vnd.ms-excel"; charset=" + StandardCharsets.UTF_8);
|
|
httpExchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*");
|
httpExchange.getResponseHeaders().set("Accept", "*/*");
|
|
if (httpExchange.getRequestMethod().equalsIgnoreCase("OPTIONS"))
|
{
|
httpExchange.getResponseHeaders().add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
httpExchange.getResponseHeaders().add("Access-Control-Allow-Headers", "Content-Type,Authorization");
|
|
try
|
{
|
httpExchange.sendResponseHeaders(204, -1);
|
}
|
catch (Exception e)
|
{
|
}
|
|
httpExchange.close();
|
return;
|
}
|
|
if (response.mime == null)
|
{
|
httpExchange.getResponseHeaders().set("Content-Type", "application/json; charset=" + StandardCharsets.UTF_8);
|
}
|
else
|
{
|
httpExchange.getResponseHeaders().set("Content-Type", response.mime + "; charset=" + StandardCharsets.UTF_8);
|
}
|
|
|
// Check if response is a file
|
|
if (response.name != null)
|
{
|
try
|
{
|
// For filenames with polish characters
|
|
byte[] filenameBytes = response.name.getBytes("UTF-8");
|
String filename = "";
|
for (byte character : filenameBytes) filename += (char)(character & 0xFF);
|
httpExchange.getResponseHeaders().set("Content-Disposition", "attachment; filename=\"" + filename + "\"");
|
}
|
catch (Exception e)
|
{
|
httpExchange.getResponseHeaders().set("Content-Disposition", "attachment; filename=\"" + response.name + "\"");
|
}
|
}
|
|
|
// Check mime text/plain
|
|
if (response.mime != null)
|
{
|
if (response.mime.equalsIgnoreCase("text/plain"))
|
{
|
try
|
{
|
byte[] data = ((String)response.getValue()[0]).getBytes();
|
result(httpExchange, 200, data);
|
httpExchange.close();
|
return;
|
}
|
catch (Exception exception)
|
{
|
manageException(httpExchange, exception);
|
}
|
|
return;
|
}
|
else if (response.mime.equalsIgnoreCase("application/json"))
|
{
|
try
|
{
|
if (response.array == true)
|
{
|
String message = Serialization.toString(response.getValue());
|
result(httpExchange, 200, message.getBytes());
|
}
|
else
|
{
|
String message = Serialization.toString(response.getValue()[0]);
|
result(httpExchange, 200, message.getBytes());
|
}
|
}
|
catch (Exception e)
|
{
|
manageException(httpExchange, e);
|
}
|
|
return;
|
}
|
}
|
|
|
// Try send raw bytes
|
|
try
|
{
|
if (response.getValue().length == 0)
|
{
|
String message = Serialization.toString(response.getValue());
|
result(httpExchange, 200, message.getBytes());
|
httpExchange.close();
|
return;
|
}
|
|
byte[] data = (byte[])response.getValue()[0];
|
result(httpExchange, 200, data);
|
httpExchange.close();
|
return;
|
}
|
catch (ClassCastException exception)
|
{
|
}
|
catch (Exception exception)
|
{
|
manageException(httpExchange, exception);
|
}
|
|
|
|
// Default JSON
|
|
try
|
{
|
if (response.array == false)
|
{
|
String message = Serialization.toString(response.getValue()[0]);
|
result(httpExchange, 200, message.getBytes());
|
httpExchange.close();
|
return;
|
}
|
else
|
{
|
if (response.getValue().length == 0)
|
{
|
String message = Serialization.toString(response.getValue());
|
result(httpExchange, 200, message.getBytes());
|
httpExchange.close();
|
return;
|
}
|
else
|
{
|
String message = Serialization.toString(response.getValue());
|
result(httpExchange, 200, message.getBytes());
|
httpExchange.close();
|
return;
|
}
|
}
|
}
|
catch (Exception exception)
|
{
|
manageException(httpExchange, exception);
|
}
|
|
}
|
|
|
|
|
|
protected void result (HttpExchange httpExchange, int httpErrorCode, String language, Exception exception)
|
{
|
if (((exception instanceof SerializationException) || (exception instanceof ServerException)) && (exception.getMessage() != null))
|
{
|
result(httpExchange, httpErrorCode, Shared.getMessage(language, exception.getMessage()));
|
}
|
else if ((exception instanceof SerializationException) && (((SerializationException)exception).getStackMessage() != null))
|
{
|
result(httpExchange, httpErrorCode, ((SerializationException)exception).getStackMessage());
|
}
|
else if ((exception instanceof ServerException) && (((ServerException)exception).getStackMessage() != null))
|
{
|
result(httpExchange, httpErrorCode, ((ServerException)exception).getStackMessage());
|
}
|
else
|
{
|
StringWriter sw = new StringWriter();
|
exception.printStackTrace(new PrintWriter(sw));
|
String message = sw.toString();
|
result(httpExchange, httpErrorCode, message);
|
}
|
}
|
|
|
|
|
protected void result (HttpExchange httpExchange, int httpErrorCode, String message)
|
{
|
try
|
{
|
if (message != null)
|
{
|
result(httpExchange, httpErrorCode, message.getBytes());
|
}
|
else
|
{
|
result(httpExchange, httpErrorCode, new String().getBytes());
|
}
|
}
|
catch (Exception e)
|
{
|
manageException(httpExchange, e);
|
}
|
}
|
|
|
|
|
// </editor-fold>
|
|
|
|
// <editor-fold defaultstate="collapsed" desc="Exception">
|
|
|
private void manageException (HttpExchange httpExchange, Exception exception)
|
{
|
try
|
{
|
httpExchange.close();
|
}
|
catch (Exception e)
|
{
|
}
|
|
if (exception instanceof IOException)
|
{
|
String message = exception.toString().toLowerCase();
|
|
if (message.contains("an established connection was aborted by the software in your host machine") == true)
|
{
|
if (server != null)
|
{
|
Shared.traceError(name, "Disconnecting", exception);
|
try{server.stop(10);} catch (Exception ex){};
|
server = null;
|
connect();
|
}
|
}
|
}
|
}
|
|
|
// </editor-fold>
|
|
|
}
|