猿问

使 go http 客户端与非标准 http 服务器一起工作

Shoutcast 服务器基本上使用 http,但有一个重要区别:它们GETICY 200 OK代替 来响应请求HTTP/1.1 200 OK

Go 不会有它,并且正确地失败并显示错误malformed HTTP version "ICY"

但是,我想让事情顺利进行,并且想知道最好的方法是什么。到目前为止我的想法:

  1. 使用自定义 http.Transport.Proxy 更改ICYHTTP/1.1飞行中

  2. 一个做同样事情的进程外代理

  3. 重载http.ParseHTTPVersion(但 golang 没有函数重载)

  4. 复制整个http包,只是为了修改 ParseHTTPVersion

数字 1. 似乎最具吸引力,但我不知道如何尊重 http“范围”并实际修改给定 http 版本上的所有响应。这种事情http.Transport.Proxy能搞定吗?

任何人都可以给我任何指示吗?


慕妹3242003
浏览 168回答 1
1回答

FFIVE

我通过创建一个返回包装连接的自定义 Dial 函数来实现这一点。我的包装器拦截了连接上的第一次读取,并用 HTTP/1.1 替换了 ICY。不是超级健壮,但证明了这个概念:package mainimport (    "fmt"    "net"    "net/http")type IcyConnWrapper struct {    net.Conn    haveReadAny bool}func (i *IcyConnWrapper) Read(b []byte) (int, error) {    if i.haveReadAny {        return i.Conn.Read(b)    }    i.haveReadAny = true    //bounds checking ommitted. There are a few ways this can go wrong.    //always check array sizes and returned n.    n, err := i.Conn.Read(b[:3])    if err != nil {        return n, err    }    if string(b[:3]) == "ICY" {        //write Correct http response into buffer        copy(b, []byte("HTTP/1.1"))        return 8, nil    }    return n, nil}func main() {    tr := &http.Transport{        Dial: func(network, a string) (net.Conn, error) {            realConn, err := net.Dial(network, a)            if err != nil {                return nil, err            }            return &IcyConnWrapper{Conn: realConn}, nil        },    }    client := &http.Client{Transport: tr}    http.DefaultClient = client    resp, err := http.Get("http://178.33.230.189:8100") //random url I found on the internet    fmt.Println(err)    fmt.Println(resp.StatusCode)}
随时随地看视频慕课网APP

相关分类

Go
我要回答