github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/runtime/handler/build.go (about) 1 package handler 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 8 pb "github.com/tickoalcantara12/micro/v3/proto/runtime" 9 "github.com/tickoalcantara12/micro/v3/service/auth" 10 "github.com/tickoalcantara12/micro/v3/service/errors" 11 "github.com/tickoalcantara12/micro/v3/service/store" 12 ) 13 14 const bufferSize = 1024 15 16 // Build implements the proto build service interface 17 type Build struct{} 18 19 func (b *Build) Read(ctx context.Context, req *pb.Service, stream pb.Build_ReadStream) error { 20 defer stream.Close() 21 22 // authorize the request 23 acc, ok := auth.AccountFromContext(ctx) 24 if !ok { 25 return errors.Unauthorized("runtime.Build.Read", "An account is required to read builds") 26 } 27 28 // validate the request 29 if len(req.Name) == 0 { 30 return errors.BadRequest("runtime.Build.Read", "Missing name") 31 } 32 if len(req.Version) == 0 { 33 return errors.BadRequest("runtime.Build.Read", "Missing version") 34 } 35 36 // lookup the build from the blob store 37 key := fmt.Sprintf("build://%v:%v", req.Name, req.Version) 38 build, err := store.DefaultBlobStore.Read(key, store.BlobNamespace(acc.Issuer)) 39 if err == store.ErrNotFound { 40 return errors.NotFound("runtime.Build.Read", "Build not found") 41 } else if err != nil { 42 return err 43 } 44 45 // read bytes from the store and stream it to the client 46 buffer := make([]byte, bufferSize) 47 for { 48 num, err := build.Read(buffer) 49 if err == io.EOF { 50 return nil 51 } else if err != nil { 52 return errors.InternalServerError("runtime.Build.Read", "Error reading build from store: %v", err) 53 } 54 55 if err := stream.Send(&pb.BuildReadResponse{Data: buffer[:num]}); err != nil { 56 return err 57 } 58 } 59 }