doc: add ESM examples in http.md
PR-URL: https://github.com/nodejs/node/pull/47763 Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
parent
23d65e7281
commit
48c613e5a7
326
doc/api/http.md
326
doc/api/http.md
@ -187,7 +187,14 @@ of these values set to their respective defaults.
|
||||
|
||||
To configure any of them, a custom [`http.Agent`][] instance must be created.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import { Agent, request } from 'node:http';
|
||||
const keepAliveAgent = new Agent({ keepAlive: true });
|
||||
options.agent = keepAliveAgent;
|
||||
request(options, onResponseCallback);
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
const keepAliveAgent = new http.Agent({ keepAlive: true });
|
||||
options.agent = keepAliveAgent;
|
||||
@ -474,7 +481,62 @@ type other than {net.Socket}.
|
||||
|
||||
A client and server pair demonstrating how to listen for the `'connect'` event:
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import { createServer, request } from 'node:http';
|
||||
import { connect } from 'node:net';
|
||||
import { URL } from 'node:url';
|
||||
|
||||
// Create an HTTP tunneling proxy
|
||||
const proxy = createServer((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('okay');
|
||||
});
|
||||
proxy.on('connect', (req, clientSocket, head) => {
|
||||
// Connect to an origin server
|
||||
const { port, hostname } = new URL(`http://${req.url}`);
|
||||
const serverSocket = connect(port || 80, hostname, () => {
|
||||
clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
|
||||
'Proxy-agent: Node.js-Proxy\r\n' +
|
||||
'\r\n');
|
||||
serverSocket.write(head);
|
||||
serverSocket.pipe(clientSocket);
|
||||
clientSocket.pipe(serverSocket);
|
||||
});
|
||||
});
|
||||
|
||||
// Now that proxy is running
|
||||
proxy.listen(1337, '127.0.0.1', () => {
|
||||
|
||||
// Make a request to a tunneling proxy
|
||||
const options = {
|
||||
port: 1337,
|
||||
host: '127.0.0.1',
|
||||
method: 'CONNECT',
|
||||
path: 'www.google.com:80',
|
||||
};
|
||||
|
||||
const req = request(options);
|
||||
req.end();
|
||||
|
||||
req.on('connect', (res, socket, head) => {
|
||||
console.log('got connected!');
|
||||
|
||||
// Make a request over an HTTP tunnel
|
||||
socket.write('GET / HTTP/1.1\r\n' +
|
||||
'Host: www.google.com:80\r\n' +
|
||||
'Connection: close\r\n' +
|
||||
'\r\n');
|
||||
socket.on('data', (chunk) => {
|
||||
console.log(chunk.toString());
|
||||
});
|
||||
socket.on('end', () => {
|
||||
proxy.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
const net = require('node:net');
|
||||
const { URL } = require('node:url');
|
||||
@ -570,7 +632,25 @@ Upgrade). The listeners of this event will receive an object containing the
|
||||
HTTP version, status code, status message, key-value headers object,
|
||||
and array with the raw header names followed by their respective values.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import { request } from 'node:http';
|
||||
|
||||
const options = {
|
||||
host: '127.0.0.1',
|
||||
port: 8080,
|
||||
path: '/length_request',
|
||||
};
|
||||
|
||||
// Make a request
|
||||
const req = request(options);
|
||||
req.end();
|
||||
|
||||
req.on('information', (info) => {
|
||||
console.log(`Got information prior to main response: ${info.statusCode}`);
|
||||
});
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
const options = {
|
||||
@ -648,7 +728,49 @@ type other than {net.Socket}.
|
||||
|
||||
A client server pair demonstrating how to listen for the `'upgrade'` event.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
import process from 'node:process';
|
||||
|
||||
// Create an HTTP server
|
||||
const server = http.createServer((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('okay');
|
||||
});
|
||||
server.on('upgrade', (req, socket, head) => {
|
||||
socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
|
||||
'Upgrade: WebSocket\r\n' +
|
||||
'Connection: Upgrade\r\n' +
|
||||
'\r\n');
|
||||
|
||||
socket.pipe(socket); // echo back
|
||||
});
|
||||
|
||||
// Now that server is running
|
||||
server.listen(1337, '127.0.0.1', () => {
|
||||
|
||||
// make a request
|
||||
const options = {
|
||||
port: 1337,
|
||||
host: '127.0.0.1',
|
||||
headers: {
|
||||
'Connection': 'Upgrade',
|
||||
'Upgrade': 'websocket',
|
||||
},
|
||||
};
|
||||
|
||||
const req = http.request(options);
|
||||
req.end();
|
||||
|
||||
req.on('upgrade', (res, socket, upgradeHead) => {
|
||||
console.log('got upgraded!');
|
||||
socket.end();
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
// Create an HTTP server
|
||||
@ -1019,7 +1141,28 @@ When sending request through a keep-alive enabled agent, the underlying socket
|
||||
might be reused. But if server closes connection at unfortunate time, client
|
||||
may run into a 'ECONNRESET' error.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
|
||||
// Server has a 5 seconds keep-alive timeout by default
|
||||
http
|
||||
.createServer((req, res) => {
|
||||
res.write('hello\n');
|
||||
res.end();
|
||||
})
|
||||
.listen(3000);
|
||||
|
||||
setInterval(() => {
|
||||
// Adapting a keep-alive agent
|
||||
http.get('http://localhost:3000', { agent }, (res) => {
|
||||
res.on('data', (data) => {
|
||||
// Do nothing
|
||||
});
|
||||
});
|
||||
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
// Server has a 5 seconds keep-alive timeout by default
|
||||
@ -1043,7 +1186,27 @@ setInterval(() => {
|
||||
By marking a request whether it reused socket or not, we can do
|
||||
automatic error retry base on it.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
const agent = new http.Agent({ keepAlive: true });
|
||||
|
||||
function retriableRequest() {
|
||||
const req = http
|
||||
.get('http://localhost:3000', { agent }, (res) => {
|
||||
// ...
|
||||
})
|
||||
.on('error', (err) => {
|
||||
// Check if retry is needed
|
||||
if (req.reusedSocket && err.code === 'ECONNRESET') {
|
||||
retriableRequest();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
retriableRequest();
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
const agent = new http.Agent({ keepAlive: true });
|
||||
|
||||
@ -1153,7 +1316,22 @@ Reference to the underlying socket. Usually users will not want to access
|
||||
this property. In particular, the socket will not emit `'readable'` events
|
||||
because of how the protocol parser attaches to the socket.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
const options = {
|
||||
host: 'www.google.com',
|
||||
};
|
||||
const req = http.get(options);
|
||||
req.end();
|
||||
req.once('response', (res) => {
|
||||
const ip = req.socket.localAddress;
|
||||
const port = req.socket.localPort;
|
||||
console.log(`Your IP address is ${ip} and your source port is ${port}.`);
|
||||
// Consume response object
|
||||
});
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
const options = {
|
||||
host: 'www.google.com',
|
||||
@ -1326,7 +1504,19 @@ immediately destroyed.
|
||||
|
||||
`socket` is the [`net.Socket`][] object that the error originated from.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
res.end();
|
||||
});
|
||||
server.on('clientError', (err, socket) => {
|
||||
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
|
||||
});
|
||||
server.listen(8000);
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
@ -2034,7 +2224,16 @@ this property. In particular, the socket will not emit `'readable'` events
|
||||
because of how the protocol parser attaches to the socket. After
|
||||
`response.end()`, the property is nulled.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
const server = http.createServer((req, res) => {
|
||||
const ip = res.socket.remoteAddress;
|
||||
const port = res.socket.remotePort;
|
||||
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
|
||||
}).listen(3000);
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
const server = http.createServer((req, res) => {
|
||||
const ip = res.socket.remoteAddress;
|
||||
@ -3306,6 +3505,20 @@ Returns a new instance of [`http.Server`][].
|
||||
The `requestListener` is a function which is automatically
|
||||
added to the [`'request'`][] event.
|
||||
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
|
||||
// Create a local server to receive data from
|
||||
const server = http.createServer((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({
|
||||
data: 'Hello World!',
|
||||
}));
|
||||
});
|
||||
|
||||
server.listen(8000);
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
@ -3320,6 +3533,23 @@ const server = http.createServer((req, res) => {
|
||||
server.listen(8000);
|
||||
```
|
||||
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
|
||||
// Create a local server to receive data from
|
||||
const server = http.createServer();
|
||||
|
||||
// Listen to the request event
|
||||
server.on('request', (request, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({
|
||||
data: 'Hello World!',
|
||||
}));
|
||||
});
|
||||
|
||||
server.listen(8000);
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
@ -3569,7 +3799,47 @@ the [`'response'`][] event.
|
||||
class. The `ClientRequest` instance is a writable stream. If one needs to
|
||||
upload a file with a POST request, then write to the `ClientRequest` object.
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import http from 'node:http';
|
||||
import { Buffer } from 'node:buffer';
|
||||
|
||||
const postData = JSON.stringify({
|
||||
'msg': 'Hello World!',
|
||||
});
|
||||
|
||||
const options = {
|
||||
hostname: 'www.google.com',
|
||||
port: 80,
|
||||
path: '/upload',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(postData),
|
||||
},
|
||||
};
|
||||
|
||||
const req = http.request(options, (res) => {
|
||||
console.log(`STATUS: ${res.statusCode}`);
|
||||
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', (chunk) => {
|
||||
console.log(`BODY: ${chunk}`);
|
||||
});
|
||||
res.on('end', () => {
|
||||
console.log('No more data in response.');
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', (e) => {
|
||||
console.error(`problem with request: ${e.message}`);
|
||||
});
|
||||
|
||||
// Write data to request body
|
||||
req.write(postData);
|
||||
req.end();
|
||||
```
|
||||
|
||||
```cjs
|
||||
const http = require('node:http');
|
||||
|
||||
const postData = JSON.stringify({
|
||||
@ -3777,7 +4047,19 @@ Examples:
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import { validateHeaderName } from 'node:http';
|
||||
|
||||
try {
|
||||
validateHeaderName('');
|
||||
} catch (err) {
|
||||
console.error(err instanceof TypeError); // --> true
|
||||
console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN'
|
||||
console.error(err.message); // --> 'Header name must be a valid HTTP token [""]'
|
||||
}
|
||||
```
|
||||
|
||||
```cjs
|
||||
const { validateHeaderName } = require('node:http');
|
||||
|
||||
try {
|
||||
@ -3811,7 +4093,27 @@ or response. The HTTP module will automatically validate such headers.
|
||||
|
||||
Examples:
|
||||
|
||||
```js
|
||||
```mjs
|
||||
import { validateHeaderValue } from 'node:http';
|
||||
|
||||
try {
|
||||
validateHeaderValue('x-my-header', undefined);
|
||||
} catch (err) {
|
||||
console.error(err instanceof TypeError); // --> true
|
||||
console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true
|
||||
console.error(err.message); // --> 'Invalid value "undefined" for header "x-my-header"'
|
||||
}
|
||||
|
||||
try {
|
||||
validateHeaderValue('x-my-header', 'oʊmɪɡə');
|
||||
} catch (err) {
|
||||
console.error(err instanceof TypeError); // --> true
|
||||
console.error(err.code === 'ERR_INVALID_CHAR'); // --> true
|
||||
console.error(err.message); // --> 'Invalid character in header content ["x-my-header"]'
|
||||
}
|
||||
```
|
||||
|
||||
```cjs
|
||||
const { validateHeaderValue } = require('node:http');
|
||||
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user