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