proxy_worker.mx raw
1 package wire
2
3 import (
4 "git.smesh.lol/morly/pkg/mediaproxy"
5 )
6
7 // ProxyWorker is the spawn target for a media proxy domain. Receives
8 // ProxyRequest over its spawn channel, fetches the URL, and replies with a
9 // ProxyResponse. Loops until the request channel closes.
10 func ProxyWorker(in chan ProxyRequest, out chan ProxyResponse) {
11 for {
12 req, ok := <-in
13 if !ok {
14 return
15 }
16 out <- proxyFetch(req)
17 }
18 }
19
20 // proxyFetch performs one media fetch and maps the result onto the wire form.
21 // A free function: its scratch arena dies at return, so a long-lived worker
22 // does not accumulate one fetch's working set per request.
23 func proxyFetch(req ProxyRequest) (resp ProxyResponse) {
24 resp = ProxyResponse{ReqID: req.ReqID}
25 maxBytes := int64(req.MaxBytes)
26 if maxBytes <= 0 {
27 maxBytes = 32 * 1024 * 1024
28 }
29 status, upstream, body, err := mediaproxy.Fetch(string(req.URL), maxBytes)
30 if err != nil {
31 resp.Status = -1
32 resp.Err = []byte(err.Error())
33 return resp
34 }
35 resp.Status = int32(status)
36 if status >= 200 && status < 300 {
37 ct := upstream["content-type"]
38 if !proxyAllowedCT(ct) {
39 resp.Status = 415
40 return resp
41 }
42 resp.ContentType = []byte(ct)
43 resp.Body = body
44 }
45 return resp
46 }
47
48 // proxyAllowedCT restricts proxied responses to image/video/octet-stream.
49 func proxyAllowedCT(ct string) (ok bool) {
50 if len(ct) >= 6 && (ct[:6] == "image/" || ct[:6] == "video/") {
51 return true
52 }
53 return ct == "application/octet-stream" || ct == "application/octet-stream; charset=utf-8"
54 }
55