Shoutcast servers basically speak http, with one important difference: they respond to GET requests with ICY 200 OK instead of HTTP/1.1 200 OK.
Go won't have a bar of it, and correctly fails with the error malformed HTTP version "ICY".
However I would like to make things work and am wondering what the best approach is. My ideas so far:
ICY to HTTP/1.1 in-flighthttp.ParseHTTPVersion (but golang doesn't have function overloading)ParseHTTPVersion
Number 1. seems the most attractive attractive, but I have no idea how to respect the http "scope" and actually modify all responses on a given http version. Is this the kind of thing http.Transport.Proxy can handle?
Can anyone give me any pointers?
I got this working by creating a custom Dial function that returns a wrapped connection. My wrapper intercepts the first read on the connection and replaces ICY with HTTP/1.1. Not super robust, but proves the concept:
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)
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With