I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit e6d44a61 authored by zzz's avatar zzz
Browse files

* I2PTunnelHTTPServer: Don't compress small responses or images

parent 6630c290
No related branches found
No related tags found
No related merge requests found
......@@ -46,6 +46,9 @@ class HTTPResponseOutputStream extends FilterOutputStream {
private final byte _buf1[];
protected boolean _gzip;
private long _dataWritten;
protected long _dataExpected;
protected String _contentType;
private static final int CACHE_SIZE = 8*1024;
private static final ByteCache _cache = ByteCache.getInstance(8, CACHE_SIZE);
// OOM DOS prevention
......@@ -130,10 +133,11 @@ class HTTPResponseOutputStream extends FilterOutputStream {
}
/**
* Tweak that first HTTP response line (HTTP 200 OK, etc)
* Possibly tweak that first HTTP response line (HTTP/1.0 200 OK, etc).
* Overridden on server side.
*
*/
protected static String filterResponseLine(String line) {
protected String filterResponseLine(String line) {
return line;
}
......@@ -184,6 +188,15 @@ class HTTPResponseOutputStream extends FilterOutputStream {
} else if ("Proxy-Authenticate".equalsIgnoreCase(key)) {
// filter this hop-by-hop header; outproxy authentication must be configured in I2PTunnelHTTPClient
} else {
if ("Content-Length".equalsIgnoreCase(key)) {
// save for compress decision on server side
try {
_dataExpected = Long.parseLong(val);
} catch (NumberFormatException nfe) {}
} else if ("Content-Type".equalsIgnoreCase(key)) {
// save for compress decision on server side
_contentType = val;
}
out.write((key.trim() + ": " + val.trim() + "\r\n").getBytes());
}
break;
......
......@@ -303,19 +303,48 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
}
}
/**
* This plus a typ. HTTP response header will fit into a 1730-byte streaming message.
*/
private static final int MIN_TO_COMPRESS = 1300;
private static class CompressedResponseOutputStream extends HTTPResponseOutputStream {
private InternalGZIPOutputStream _gzipOut;
public CompressedResponseOutputStream(OutputStream o) {
super(o);
_dataExpected = -1;
}
/**
* Overridden to peek at response code. Always returns line.
*/
@Override
protected String filterResponseLine(String line) {
String[] s = line.split(" ", 3);
if (s.length > 1 &&
(s[1].startsWith("3") || s[1].startsWith("5")))
_dataExpected = 0;
return line;
}
/**
* Don't compress small responses or images.
* Compression is inline but decompression on the client side
* creates a new thread.
*/
@Override
protected boolean shouldCompress() { return true; }
protected boolean shouldCompress() {
return (_dataExpected < 0 || _dataExpected >= MIN_TO_COMPRESS) &&
(_contentType == null || !_contentType.startsWith("image/"));
}
@Override
protected void finishHeaders() throws IOException {
//if (_log.shouldLog(Log.INFO))
// _log.info("Including x-i2p-gzip as the content encoding in the response");
out.write("Content-encoding: x-i2p-gzip\r\n".getBytes());
if (shouldCompress())
out.write("Content-encoding: x-i2p-gzip\r\n".getBytes());
super.finishHeaders();
}
......@@ -324,9 +353,12 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
//if (_log.shouldLog(Log.INFO))
// _log.info("Beginning compression processing");
//out.flush();
_gzipOut = new InternalGZIPOutputStream(out);
out = _gzipOut;
if (shouldCompress()) {
_gzipOut = new InternalGZIPOutputStream(out);
out = _gzipOut;
}
}
public long getTotalRead() {
InternalGZIPOutputStream gzipOut = _gzipOut;
if (gzipOut != null)
......@@ -334,6 +366,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
else
return 0;
}
public long getTotalCompressed() {
InternalGZIPOutputStream gzipOut = _gzipOut;
if (gzipOut != null)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment