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 processor = new MasterServer.Processor( 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" ); } }