-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhandler.go
More file actions
75 lines (59 loc) · 1.67 KB
/
handler.go
File metadata and controls
75 lines (59 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package icyproxy
import (
"fmt"
"html/template"
"io"
"net/http"
"net/url"
"strconv"
)
func makeRequestHandler(s Source) (http.Handler, error) {
u, err := url.Parse(s.URL)
if err != nil {
return nil, fmt.Errorf("error parsing URL: %w", err)
}
metadataJsonUrl, err := url.Parse(s.MetadataJsonURL)
if err != nil {
return nil, fmt.Errorf("error parsing metadata JSON URL: %w", err)
}
metadataTmpl, err := template.New("").Parse(s.MetadataFormat)
if err != nil {
return nil, fmt.Errorf("error parsing metadata format: %w", err)
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
upstreamRequest := http.Request{
Method: http.MethodGet,
URL: u,
}
res, err := http.DefaultClient.Do(&upstreamRequest)
if err != nil {
http.Error(w, "error contacting upstream", http.StatusBadGateway)
return
}
defer res.Body.Close()
for k, v := range res.Header {
w.Header()[k] = v
}
wantIcy := r.Header.Get("Icy-Metadata") == "1"
canIcy := res.Header.Get("icy-metaint") != ""
var source io.Reader = res.Body
if wantIcy && !canIcy {
w.Header().Add("icy-metaint", strconv.Itoa(IcyReaderInterval))
reader := &IcyReader{AudioData: res.Body}
StartMetadataFetcher(r.Context(), reader, metadataJsonUrl, metadataTmpl)
source = reader
}
io.Copy(w, source)
}), nil
}
func MakeHandler(sources map[string]Source) (http.Handler, error) {
res := http.NewServeMux()
for sourceId, source := range sources {
sourceHandler, err := makeRequestHandler(source)
if err != nil {
return nil, fmt.Errorf("error setting up handler for source %s: %w", sourceId, err)
}
res.Handle("GET /"+sourceId, sourceHandler)
}
return res, nil
}