diff --git a/README.md b/README.md index 65f5371..8730f05 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,7 @@ To fetch the stats of the given user: To get data provided by the iConomy plugin: http://server:port/money.xml + +You can request gzip compressed files by using the parameter gzip=true. This works on all files: + + http://server:port/userstats.xml?gzip=true \ No newline at end of file diff --git a/src/de/sockenklaus/XmlStats/Datasource/MoneyDS.java b/src/de/sockenklaus/XmlStats/Datasource/MoneyDS.java index 9cf0db3..bd0be8e 100644 --- a/src/de/sockenklaus/XmlStats/Datasource/MoneyDS.java +++ b/src/de/sockenklaus/XmlStats/Datasource/MoneyDS.java @@ -59,9 +59,9 @@ public class MoneyDS extends Datasource { Holdings balance = account.getHoldings(); result = balance.balance(); } - else XmlStats.LogError("The player has an account but it isn't valid. Bad data will return."); + else XmlStats.LogWarn("The player \""+playerName+"\" has an account but it isn't valid. Bad data will return."); } - else XmlStats.LogError("This player doesn't have a bank account and this action will return bad data"); + else XmlStats.LogWarn("The player \""+playerName+"\" doesn't have a bank account and this action will return bad data"); } else { XmlStats.LogError("Something went wrong! /money.xml shouldn't be enabled but it's datasource was called! This will return bad results."); diff --git a/src/de/sockenklaus/XmlStats/XmlStatsRegistry.java b/src/de/sockenklaus/XmlStats/XmlStatsRegistry.java new file mode 100644 index 0000000..c13bf08 --- /dev/null +++ b/src/de/sockenklaus/XmlStats/XmlStatsRegistry.java @@ -0,0 +1,33 @@ +/** + * + */ +package de.sockenklaus.XmlStats; + +import java.util.HashMap; + +/** + * @author socrates + * + */ +public class XmlStatsRegistry { + private HashMap register = null; + private static XmlStatsRegistry instance = null; + + private XmlStatsRegistry(){ + register = new HashMap(); + } + + public static void put(String key, Object value){ + if(instance == null){ + instance = new XmlStatsRegistry(); + } + instance.register.put(key, value); + } + + static public Object get(String key){ + if(instance == null){ + instance = new XmlStatsRegistry(); + } + return instance.register.get(key); + } +} diff --git a/src/de/sockenklaus/XmlStats/XmlStatsServerListener.java b/src/de/sockenklaus/XmlStats/XmlStatsServerListener.java new file mode 100644 index 0000000..2dee615 --- /dev/null +++ b/src/de/sockenklaus/XmlStats/XmlStatsServerListener.java @@ -0,0 +1,47 @@ +/** + * + */ +package de.sockenklaus.XmlStats; + +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.event.server.ServerListener; +import org.bukkit.plugin.Plugin; + +import com.iConomy.iConomy; +import com.nidefawl.Stats.Stats; + +/** + * @author socrates + * + */ +public class XmlStatsServerListener extends ServerListener { + private XmlStats plugin; + + public XmlStatsServerListener(XmlStats plugin){ + this.plugin = plugin; + } + + public void onPluginDisable(PluginDisableEvent event){ + iConomy iConomy = (iConomy)XmlStatsRegistry.get("iconomy"); + Stats Stats = (Stats)XmlStatsRegistry.get("stats"); + + if(iConomy != null){ + if(event.getPlugin().getDescription().getName().equals("iConomy")){ + iConomy = null; + XmlStats.LogInfo("iConomy is disabled now. Unhooking."); + } + } + if(Stats != null){ + if(event.getPlugin().getDescription().getName().equals("Stats")){ + Stats = null; + XmlStats.LogInfo("Stats is disabled now. Unhooking."); + } + } + + } + + public void onPluginEnable(PluginEnableEvent event){ + plugin.hookPlugins(); + } +} diff --git a/src/de/sockenklaus/XmlStats/XmlWorkers/XmlWorker.java b/src/de/sockenklaus/XmlStats/XmlWorkers/XmlWorker.java index 5a81bb0..c90f6ba 100644 --- a/src/de/sockenklaus/XmlStats/XmlWorkers/XmlWorker.java +++ b/src/de/sockenklaus/XmlStats/XmlWorkers/XmlWorker.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.zip.GZIPOutputStream; import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpExchange; @@ -55,59 +56,39 @@ public abstract class XmlWorker implements HttpHandler { byte[] byteResponse = null; try { - parameters = parseParameters(queryString); - } catch(UnsupportedEncodingException ex){ - XmlStats.LogError("Fehler beim Parsen des HTTP-Query-Strings."); - XmlStats.LogError(ex.getMessage()); + XmlStats.LogWarn("Fehler beim Parsen des HTTP-Query-Strings."); + XmlStats.LogWarn(ex.getMessage()); } xmlResponse = getXML(parameters); - + + /* * Check if the clients sends the header "Accept-encoding", the option "gzip-enabled" is true and the clients supports gzip. */ - if(headers.containsKey("Accept-encoding") && settingsTemp.getBoolean("options.gzip-enabled")){ - XmlStats.LogDebug("Compression seems to be accepted by the client and activated in this plugin."); - List header = headers.get("Accept-encoding"); - try { - XmlStats.LogDebug("There are "+header.size()+" values in the header"); - XmlStats.LogDebug("Let's take a look at the headers values:"); - } - catch (Exception e){ - XmlStats.LogError(e.getMessage()); - e.printStackTrace(); - } - for(String val : header){ - XmlStats.LogDebug("Accept-encoding: "+val); - if(val.toLowerCase().indexOf("gzip") > -1){ - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - XmlStats.LogDebug("OK... let's try gzip compression..."); - XmlStats.LogDebug("Actual size of the xml file: "+xmlResponse.getBytes().length+"Bytes"); - GZIPOutputStream gzip = new GZIPOutputStream(out); - gzip.write(xmlResponse.getBytes()); - gzip.close(); - byteResponse = out.toByteArray(); - XmlStats.LogDebug("Compressed size of the xml file: "+byteResponse.length+"Bytes"); - exchange.getResponseHeaders().add("Content-encoding", "gzip"); - - } catch (Exception e) { - XmlStats.LogError("GZIP-Compression failed! Falling back to non-compressed output."); - XmlStats.LogError(e.getMessage()); - e.printStackTrace(); - byteResponse = xmlResponse.getBytes(); - } - } - } + + + + if(parameters.containsKey("gzip") && parameters.get("gzip").contains("true")){ + XmlStats.LogDebug("Raw gzip requested."); + HttpContext context = exchange.getHttpContext(); + String filename = context.getPath().substring(1); + + byteResponse = compressData(xmlResponse.getBytes()); + exchange.getResponseHeaders().set("Content-type", "application/gzip"); + exchange.getResponseHeaders().set("Content-disposition", "attachment; filename="+filename+".gzip"); } - if (byteResponse == null || byteResponse.length == 0) { - XmlStats.LogDebug("Compression is not enabled or doesn't work properly. Fallback to uncompressed output."); + else if(clientAcceptsGzip(headers)) { + byteResponse = compressData(xmlResponse.getBytes()); + exchange.getResponseHeaders().set("Content-encoding", "gzip"); + } + else { byteResponse = xmlResponse.getBytes(); } - + try { exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, byteResponse.length); exchange.getResponseBody().write(byteResponse); @@ -171,4 +152,40 @@ public abstract class XmlWorker implements HttpHandler { * @return the xML */ abstract String getXML(Map> parameters); + + private byte[] compressData(byte[] input){ + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] output; + + try { + XmlStats.LogDebug("OK... let's try gzip compression..."); + XmlStats.LogDebug("Actual size of the xml file: "+input.length+"Bytes"); + GZIPOutputStream gzip = new GZIPOutputStream(out); + gzip.write(input); + gzip.close(); + output = out.toByteArray(); + XmlStats.LogDebug("Compressed size of the xml file: "+output.length+"Bytes"); + } + catch(IOException e){ + XmlStats.LogError("GZIP-Compression failed! Returning empty byte[]"); + output = new byte[0]; + } + + return output; + } + + private boolean clientAcceptsGzip(Headers headers){ + if(headers.containsKey("Accept-encoding")){ + List header = headers.get("Accept-encoding"); + + for(String val : header){ + if(val.toLowerCase().indexOf("gzip") > -1){ + return true; + } + } + + } + + return false; + } }