我想知道是否有可能在整个HTTP通过网络时将其转储。
我不想得到方法,路径信息,查询字符串,标题,cookie,主体等等。理论上我可以自己组装原始数据,但是这样就不需要HTTP库了,对吧?
此外,我希望准确地转储通过导线的字节。
我想要这张图片中的原始数据

取自此页。
我使用当前的node.js作为request的HTTP。它是普通的HTTP (没有HTTPS)。
在node.js中安装代理是一种选择,但我并不坚持使用库。我可以想象封装套接字读和写函数,但我看不出如何到达所使用的套接字。
发布于 2018-06-13 03:59:53
请求模块返回增强的本机对象。返回值是一个增广的http.ClientRequest对象(某种),回调作为第二个参数提供了一个增广的http.IncomingMessage。您可以使用各种属性来重构响应,但不能直接从这里获得响应。Node提供的本地http抽象出原始响应。
( IncomingMessage和ClientRequest的文档在这里:https://nodejs.org/api/http.html)。
更有趣的是,这两者都是net.Socket上的抽象。如果使用本机http API,则可以在发送ClientRequest (与.end一起)之前侦听此ClientRequest。这将给您一个包含HTTP的Buffer。
let http = require("http");
let nativeRequest = http.get({
host: "google.com"
}); //get a ClientRequest object
nativeRequest.on('socket', function (socket) {
socket.on('data', function (data) { console.log(data.toString()); });
});
nativeRequest.end();它看起来不允许您窥探出站请求,但是它对响应非常有用。
回到抽象链上,这可以很好地处理请求。我将跳过片段,因为它几乎与前面的和即将到来的都一样。
为了得到这个请求,我们可以在一个套接字的内部四处窥探看是否有什么东西我们可以滥用。Object.keys(socket)返回以下数组:
[
"connecting",
"_hadError",
"_handle",
"_parent",
"_host",
"_readableState",
"readable",
"domain",
"_events",
"_eventsCount",
"_maxListeners",
"_writableState",
"writable",
"allowHalfOpen",
"destroyed",
"_bytesDispatched",
"_sockname",
"_pendingData",
"_pendingEncoding",
"server",
"_server",
"parser",
"_httpMessage"
]事实上,如果我们戳到可疑的_pendingData,我们可以在发送请求之前查看它:
let request = require('request');
let req = request("http://google.com", function (e, r, d) {});
req.on('socket', function (socket) {
console.log("========\nRequest\n========")
console.log(JSON.stringify(socket._pendingData, null, 3));
console.log("========\nResponse\n========");
socket.on('data', function (data) { console.log(data.toString()); });
});发布于 2018-06-10 01:06:50
这将返回作为reponse发送的请求头。
const http = require("http")
function getRawHeader(req, res) {
const httpVersion = req.httpVersion
let str = `${req.method.toUpperCase()} ${req.url} HTTP/${httpVersion}\n`
for (let i = 0; i < req.rawHeaders.length; i = i + 2) {
str += `${req.rawHeaders[1]} : ${req.rawHeaders[i + 1]}\n`
console.log(i)
}
let written = false
req.on("readable", (chunk) => {
const data = req.read()
if (!written) {
res.write(str)
res.write("\n")
}
written = true
if (data) res.write(data)
})
}
http.createServer((req, res) => {
getRawHeader(req, res)
req.on("end", () =>res.end())
}).listen(7200, () => console.log("server f is running"))发布于 2018-06-13 14:37:12
http.request还可以选择传递您自己的连接(createConnection)。您可以使用此选项提供您自己创建的连接,它是到记录器转换流的“管道()”。
const { Transform } = require('stream');
const http = require('http');
const agent = new http.Agent();
let nativeRequest = http.get({
host: 'google.com',
createConnection: options => {
let connection = agent.createConnection(options);
let logger = new Transform({
transform: (chunk, encoding, callback) => {
console.log(chunk.toString());
connection.write(chunk, encoding, callback);
},
flush: () => {},
});
connection.pipe(logger);
return logger;
},
});
nativeRequest.on('socket', function(socket) {
socket.on('data', function(data) {
console.log(data.toString());
});
});
nativeRequest.end();一些笔记
我尝试实现PassThrough流而不是Transform。当我将PassThrough流输送到连接时,这给了我HTTP解析错误。我不知道为什么要说实话。
从文档中包含flush: () => {}是很重要的
这将在没有更多的书面数据被消耗时调用,但是在发出发出可读流结束信号的“end”事件之前。
https://stackoverflow.com/questions/50688524
复制相似问题