作者:Zarten知乎专栏:Go开发深入详解知乎ID: Zarten简介: 互联网一线工作者,尊重原创并欢迎评论留言指出不足之处,也希望多些关注和点赞是给作者最好的鼓励 !

概述

http(s)代理在日常使用中比较常用,所以这里写了一个https代理服务器,只需另外一台机器就可搭建自己的代理服务器了。

此服务器使用Go语言编写,全部使用go语言标准库,没有使用任何第三方库,编译后可以直接使用。下面将从代码底层讲述如何实现一个https代理服务器。

实现代码

此项目主要包含一个main函数和两个包,两个包包括一个https服务和一个proxy服务。

main函数

main函数是程序的启动入口,启动时需要传入https服务器的监听地址和端口,代码如下

func main(){var listenAdress stringflag.StringVar(&listenAdress, "L", "0.0.0.0:8080", "listen address.eg: 127.0.0.1:8080")flag.Parse()if !checkAdress(listenAdress){logger.Fatal("-L listen address format incorrect.Please check it")}httpsserve.Serve(listenAdress)}

使用-L参数指定监听地址和端口,若没有指定,默认为“0.0.0.0:8080”,同时会通过checkAdress函数检查地址的合法性。

最后调用httpsserve包中的Serve函数启动https服务。

https服务

https服务包含了http和https协议的服务,因为包含https,所以需要证书,在这里会自动生成证书。代码如下

func Serve(listenAdress string){cert, err := genCertificate()if err != nil {logger.Fatal(err)}server := &http.Server{Addr: listenAdress,TLSConfig:     &tls.Config{Certificates: []tls.Certificate{cert},},Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {proxy.Serve(w, r)}),}logger.Fatal(server.ListenAndServe())}

https服务器使用标准库中的net/http库,使用TLSConfig参数来配置证书信息,在Handler参数中调用proxy服务。

下面将重点讲解此项目的核心proxy服务。

proxy服务

此服务也是项目的核心所处,下面将重点讲解。

由于代理的使用者可能请求的网站是https或http的,所以这2种情况要分别处理。若请求的是https,实际上会先发送一个CONNECT请求。代码如下

func Serve(w http.ResponseWriter, r *http.Request){if r.Method == http.MethodConnect {handleHttps(w, r)} else {handleHttp(w, r)}}

  • handleHttps

若检测到是CONNECT请求,则会经过此函数处理。

此函数首先会使用函数net.DialTimeout根据客户端请求的目标网址来进行一次请求并获得连接信息,并回复一个200状态码给客户端。之后会使用Hijack来接管http服务来进行通信转发。代码如下

func handleHttps(w http.ResponseWriter, r *http.Request){destConn, err := net.DialTimeout("tcp", r.Host, 60*time.Second)if err != nil {http.Error(w, err.Error(), http.StatusServiceUnavailable)return}w.WriteHeader(http.StatusOK)hijacker, ok := w.(http.Hijacker)if !ok {http.Error(w, "Hijacking not supported", http.StatusInternalServerError)return}clientConn, _, err := hijacker.Hijack()if err != nil {http.Error(w, err.Error(), http.StatusServiceUnavailable)}go transfer(destConn, clientConn)go transfer(clientConn, destConn)}

函数transfer会进行转发操作,内部调用了io.Copy来进行转发。

  • handleHttp

此函数处理http请求的情况。

首先会根据目标地址调用标准库中的http.DefaultTransport.RoundTrip函数进行请求,RoundTrip函数会保持原样请求,并不能修改一些细节包括重定向、认证、cookie等。

最后需要将回复的http头信息复制后回复给客户端。代码如下

func handleHttp(w http.ResponseWriter, r *http.Request){resp, err := http.DefaultTransport.RoundTrip(r)if err != nil {http.Error(w, err.Error(), http.StatusServiceUnavailable)return}defer resp.Body.Close()copyHeader(w.Header(), resp.Header)w.WriteHeader(resp.StatusCode)io.Copy(w, resp.Body)}

总结

全部源码已上传至Github,地址:Zartenc/httpsproxy

上面是代码的主要部分,可以看到代理的核心思想就是做信息的转发。

另外若代理搭建在国外服务器,在国内访问某些网站时仍然会被墙,这是因为请求的网站信息已经在电信部门监听中,固无法访问。无法访问的限制原理可以看这篇文章,突破限制的主要思想是隐藏请求信息,目前shadowscoks协议在这方面做的比较出色。

