2015-11-02 115 views
4

Shoutcast服务器基本上讲http,有一个重要区别:他们回应GET请求与ICY 200 OK而不是HTTP/1.1 200 OK制作http客户端与非标准http服务器工作

Go将不会有一个栏,并正确地失败,错误malformed HTTP version "ICY"

但是我想让事情有效并且想知道最好的方法是什么。我的想法而已:

  1. 使用自定义http.Transport.Proxy改变ICYHTTP/1.1飞行
  2. 的进程外代理,做同样的事情
  3. 超载http.ParseHTTPVersion(但golang没有按”吨有函数重载)
  4. 复制整个HTTP包,只需修改ParseHTTPVersion

号码1.似乎是最有吸引力的attractiv e,但我不知道如何尊重http范围,并实际修改给定http版本上的所有响应。这是http.Transport.Proxy可以处理的那种东西吗?

任何人都可以给我任何指针?

+1

谁的想法是偏离规范在这样一个基本的方式?这似乎是一个糟糕的主意。你有没有考虑分出net/http包并使其不那么严格? – captncraig

+4

这是错的。 Icecast不会这样回复。这是一个HTTP 1.0兼容的服务器。另一方面,Shoutcast正在被推迟,而不是HTTP服务器。 – TBR

+1

@ captncraig 1997是一个更简单的时间...并不是说它找不到它。 – Brad

回答

3

我通过创建一个自定义拨号函数返回一个包装连接来得到这个工作。我的包装拦截了连接上的第一次读取,并用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) 
} 
+0

我建议指出一个较低的HTTP协议版本。我似乎记得Shoutcast是HTTP 0.9的变种。这样或者1.0可以避免客户端的问题。 – TBR

+0

可能是一个好主意,但我怀疑符合1.0的应答对1.1客户端会有什么不可比拟的。如果它实际上是1.0兼容是另一个问题。 – captncraig

+0

这对连接重用不起作用,但是这让我不知所措,我在开玩笑,我可能会在生产多年之前开始正确实施icecast。谢谢! –

相关问题