golang 实现HTTP代理和反向代理
正向代理
package main import (
"fmt"
"io"
"net"
"net/http"
"strings"
) type Pxy struct{} func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
fmt.Printf("Received request %s %s %s\n", req.Method, req.Host, req.RemoteAddr) transport := http.DefaultTransport // step 1
outReq := new(http.Request)
*outReq = *req // this only does shallow copies of maps if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
if prior, ok := outReq.Header["X-Forwarded-For"]; ok {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
outReq.Header.Set("X-Forwarded-For", clientIP)
} // step 2
res, err := transport.RoundTrip(outReq)
if err != nil {
rw.WriteHeader(http.StatusBadGateway)
return
} // step 3
for key, value := range res.Header {
for _, v := range value {
rw.Header().Add(key, v)
}
} rw.WriteHeader(res.StatusCode)
io.Copy(rw, res.Body)
res.Body.Close()
} func main() {
fmt.Println("Serve on :8080")
http.Handle("/", &Pxy{})
http.ListenAndServe("0.0.0.0:8080", nil)
}
上面的代码运行之后,会在本地的 8080 端口启动代理服务。修改浏览器的代理为 127.0.0.1::8080 再访问http网站,可以验证代理正常工作,也能看到它在终端打印出所有的请求信息。
如果了解 HTTPS 协议的话,你会明白这种模式下是无法完成 HTTPS 握手的,虽然代理可以和真正的服务器建立连接(知道了对方的公钥和证书),但是代理无法代表服务器和客户端建立连接,因为代理服务器无法知道真正服务器的私钥。
反向代理
编写反向代理按照上面的思路当然没有问题,只需要在第二步的时候,根据之前的配置修改 outReq 的 URL Host 地址可以了。不过 Golang 已经给我们提供了编写代理的框架: httputil.ReverseProxy。我们可以用非常简短的代码来实现自己的代理,而且内部的细节问题都已经被很好地处理了。
package main import (
"log"
"net/http"
"net/http/httputil"
) func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
director := func(req *http.Request) {
req = r
req.URL.Scheme = "http"
req.URL.Host = r.Host
}
proxy := &httputil.ReverseProxy{Director: director}
proxy.ServeHTTP(w, r)
}) log.Fatal(http.ListenAndServe(":8888", nil))
}
感觉用法与正向代理没区别,也是设置浏览器代理地址后,用于访问http网站
用代理访问HTTPS
可以在远程服务器上用http.Get 或client.Do获取http或https网页内容。然后用http.ListenAndServe向本地返回获取到的内容。
package main import (
"fmt"
"io/ioutil"
"net/http"
) func main() {
resp, _ := http.Get("https://www.baidu.com")
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body)) }
或
package main import (
"fmt"
"io/ioutil"
"net/http"
) func main() {
client := &http.Client{}
req, _ := http.NewRequest("GET", "https://www.baidu.com", nil)
//req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
//req.Header.Set("Cookie", "name=any")
resp, err := client.Do(req)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
// handle error
}
fmt.Println(string(body)) }
其实也不必用这种土办法,直接在远程服务器上装ss就好了。(下面的参考中也有一个“用不到 100 行的 Golang 代码实现 HTTP(S) 代理”的代码)
参考:
https://blog.csdn.net/mengxinghuiku/article/details/65448600
https://www.jianshu.com/p/f868c88b45e1
https://studygolang.com/articles/11967?fr=sidebar
https://studygolang.com/articles/12525?fr=sidebar
https://segmentfault.com/a/1190000003735562
https://www.cnblogs.com/freecast/p/9687733.html
https://studygolang.com/articles/14917?fr=sidebar
http://www.01happy.com/golang-http-client-get-and-post/
golang 实现HTTP代理和反向代理的更多相关文章
- nginx正向代理,反向代理,透明代理(总结)
1正向代理 正向代理,也就是传说中的代理,他的工作原理就像一个跳板, 简单的说, 我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 这个代理服务器呢,他能访问那个我不能访问的网站 于是我先连 ...
- 正向代理与反向代理的区别【Nginx读书笔记】
正向代理的概念 正向代理,也就是传说中的代理,他的工作原理就像一个跳板, 简单的说, 我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 这个代理服务器呢,他能访问那个我不能访问的网站 于是我 ...
- 正向代理与反向代理的区别【Nginx读书笔记】(zz)
正向代理与反向代理的区别[Nginx读书笔记] 正向代理的概念 正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 ...
- Atitit.HTTP 代理原理及实现 正向代理与反向代理attilax总结
Atitit.HTTP 代理原理及实现 正向代理与反向代理attilax总结 1. 普通代理1 1.1.1. 普通代理2 2. 隧道代理3 3. 反向代理 4 4. 正向代理也可以使用apache实现 ...
- Apache代理和反向代理
服务器上安装了多个服务,包括apache的80端口,以及tomcat的8080和8090,为了访问使用方便,尝试了代理和反向代理.下面是部分配置以备参考: NameVirtualHost *:80 & ...
- Forward Proxy & Reverse Proxy | 正向代理 和 反向代理
对请求和响应内容不做修改的转发的服务器,被称为代理服务器.代理服务器分为两种类型:正向代理 和 反向代理. 正向代理:面向互联网,从更广范围获取信息的代理. 反向代理:面向内部,一般用于某企业的网站的 ...
- 正向代理vs.反向代理
正向代理 也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器这个代理服务器呢,他能访问那个我不能访问的网站于是我先连上代 ...
- Nginx的正向代理与反向代理详解
正向代理和反向代理的概念 代理服务(Proxy),通常也称为正向代理服务. 如果把局域网外Internet想象成一个巨大的资源库,那么资源就分布到了Internet的各个点上,局域网内的客户端要访问这 ...
- Nginx(三)-正向代理与反向代理
原文:正向代理与反向代理的区别 正向代理中,proxy和client同属一个LAN,对server透明: 反向代理中,proxy和server同属一个LAN,对client透明. 实际上proxy在两 ...
随机推荐
- cmd命令重定向到剪切板
Windows下 使用系统自带的 clip 命令. # 位于 C:\Windows\system32\clip.exe. 示例: # 将字符串 Hello 放入 Windows 剪贴板 echo He ...
- 异常:System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms FIPS信息标准限值了MD5加密
最近做的winform项目中,有个功能使用了MD5 加密,本地测试是没有问题的,但是上线后有些用户反馈说提示如下错误 一.问题描述 中文版错误截图 英语版错误截图 具体错误信息: 有关调用实时(JIT ...
- vscode创建net core控制台程序
vscode近来深受的开发人员的喜爱.在下的前端同事们也纷纷使用vscode.在下就想了我等后端程序员也可以用vscode写C#代码.毕竟是从宇宙第一IDE ----Visual Studio衍生的 ...
- Hadoop系列003-Hadoop运行环境搭建
本人微信公众号,欢迎扫码关注! Hadoop运行环境搭建 1.虚拟机网络模式设置为NAT 2.克隆虚拟机 3.修改为静态ip 4. 修改主机名 5.关闭防火墙 1)查看防火墙开机启动状态 chkcon ...
- Python开发:部分第三方库无法在线安装解决方法
前言:Python开发:Python2和Python3的共存和切换使用 一.问题如下: 1.截图: 2.错误信息: Could not find a version that satisfies th ...
- 理解滑动平均(exponential moving average)
1. 用滑动平均估计局部均值 滑动平均(exponential moving average),或者叫做指数加权平均(exponentially weighted moving average),可以 ...
- ansible离线安装
目录 1. ansible离线安装 2. ansible配置文件 3. ansible常用的命令: 1. ansible离线安装 最近要在内网部署一台ansible服务器,只能手动离线安装ansibl ...
- TabBottomFragmentLayout【自定义底部选项卡区域(搭配Fragment)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 自定义底部选项卡布局LinearLayout类,然后配合Fragment,实现切换Fragment功能. 缺点: 1.底部选项卡区域 ...
- ReentrantLock是如何基于AQS实现的
ReentrantLock是一个可重入的互斥锁,基于AQS实现,它具有与使用 synchronized 方法和语句相同的一些基本行为和语义,但功能更强大. lock和unlock ReentrantL ...
- C++ Sqlite3的基本使用
|SQLite3简介 SQLite3只是一个轻型的嵌入式数据库引擎,占用资源非常低,处理速度比Mysql还快,专门用于移动设备上进行适量的数据存取,它只是一个文件,不需要服务器进程. SQL语句是S ...