Node 实现简单 HTTP 代理服务器

2018年02月20日

 1// node.js 中基于express 实现简单http代理服务
 2const express = require('express');
 3const morgan = require('morgan');
 4const ip = require('ip');
 5const url = require('url');
 6const http = require('http');
 7const net = require('net');
 8const request = require('request');
 9const app = express();
10const config = {
11  port: 8888,
12};
13const { port } = config;
14
15app.use(morgan('dev'));
16
17// 代理HTTP 正常流量
18app.use((req, res) => {
19  const { method, headers } = req;
20
21  // req => request => res
22  req.pipe(
23    request(
24      {
25        method,
26        headers,
27        uri: req.url,
28        // 表示解压缩数据
29        gzip: true,
30      },
31      (error, response, body) => {
32        // body is the decompressed response body
33        // 此处可对返回数据进行处理等
34        // console.log(body);
35      }
36    ).on('response', (response) => {
37      // unmodified http.IncomingMessage object
38      res.writeHead(response.statusCode, response.headers);
39      response.pipe(res);
40    })
41  );
42});
43
44const server = http.createServer(app);
45
46// HTTP 隧道 代理HTTPS 流量 但由于加密 不能处理
47server.on('connect', (req, socket) => {
48  console.log('connect', req.url);
49  const parsedUrl = url.parse('http://' + req.url);
50  const { port, hostname } = parsedUrl;
51  const clientSocket = net
52    .connect(port, hostname, () => {
53      socket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
54      clientSocket.pipe(socket);
55    })
56    .on('error', (e) => {
57      console.log(e);
58      socket.end();
59    });
60  socket.pipe(clientSocket);
61});
62
63// 开启server 监听指定端口
64server.listen(port, () => {
65  // 打印当前ip 地址和port
66  console.log(`address: ${ip.address()}:${port}`);
67});