Skip to content

Commit d8dd8d7

Browse files
author
Mikko Tiihonen
committed
Handle quality values for Accept-Encoding field. Handle identity and * encoding types
1 parent b5718b6 commit d8dd8d7

2 files changed

Lines changed: 66 additions & 4 deletions

File tree

index.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,12 +307,26 @@ SendStream.prototype.getAcceptEncodingExtensions = function() {
307307
var accepted = []
308308
var header = this.req.headers['accept-encoding']
309309
if (header) {
310-
this._precompressionFormats.forEach(function (format) {
310+
var self = this
311+
self._precompressionFormats.forEach(function (format) {
311312
header.split(',').forEach(function (reqEncoding) {
312-
if (reqEncoding.trim().indexOf(format.encoding) === 0)
313-
accepted.push(format.extension)
313+
var vals = reqEncoding.split(';')
314+
var quality = 1
315+
if (vals.length > 1) {
316+
quality = parseFloat(vals[1].split('=')[1])
317+
}
318+
var encoding = vals[0].trim()
319+
if (encoding === 'identity') {
320+
accepted.push({format:'identity', quality:quality})
321+
} else if (encoding === '*' || encoding.indexOf(format.encoding) === 0) {
322+
accepted.push({format:format.extension, quality:quality})
323+
}
314324
})
315325
})
326+
accepted.sort(function(a,b) {return b.quality - a.quality} );
327+
if (accepted.length >= 1 && accepted[0].format === 'identity') {
328+
accepted = []
329+
}
316330
}
317331
return accepted;
318332
};
@@ -704,7 +718,7 @@ SendStream.prototype.sendFile = function sendFile(path) {
704718
var extensions = self.getAcceptEncodingExtensions()
705719
for (var e = 0; e < extensions.length && !preferredContent; e++) {
706720
for (var c = 0; c < contents.length; c++) {
707-
if (extensions[e] === contents[c].ext) {
721+
if (extensions[e].format === contents[c].ext) {
708722
preferredContent = contents[c]
709723
break
710724
}

test/send.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,7 @@ describe('send(file, options)', function(){
10871087
.get('/name.txt')
10881088
.set('Accept-Encoding', 'gzip')
10891089
.expect(shouldNotHaveHeader('Vary'))
1090+
.expect(shouldNotHaveHeader('Content-Encoding'))
10901091
.expect(200, done)
10911092
})
10921093

@@ -1100,6 +1101,7 @@ describe('send(file, options)', function(){
11001101
.get('/name.html')
11011102
.set('Accept-Encoding', '')
11021103
.expect('Content-Length', '11')
1104+
.expect(shouldNotHaveHeader('Content-Encoding'))
11031105
.expect('Content-Type', 'text/html; charset=UTF-8')
11041106
.expect('Vary', 'Accept-Encoding', done)
11051107
})
@@ -1172,6 +1174,7 @@ describe('send(file, options)', function(){
11721174
request(app)
11731175
.get('/name.html')
11741176
.set('Accept-Encoding', 'gzip')
1177+
.expect(shouldNotHaveHeader('Content-Encoding'))
11751178
.expect('Content-Length', '11', done)
11761179
})
11771180

@@ -1184,6 +1187,51 @@ describe('send(file, options)', function(){
11841187
.get('/name.html')
11851188
.expect('Vary', 'custom, Accept-Encoding', done);
11861189
})
1190+
1191+
it('should honour accept-encoding quality values', function(done){
1192+
var app = http.createServer(function(req, res){
1193+
send(req, req.url, {precompressed: true, root: fixtures})
1194+
.pipe(res);
1195+
});
1196+
1197+
request(app)
1198+
.get('/name.html')
1199+
.set('Accept-Encoding', 'gzip;q=0.9, deflate;q=1, br;q=0.1')
1200+
.expect('Vary', 'Accept-Encoding')
1201+
.expect('Content-Encoding', 'gzip')
1202+
.expect('Content-Type', 'text/html; charset=UTF-8')
1203+
.expect('Content-Length', '31', done)
1204+
})
1205+
1206+
it('should return no encoding if identity encoding preferred in accept-encoding', function(done){
1207+
var app = http.createServer(function(req, res){
1208+
send(req, req.url, {precompressed: true, root: fixtures})
1209+
.pipe(res);
1210+
});
1211+
1212+
request(app)
1213+
.get('/name.html')
1214+
.set('Accept-Encoding', 'gzip;q=0.8, identity')
1215+
.expect('Vary', 'Accept-Encoding')
1216+
.expect(shouldNotHaveHeader('Content-Encoding'))
1217+
.expect('Content-Type', 'text/html; charset=UTF-8')
1218+
.expect('Content-Length', '11', done)
1219+
})
1220+
1221+
it('should return server preferred format for accept-encoding *', function(done){
1222+
var app = http.createServer(function(req, res){
1223+
send(req, req.url, {precompressed: true, root: fixtures})
1224+
.pipe(res);
1225+
});
1226+
1227+
request(app)
1228+
.get('/name.html')
1229+
.set('Accept-Encoding', '*;q=0.9; gzip;q=0.8')
1230+
.expect('Vary', 'Accept-Encoding')
1231+
.expect('Content-Encoding', 'br')
1232+
.expect('Content-Type', 'text/html; charset=UTF-8')
1233+
.expect('Content-Length', '15', done)
1234+
})
11871235
})
11881236

11891237
describe('index', function(){

0 commit comments

Comments
 (0)