go语言搭建代理服务器_Go实现Https代理服务相关推荐

  1. R语言搭建炫酷的线上博客系统

    本文转载自R语言中文社区,转载已获授权. 作者简介Introduction 徐静 硕士研究生.算法工程师 兴趣方向:统计机器学习,深度学习,模型的线上化部署.网络爬虫,前端可视化. 个人博客:http ...

  2. 如何使用 Go 语言搭建企业级高并发服务器?

    每到节假日和过年,需要外出通行的人几乎都会遇到一个问题:抢火车票!当全国上亿人都在固定的时间段抢票,服务器动辄就要承受上百万级并发的情况时,你就会明白,一个支持高并发的服务器架构有多重要! 在后端程序 ...

  3. go语言视频教程_ go语言入门视频教程_go语言实战视频教程

    许多人可能知道go语言的优点在哪里,但他们不知道go语言适合在哪里使用.通过学习go语言视频教程,可以清楚的知道go语言主要用于服务器端开发,其定位是用来开发"大型软件".学习go ...

  4. 使用TinyProxy搭建代理服务器

    背景 办公电脑所在网络无法连接外网,机房服务器可以连接外网,通过服务器代理上网: 一.CentOS下TinyProxy安装–搭建代理服务器 TinyProxy是个轻量级简单的HTTP/HTTPS代理程 ...

  5. linux搭建代理服务器+蚁剑配置客户端代理

    一:linux搭建代理服务器 0x00 介绍 关于搭建代理服务器的方法,我也是刚刚接触,从网上找了一些能够行得通的方法来给大家做个分享: 这里我用的是Tinyproxy作为代理服务软件.这个东西很小, ...

  6. 使用易语言搭建WEB服务器且支持大文件下载/断点传输

    易语言搭建WEB服务器,无非就是对数据处理与协议头分析做得好即可,扩展插件也不难,只需要接入相应接口即可,那么这次也是直接使用WINDOWS API的socket套接字进行搭建的WEB服务器. 目前尚 ...

  7. 用nodejs搭建代理服务器步骤

    前端开发者在工作中常常遇到跨域的问题,一般我们遇到跨域问题主要使用以下办法来解决: 1.jsonp 2.cors 3.配置代理服务器. jsonp不是很灵活,只能发送get请求,不能发送psot请求, ...

  8. privoxy支持同时代理多少个_Privoxy搭建代理服务器

    Privoxy搭建代理服务器 Dockerfile FROM alpine EXPOSE 8118 RUN apk --no-cache --update add privoxy wget ca-ce ...

  9. python搭建自动化测试平台_如何用python语言搭建自动化测试环境

    原标题:如何用python语言搭建自动化测试环境 技术分享:基于Python语言的Web自动化测试环境搭建 近期发现很多初学者在学习自动化的过程当中,在环境安装环节总是出现问题,所以详细的出一篇环境搭 ...

最新文章

  1. 偏移shaderuv_Unity Shader UV平移、旋转、缩放效果
  2. easy and hard things
  3. 贷款秒拒?你可能进了“灰名单”!
  4. 防止多次提交的几个比较
  5. c语言简易调度器,给大家分析SD调度器
  6. sql删除语句_推荐强大开源的数据库SQL语句审核平台,再也不用担心删除跑路了!...
  7. 二叉树(前中后序递归非递归遍历,层次遍历
  8. 大数据分析的特点有哪些
  9. 星球大战 BZOJ 1015
  10. java 通过System.getProperties()获取系统参数
  11. 概率算法/拉斯维加斯 蒙特卡洛 舍伍德算法
  12. 局域网 以太网 令牌环网(二)
  13. python2读取excel文件_python读取excel文件
  14. 机器学习-sklearn第十二天——笔记
  15. C语言入夏标志,[二级C语言程序设计.docx
  16. nodejs控制台打印图案
  17. 嵌入式系统主要应用于哪些行业中?
  18. Unity2D学习笔记Day6:无限跳跃bug和卡墙bug处理(补8.13)
  19. 工业控制系统安全评估流程威胁事件构建
  20. java生成英雄与怪物对象,java 创建一个LOL中的英雄类和怪物类 初学者,求大神指点...

热门文章

  1. php.ini配置文件详解
  2. WebService简单验证:SoapHeader
  3. IronRuby - 如何在VS2010下调试IronRuby代码
  4. Source Insight 经典教程
  5. [转载]静态构造函数
  6. 一个在windowsXP启动linux as(grub引导)的简单方法
  7. 假设训练数据集中有10万个词,四元语法需要存储多少词频和多词相邻频率?《动手学深度学习 李沐》 转
  8. HMM 前向 后向 Viterbi算法讲解通透的
  9. oracle 的替代变量和
  10. JAVA中是传值还是传引用?回答KEZHANG问题