You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS TCP代理服务器改造:实现请求转发与响应回写

简单代理服务器问题

现有运行在8080端口的Node.js TCP代理服务器代码,已将Firefox配置为通过该端口发送HTTP请求,目前能在命令行打印请求头,但需要实现以下功能:

  • 将接收的请求数据转发至目标互联网服务器
  • 获取目标服务器的响应并写回客户端套接字,实现正常网页浏览

原代码

const net = require('net')
const PORT = 8080

var clients = []

let date_ob = new Date()
let date = ("0" + date_ob.getDate()).slice(-2)
let month = ("0" + (date_ob.getMonth() + 1)).slice(-2)
let year = date_ob.getFullYear()
let hours = date_ob.getHours()
let minutes = date_ob.getMinutes()
let seconds = date_ob.getSeconds()

const server = net.createServer((socket)=>{

    let sock_name = socket.remoteAddress + ":" + socket.remotePort
    clients.push(socket)
    
    socket.on('data', (data)=> {
        console.log(year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds)  
        console.log(sock_name)
/*This "data" should send to internet dynamically like java socket applications and get back the respose*/          
console.log(""+data)        
    })
    
    socket.on('end', ()=>{
      clients.splice(clients.indexOf(socket), 1)
      console.log(sock_name +" left\n")
   })
   
   socket.on('error',(error)=>{
     console.log(error) 
   })       
    
}).listen(PORT)

server.on('error', (error) => {
    console.log(error)  
})

console.log("Server running at port 8080\n")

需求

  • 将从浏览器接收的请求数据转发至互联网目标服务器
  • 将目标服务器的响应写回客户端套接字

解决方案

要实现完整的TCP代理,需要处理普通HTTP请求和HTTPS CONNECT隧道两种场景,核心逻辑是解析目标地址、创建目标服务器连接、双向转发数据。修改后的完整代码如下:

const net = require('net')
const PORT = 8080

const server = net.createServer((clientSocket) => {
    let clientId = `${clientSocket.remoteAddress}:${clientSocket.remotePort}`
    console.log(`新客户端连接: ${clientId}`)

    // 处理客户端发送的数据
    clientSocket.on('data', (data) => {
        const dataStr = data.toString()
        // 优化日志日期格式
        const now = new Date().toISOString().slice(0, 19).replace('T', ' ')
        console.log(`[${now}] ${clientId}`)
        console.log(dataStr)

        let targetHost, targetPort
        // 区分处理HTTPS CONNECT请求和普通HTTP请求
        if (dataStr.startsWith('CONNECT')) {
            // 解析CONNECT请求中的目标地址
            const connectMatch = dataStr.match(/CONNECT (\S+):(\d+) HTTP/)
            if (connectMatch) {
                targetHost = connectMatch[1]
                targetPort = parseInt(connectMatch[2])
                // 返回隧道建立成功响应
                clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n')
            }
        } else {
            // 从HTTP请求的Host头解析目标地址
            const hostMatch = dataStr.match(/Host: (\S+)/)
            if (hostMatch) {
                const hostPart = hostMatch[1].split(':')
                targetHost = hostPart[0]
                targetPort = hostPart.length > 1 ? parseInt(hostPart[1]) : 80
            }
        }

        // 解析失败返回错误响应
        if (!targetHost || !targetPort) {
            clientSocket.end('HTTP/1.1 400 Bad Request\r\n\r\n')
            return
        }

        // 创建到目标服务器的连接
        const serverSocket = net.connect({ host: targetHost, port: targetPort }, () => {
            // 转发客户端数据到目标服务器
            serverSocket.write(data)
        })

        // 转发目标服务器响应回客户端
        serverSocket.on('data', (serverData) => {
            clientSocket.write(serverData)
        })

        // 目标服务器连接关闭时,关闭客户端连接
        serverSocket.on('end', () => {
            console.log(`与目标服务器 ${targetHost}:${targetPort} 的连接已关闭`)
            clientSocket.end()
        })

        // 处理目标服务器连接错误
        serverSocket.on('error', (err) => {
            console.error(`目标服务器连接错误: ${err.message}`)
            clientSocket.end(`HTTP/1.1 502 Bad Gateway\r\n\r\n`)
        })
    })

    // 客户端连接关闭日志
    clientSocket.on('end', () => {
        console.log(`客户端 ${clientId} 已断开连接`)
    })

    // 客户端连接错误处理
    clientSocket.on('error', (err) => {
        console.error(`客户端连接错误: ${err.message}`)
    })
}).listen(PORT)

server.on('error', (err) => {
    console.error(`代理服务器启动失败: ${err.message}`)
})

console.log(`代理服务器运行在端口 ${PORT}`)

关键改动说明

  • 日志优化:使用toISOString()简化日期格式生成,避免冗余代码
  • 目标地址解析:分别处理HTTP请求的Host头和HTTPS的CONNECT请求,准确提取目标主机与端口
  • 双向转发:建立客户端与目标服务器的双向数据通道,实现请求与响应的转发
  • 错误处理:完善各类连接错误的捕获与处理,返回标准HTTP错误码
  • HTTPS支持:处理CONNECT请求并建立隧道,支持HTTPS网页访问

内容的提问来源于stack exchange,提问作者user20537415

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:00:28