Added the possibility to request gzipped xml files.

This commit is contained in:
Pascal Koenig
2011-08-28 20:38:09 +02:00
parent c4f7db2d0d
commit 265989c5c4
5 changed files with 144 additions and 43 deletions

View File

@@ -27,3 +27,7 @@ To fetch the stats of the given user:
To get data provided by the iConomy plugin: To get data provided by the iConomy plugin:
http://server:port/money.xml 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

View File

@@ -59,9 +59,9 @@ public class MoneyDS extends Datasource {
Holdings balance = account.getHoldings(); Holdings balance = account.getHoldings();
result = balance.balance(); 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 { else {
XmlStats.LogError("Something went wrong! /money.xml shouldn't be enabled but it's datasource was called! This will return bad results."); XmlStats.LogError("Something went wrong! /money.xml shouldn't be enabled but it's datasource was called! This will return bad results.");

View File

@@ -0,0 +1,33 @@
/**
*
*/
package de.sockenklaus.XmlStats;
import java.util.HashMap;
/**
* @author socrates
*
*/
public class XmlStatsRegistry {
private HashMap<String, Object> register = null;
private static XmlStatsRegistry instance = null;
private XmlStatsRegistry(){
register = new HashMap<String, Object>();
}
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);
}
}

View File

@@ -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();
}
}

View File

@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
@@ -55,59 +56,39 @@ public abstract class XmlWorker implements HttpHandler {
byte[] byteResponse = null; byte[] byteResponse = null;
try { try {
parameters = parseParameters(queryString); parameters = parseParameters(queryString);
} catch(UnsupportedEncodingException ex){ } catch(UnsupportedEncodingException ex){
XmlStats.LogError("Fehler beim Parsen des HTTP-Query-Strings."); XmlStats.LogWarn("Fehler beim Parsen des HTTP-Query-Strings.");
XmlStats.LogError(ex.getMessage()); XmlStats.LogWarn(ex.getMessage());
} }
xmlResponse = getXML(parameters); xmlResponse = getXML(parameters);
/* /*
* Check if the clients sends the header "Accept-encoding", the option "gzip-enabled" is true and the clients supports gzip. * 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<String> header = headers.get("Accept-encoding");
try { if(parameters.containsKey("gzip") && parameters.get("gzip").contains("true")){
XmlStats.LogDebug("There are "+header.size()+" values in the header"); XmlStats.LogDebug("Raw gzip requested.");
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();
}
}
}
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) { else if(clientAcceptsGzip(headers)) {
XmlStats.LogDebug("Compression is not enabled or doesn't work properly. Fallback to uncompressed output."); byteResponse = compressData(xmlResponse.getBytes());
exchange.getResponseHeaders().set("Content-encoding", "gzip");
}
else {
byteResponse = xmlResponse.getBytes(); byteResponse = xmlResponse.getBytes();
} }
try { try {
exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, byteResponse.length); exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, byteResponse.length);
exchange.getResponseBody().write(byteResponse); exchange.getResponseBody().write(byteResponse);
@@ -171,4 +152,40 @@ public abstract class XmlWorker implements HttpHandler {
* @return the xML * @return the xML
*/ */
abstract String getXML(Map<String, List<String>> parameters); abstract String getXML(Map<String, List<String>> 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<String> header = headers.get("Accept-encoding");
for(String val : header){
if(val.toLowerCase().indexOf("gzip") > -1){
return true;
}
}
}
return false;
}
} }