2015-10-19 17:43:46 +00:00
package me.totalfreedom.totalfreedommod.httpd ;
2013-08-27 01:48:04 +00:00
2013-09-03 19:20:28 +00:00
import java.io.File ;
import java.io.FileInputStream ;
2013-08-27 01:48:04 +00:00
import java.io.IOException ;
2013-08-27 13:01:12 +00:00
import java.util.concurrent.Callable ;
2013-09-03 19:20:28 +00:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2015-11-15 23:32:04 +00:00
import me.totalfreedom.totalfreedommod.TotalFreedomMod ;
2015-10-19 17:43:46 +00:00
import me.totalfreedom.totalfreedommod.config.ConfigEntry ;
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD.HTTPSession ;
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD.Response ;
import me.totalfreedom.totalfreedommod.util.FLog ;
import net.pravian.aero.component.service.AbstractService ;
2014-11-29 19:16:00 +00:00
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.exception.ExceptionUtils ;
2013-08-27 13:01:12 +00:00
import org.bukkit.Bukkit ;
2013-08-27 01:48:04 +00:00
2015-10-19 17:43:46 +00:00
public class HTTPDaemon extends AbstractService < TotalFreedomMod >
2013-08-27 01:48:04 +00:00
{
2015-11-15 23:32:04 +00:00
2015-10-19 17:43:46 +00:00
public static String MIME_DEFAULT_BINARY = " application/octet-stream " ;
2013-09-18 01:31:46 +00:00
//
2015-10-19 17:43:46 +00:00
private static final Pattern EXT_REGEX = Pattern . compile ( " \\ .([^ \\ . \\ s]+)$ " ) ;
2013-09-03 19:20:28 +00:00
//
2015-10-19 17:43:46 +00:00
public static final int PORT = ConfigEntry . HTTPD_PORT . getInteger ( ) ;
2013-08-27 01:48:04 +00:00
//
2015-10-19 17:43:46 +00:00
private static final TFM_HTTPD HTTPD = new TFM_HTTPD ( PORT ) ;
2013-08-27 01:48:04 +00:00
2015-11-15 23:32:04 +00:00
public HTTPDaemon ( TotalFreedomMod plugin )
2013-08-27 01:48:04 +00:00
{
2015-10-19 17:43:46 +00:00
super ( plugin ) ;
2013-08-27 01:48:04 +00:00
}
2015-10-19 17:43:46 +00:00
@Override
public void onStart ( )
2014-05-19 17:32:25 +00:00
{
2015-10-19 17:43:46 +00:00
if ( ! ConfigEntry . HTTPD_ENABLED . getBoolean ( ) )
2013-08-28 00:20:11 +00:00
{
return ;
}
2013-08-27 01:48:04 +00:00
try
{
2014-05-19 17:32:25 +00:00
HTTPD . start ( ) ;
2013-08-27 16:39:28 +00:00
2014-05-19 17:32:25 +00:00
if ( HTTPD . isAlive ( ) )
2013-08-27 16:39:28 +00:00
{
2015-10-19 17:43:46 +00:00
FLog . info ( " TFM HTTPd started. Listening on port: " + HTTPD . getListeningPort ( ) ) ;
2013-08-27 16:39:28 +00:00
}
else
{
2015-10-19 17:43:46 +00:00
FLog . info ( " Error starting TFM HTTPd. " ) ;
2013-08-27 16:39:28 +00:00
}
2013-08-27 01:48:04 +00:00
}
catch ( IOException ex )
{
2015-10-19 17:43:46 +00:00
FLog . severe ( ex ) ;
2013-08-27 01:48:04 +00:00
}
}
2015-10-19 17:43:46 +00:00
@Override
public void onStop ( )
2013-08-27 01:48:04 +00:00
{
2015-10-19 17:43:46 +00:00
if ( ! ConfigEntry . HTTPD_ENABLED . getBoolean ( ) )
2013-08-28 00:20:11 +00:00
{
return ;
}
2014-05-19 17:32:25 +00:00
HTTPD . stop ( ) ;
2013-08-27 16:39:28 +00:00
2015-10-19 17:43:46 +00:00
FLog . info ( " TFM HTTPd stopped. " ) ;
2013-08-27 01:48:04 +00:00
}
2013-08-28 00:20:11 +00:00
private static enum ModuleType
{
2015-11-15 23:32:04 +00:00
2013-09-18 01:31:46 +00:00
DUMP ( new ModuleExecutable ( false , " dump " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Response ( Response . Status . OK , NanoHTTPD . MIME_PLAINTEXT , " The DUMP module is disabled. It is intended for debugging use only. " ) ;
}
} ) ,
HELP ( new ModuleExecutable ( true , " help " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_help ( session ) . getResponse ( ) ;
}
} ) ,
LIST ( new ModuleExecutable ( true , " list " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_list ( session ) . getResponse ( ) ;
}
} ) ,
FILE ( new ModuleExecutable ( false , " file " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_file ( session ) . getResponse ( ) ;
}
} ) ,
SCHEMATIC ( new ModuleExecutable ( false , " schematic " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_schematic ( session ) . getResponse ( ) ;
}
} ) ,
PERMBANS ( new ModuleExecutable ( false , " permbans " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_permbans ( session ) . getResponse ( ) ;
}
2013-12-18 13:12:15 +00:00
} ) ,
PLAYERS ( new ModuleExecutable ( true , " players " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_players ( session ) . getResponse ( ) ;
}
2014-07-13 22:04:08 +00:00
} ) ,
LOGS ( new ModuleExecutable ( false , " logs " )
{
@Override
public Response getResponse ( HTTPSession session )
{
return new Module_logs ( session ) . getResponse ( ) ;
}
2013-09-18 01:31:46 +00:00
} ) ;
//
private final ModuleExecutable moduleExecutable ;
private ModuleType ( ModuleExecutable moduleExecutable )
{
this . moduleExecutable = moduleExecutable ;
2013-08-28 00:20:11 +00:00
}
2013-09-18 01:31:46 +00:00
private abstract static class ModuleExecutable
2013-08-28 00:20:11 +00:00
{
2015-11-15 23:32:04 +00:00
2013-09-18 01:31:46 +00:00
private final boolean runOnBukkitThread ;
private final String name ;
2015-10-19 17:43:46 +00:00
private ModuleExecutable ( boolean runOnBukkitThread , String name )
2013-09-18 01:31:46 +00:00
{
this . runOnBukkitThread = runOnBukkitThread ;
this . name = name ;
}
public Response execute ( final HTTPSession session )
{
try
{
if ( this . runOnBukkitThread )
{
return Bukkit . getScheduler ( ) . callSyncMethod ( TotalFreedomMod . plugin , new Callable < Response > ( )
{
@Override
public Response call ( ) throws Exception
{
return getResponse ( session ) ;
}
} ) . get ( ) ;
}
else
{
return getResponse ( session ) ;
}
}
catch ( Exception ex )
{
2015-10-19 17:43:46 +00:00
FLog . severe ( ex ) ;
2013-09-18 01:31:46 +00:00
}
return null ;
}
public abstract Response getResponse ( HTTPSession session ) ;
public String getName ( )
{
return name ;
}
2013-08-28 00:20:11 +00:00
}
2013-09-18 01:31:46 +00:00
public ModuleExecutable getModuleExecutable ( )
2013-08-28 00:20:11 +00:00
{
2013-09-18 01:31:46 +00:00
return moduleExecutable ;
2013-08-28 00:20:11 +00:00
}
private static ModuleType getByName ( String needle )
{
for ( ModuleType type : values ( ) )
{
2013-09-18 01:31:46 +00:00
if ( type . getModuleExecutable ( ) . getName ( ) . equalsIgnoreCase ( needle ) )
2013-08-28 00:20:11 +00:00
{
return type ;
}
}
return FILE ;
}
}
2013-08-27 01:48:04 +00:00
private static class TFM_HTTPD extends NanoHTTPD
{
2015-11-15 23:32:04 +00:00
2013-08-27 01:48:04 +00:00
public TFM_HTTPD ( int port )
{
super ( port ) ;
}
public TFM_HTTPD ( String hostname , int port )
{
super ( hostname , port ) ;
}
@Override
2013-09-18 01:31:46 +00:00
public Response serve ( HTTPSession session )
2013-08-27 01:48:04 +00:00
{
2013-09-18 01:31:46 +00:00
Response response ;
2013-08-27 01:48:04 +00:00
2013-09-03 21:47:42 +00:00
try
2013-08-27 01:48:04 +00:00
{
2013-09-18 01:31:46 +00:00
final String [ ] args = StringUtils . split ( session . getUri ( ) , " / " ) ;
2013-09-03 21:47:42 +00:00
final ModuleType moduleType = args . length > = 1 ? ModuleType . getByName ( args [ 0 ] ) : ModuleType . FILE ;
2013-09-18 01:31:46 +00:00
response = moduleType . getModuleExecutable ( ) . execute ( session ) ;
2013-08-27 01:48:04 +00:00
}
2013-09-03 21:47:42 +00:00
catch ( Exception ex )
2013-08-28 00:20:11 +00:00
{
2013-09-04 12:35:12 +00:00
response = new Response ( Response . Status . INTERNAL_ERROR , MIME_PLAINTEXT , " Error 500: Internal Server Error \ r \ n " + ex . getMessage ( ) + " \ r \ n " + ExceptionUtils . getStackTrace ( ex ) ) ;
2013-08-28 00:20:11 +00:00
}
2013-08-27 01:48:04 +00:00
if ( response = = null )
{
2013-09-03 21:47:42 +00:00
response = new Response ( Response . Status . NOT_FOUND , MIME_PLAINTEXT , " Error 404: Not Found - The requested resource was not found on this server. " ) ;
2013-08-27 01:48:04 +00:00
}
2013-09-03 21:47:42 +00:00
return response ;
2013-08-27 01:48:04 +00:00
}
}
2013-09-03 19:20:28 +00:00
public static Response serveFileBasic ( File file )
{
Response response = null ;
if ( file ! = null & & file . exists ( ) )
{
try
{
String mimetype = null ;
Matcher matcher = EXT_REGEX . matcher ( file . getCanonicalPath ( ) ) ;
if ( matcher . find ( ) )
{
mimetype = Module_file . MIME_TYPES . get ( matcher . group ( 1 ) ) ;
}
if ( mimetype = = null | | mimetype . trim ( ) . isEmpty ( ) )
{
2013-09-18 01:31:46 +00:00
mimetype = MIME_DEFAULT_BINARY ;
2013-09-03 19:20:28 +00:00
}
2013-09-18 01:31:46 +00:00
response = new Response ( Response . Status . OK , mimetype , new FileInputStream ( file ) ) ;
2013-09-03 19:20:28 +00:00
response . addHeader ( " Content-Length " , " " + file . length ( ) ) ;
}
catch ( IOException ex )
{
2015-10-19 17:43:46 +00:00
FLog . severe ( ex ) ;
2013-09-03 19:20:28 +00:00
}
}
return response ;
}
2013-08-27 01:48:04 +00:00
}