• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jshttp / negotiator / 16975966097

14 Aug 2025 08:29PM UTC coverage: 41.29% (-58.0%) from 99.296%
16975966097

Pull #73

github

web-flow
Merge 151fff76a into 1fe49ae50
Pull Request #73: replace `mocha` and `nyc` with native node test runner and `c8`

384 of 930 relevant lines covered (41.29%)

20.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.61
/lib/encoding.js
1
/**
28✔
2
 * negotiator
28✔
3
 * Copyright(c) 2012 Isaac Z. Schlueter
28✔
4
 * Copyright(c) 2014 Federico Romero
28✔
5
 * Copyright(c) 2014-2015 Douglas Christopher Wilson
28✔
6
 * MIT Licensed
28✔
7
 */
28✔
8

28✔
9
'use strict';
28✔
10

28✔
11
/**
28✔
12
 * Module exports.
28✔
13
 * @public
28✔
14
 */
28✔
15

28✔
16
module.exports = preferredEncodings;
28✔
17
module.exports.preferredEncodings = preferredEncodings;
28✔
18

28✔
19
/**
28✔
20
 * Module variables.
28✔
21
 * @private
28✔
22
 */
28✔
23

28✔
24
var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
28✔
25

28✔
26
/**
28✔
27
 * Parse the Accept-Encoding header.
28✔
28
 * @private
28✔
29
 */
28✔
30

28✔
31
function parseAcceptEncoding(accept) {
×
32
  var accepts = accept.split(',');
×
33
  var hasIdentity = false;
×
34
  var minQuality = 1;
×
35

×
36
  for (var i = 0, j = 0; i < accepts.length; i++) {
×
37
    var encoding = parseEncoding(accepts[i].trim(), i);
×
38

×
39
    if (encoding) {
×
40
      accepts[j++] = encoding;
×
41
      hasIdentity = hasIdentity || specify('identity', encoding);
×
42
      minQuality = Math.min(minQuality, encoding.q || 1);
×
43
    }
×
44
  }
×
45

×
46
  if (!hasIdentity) {
×
47
    /*
×
48
     * If identity doesn't explicitly appear in the accept-encoding header,
×
49
     * it's added to the list of acceptable encoding with the lowest q
×
50
     */
×
51
    accepts[j++] = {
×
52
      encoding: 'identity',
×
53
      q: minQuality,
×
54
      i: i
×
55
    };
×
56
  }
×
57

×
58
  // trim accepts
×
59
  accepts.length = j;
×
60

×
61
  return accepts;
×
62
}
×
63

28✔
64
/**
28✔
65
 * Parse an encoding from the Accept-Encoding header.
28✔
66
 * @private
28✔
67
 */
28✔
68

28✔
69
function parseEncoding(str, i) {
×
70
  var match = simpleEncodingRegExp.exec(str);
×
71
  if (!match) return null;
×
72

×
73
  var encoding = match[1];
×
74
  var q = 1;
×
75
  if (match[2]) {
×
76
    var params = match[2].split(';');
×
77
    for (var j = 0; j < params.length; j++) {
×
78
      var p = params[j].trim().split('=');
×
79
      if (p[0] === 'q') {
×
80
        q = parseFloat(p[1]);
×
81
        break;
×
82
      }
×
83
    }
×
84
  }
×
85

×
86
  return {
×
87
    encoding: encoding,
×
88
    q: q,
×
89
    i: i
×
90
  };
×
91
}
×
92

28✔
93
/**
28✔
94
 * Get the priority of an encoding.
28✔
95
 * @private
28✔
96
 */
28✔
97

28✔
98
function getEncodingPriority(encoding, accepted, index) {
×
99
  var priority = {encoding: encoding, o: -1, q: 0, s: 0};
×
100

×
101
  for (var i = 0; i < accepted.length; i++) {
×
102
    var spec = specify(encoding, accepted[i], index);
×
103

×
104
    if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
×
105
      priority = spec;
×
106
    }
×
107
  }
×
108

×
109
  return priority;
×
110
}
×
111

28✔
112
/**
28✔
113
 * Get the specificity of the encoding.
28✔
114
 * @private
28✔
115
 */
28✔
116

28✔
117
function specify(encoding, spec, index) {
×
118
  var s = 0;
×
119
  if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
×
120
    s |= 1;
×
121
  } else if (spec.encoding !== '*' ) {
×
122
    return null
×
123
  }
×
124

×
125
  return {
×
126
    encoding: encoding,
×
127
    i: index,
×
128
    o: spec.i,
×
129
    q: spec.q,
×
130
    s: s
×
131
  }
×
132
};
28✔
133

28✔
134
/**
28✔
135
 * Get the preferred encodings from an Accept-Encoding header.
28✔
136
 * @public
28✔
137
 */
28✔
138

28✔
139
function preferredEncodings(accept, provided, preferred) {
×
140
  var accepts = parseAcceptEncoding(accept || '');
×
141

×
142
  var comparator = preferred ? function comparator (a, b) {
×
143
    if (a.q !== b.q) {
×
144
      return b.q - a.q // higher quality first
×
145
    }
×
146

×
147
    var aPreferred = preferred.indexOf(a.encoding)
×
148
    var bPreferred = preferred.indexOf(b.encoding)
×
149

×
150
    if (aPreferred === -1 && bPreferred === -1) {
×
151
      // consider the original specifity/order
×
152
      return (b.s - a.s) || (a.o - b.o) || (a.i - b.i)
×
153
    }
×
154

×
155
    if (aPreferred !== -1 && bPreferred !== -1) {
×
156
      return aPreferred - bPreferred // consider the preferred order
×
157
    }
×
158

×
159
    return aPreferred === -1 ? 1 : -1 // preferred first
×
160
  } : compareSpecs;
×
161

×
162
  if (!provided) {
×
163
    // sorted list of all encodings
×
164
    return accepts
×
165
      .filter(isQuality)
×
166
      .sort(comparator)
×
167
      .map(getFullEncoding);
×
168
  }
×
169

×
170
  var priorities = provided.map(function getPriority(type, index) {
×
171
    return getEncodingPriority(type, accepts, index);
×
172
  });
×
173

×
174
  // sorted list of accepted encodings
×
175
  return priorities.filter(isQuality).sort(comparator).map(function getEncoding(priority) {
×
176
    return provided[priorities.indexOf(priority)];
×
177
  });
×
178
}
×
179

28✔
180
/**
28✔
181
 * Compare two specs.
28✔
182
 * @private
28✔
183
 */
28✔
184

28✔
185
function compareSpecs(a, b) {
×
186
  return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i);
×
187
}
×
188

28✔
189
/**
28✔
190
 * Get full encoding string.
28✔
191
 * @private
28✔
192
 */
28✔
193

28✔
194
function getFullEncoding(spec) {
×
195
  return spec.encoding;
×
196
}
×
197

28✔
198
/**
28✔
199
 * Check if a spec has any quality.
28✔
200
 * @private
28✔
201
 */
28✔
202

28✔
203
function isQuality(spec) {
×
204
  return spec.q > 0;
×
205
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc