0
# on-headers
1
2
## Overview
3
4
A lightweight Node.js utility that executes listeners when HTTP response headers are about to be written. This package provides a simple hook mechanism for the HTTP response lifecycle, allowing developers to modify headers, add security measures, or perform logging right before headers are sent to the client.
5
6
**Key Features:**
7
- Hook into the HTTP response lifecycle before headers are sent
8
- Support for multiple listeners with reverse-order execution
9
- Compatible with native Node.js HTTP module and frameworks like Express
10
- Minimal overhead with single-execution guarantee
11
- Built-in error handling for invalid arguments
12
13
## Package Information
14
15
- **Package Name**: on-headers
16
- **Package Type**: npm
17
- **Language**: JavaScript
18
- **Installation**: `npm install on-headers`
19
20
## Core Imports
21
22
```javascript
23
var onHeaders = require('on-headers');
24
```
25
26
**Note**: This package uses CommonJS and does not provide native ES module exports. For ES module environments, use dynamic imports:
27
28
```javascript
29
const { default: onHeaders } = await import('on-headers');
30
```
31
32
## Architecture
33
34
The on-headers package works by intercepting the Node.js HTTP response lifecycle. It hooks into the `writeHead` method of the `ServerResponse` object, allowing listeners to execute right before headers are sent to the client.
35
36
**Key Components:**
37
- **Hook Mechanism**: Replaces the original `writeHead` method with a wrapper function
38
- **Listener Queue**: Maintains listeners in registration order, executes in reverse order
39
- **Single Execution**: Ensures listeners fire only once per response, even with multiple `writeHead` calls
40
- **Context Binding**: Binds the response object as `this` context to listener functions
41
42
## Basic Usage
43
44
```javascript
45
var http = require('http');
46
var onHeaders = require('on-headers');
47
48
http
49
.createServer(onRequest)
50
.listen(3000);
51
52
function addPoweredBy() {
53
// set if not set by end of request
54
if (!this.getHeader('X-Powered-By')) {
55
this.setHeader('X-Powered-By', 'Node.js');
56
}
57
}
58
59
function onRequest(req, res) {
60
onHeaders(res, addPoweredBy);
61
62
res.setHeader('Content-Type', 'text/plain');
63
res.end('hello!');
64
}
65
```
66
67
## Capabilities
68
69
### Header Listener Registration
70
71
Registers a listener function to execute when HTTP response headers are about to be written. The listener receives the response object as its context and can modify headers before they are sent to the client.
72
73
```javascript { .api }
74
/**
75
* Execute a listener when a response is about to write headers
76
* @param {ServerResponse} res - HTTP response object (ServerResponse instance)
77
* @param {HeaderListener} listener - Callback function to execute when headers are about to be written
78
* @throws {TypeError} When res argument is missing
79
* @throws {TypeError} When listener is not a function
80
*/
81
function onHeaders(res, listener);
82
83
/**
84
* Header listener function that executes before headers are written
85
* @callback HeaderListener
86
* @this {ServerResponse} The HTTP response object
87
*/
88
typedef HeaderListener = () => void;
89
```
90
91
**Key behaviors:**
92
93
- **Context Binding**: The listener function is called with the response object as its context (`this`), providing direct access to `this.setHeader()`, `this.getHeader()`, `this.statusCode`, etc.
94
- **Single Emission**: Headers are considered emitted only once, right before being sent to the client
95
- **Reverse Order Execution**: Multiple listeners on the same response fire in **reverse order** of registration (last registered fires first)
96
- **Single Execution Guarantee**: The listener will only fire once per response, even if `writeHead` is called multiple times
97
- **Mutable Response**: The response object can be modified within the listener (headers, status code, etc.) before being sent to the client
98
- **Timing**: Listeners execute after all application code but before headers reach the client
99
100
**Multiple Listeners Example:**
101
102
```javascript
103
var http = require('http');
104
var onHeaders = require('on-headers');
105
106
function onRequest(req, res) {
107
// These will fire in reverse order: listener3, listener2, listener1
108
onHeaders(res, function listener1() {
109
console.log('First registered, fires last');
110
});
111
112
onHeaders(res, function listener2() {
113
console.log('Second registered, fires second');
114
});
115
116
onHeaders(res, function listener3() {
117
console.log('Third registered, fires first');
118
});
119
120
res.end('done');
121
}
122
```
123
124
**Header Modification Example:**
125
126
```javascript
127
var onHeaders = require('on-headers');
128
129
function setDefaultHeaders() {
130
// Add security headers if not already set
131
if (!this.getHeader('X-Content-Type-Options')) {
132
this.setHeader('X-Content-Type-Options', 'nosniff');
133
}
134
135
if (!this.getHeader('X-Frame-Options')) {
136
this.setHeader('X-Frame-Options', 'DENY');
137
}
138
}
139
140
// Usage in Express.js middleware
141
function securityMiddleware(req, res, next) {
142
onHeaders(res, setDefaultHeaders);
143
next();
144
}
145
```
146
147
## Error Handling
148
149
The function throws `TypeError` in the following cases:
150
151
- When the `res` parameter is missing or falsy
152
- When the `listener` parameter is not a function
153
154
```javascript
155
// These will throw TypeError
156
onHeaders(); // Missing res argument
157
onHeaders(res); // Missing listener argument
158
onHeaders(res, 'not a function'); // Invalid listener type
159
```
160
161
## Types
162
163
```javascript { .api }
164
/**
165
* Node.js HTTP ServerResponse object
166
* @typedef {object} ServerResponse
167
* @property {function} setHeader - Set a single header value
168
* @property {function} getHeader - Get a header value
169
* @property {function} removeHeader - Remove a header
170
* @property {function} writeHead - Write the response head
171
* @property {number} statusCode - HTTP status code
172
* @property {function} end - End the response
173
* @property {function} write - Write response data
174
*/
175
176
/**
177
* Header listener callback function
178
* @callback HeaderListener
179
* @this {ServerResponse} The HTTP response object bound as context
180
*/
181
```
182
183
## Node.js Compatibility
184
185
- **Minimum Node.js Version**: 0.8
186
- **Compatible with**: All modern Node.js versions
187
- **HTTP Framework Support**: Works with native `http` module, Express.js, and other Node.js HTTP frameworks
188
- **Response Object**: Works with standard Node.js `ServerResponse` instances