blossom_worker.mx raw

   1  package wire
   2  
   3  import (
   4  	"fmt"
   5  
   6  	"smesh.lol/pkg/blossom"
   7  )
   8  
   9  // BlossomWorker is the spawn target for the blossom blob-storage domain.
  10  // Reads BlossomRequest, performs file I/O, writes BlossomResponse. Loops
  11  // forever. Dir is carried in each request so the worker can lazily init.
  12  func BlossomWorker(in chan BlossomRequest, out chan BlossomResponse) {
  13  	var srv *blossom.Server
  14  	var srvDir string
  15  	for {
  16  		req, ok := <-in
  17  		if !ok {
  18  			return
  19  		}
  20  		dir := string(req.Dir)
  21  		if srv == nil || dir != srvDir {
  22  			var err error
  23  			srv, err = blossom.New(dir)
  24  			if err != nil {
  25  				out <- BlossomResponse{
  26  					ReqID:  req.ReqID,
  27  					Status: 500,
  28  					Body:   []byte(fmt.Sprintf("blossom init: %v", err)),
  29  				}
  30  				continue
  31  			}
  32  			srvDir = dir
  33  		}
  34  		headers := map[string]string{"content-type": string(req.ContentType)}
  35  		status, respHeaders, body := srv.HandleRawWithUpstream(string(req.Method), string(req.Path), headers, req.Body, string(req.Upstream))
  36  		resp := BlossomResponse{ReqID: req.ReqID, Status: int32(status)}
  37  		if ct, ok := respHeaders["Content-Type"]; ok {
  38  			resp.CT = []byte(ct)
  39  		}
  40  		if string(req.Method) == "HEAD" {
  41  			if cl, ok := respHeaders["Content-Length"]; ok {
  42  				n := int64(0)
  43  				for i := 0; i < len(cl); i++ {
  44  					c := cl[i]
  45  					if c >= '0' && c <= '9' {
  46  						n = n*10 + int64(c-'0')
  47  					}
  48  				}
  49  				resp.Size = n
  50  			}
  51  		}
  52  		resp.Body = body
  53  		out <- resp
  54  	}
  55  }
  56