TotalFreedomMod/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDaemon.java

286 lines
8.1 KiB
Java
Raw Normal View History

package me.totalfreedom.totalfreedommod.httpd;
2013-08-27 01:48:04 +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;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
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;
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
public class HTTPDaemon extends AbstractService<TotalFreedomMod>
2013-08-27 01:48:04 +00:00
{
public static String MIME_DEFAULT_BINARY = "application/octet-stream";
//
private static final Pattern EXT_REGEX = Pattern.compile("\\.([^\\.\\s]+)$");
//
public static final int PORT = ConfigEntry.HTTPD_PORT.getInteger();
2013-08-27 01:48:04 +00:00
//
private static final TFM_HTTPD HTTPD = new TFM_HTTPD(PORT);
2013-08-27 01:48:04 +00:00
public HTTPDaemon(TotalFreedomMod plugin)
2013-08-27 01:48:04 +00:00
{
super(plugin);
2013-08-27 01:48:04 +00:00
}
@Override
public void onStart()
{
if (!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())
2013-08-27 16:39:28 +00:00
{
FLog.info("TFM HTTPd started. Listening on port: " + HTTPD.getListeningPort());
2013-08-27 16:39:28 +00:00
}
else
{
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)
{
FLog.severe(ex);
2013-08-27 01:48:04 +00:00
}
}
@Override
public void onStop()
2013-08-27 01:48:04 +00:00
{
if (!ConfigEntry.HTTPD_ENABLED.getBoolean())
{
return;
}
HTTPD.stop();
2013-08-27 16:39:28 +00:00
FLog.info("TFM HTTPd stopped.");
2013-08-27 01:48:04 +00:00
}
private static enum ModuleType
{
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();
}
});
//
private final ModuleExecutable moduleExecutable;
private ModuleType(ModuleExecutable moduleExecutable)
{
this.moduleExecutable = moduleExecutable;
}
private abstract static class ModuleExecutable
{
private final boolean runOnBukkitThread;
private final String name;
private ModuleExecutable(boolean runOnBukkitThread, String name)
{
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)
{
FLog.severe(ex);
}
return null;
}
public abstract Response getResponse(HTTPSession session);
public String getName()
{
return name;
}
}
public ModuleExecutable getModuleExecutable()
{
return moduleExecutable;
}
private static ModuleType getByName(String needle)
{
for (ModuleType type : values())
{
if (type.getModuleExecutable().getName().equalsIgnoreCase(needle))
{
return type;
}
}
return FILE;
}
}
2013-08-27 01:48:04 +00:00
private static class TFM_HTTPD extends NanoHTTPD
{
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
public Response serve(HTTPSession session)
2013-08-27 01:48:04 +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
{
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;
response = moduleType.getModuleExecutable().execute(session);
2013-08-27 01:48:04 +00:00
}
2013-09-03 21:47:42 +00:00
catch (Exception ex)
{
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-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
}
}
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 = MIME_DEFAULT_BINARY;
}
response = new Response(Response.Status.OK, mimetype, new FileInputStream(file));
response.addHeader("Content-Length", "" + file.length());
}
catch (IOException ex)
{
FLog.severe(ex);
}
}
return response;
}
2013-08-27 01:48:04 +00:00
}