gzip support. also needs a slightly customized std.zlib so it is on a version for now

This commit is contained in:
Adam D. Ruppe 2011-08-23 16:06:44 -04:00
parent 20865bd68a
commit 20d971be0f
2 changed files with 42 additions and 8 deletions

34
cgi.d
View File

@ -19,6 +19,9 @@ import std.range;
import std.process;
version(with_gzip)
import arsd.zlib; // very minor diff from the std.zlib. If std.zlib gets my changes, this can die.
T[] consume(T)(T[] range, int count) {
if(count > range.length)
count = range.length;
@ -158,6 +161,10 @@ class Cgi {
else
port = 0; // this was probably called from the command line
auto ae = getenv("HTTP_ACCEPT_ENCODING");
if(ae.length && ae.indexOf("gzip") != -1)
acceptsGzip = true;
auto rm = getenv("REQUEST_METHOD");
if(rm.length)
requestMethod = to!RequestMethod(getenv("REQUEST_METHOD"));
@ -299,6 +306,10 @@ class Cgi {
case "host":
host = value;
break;
case "accept-encoding":
if(value.indexOf("gzip") != -1)
acceptsGzip = true;
break;
case "user-agent":
userAgent = value;
break;
@ -511,6 +522,12 @@ class Cgi {
noCache = !allowCaching;
}
/// Set to true and use cgi.write(data, true); to send a gzipped response to browsers
/// who can accept it
bool gzipResponse;
immutable bool acceptsGzip;
/// This gets a full url for the current request, including port, protocol, host, path, and query
string getCurrentCompleteUri() const {
return format("http%s://%s%s%s",
@ -685,6 +702,10 @@ class Cgi {
} else
hd ~= "Content-Type: text/html; charset=utf-8";
if(gzipResponse && acceptsGzip && isAll) { // FIXME: isAll really shouldn't be necessary
hd ~= "Content-Encoding: gzip";
}
if(customHeaders !is null)
hd ~= customHeaders;
@ -704,6 +725,19 @@ class Cgi {
outputtedResponseData = true;
}
if(gzipResponse && acceptsGzip && isAll) { // FIXME: isAll really shouldn't be necessary
// actually gzip the data here
auto c = new Compress(true); // want gzip
auto data = c.compress(t);
data ~= c.flush();
std.file.write("/tmp/last-item", data);
t = data;
}
if(requestMethod != RequestMethod.HEAD && t.length > 0) {
if (autoBuffer) {
outputBuffer ~= cast(ubyte[]) t;

16
web.d
View File

@ -812,7 +812,7 @@ void run(Provider)(Cgi cgi, Provider instantiation, int pathInfoStartingPoint =
// kinda a hack, but this kind of thing should be available anyway
if(funName == "functions.js") {
cgi.setResponseContentType("text/javascript");
cgi.write(makeJavascriptApi(reflection, replace(cast(string) cgi.requestUri, "functions.js", "")));
cgi.write(makeJavascriptApi(reflection, replace(cast(string) cgi.requestUri, "functions.js", "")), true);
cgi.close();
return;
}
@ -952,7 +952,7 @@ void run(Provider)(Cgi cgi, Provider instantiation, int pathInfoStartingPoint =
auto document = inst._defaultPage();
if(document !is null) {
instantiation._postProcess(document);
cgi.write(document.toString());
cgi.write(document.toString(), true);
}
cgi.close();
envelopeFormat = "no-processing";
@ -1082,19 +1082,19 @@ void run(Provider)(Cgi cgi, Provider instantiation, int pathInfoStartingPoint =
// this makes firefox ugly
//cgi.setResponseContentType("application/json");
auto json = toJsonValue(result);
cgi.write(toJSON(&json));
cgi.write(toJSON(&json), true);
break;
case "none":
cgi.setResponseContentType("text/plain");
if(result.success) {
if(result.result.type == JSON_TYPE.STRING) {
cgi.write(result.result.str);
cgi.write(result.result.str, true);
} else {
cgi.write(toJSON(&result.result));
cgi.write(toJSON(&result.result), true);
}
} else {
cgi.write(result.errorMessage);
cgi.write(result.errorMessage, true);
}
break;
case "document":
@ -1123,9 +1123,9 @@ void run(Provider)(Cgi cgi, Provider instantiation, int pathInfoStartingPoint =
returned = document.toString;
}
cgi.write(returned);
cgi.write(returned, true);
} else
cgi.write(htmlEntitiesEncode(toJSON(&result.result)));
cgi.write(htmlEntitiesEncode(toJSON(&result.result)), true);
break;
}