Manipulate the HTTP Vary header
npx @tessl/cli install tessl/npm-vary@1.1.00
# Vary
1
2
Vary is a Node.js utility library for manipulating HTTP Vary headers. It enables web applications to properly indicate which request headers affect the response content for HTTP caching and content negotiation. The library provides functions to set Vary headers on HTTP response objects and build Vary header strings programmatically.
3
4
## Package Information
5
6
- **Package Name**: vary
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install vary`
10
11
## Core Imports
12
13
```javascript
14
const vary = require('vary');
15
```
16
17
ESM:
18
19
```javascript
20
import vary from 'vary';
21
// Named imports not supported - use default import
22
```
23
24
## Basic Usage
25
26
```javascript
27
const http = require('http');
28
const vary = require('vary');
29
30
http.createServer(function onRequest (req, res) {
31
// Mark that response content varies based on User-Agent
32
vary(res, 'User-Agent');
33
34
const ua = req.headers['user-agent'] || '';
35
const isMobile = /mobi|android|touch|mini/i.test(ua);
36
37
res.setHeader('Content-Type', 'text/html');
38
res.end('You are (probably) ' + (isMobile ? '' : 'not ') + 'a mobile user');
39
});
40
```
41
42
## Architecture
43
44
The vary library implements HTTP Vary header manipulation through two key components:
45
46
- **Main Function (`vary`)**: Modifies HTTP response objects directly by reading existing Vary headers and appending new field names while preserving case and preventing duplicates
47
- **Utility Function (`vary.append`)**: Provides string manipulation for Vary header values without requiring an HTTP response object, enabling middleware and programmatic header construction
48
- **Field Parsing**: Internal comma-separated value parser handles RFC 7230 compliant field name extraction and validation
49
- **Case Preservation**: Maintains original case of field names while performing case-insensitive duplicate detection
50
- **Wildcard Handling**: Special logic for the "*" field value that indicates response varies on all possible headers
51
52
## Capabilities
53
54
### Set Vary Header on Response
55
56
Adds header field(s) to the Vary response header of an HTTP response object, ensuring proper cache control for content that depends on specific request headers.
57
58
```javascript { .api }
59
/**
60
* Mark that a request is varied on a header field
61
* @param {Object} res - HTTP response object with getHeader/setHeader methods
62
* @param {String|Array} field - Header field name(s) to add to Vary header
63
* @throws {TypeError} If res is invalid or field contains invalid header names
64
*/
65
function vary(res, field);
66
```
67
68
**Usage Examples:**
69
70
```javascript
71
const http = require('http');
72
const vary = require('vary');
73
74
// Single header field
75
vary(res, 'Origin');
76
77
// Multiple header fields as array
78
vary(res, ['Accept', 'User-Agent']);
79
80
// Multiple header fields as comma-separated string
81
vary(res, 'Accept, User-Agent');
82
83
// Wildcard - indicates response varies on all headers
84
vary(res, '*');
85
```
86
87
**Behavior:**
88
- Appends field if not already listed, preserves existing location if already present
89
- Performs case-insensitive comparison but preserves original case
90
- Special handling for wildcard (`*`) - overrides all other fields
91
- Validates field names against RFC 7230 specification
92
- Works with any object having `getHeader()` and `setHeader()` methods
93
94
### Build Vary Header String
95
96
Creates or appends to a Vary header string without modifying an HTTP response object. Useful for programmatic header construction and middleware that needs to build headers before setting them.
97
98
```javascript { .api }
99
/**
100
* Append a field to a vary header string
101
* @param {String} header - Existing Vary header value
102
* @param {String|Array} field - Header field name(s) to append
103
* @returns {String} Updated header value
104
* @throws {TypeError} If header is not string or field contains invalid header names
105
*/
106
vary.append = function append(header, field);
107
```
108
109
**Usage Examples:**
110
111
```javascript
112
const vary = require('vary');
113
114
// Build from empty header
115
const header1 = vary.append('', 'Origin');
116
// Result: "Origin"
117
118
// Append to existing header
119
const header2 = vary.append('Accept', 'User-Agent');
120
// Result: "Accept, User-Agent"
121
122
// Append multiple fields
123
const header3 = vary.append('Accept', ['Origin', 'User-Agent']);
124
// Result: "Accept, Origin, User-Agent"
125
126
// Wildcard handling
127
const header4 = vary.append('Accept, Origin', '*');
128
// Result: "*"
129
```
130
131
**Behavior:**
132
- Returns new header string with field(s) appended
133
- Handles case-insensitive deduplication while preserving case
134
- Supports wildcard (`*`) behavior - returns `*` when wildcard is present
135
- Validates field names using RFC 7230 compliant regex
136
- Processes comma-separated field strings and arrays identically
137
138
## Error Handling
139
140
Both functions throw `TypeError` for invalid arguments:
141
142
```javascript { .api }
143
// Invalid response object
144
vary({}, 'Origin'); // TypeError: res argument is required
145
146
// Invalid header argument
147
vary.append(42, 'Origin'); // TypeError: header argument is required
148
149
// Missing field argument
150
vary(res); // TypeError: field argument is required
151
vary.append('Accept'); // TypeError: field argument is required
152
153
// Invalid field names (violate RFC 7230)
154
vary(res, 'invalid:header'); // TypeError: field argument contains an invalid header name
155
vary(res, 'invalid header'); // TypeError: field argument contains an invalid header name
156
vary.append('', 'invalid\nheader'); // TypeError: field argument contains an invalid header name
157
```
158
159
## Types
160
161
```javascript { .api }
162
// HTTP Response-like object (Node.js http.ServerResponse or compatible)
163
interface ResponseLike {
164
getHeader(name: string): string | string[] | undefined;
165
setHeader(name: string, value: string): void;
166
}
167
168
// Field specification types
169
type FieldSpec = string | string[];
170
171
// Header field name validation
172
const FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
173
```