HTTP Deceiver
http-deceiver is a low-level Node.js module specifically engineered to provide granular control over HTTP stream parsing, allowing developers to process or manipulate raw HTTP request and response data, including potentially malformed or unconventional payloads. This capability makes it suitable for advanced network debugging, security testing (e.g., fuzzing HTTP parsers), or implementing custom proxy solutions where standard HTTP modules might be too restrictive. The package's current stable version is 1.2.7. Given its last update approximately eight years ago (around 2018), it is effectively an abandoned project with no ongoing maintenance or active development. Its event-driven API operates by accepting raw buffer chunks and emitting 'header', 'data', and 'end' events, providing a programmatic interface to dissect and reassemble HTTP message components. Unlike higher-level HTTP client or server libraries, `http-deceiver` directly interacts with the byte stream, offering a unique approach for deep-level HTTP protocol inspection and modification.
Common errors
-
TypeError: Deceiver is not a constructor
cause Attempting to instantiate `http-deceiver` without the `new` keyword, or calling it as a regular function.fixEnsure that `Deceiver` is instantiated as a class: `const deceiver = new Deceiver();`. -
ERR_REQUIRE_ESM: require() of ES Module ... not supported
cause Attempting to use `require()` to import an ES module, or more likely, using `import` syntax for this CommonJS-only package in an ESM context.fixThis package is strictly CommonJS. If you are in an ESM project, you might need a wrapper or dynamic import if your environment supports it, but the primary fix is to ensure the consuming code is CommonJS or use `const Deceiver = require('http-deceiver');` if your setup allows CJS imports in ESM. -
Deceiver error: Parse Error: ... (or similar error message related to parsing)
cause The raw buffer data fed into the `deceiver.write()` method contained syntactical errors or unexpected structures that the parser could not reconcile, even with its 'deceiving' capabilities.fixCarefully examine the raw HTTP buffer being provided. While `http-deceiver` is designed for flexibility, it still expects a certain underlying structure. Debug the raw bytes to ensure they align with the intended (even if malformed) HTTP protocol. Implement comprehensive error handling for the 'error' event emitted by the deceiver.
Warnings
- breaking The `http-deceiver` package has not been updated in approximately eight years and is considered abandoned. This means it is highly unlikely to receive bug fixes, security patches, or compatibility updates for newer Node.js versions or evolving HTTP standards. Using it in production environments is strongly discouraged due to potential security vulnerabilities and instability.
- gotcha Due to its age and CommonJS-only design, `http-deceiver` does not support ES module (ESM) import syntax. Attempting to use `import Deceiver from 'http-deceiver';` will result in a runtime error.
- gotcha The library's low-level nature means it expects raw buffer inputs and emits events based on its parsing. Mismanagement of input buffers (e.g., incorrect chunking or malformed HTTP beyond its intended 'deceiving' scope) can lead to 'error' events or unexpected parsing behavior.
Install
-
npm install http-deceiver -
yarn add http-deceiver -
pnpm add http-deceiver
Imports
- Deceiver
import Deceiver from 'http-deceiver';
const Deceiver = require('http-deceiver');
Quickstart
const Deceiver = require('http-deceiver');
const net = require('net');
const rawHttpRequest = Buffer.from(
'GET /malformed-path HTTP/1.1\r\n' +
'Host: example.com\r\n' +
'X-Custom-Header: potential-injection-attempt\r\n' +
'Content-Length: 0\r\n' +
'\r\n' // Note: A standard HTTP/1.1 request requires two CRLFs at the end of headers.
);
const server = net.createServer((socket) => {
console.log('Client connected to server.');
const deceiver = new Deceiver();
deceiver.on('error', (err) => {
console.error('Deceiver parsing error:', err.message);
socket.end('HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nDeceiver encountered a parsing error.\n');
});
deceiver.on('header', (header) => {
console.log('Parsed Header:', header);
// Example: Manipulate headers for a proxy or security scan
if (header['x-custom-header'] && header['x-custom-header'].includes('injection')) {
console.warn('Potential injection attempt detected in X-Custom-Header!');
}
});
deceiver.on('data', (data) => {
console.log('Parsed Data (body chunk):', data.toString());
});
deceiver.on('end', () => {
console.log('Deceiver parsing ended successfully.');
socket.write('HTTP/1.1 200 OK\r\nContent-Length: 18\r\nContent-Type: text/plain\r\n\r\nDeceiver processed it!\n');
socket.end();
});
socket.on('data', (chunk) => {
console.log('Received raw chunk from client:', chunk.toString().trim());
deceiver.write(chunk); // Feed client data to the deceiver
});
socket.on('end', () => {
console.log('Client disconnected from server.');
deceiver.end(); // Signal end of input to the deceiver
});
});
server.listen(3000, () => {
console.log('Server listening on port 3000. Simulating client request...');
const client = net.connect({ port: 3000 }, () => {
console.log('Simulated client connected.');
client.write(rawHttpRequest);
client.end(); // End client connection after sending the request
});
client.on('data', (data) => {
console.log('Simulated client received response:', data.toString().trim());
server.close(); // Close server after receiving response
});
client.on('end', () => {
console.log('Simulated client disconnected after response.');
});
});