> **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](https://www.heise.de/newsticker/meldung/Massenhafter-Ausfall-von-Internetradios-4417248.html).
>
> 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.
{.info}

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](https://www.unix-ag.uni-kl.de/~guenther/tcpdump-fun.html),
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.

![](/images/diagram600.png)

Reverse proxies are simple to write in Go: use
[`httputil.NewSingleHostReverseProxy`](https://golang.org/pkg/net/http/httputil/#NewSingleHostReverseProxy)
and then set the `ReverseProxy.ModifyResponse` property on the
returned object to an appropriate modification function such as:

``` go
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":

![](/images/radio600.png)
