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在两 ...
随机推荐
- 新DevOps八荣八耻
昀哥 20181001以随时可扩容可缩容可重启可切换机房流量为荣,以不能迁移为耻. 以可配置为荣,以硬编码为耻. 以系统互备为荣,以系统单点为耻. 以交付时有监控报警为荣,以交付裸奔系统为耻. 以无状 ...
- SpringBoot整合Spring Security使用Demo
https://start.spring.io/ 生成SpringBoot项目 pom文件应该是我这样的: <?xml version="1.0" encoding=&quo ...
- 阿里云服务器建站——centos7部署apache+mysql+php
自己也是忙活了半天,才完成了阿里云服务器的建站,这里就来分享一下. 首先如果是要自己搭建一个网站的话,除了服务器以外还要购买域名,并且要去备案,一般在哪买的域名都有备案的系统,备案的话一般要两到三个星 ...
- .net core自定义高性能的Web API服务网关
网关对于服务起到一个统一控制处理的作用,也便于客户端更好的调用:通过网关可以灵活地控制服务应用接口负载,故障迁移,安全控制,监控跟踪和日志处理等.由于网关在性能和可靠性上都要求非常严格,所以针对业务需 ...
- 实体继承与@Builder注解共存
在面向对象的设计里,继承是非常必要的,我们会把共有的属性和方法抽象到父类中,由它统一去实现,而在进行lombok时代之后,更多的打法是使用@Builder来进行对象赋值,我们直接在类上加@Builde ...
- 接口自动化:HttpClient + TestNG + Java(五) - 接口测试数据驱动
在上一篇中,我们实现了post方法请求的封装和测试,这一篇我们做测试数据的分离. 5.1 测试数据处理思路 5.1.1 测试数据分离 这里我想到,我们之前的测试demo里,全都是在testNG类里去写 ...
- Session的使用与Session共享问题
Session的使用与Session共享问题 Session方法 getId():获取sessionId,这个id不一定是数字,比方说它用字符串来表示唯一标识,所以它返回值是String; boole ...
- msql分区
确认mysql服务器是否支持分区表: show plugins; 如果能看到partition则表示能分区. HASH分区的特点: 根据MOD(分区键,分区数)的值把数据行存储到表的不同分区中 数据可 ...
- 1.5准备CentOS和Nginx环境「深入浅出ASP.NET Core系列」
准备CentOS 1.1虚拟机 CentOS的安装这里使用vmware workstation 14来做虚拟机,当然你也可以用Oracle的虚拟机或者不用虚拟机,使用云服务或者使用双系统,不是什么大问 ...
- ASP.NET Core 2.2 十八.各种Filter的内部处理机制及执行顺序
ASP.NET core 的Filter是系统中经常用到的,本文详细分享一下各种Filter定义.执行的内部机制以及执行顺序.(ASP.NET Core 系列目录) 一. 概述 ASP.NET Cor ...