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 {
20    method,
21    headers
22  } = req;
23
24  // req => request => res
25  req.pipe(
26    request({
27      method,
28      headers,
29      uri: req.url,
30      // 表示解压缩数据
31      gzip: true
32    }, (error, response, body) => {
33      // body is the decompressed response body
34      // 此处可对返回数据进行处理等
35      // console.log(body);
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.connect(port, hostname, () => {
52    socket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
53    clientSocket.pipe(socket);
54  }).on('error', e => {
55    console.log(e);
56    socket.end();
57  });
58  socket.pipe(clientSocket);
59});
60
61// 开启server 监听指定端口
62server.listen(port, () => {
63  // 打印当前ip 地址和port
64  console.log(`address: ${ip.address()}:${port}`);
65});