gzipEncodeResponse function
FutureOr<Response>
gzipEncodeResponse(
- Response response, {
- int minimalGzipContentLength = _defaultMinimalGzipContentLength,
- _AlreadyCompressedContentType? alreadyCompressedContentType,
- int compressionLevel = _defaultGzipCompressionLevel,
- bool addCompressionRatioHeader = true,
- bool addServerTiming = false,
- String serverTimingEntryName = 'gzip',
Converts response
to a gzip
encoding response.
Checks canGzipEncodeResponse.
minimalGzipContentLength
is the minimal size for a content to be compressed. Default to512
.alreadyCompressedContentType
is a function that returnstrue
if the passedcontentType
is already compressed, like aPNG
,JPEG
orZip
. Defaults to isAlreadyCompressedContentType.- If
addCompressionRatioHeader
istrue
it adds the headerX-Compression-Ratio
, with compression info, e.g.:0.55 (550/1000)
- If
addServerTiming
istrue
, include or append Gzip encoding timing to theserver-timing
header. serverTimingEntryName
is the entry name to be used in theserver-timing
header. See createGzipMiddleware.
Implementation
FutureOr<Response> gzipEncodeResponse(
Response response, {
int minimalGzipContentLength = _defaultMinimalGzipContentLength,
_AlreadyCompressedContentType? alreadyCompressedContentType,
int compressionLevel = _defaultGzipCompressionLevel,
bool addCompressionRatioHeader = true,
bool addServerTiming = false,
String serverTimingEntryName = 'gzip',
}) async {
if (!canGzipEncodeResponse(response,
minimalGzipContentLength: minimalGzipContentLength,
alreadyCompressedContentType: alreadyCompressedContentType)) {
return response;
}
var gzipInit = DateTime.now();
var bufferInitialCapacity = response.contentLength ?? 1024 * 4;
// Read the body bytes from the response:
var bytesBuffer = await response.read().fold<_BytesBuffer>(
_BytesBuffer(bufferInitialCapacity),
(result, bytes) => result..addAll(bytes));
var gzipEncoder = compressionLevel == _defaultGzipCompressionLevel
? _defaultGzipEncoder
: ZLibEncoder(gzip: true, level: compressionLevel);
// Compressed body:
var compressedBody = gzipEncoder.convert(bytesBuffer.toUint8List());
var bodyLength = bytesBuffer.length;
var compressedBodyLength = compressedBody.length;
var headers = Map<String, String>.from(response.headers);
headers[HttpHeaders.contentEncodingHeader] = 'gzip';
headers[HttpHeaders.contentLengthHeader] = compressedBodyLength.toString();
if (addCompressionRatioHeader) {
var compressionRatio = compressedBodyLength / bodyLength;
var compressionRatioStr = '$compressionRatio';
if (compressionRatioStr.length > 6) {
compressionRatioStr = compressionRatio.toStringAsFixed(4);
}
headers['X-Compression-Ratio'] =
'$compressionRatioStr ($compressedBodyLength/$bodyLength)';
}
if (addServerTiming) {
const headerServerTiming = 'server-timing';
var gzipTime = DateTime.now().difference(gzipInit);
var dur = gzipTime.inMicroseconds / 1000;
var serverTiming2 = StringBuffer();
var serverTiming = headers[headerServerTiming];
if (serverTiming != null && serverTiming.isNotEmpty) {
serverTiming2.write(serverTiming);
serverTiming2.write(',');
}
serverTiming2.write(serverTimingEntryName);
serverTiming2.write(';dur=');
serverTiming2.write(dur);
headers[headerServerTiming] = serverTiming2.toString();
}
return response.change(headers: headers, body: compressedBody);
}