go http-proxy

这篇具有很好参考价值的文章主要介绍了go http-proxy。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        我们这里主要讲使用HTTP/1.1协议中的CONNECT方法建立起来的隧道连接,实现的HTTP Proxy。这种代理的好处就是不用知道客户端请求的数据,只需要原封不动的转发就可以了,对于处理HTTPS的请求就非常方便了,不用解析他的内容,就可以实现代理。

  • 启动代理监听

        要想做一个HTTP Proxy,我们需要启动一个服务器,监听一个端口,用于接收客户端的请求。Golang给我们提供了强大的net包供我们使用,我们启动一个代理服务器监听非常方便。

l, err := net.Listen("tcp", ":8080") 

if err != nil {

    log.Panic(err)

}

        以上代理我们就实现了一个在8080端口上监听的服务器,我们这里没有写ip地址,默认在所有ip地址上进行监听。如果你只想本机适用,可以使用127.0.0.1:8080,这样机器就访问不了你的代理服务器了。

  • 监听接收代理请求

        启动了代理服务器,就可以开始接受不了代理请求了,有了请求,我们才能做进一步的处理。

for {

    client, err := l.Accept() 
    if err != nil {

        log.Panic(err)

    } 

    go handleClientRequest(client)

}

        Listener接口的Accept方法,会接受客户端发来的连接数据,这是一个阻塞型的方法,如果客户端没有连接数据发来,他就是阻塞等待。接收来的连接数据,会马上交给handleClientRequest方法进行处理,这里使用一个go关键字开一个goroutine的目的是不阻塞客户端的接收,代理服务器可以马上接收下一个连接请求。

  • 解析请求,获取要访问的IP和端口

        有了客户端的代理请求了,我们还得从请求里提取客户端要访问的远程主机的IP和端口,这样我们的代理服务器才可以建立和远程主机的连接,代理转发。

        HTTP协议的头信息里就包含有我们需要的主机名(IP)和端口信息,并且是明文的,协议很规范,类似于:

CONNECT www.google.com:443 HTTP/1.1

Host: www.google.com:443

Proxy-Connection: keep-alive

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36

        可以看到我们需要的在第一行,第一个行的信息以空格分开,第一部分CONNECT是请求方法,这里是CONNECT,除此之外还有GET,POST等,都是HTTP协议的标准方法。

        第二部分是URL,https的请求只有host和port,http的请求是一个完成的url,等下会看个样例,就明白了。

        第三部是HTTP的协议和版本,这个我们不用太关注。

        以上是一个https的请求,我们看下http的:

GET http://www.flysnow.org/ HTTP/1.1

Host: www.flysnow.org

Proxy-Connection: keep-alive

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36

可以看到htt的,没有端口号(默认是80);比https多了schame—http://。

有了分析,下面我们就可以从HTTP头信息中获取请求的url和method信息了。

var b [1024]byte

n, err := client.Read(b[:]) 
if err != nil {

    log.Println(err) return

} 
var method, host, address string

fmt.Sscanf(string(b[:bytes.IndexByte(b[:], '\n')]), "%s%s", &method, &host)

hostPortURL, err := url.Parse(host) 

if err != nil {

    log.Println(err) return

}

然后需要进一步对url进行解析,获取我们需要的远程服务器信息

