2013-08-27 01:48:04 +00:00
package me.StevenLawson.TotalFreedomMod.HTTPD ;
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-09-03 14:28:56 +00:00
import java.net.Socket ;
2013-08-27 01:48:04 +00:00
import java.util.Map ;
2013-08-27 13:01:12 +00:00
import java.util.concurrent.Callable ;
import java.util.concurrent.Future ;
2013-09-03 19:20:28 +00:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
import me.StevenLawson.TotalFreedomMod.HTTPD.NanoHTTPD.Response ;
2013-08-28 00:20:11 +00:00
import me.StevenLawson.TotalFreedomMod.TFM_ConfigEntry ;
2013-08-27 01:48:04 +00:00
import me.StevenLawson.TotalFreedomMod.TFM_Log ;
2013-08-27 13:01:12 +00:00
import me.StevenLawson.TotalFreedomMod.TotalFreedomMod ;
2013-08-27 01:48:04 +00:00
import org.apache.commons.lang.StringUtils ;
2013-09-03 21:47:42 +00:00
import org.apache.commons.lang.exception.ExceptionUtils ;
2013-08-27 13:01:12 +00:00
import org.bukkit.Bukkit ;
2013-08-27 01:48:04 +00:00
public class TFM_HTTPD_Manager
{
2013-09-03 19:20:28 +00:00
private static final Pattern EXT_REGEX = Pattern . compile ( " \\ .([^ \\ . \\ s]+)$ " ) ;
//
2013-08-28 00:20:11 +00:00
public static final int PORT = TFM_ConfigEntry . HTTPD_PORT . getInteger ( ) ;
2013-08-27 01:48:04 +00:00
//
private final TFM_HTTPD httpd = new TFM_HTTPD ( PORT ) ;
private TFM_HTTPD_Manager ( )
{
}
public void start ( )
{
2013-08-28 00:20:11 +00:00
if ( ! TFM_ConfigEntry . HTTPD_ENABLED . getBoolean ( ) )
{
return ;
}
2013-08-27 01:48:04 +00:00
try
{
httpd . start ( ) ;
2013-08-27 16:39:28 +00:00
if ( httpd . isAlive ( ) )
{
TFM_Log . info ( " TFM HTTPd started. Listening on port: " + httpd . getListeningPort ( ) ) ;
}
else
{
TFM_Log . info ( " Error starting TFM HTTPd. " ) ;
}
2013-08-27 01:48:04 +00:00
}
catch ( IOException ex )
{
TFM_Log . severe ( ex ) ;
}
}
public void stop ( )
{
2013-08-28 00:20:11 +00:00
if ( ! TFM_ConfigEntry . HTTPD_ENABLED . getBoolean ( ) )
{
return ;
}
2013-08-27 01:48:04 +00:00
httpd . stop ( ) ;
2013-08-27 16:39:28 +00:00
TFM_Log . info ( " TFM HTTPd stopped. " ) ;
2013-08-27 01:48:04 +00:00
}
2013-08-28 00:20:11 +00:00
private static enum ModuleType
{
DUMP ( false , " dump " ) ,
HELP ( true , " help " ) ,
LIST ( true , " list " ) ,
2013-09-03 14:28:56 +00:00
FILE ( false , " file " ) ,
SCHEMATIC ( false , " schematic " ) ;
2013-08-28 00:20:11 +00:00
private final boolean runOnBukkitThread ;
private final String name ;
private ModuleType ( boolean runOnBukkitThread , String name )
{
this . runOnBukkitThread = runOnBukkitThread ;
this . name = name ;
}
public boolean isRunOnBukkitThread ( )
{
return runOnBukkitThread ;
}
public String getName ( )
{
return name ;
}
private static ModuleType getByName ( String needle )
{
for ( ModuleType type : values ( ) )
{
if ( type . getName ( ) . equalsIgnoreCase ( needle ) )
{
return type ;
}
}
return FILE ;
}
}
2013-08-27 01:48:04 +00:00
private static class TFM_HTTPD extends NanoHTTPD
{
public TFM_HTTPD ( int port )
{
super ( port ) ;
}
public TFM_HTTPD ( String hostname , int port )
{
super ( hostname , port ) ;
}
@Override
2013-09-03 14:28:56 +00:00
public Response serve (
final String uri ,
final Method method ,
final Map < String , String > headers ,
final Map < String , String > params ,
final Map < String , String > files ,
final Socket socket )
2013-08-27 01:48:04 +00:00
{
Response response = null ;
2013-09-03 21:47:42 +00:00
try
2013-08-27 01:48:04 +00:00
{
2013-09-03 21:47:42 +00:00
final String [ ] args = StringUtils . split ( uri , " / " ) ;
final ModuleType moduleType = args . length > = 1 ? ModuleType . getByName ( args [ 0 ] ) : ModuleType . FILE ;
if ( moduleType . isRunOnBukkitThread ( ) )
2013-08-27 01:48:04 +00:00
{
2013-09-03 21:47:42 +00:00
Future < Response > responseCall = Bukkit . getScheduler ( ) . callSyncMethod ( TotalFreedomMod . plugin , new Callable < Response > ( )
2013-08-27 13:01:12 +00:00
{
2013-09-03 21:47:42 +00:00
@Override
public Response call ( ) throws Exception
2013-08-27 13:01:12 +00:00
{
2013-09-03 21:47:42 +00:00
switch ( moduleType )
{
case HELP :
return new Module_help ( uri , method , headers , params , files , socket ) . getResponse ( ) ;
case LIST :
return new Module_list ( uri , method , headers , params , files , socket ) . getResponse ( ) ;
default :
return null ;
}
2013-08-27 13:01:12 +00:00
}
2013-09-03 21:47:42 +00:00
} ) ;
2013-08-27 13:01:12 +00:00
2013-09-03 21:47:42 +00:00
try
{
response = responseCall . get ( ) ;
}
catch ( Exception ex )
{
TFM_Log . severe ( ex ) ;
}
2013-08-27 01:48:04 +00:00
}
2013-09-03 21:47:42 +00:00
else
2013-08-27 01:48:04 +00:00
{
2013-09-03 21:47:42 +00:00
switch ( moduleType )
{
case DUMP :
//response = new Module_dump(uri, method, headers, params, files, socket).getResponse();
response = new Response ( Response . Status . OK , MIME_PLAINTEXT , " The DUMP module is disabled. It is intended for debugging use only. " ) ;
break ;
case SCHEMATIC :
response = new Module_schematic ( uri , method , headers , params , files , socket ) . getResponse ( ) ;
break ;
default :
response = new Module_file ( uri , method , headers , params , files , socket ) . getResponse ( ) ;
}
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-03 21:47:42 +00:00
response = new Response ( Response . Status . INTERNAL_ERROR , MIME_PLAINTEXT , " Error 500: Internal Server Error \ r \ n " + ex . getMessage ( ) + " \ r \ n " + ExceptionUtils . getFullStackTrace ( 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 ( ) )
{
mimetype = NanoHTTPD . MIME_DEFAULT_BINARY ;
}
response = new NanoHTTPD . Response ( NanoHTTPD . Response . Status . OK , mimetype , new FileInputStream ( file ) ) ;
response . addHeader ( " Content-Length " , " " + file . length ( ) ) ;
}
catch ( IOException ex )
{
TFM_Log . severe ( ex ) ;
}
}
return response ;
}
2013-08-27 01:48:04 +00:00
public static TFM_HTTPD_Manager getInstance ( )
{
return TFM_HTTPDManagerHolder . INSTANCE ;
}
private static class TFM_HTTPDManagerHolder
{
private static final TFM_HTTPD_Manager INSTANCE = new TFM_HTTPD_Manager ( ) ;
}
}