2015-11-02 45 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。謝謝! –

相關問題