summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2023-02-14 15:02:02 +0100
committerSimon Rettberg2023-02-14 15:02:02 +0100
commitb0e5ac41a3c9e296c54edaf0d5aa69c52ee94023 (patch)
treeb65b3781451c71d3e2e57941dca25f959da88f8e
parentFormatting (diff)
downloadmasterserver-b0e5ac41a3c9e296c54edaf0d5aa69c52ee94023.tar.gz
masterserver-b0e5ac41a3c9e296c54edaf0d5aa69c52ee94023.tar.xz
masterserver-b0e5ac41a3c9e296c54edaf0d5aa69c52ee94023.zip
Add thrift json/http listener
-rw-r--r--src/main/java/org/openslx/imagemaster/App.java10
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/HttpListener.java95
2 files changed, 105 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/imagemaster/App.java b/src/main/java/org/openslx/imagemaster/App.java
index 12e583d..92f7326 100644
--- a/src/main/java/org/openslx/imagemaster/App.java
+++ b/src/main/java/org/openslx/imagemaster/App.java
@@ -13,6 +13,7 @@ import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.thrift.transport.TTransportException;
import org.openslx.imagemaster.localrpc.NetworkHandler;
import org.openslx.imagemaster.thrift.server.BinaryListener;
+import org.openslx.imagemaster.thrift.server.HttpListener;
import org.openslx.sat.thrift.version.Version;
import org.openslx.util.AppUtil;
@@ -62,6 +63,15 @@ public class App
}
}
+ // Spawn HTTP thrift listener - always do this on localhost, expected to be proxied with SSL
+ try {
+ t = new Thread( new HttpListener( "127.0.0.1", 8090 ), "JSON-HTTP" );
+ servers.add( t );
+ t.start();
+ } catch ( Exception e ) {
+ log.warn( "No JSON-HTTP available", e );
+ }
+
// Run more servers
// ...
// Wait for all servers to die
diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/HttpListener.java b/src/main/java/org/openslx/imagemaster/thrift/server/HttpListener.java
new file mode 100644
index 0000000..f130989
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/HttpListener.java
@@ -0,0 +1,95 @@
+package org.openslx.imagemaster.thrift.server;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.thrift.protocol.TJSONProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TMemoryBuffer;
+import org.openslx.bwlp.thrift.iface.MasterServer;
+import org.openslx.util.Util;
+
+import fi.iki.elonen.NanoHTTPD;
+
+public class HttpListener extends NanoHTTPD
+{
+
+ private static final Logger LOGGER = LogManager.getLogger( HttpListener.class );
+
+ private final MasterServer.Processor<MasterServerHandler> processor = new MasterServer.Processor<MasterServerHandler>(
+ new MasterServerHandler() );
+
+ public HttpListener( String hostname, int port ) throws IOException
+ {
+ super( hostname, port, 64, 16 );
+ this.maxRequestSize = 1_000_000;
+ }
+
+ @Override
+ public Response serve( IHTTPSession session )
+ {
+ Method method = session.getMethod();
+ if ( Method.OPTIONS.equals( method ) ) {
+ Response response = new Response( Response.Status.NO_CONTENT, "application/json", "" );
+ addCorsHeaders( response );
+ return response;
+ }
+ if ( !Method.PUT.equals( method ) && !Method.POST.equals( method ) )
+ return new Response( Response.Status.BAD_REQUEST, "text/plain; charset=UTF-8", "Method not supported" );
+
+ try {
+ //Input
+ String str = session.getHeaders().get( "content-length" );
+ int len = 0;
+ if ( str != null ) {
+ len = Util.parseInt( str, 0 );
+ }
+ if ( len <= 0 ) {
+ len = session.getInputStream().available();
+ }
+ if ( len <= 0 )
+ return new Response( Response.Status.BAD_REQUEST, "text/plain; charset=UTF-8", "No Content-Length provided" );
+
+ byte[] buffer = session.getInputStream().readNBytes( len );
+ TMemoryBuffer inbuffer = new TMemoryBuffer( buffer.length );
+ inbuffer.write( buffer );
+ TProtocol inprotocol = new TJSONProtocol( inbuffer );
+
+ //Output
+ TMemoryBuffer outbuffer = new TMemoryBuffer( 900 );
+ TProtocol outprotocol = new TJSONProtocol( outbuffer );
+
+ processor.process( inprotocol, outprotocol );
+
+ buffer = new byte[ outbuffer.length() ];
+ outbuffer.readAll( buffer, 0, buffer.length );
+
+ Response response = new Response( Response.Status.OK, "application/json", buffer );
+ addCorsHeaders( response );
+ return response;
+ } catch ( Throwable t ) {
+ if ( !t.getMessage().contains( "Remote side has closed" ) ) {
+ LOGGER.warn( "Error handling HTTP thrift", t );
+ }
+ return new Response( Response.Status.INTERNAL_ERROR, "text/plain; charset=UTF-8", t.getMessage() );
+ }
+
+ }
+
+ @Override
+ public void serverStopped()
+ {
+ System.exit( 1 );
+ }
+
+ private static void addCorsHeaders( Response response )
+ {
+ response.addHeader( "Allow", "OPTIONS, GET, HEAD, POST, PUT" );
+ response.addHeader( "Access-Control-Allow-Methods", "*" );
+ response.addHeader( "Access-Control-Allow-Origin", "*" );
+ response.addHeader( "Access-Control-Allow-Headers", "*, Content-Type" );
+ response.addHeader( "Access-Control-Max-Age", "86400" );
+ }
+
+}