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 ;
2016-05-12 19:40:39 +00:00
import java.util.HashMap ;
import java.util.Map ;
2013-09-03 19:20:28 +00:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2016-03-01 16:47:01 +00:00
import me.totalfreedom.totalfreedommod.FreedomService ;
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.Response ;
2018-07-31 07:01:29 +00:00
import me.totalfreedom.totalfreedommod.httpd.module.* ;
2015-10-19 17:43:46 +00:00
import me.totalfreedom.totalfreedommod.util.FLog ;
2018-07-31 07:01:29 +00:00
import org.apache.commons.io.FilenameUtils ;
2014-11-29 19:16:00 +00:00
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.exception.ExceptionUtils ;
2013-08-27 01:48:04 +00:00
2016-03-01 16:47:01 +00:00
public class HTTPDaemon extends FreedomService
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 " ;
private static final Pattern EXT_REGEX = Pattern . compile ( " \\ .([^ \\ . \\ s]+)$ " ) ;
2013-09-03 19:20:28 +00:00
//
2016-05-12 19:40:39 +00:00
public int port ;
private HTTPD httpd ;
public Map < String , ModuleExecutable > modules = new HashMap < > ( ) ;
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 ;
}
2018-07-31 06:41:56 +00:00
port = ConfigEntry . HTTPD_PORT . getInteger ( ) ;
;
2016-05-12 19:40:39 +00:00
httpd = new HTTPD ( port ) ;
// Modules
modules . clear ( ) ;
2018-01-02 02:46:35 +00:00
module ( " admins " , Module_admins . class , true ) ;
module ( " bans " , Module_bans . class , true ) ;
2016-05-12 19:40:39 +00:00
module ( " dump " , Module_dump . class , true ) ;
module ( " file " , Module_file . class , true ) ;
module ( " help " , Module_help . class , false ) ;
module ( " list " , Module_list . class , false ) ;
2018-01-02 02:46:35 +00:00
module ( " logfile " , Module_logfile . class , true ) ;
2016-05-12 19:40:39 +00:00
module ( " logs " , Module_logs . class , true ) ;
module ( " permbans " , Module_permbans . class , true ) ;
module ( " players " , Module_players . class , false ) ;
2018-03-03 04:29:08 +00:00
module ( " punishments " , Module_punishments . class , true ) ;
2016-05-12 19:40:39 +00:00
module ( " schematic " , Module_schematic . class , true ) ;
2013-08-27 01:48:04 +00:00
try
{
2016-05-12 19:40:39 +00:00
httpd . start ( ) ;
2013-08-27 16:39:28 +00:00
2016-05-12 19:40:39 +00:00
if ( httpd . isAlive ( ) )
2013-08-27 16:39:28 +00:00
{
2016-05-12 19:40:39 +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 ;
}
2016-05-12 19:40:39 +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
}
2016-05-12 19:40:39 +00:00
private void module ( String name , Class < ? extends HTTPDModule > clazz , boolean async )
2013-08-28 00:20:11 +00:00
{
2016-05-12 19:40:39 +00:00
modules . put ( name , ModuleExecutable . forClass ( plugin , clazz , async ) ) ;
2013-08-28 00:20:11 +00:00
}
2016-05-12 19:40:39 +00:00
private class HTTPD extends NanoHTTPD
2013-08-27 01:48:04 +00:00
{
2015-11-15 23:32:04 +00:00
2016-05-12 19:40:39 +00:00
private HTTPD ( int port )
2013-08-27 01:48:04 +00:00
{
super ( port ) ;
}
2016-05-12 19:40:39 +00:00
private HTTPD ( String hostname , int port )
2013-08-27 01:48:04 +00:00
{
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
{
2016-05-12 19:40:39 +00:00
final String [ ] args = StringUtils . split ( session . getUri ( ) , " / " ) ;
2013-08-27 01:48:04 +00:00
2016-05-12 19:40:39 +00:00
ModuleExecutable mex = modules . get ( " file " ) ;
if ( args . length > = 1 )
2013-08-27 01:48:04 +00:00
{
2016-05-12 19:40:39 +00:00
mex = modules . get ( args [ 0 ] . toLowerCase ( ) ) ;
2013-08-27 01:48:04 +00:00
}
2016-05-12 19:40:39 +00:00
if ( mex = = null )
2013-08-28 00:20:11 +00:00
{
2016-05-12 19:40:39 +00:00
return new Response ( Response . Status . NOT_FOUND , MIME_PLAINTEXT , " Error 404: Not Found - The requested resource was not found on this server. " ) ;
2013-08-28 00:20:11 +00:00
}
2016-05-12 19:40:39 +00:00
try
2013-08-27 01:48:04 +00:00
{
2016-05-12 19:40:39 +00:00
return mex . execute ( session ) ;
}
catch ( Exception ex )
{
FLog . severe ( ex ) ;
return new Response ( Response . Status . INTERNAL_ERROR , MIME_PLAINTEXT , " Error 500: Internal Server Error \ r \ n " + ex . getMessage ( ) + " \ r \ n " + ExceptionUtils . getStackTrace ( ex ) ) ;
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
}
2018-07-31 06:41:56 +00:00
2018-01-02 02:46:35 +00:00
// Some browsers like firefox download the file for text/yaml mime types
if ( FilenameUtils . getExtension ( file . getName ( ) ) . equals ( " yml " ) )
{
mimetype = NanoHTTPD . MIME_PLAINTEXT ;
}
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 ;
}
2016-05-12 19:40:39 +00:00
2013-08-27 01:48:04 +00:00
}