github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/builder/builder-next/reqbodyhandler.go (about) 1 package buildkit 2 3 import ( 4 "io" 5 "net/http" 6 "strings" 7 "sync" 8 9 "github.com/moby/buildkit/identity" 10 "github.com/pkg/errors" 11 ) 12 13 const urlPrefix = "build-context-" 14 15 type reqBodyHandler struct { 16 mu sync.Mutex 17 rt http.RoundTripper 18 19 requests map[string]io.ReadCloser 20 } 21 22 func newReqBodyHandler(rt http.RoundTripper) *reqBodyHandler { 23 return &reqBodyHandler{ 24 rt: rt, 25 requests: map[string]io.ReadCloser{}, 26 } 27 } 28 29 func (h *reqBodyHandler) newRequest(rc io.ReadCloser) (string, func()) { 30 id := identity.NewID() 31 h.mu.Lock() 32 h.requests[id] = rc 33 h.mu.Unlock() 34 return "http://" + urlPrefix + id, func() { 35 h.mu.Lock() 36 delete(h.requests, id) 37 h.mu.Unlock() 38 rc.Close() 39 } 40 } 41 42 func (h *reqBodyHandler) RoundTrip(req *http.Request) (*http.Response, error) { 43 host := req.URL.Host 44 if strings.HasPrefix(host, urlPrefix) { 45 if req.Method != http.MethodGet { 46 return nil, errors.Errorf("invalid request") 47 } 48 id := strings.TrimPrefix(host, urlPrefix) 49 h.mu.Lock() 50 rc, ok := h.requests[id] 51 delete(h.requests, id) 52 h.mu.Unlock() 53 54 if !ok { 55 return nil, errors.Errorf("context not found") 56 } 57 58 resp := &http.Response{ 59 Status: "200 OK", 60 StatusCode: http.StatusOK, 61 Body: rc, 62 ContentLength: -1, 63 } 64 65 return resp, nil 66 } 67 return h.rt.RoundTrip(req) 68 }