现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。
分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
var hopHeaders = []string{
"Connection",
"Proxy-Connection",
"Keep-Alive",
"Proxy-Authenticate",
"Proxy-Authorization",
"Te",
"Trailer",
"Transfer-Encoding",
"Upgrade",
}
代理服务器需要根据情况对 hop-by-hop 请求头做一些特殊处理,并在发送给目标服务器之前删除 hop-by-hop 请求头。
HTTP 隧道代理
在 HTTP 隧道技术中,客户端会在第一次连接代理服务器时给代理服务器发送一个指令,通常是一个 HTTP 请求。这里我们可以将 HTTP 请求头中的 method 设置为 CONNECT。
CONNECT example.com:443 HTTP/1.1
- 代理服务器收到该指令后,将与目标服务器建立 TCP 连接。
- 连接建立后,代理服务器会将之后收到的请求通过 TCP 连接转发给目标服务器。
因此,只有初始连接请求是 HTTP, 之后,代理服务器将不再嗅探到任何数据,它只是完成一个转发的动作。现在如果我们去查看其他开源的代理库,就会明白为什么会对 CONNECT 方法进行单独的处理了,这是业内通用的一种标准。
func main() {
server := &http.Server{
Addr: ":9981",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodConnect {
handleTunneling(w, r)
} else {
handleHTTP(w, r)
}
}),
}
log.Fatal(server.ListenAndServe())
}
func handleTunneling(w http.ResponseWriter, r *http.Request) {
dest_conn, err := net.DialTimeout("tcp", r.Host, 10*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
}
// 我们通过 hijacker.Hijack() 拿到了客户端与代理服务器之间的底层 TCP 连接
// 当调用 hijacker.Hijack()