if hostPortURL.Opaque == "443" { //https访问

    address = hostPortURL.Scheme + ":443"

} else { //http访问

    if strings.Index(hostPortURL.Host, ":") == -1 { //host不带端口, 默认80

    address = hostPortURL.Host + ":80"

} else {

    address = hostPortURL.Host

}

这样就完整了获取了要请求服务器的信息,他们可能是以下几种格式

ip:port

hostname:port

domainname:port

就是有可能是ip(v4orv6),有可能是主机名(内网),有可能是域名(dns解析)

  • 代理服务器和远程服务器建立连接

有了远程服务器的信息了,就可以进行拨号建立连接了,有了连接,才可以通信。

//获得了请求的host和port,就开始拨号吧

server, err := net.Dial("tcp", address) 

if err != nil {

    log.Println(err) return

}

数据转发

拨号成功后,就可以进行数据代理传输了

if method == "CONNECT" {

        fmt.Fprint(client, "HTTP/1.1 200 Connection established\r\n")

} else {

        server.Write(b[:n])

} //进行转发

go io.Copy(server, client)

io.Copy(client, server)

其中对CONNECT方法有单独的回应,客户端说要建立连接,代理服务器要回应建立好了,然后才可以像HTTP一样请求访问。

完整代码

到这里,我们的代理服务器全部开发完成了,下面是完整的源代码:文章来源地址https://www.toymoban.com/news/detail-691157.html

package main

import ( 

    "bytes"
    "fmt"
    "io"
    "log"
    "net"
    "net/url"
    "strings")
func main() {

    log.SetFlags(log.LstdFlags|log.Lshortfile)

    l, err := net.Listen("tcp", ":8081") 
    if err != nil {

    log.Panic(err)
    
    } 

    for {

    client, err := l.Accept() 
        if err != nil {

        log.Panic(err)

    } 
    go handleClientRequest(client)

    }

}


func handleClientRequest(client net.Conn) { 

    if client == nil { 
        return

    } 
    defer client.Close() 
    var b [1024]byte

    n, err := client.Read(b[:]) 
    if err != nil {

    log.Println(err) 
    return

    } 
    var method, host, address string

    fmt.Sscanf(string(b[:bytes.IndexByte(b[:], '\n')]), "%s%s", &method, &host)

    hostPortURL, err := url.Parse(host) 
    if err != nil {

        log.Println(err) return

    } 
    if hostPortURL.Opaque == "443" { //https访问

        address = hostPortURL.Scheme + ":443"

    } else { //http访问

    if strings.Index(hostPortURL.Host, ":") == -1 { //host不带端口, 默认80

        address = hostPortURL.Host + ":80"

    } else {

    address = hostPortURL.Host

    }

    } 
    //获得了请求的host和port,就开始拨号吧
    server, err := net.Dial("tcp", address) 
    if err != nil {

        log.Println(err) return

    } 
    if method == "CONNECT" {

        fmt.Fprint(client, "HTTP/1.1 200 Connection established\r\n")

    } else {

        server.Write(b[:n])

    } //进行转发

    go io.Copy(server, client)

    io.Copy(client, server)

}

到了这里,关于go http-proxy的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Golang原生实现JA3指纹修改,并支持Proxy代理

    抓取某个HTTPS网站的时候 开启charles代理能够抓取成功,关闭被风控 通过检测,怀疑可能是tls的时候有区别 golang的http中,Transport.TLSClientConfig是可以自定义设置的 但起初通过随意设置并不能绕过风控 使用golang的http客户端,修改DialTLSContext函数的方式是可以实绕过风控,但使用proxy的

    2024年02月13日
    浏览(85)
  • Docker设置http proxy代理

    需求: 由于公司服务器无法正常访问公网,想要下载一些外部依赖包需要配置公司的内部代理。 Docker构建镜像或拉取镜像时需要通过代理访问外网,可以按照以下步骤设置HTTP代理 目录 创建目录 创建并编辑配置文件 重新加载Docker服务配置 重启Docker服务 检验是否加载配置

    2024年02月12日
    浏览(44)
  • HTTP Proxy Demo代码示例

    这里提供一个Python实现的HTTP Proxy Demo代码示例: 以上代码实现了一个简单的HTTP代理服务器,能够实现转发客户端的请求,并将目标服务器的响应转发给客户端。当客户端请求到达代理服务器时,代理服务器会将其转发到目标服务器上,然后将目标服务器的响应返回给客户端

    2024年02月11日
    浏览(37)
  • HTTP Proxy Demo 代码示例

    以下是一个简单的 HTTP Proxy Demo 代码,使用 Python 3 编写: ```python import socket def handle_request(client_socket): # 接收客户端请求 request_data = client_socket.recv(1024) print(request_data.decode()) # 解析请求,获取目标主机和端口号 first_line = request_data.decode().split(\\\'n\\\')[0] url = first_line.split(\\\' \\\')[1] hos

    2024年02月09日
    浏览(38)
  • java http请求设置代理 Proxy

    有如下一种需求,原本A要给C发送请求,但是因为网络原因,需要借助B才能实现,所以由原本的A-C变成了A-B-C。 这种情况,更多的见于内网请求由统一的网关做代理然后转发出去,比如你本地的机器想要对外上网,都是通过运营商给的出口IP也就是公网地址实现的。这种做法

    2024年02月11日
    浏览(56)
  • docker如何设置http proxy代理

    如果您使用Docker构建镜像或拉取镜像时需要使用代理,可以按照以下步骤设置HTTP代理: 创建或编辑Docker服务配置文件 如果您使用systemd管理Docker服务,可以编辑该服务的配置文件 /etc/systemd/system/docker.service.d/http-proxy.conf 。如果文件不存在,可以创建该文件。或者是 docker.ser

    2024年02月11日
    浏览(53)
  • Android Studio设置HTTP Proxy

    之前在Android Studio我的设置的是电子科技大学的镜像网站 但是已经不管用了!!! 所以就选择自己设置代理 科学上网选择全局模式, 复制终端代码命令到终端查看,复制host和端口号 Host和端口号填上即可

    2024年02月16日
    浏览(37)
  • Jmeter-使用http proxy代理录制脚本

    Jmeter-使用http proxy代理录制脚本 第1步:打卡jmeter工具新增1个线程组 第2步:给线程组添加1个HTTP请求默认值   第3步:设置下HTTP请求默认值 第4步:在工作台中新增1个----HTTP代理服务器   第5步:设置HTTP代理服务器 设置完后记得点击启动 第6步:浏览器设置(这里选择ie浏览器

    2024年02月16日
    浏览(47)
  • 关于Android Studio Http Proxy设置

    对敌人最大的蔑视就是沉默。--鹿丸 我们使用Android Studio  开始构建的时候会有卡顿的情况,甚至死机,也就是所谓的【android studio】构建卡住问题,如果依赖库类都是国内的,检查是否开启了代理    这个地方选择下面的自动代理 国内有很多代理可以设置,下面这个亲测有

    2024年02月12日
    浏览(44)
  • docker使用http_proxy配置代理

    钢铁知识库,一个学习python爬虫、数据分析的知识库。人生苦短,快用python。 在内网服务器中,docker经常需要下载拉取镜像,但由于没有网络要么只能手动导入镜像包,又或者通过http_proxy代理到其它服务器下载。 增加 http-proxy.conf 配置文件,正确配置好代理服务器后重启d

    2024年01月22日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包