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