diff options
author | Simon Rettberg | 2023-02-14 15:02:02 +0100 |
---|---|---|
committer | Simon Rettberg | 2023-02-14 15:02:02 +0100 |
commit | b0e5ac41a3c9e296c54edaf0d5aa69c52ee94023 (patch) | |
tree | b65b3781451c71d3e2e57941dca25f959da88f8e | |
parent | Formatting (diff) | |
download | masterserver-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.java | 10 | ||||
-rw-r--r-- | src/main/java/org/openslx/imagemaster/thrift/server/HttpListener.java | 95 |
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" ); + } + +} |