Internet of Things: Wifi Radio
Update: This setup stopped working after a few firmware updates; there were apparently some software updates after the catalog of internet radio stations broke down. Maybe they also read my bug report about the broken encoding and found my blog post. I didn’t investigate much; superficially it looked like the radio is just ignoring the returned IP address if it’s a local one.
Have you ever wondered what your Internet-connected devices are doing behind your back?
My internet radio had some problems with displaying special characters in the list of radio stations. When I checked the network traffic on Wireshark, I found that the protocol for connecting back was unencrypted, so I made it talk through a proxy which modifies the responses on the fly to fix up wrong character encoding in the server responses.
Basic setup:
- The router giving out DHCP leases makes clients talk to its own local DNS service.
- The DNS service rewires the hostname for the radio API to the local Raspberry Pi’s IP
- The Raspberry Pi acts as a reverse HTTP proxy for the actual domain and modifies requests along the way.
Reverse proxies are simple to write in Go: use
httputil.NewSingleHostReverseProxy
and then set the ReverseProxy.ModifyResponse
property on the
returned object to an appropriate modification function such as:
func Modify(resp *http.Response) error {
b, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return err
}
b = ModifyBody(b) // Actual replacements done here.
resp.Body = ioutil.NopCloser(bytes.NewReader(b))
resp.ContentLength = int64(len(b))
resp.Header.Set("Content-Length", strconv.Itoa(len(b)))
return nil
}
In my implementation, I’m replacing some wrongly encoded characters with correct ones in the server response, and for demo purposes and some silly entertainment, I’m changing the German word for Switzerland to “Swizzle”: