首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将整个HTTP通信转储为nodejs中的原始数据

将整个HTTP通信转储为nodejs中的原始数据
EN

Stack Overflow用户
提问于 2018-06-04 20:46:33
回答 3查看 5.3K关注 0票数 20

我想知道是否有可能在整个HTTP通过网络时将其转储。

我不想得到方法,路径信息,查询字符串,标题,cookie,主体等等。理论上我可以自己组装原始数据,但是这样就不需要HTTP库了,对吧?

此外,我希望准确地转储通过导线的字节。

我想要这张图片中的原始数据

取自此页

我使用当前的node.js作为request的HTTP。它是普通的HTTP (没有HTTPS)。

在node.js中安装代理是一种选择,但我并不坚持使用库。我可以想象封装套接字读和写函数,但我看不出如何到达所使用的套接字。

EN

回答 3

Stack Overflow用户

发布于 2018-06-13 03:59:53

请求模块返回增强的本机对象。返回值是一个增广的http.ClientRequest对象(某种),回调作为第二个参数提供了一个增广的http.IncomingMessage。您可以使用各种属性来重构响应,但不能直接从这里获得响应。Node提供的本地http抽象出原始响应。

( IncomingMessageClientRequest的文档在这里:https://nodejs.org/api/http.html)。

更有趣的是,这两者都是net.Socket上的抽象。如果使用本机http API,则可以在发送ClientRequest (与.end一起)之前侦听此ClientRequest。这将给您一个包含HTTP的Buffer

代码语言:javascript
复制
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)返回以下数组:

代码语言:javascript
复制
[
   "connecting",
   "_hadError",
   "_handle",
   "_parent",
   "_host",
   "_readableState",
   "readable",
   "domain",
   "_events",
   "_eventsCount",
   "_maxListeners",
   "_writableState",
   "writable",
   "allowHalfOpen",
   "destroyed",
   "_bytesDispatched",
   "_sockname",
   "_pendingData",
   "_pendingEncoding",
   "server",
   "_server",
   "parser",
   "_httpMessage"
]

事实上,如果我们戳到可疑的_pendingData,我们可以在发送请求之前查看它:

代码语言:javascript
复制
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()); });
});
票数 8
EN

Stack Overflow用户

发布于 2018-06-10 01:06:50

这将返回作为reponse发送的请求头。

代码语言:javascript
复制
 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"))
票数 0
EN

Stack Overflow用户

发布于 2018-06-13 14:37:12

http.request还可以选择传递您自己的连接(createConnection)。您可以使用此选项提供您自己创建的连接,它是到记录器转换流的“管道()”。

代码语言:javascript
复制
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”事件之前。

回调

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50688524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档