@gr2m/http-recorder
Library agnostic in-process recording of http(s) requests and responses
Install
npm install @gr2m/http-recorder
Usage
import http from "node:http";
import httpRecorder from "@gr2m/http-recorder";
httpRecorder.start();
httpRecorder.addListener(
"record",
({ request, response, requestBody, responseBody }) => {
const { method, protocol, host, path } = request;
const requestHeaders = request.getHeaders();
console.log(`> %s %s//%s%s`, method, protocol, host, path);
console.log(`> %j`, requestHeaders);
console.log(Buffer.concat(requestBody).toString());
const { statusCode, statusMessage, headers: responseHeaders } = response;
console.log(`\n< %s %s`, statusCode, statusMessage);
console.log(`< %j`, responseHeaders);
console.log(Buffer.concat(responseBody).toString());
}
);
const request = http.request("http://httpbin.org/post", { method: "post" });
request.write("data");
request.end();
// > POST http://httpbin.org/post
// > {"host":"httpbin.org"}
// data
//
// < 200 OK
// < {"content-type":"application/json",...}
// {
// "args": {},
// "data": "data",
// ...
// }
API
httpRecorder
is a singleton API.
httpRecorder.start()
Hooks into the request life cycle and emits record
events for each request sent through the http
or https
modules.
httpRecorder.stop()
Removes the hooks. No record
events will be emitted.
httpRecorder.addListener("record", listener)
Subscribe to a record
event. The listener
callback is called with an options object
options.request
: anhttp.ClientRequest
instanceoptions.response
: anhttp.IncomingMessage
instanceoptions.requestBody
: An array of Buffer chunks representing the request bodyoptions.responseBody
: An array of Buffer chunks representing the response body
httpRecorder.removeListener("record", listener)
Remove a record
event listener.
httpRecorder.removeAllListeners()
Removes all record
event listeners.
How it works
Once started, httpRecorder
hooks itself into the http.ClientRequest.prototype.onSocket
method which is conveniently called synchronously in the http.ClientRequest
constructor.
When a request is intercepted, we
- hook into the
request.write
method and therequest.end
method in order to clone the request body - subscribe to the
response
event - hook into the
response.emit
method in order to clone the response body without consuming it
and then emit a record
event with the request
, response
, requestBody
and responseBody
options.
Contributing
See CONTRIBUTING.md
Credit
The inspiration for hooking into http.ClientRequest.prototype.onSocket
method comes from Mitm.js - an http mocking library for TCP connections and http(s) requests.