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

时间:2015-11-02 06:11:54

标签: audio go shoutcast

Shoutcast服务器基本上讲http,但有一个重要区别:他们使用RewriteEngine On RewriteCond %{HTTP_HOST} ^(www\.)?old-domain\.com$ [NC] RewritRule ^article(/.*)?$ http://new-domain.com%{REQUEST_URI} [NC,R=301,L] 代替GET来回复ICY 200 OK个请求。

Go将没有条形图,并且错误地显示错误HTTP/1.1 200 OK

但是我想让事情有效,我想知道最好的方法是什么。到目前为止我的想法:

  1. 使用自定义http.Transport.Proxy将malformed HTTP version "ICY"更改为ICY飞行中
  2. 执行相同操作的进程外代理
  3. 重载http.ParseHTTPVersion(但golang没有函数重载)
  4. 复制整个http包,只是为了修改HTTP/1.1
  5. 数字1似乎是最吸引人的,但我不知道如何尊重http“范围”并实际修改给定http版本的所有响应。这是ParseHTTPVersion可以处理的事情吗?

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

1 个答案:

答案 0 :(得分:3)

我通过创建一个返回包装连接的自定义Dial函数来实现此功能。我的包装器拦截连接上的第一个读取并用HTTP / 1.1替换ICY。不是超级健壮,但证明了这个概念:

package main

import (
    "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)
}