package wire import ( "git.smesh.lol/morly/pkg/mediaproxy" ) // ProxyWorker is the spawn target for a media proxy domain. Receives // ProxyRequest over its spawn channel, fetches the URL, and replies with a // ProxyResponse. Loops until the request channel closes. func ProxyWorker(in chan ProxyRequest, out chan ProxyResponse) { for { req, ok := <-in if !ok { return } out <- proxyFetch(req) } } // proxyFetch performs one media fetch and maps the result onto the wire form. // A free function: its scratch arena dies at return, so a long-lived worker // does not accumulate one fetch's working set per request. func proxyFetch(req ProxyRequest) (resp ProxyResponse) { resp = ProxyResponse{ReqID: req.ReqID} maxBytes := int64(req.MaxBytes) if maxBytes <= 0 { maxBytes = 32 * 1024 * 1024 } status, upstream, body, err := mediaproxy.Fetch(string(req.URL), maxBytes) if err != nil { resp.Status = -1 resp.Err = []byte(err.Error()) return resp } resp.Status = int32(status) if status >= 200 && status < 300 { ct := upstream["content-type"] if !proxyAllowedCT(ct) { resp.Status = 415 return resp } resp.ContentType = []byte(ct) resp.Body = body } return resp } // proxyAllowedCT restricts proxied responses to image/video/octet-stream. func proxyAllowedCT(ct string) (ok bool) { if len(ct) >= 6 && (ct[:6] == "image/" || ct[:6] == "video/") { return true } return ct == "application/octet-stream" || ct == "application/octet-stream; charset=utf-8" }