0
# Request and Response Streaming
1
2
Comprehensive streaming capabilities for both outgoing request data and incoming response data. Stream-http provides true streaming in supported browsers and pseudo-streaming in older browsers.
3
4
## Capabilities
5
6
### ClientRequest Class
7
8
Writable stream for handling outgoing HTTP requests. Inherits from Node.js `stream.Writable`.
9
10
```javascript { .api }
11
/**
12
* HTTP request writable stream
13
* Inherits from stream.Writable
14
*/
15
class ClientRequest extends stream.Writable {
16
/**
17
* Sets an HTTP request header
18
* @param name - Header name (case-insensitive)
19
* @param value - Header value
20
* Note: Certain unsafe headers are filtered for security
21
*/
22
setHeader(name, value);
23
24
/**
25
* Gets an HTTP request header value
26
* @param name - Header name (case-insensitive)
27
* @returns Header value or null if not set
28
*/
29
getHeader(name);
30
31
/**
32
* Removes an HTTP request header
33
* @param name - Header name (case-insensitive)
34
*/
35
removeHeader(name);
36
37
/**
38
* Sets socket timeout for the request
39
* @param timeout - Timeout in milliseconds
40
* @param cb - Optional callback called on timeout
41
*/
42
setTimeout(timeout, cb);
43
44
/**
45
* Aborts the request
46
* @param err - Optional error to emit
47
*/
48
abort(err);
49
50
/**
51
* Alias for abort()
52
* @param err - Optional error to emit
53
*/
54
destroy(err);
55
56
/**
57
* Finishes sending the request
58
* @param data - Optional final data to write
59
* @param encoding - Optional encoding for data
60
* @param cb - Optional callback when finished
61
*/
62
end(data, encoding, cb);
63
64
/**
65
* No-op stub for Node.js compatibility
66
*/
67
flushHeaders();
68
69
/**
70
* No-op stub for Node.js compatibility
71
*/
72
setNoDelay();
73
74
/**
75
* No-op stub for Node.js compatibility
76
*/
77
setSocketKeepAlive();
78
}
79
```
80
81
**Usage Examples:**
82
83
```javascript
84
const http = require('stream-http');
85
86
// Writing request data in chunks
87
const req = http.request({
88
method: 'POST',
89
hostname: 'api.example.com',
90
path: '/upload',
91
headers: {
92
'Content-Type': 'application/octet-stream'
93
}
94
});
95
96
// Write data in chunks
97
req.write(Buffer.from('chunk1'));
98
req.write(Buffer.from('chunk2'));
99
req.end(Buffer.from('final-chunk'));
100
101
// Setting headers
102
req.setHeader('X-Custom-Header', 'value');
103
console.log(req.getHeader('content-type')); // 'application/octet-stream'
104
105
// Handle timeout
106
req.setTimeout(5000, function() {
107
console.log('Request timed out');
108
req.abort();
109
});
110
```
111
112
### Header Security
113
114
Stream-http automatically filters unsafe headers for security reasons. These headers are blocked by browsers:
115
116
```javascript { .api }
117
/**
118
* Headers that are filtered for security (cannot be set manually)
119
*/
120
const unsafeHeaders = [
121
'accept-charset', 'accept-encoding', 'access-control-request-headers',
122
'access-control-request-method', 'connection', 'content-length',
123
'cookie', 'cookie2', 'date', 'dnt', 'expect', 'host', 'keep-alive',
124
'origin', 'referer', 'te', 'trailer', 'transfer-encoding',
125
'upgrade', 'via'
126
];
127
```
128
129
Attempting to set these headers via `setHeader()` will be silently ignored to prevent warnings from browsers.
130
131
### IncomingMessage Class
132
133
Readable stream for handling incoming HTTP responses. Inherits from Node.js `stream.Readable`.
134
135
```javascript { .api }
136
/**
137
* HTTP response readable stream
138
* Inherits from stream.Readable
139
*/
140
class IncomingMessage extends stream.Readable {
141
/** Response headers with lowercase keys */
142
headers: object;
143
144
/** Raw response headers as array [name, value, name, value, ...] */
145
rawHeaders: string[];
146
147
/** Response trailers (always empty in browser) */
148
trailers: object;
149
150
/** Raw response trailers (always empty in browser) */
151
rawTrailers: string[];
152
153
/** HTTP status code */
154
statusCode: number;
155
156
/** HTTP status message */
157
statusMessage: string;
158
159
/** Final URL after redirects (if supported by browser) */
160
url: string;
161
}
162
```
163
164
**Usage Examples:**
165
166
```javascript
167
http.get('https://api.example.com/data', function(res) {
168
console.log('Status:', res.statusCode);
169
console.log('Headers:', res.headers);
170
console.log('Content-Type:', res.headers['content-type']);
171
console.log('Final URL:', res.url);
172
173
let responseData = '';
174
175
res.on('data', function(chunk) {
176
responseData += chunk.toString();
177
});
178
179
res.on('end', function() {
180
console.log('Complete response:', responseData);
181
});
182
183
res.on('error', function(err) {
184
console.error('Response error:', err);
185
});
186
});
187
```
188
189
## Streaming Events
190
191
### ClientRequest Events
192
193
```javascript { .api }
194
// Event emitters for ClientRequest
195
req.on('response', function(response) {
196
// Emitted when response headers are received
197
// response is an IncomingMessage instance
198
});
199
200
req.on('error', function(error) {
201
// Emitted on request errors (network, timeout, etc.)
202
});
203
204
req.on('timeout', function() {
205
// Emitted when socket timeout occurs
206
});
207
208
req.on('requestTimeout', function() {
209
// Emitted when request timeout occurs (browser-specific)
210
});
211
```
212
213
### IncomingMessage Events
214
215
```javascript { .api }
216
// Event emitters for IncomingMessage
217
res.on('data', function(chunk) {
218
// Emitted for each chunk of response data
219
// chunk is a Buffer
220
});
221
222
res.on('end', function() {
223
// Emitted when response is complete
224
});
225
226
res.on('close', function() {
227
// Emitted after 'end' (fake event for Node.js compatibility)
228
});
229
230
res.on('error', function(error) {
231
// Emitted on response errors
232
});
233
```
234
235
## Streaming Performance
236
237
### True Streaming (Modern Browsers)
238
239
Supported in:
240
- Chrome 43+ (using Fetch API)
241
- Firefox 9+ (using `moz-chunked-arraybuffer`)
242
243
Benefits:
244
- Low memory usage (only current chunk in memory)
245
- Backpressure support (Chrome 58+ with WritableStream)
246
- Real-time data processing
247
248
### Pseudo-Streaming (Legacy Browsers)
249
250
- Data available before request completion
251
- Entire response held in memory
252
- Still useful for progress indication
253
254
### Memory Management
255
256
```javascript
257
// Efficient streaming example
258
http.get('https://api.example.com/large-file', function(res) {
259
const chunks = [];
260
261
res.on('data', function(chunk) {
262
// Process chunk immediately to minimize memory usage
263
processChunk(chunk);
264
265
// Or collect for later processing
266
chunks.push(chunk);
267
});
268
269
res.on('end', function() {
270
if (chunks.length > 0) {
271
const fullData = Buffer.concat(chunks);
272
processFullData(fullData);
273
}
274
});
275
});
276
```
277
278
## Browser Compatibility
279
280
### Response URL Support
281
282
The `response.url` property (final URL after redirects) is available in:
283
- Chrome 37+
284
- Firefox 32+
285
- Safari 9+
286
- Not supported in IE/Edge (older versions)
287
288
### Streaming Capabilities
289
290
Stream-http automatically detects and uses the best available method:
291
1. **Fetch API** (preferred): Modern browsers with full streaming support
292
2. **XHR with chunked responses**: Firefox with `moz-chunked-arraybuffer`
293
3. **XHR with MS Stream**: Internet Explorer with `ms-stream`
294
4. **Standard XHR**: Universal fallback with pseudo-streaming