MCPcopy
hub / github.com/perkeep/perkeep / ServeBlobRef

Function ServeBlobRef

pkg/blobserver/gethandler/get.go:63–120  ·  view source on GitHub ↗

ServeBlobRef serves a blob.

(rw http.ResponseWriter, req *http.Request, blobRef blob.Ref, fetcher blob.Fetcher)

Source from the content-addressed store, hash-verified

61
62// ServeBlobRef serves a blob.
63func ServeBlobRef(rw http.ResponseWriter, req *http.Request, blobRef blob.Ref, fetcher blob.Fetcher) {
64 ctx := req.Context()
65 if fetcher == nil {
66 log.Printf("gethandler: no fetcher configured for %s (ref=%v)", req.URL.Path, blobRef)
67 rw.WriteHeader(http.StatusNotFound)
68 io.WriteString(rw, "no fetcher configured")
69 return
70 }
71 rc, size, err := fetcher.Fetch(ctx, blobRef)
72 switch err {
73 case nil:
74 break
75 case os.ErrNotExist:
76 rw.WriteHeader(http.StatusNotFound)
77 fmt.Fprintf(rw, "Blob %q not found", blobRef)
78 return
79 default:
80 httputil.ServeError(rw, req, err)
81 return
82 }
83 defer rc.Close()
84 rw.Header().Set("Content-Type", "application/octet-stream")
85 rw.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d, immutable", int(HTTP_CACHE_DURATION.Seconds())))
86
87 var content = readerutil.NewFakeSeeker(rc, int64(size))
88 rangeHeader := req.Header.Get("Range") != ""
89 const small = 32 << 10
90 var b *blob.Blob
91 if rangeHeader || size < small {
92 // Slurp to memory, so we can actually seek on it (for Range support),
93 // or if we're going to be showing it in the browser (below).
94 b, err = blob.FromReader(ctx, blobRef, rc, size)
95 if err != nil {
96 httputil.ServeError(rw, req, err)
97 return
98 }
99 content, err = b.ReadAll(ctx)
100 if err != nil {
101 httputil.ServeError(rw, req, err)
102 return
103 }
104 }
105 if !rangeHeader && size < small {
106 // If it's small and all UTF-8, assume it's text and
107 // just render it in the browser. This is more for
108 // demos/debuggability than anything else. It isn't
109 // part of the spec.
110 isUTF8, err := b.IsUTF8(ctx)
111 if err != nil {
112 httputil.ServeError(rw, req, err)
113 return
114 }
115 if isUTF8 {
116 rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
117 }
118 }
119 http.ServeContent(rw, req, "", dummyModTime, content)
120}

Callers 4

handleGetViaSharingMethod · 0.92
TestServeBlobRef_RangeFunction · 0.85
testServeBlobRefFunction · 0.85
ServeHTTPMethod · 0.85

Calls 11

ReadAllMethod · 0.95
IsUTF8Method · 0.95
ServeErrorFunction · 0.92
FromReaderFunction · 0.92
ContextMethod · 0.80
PrintfMethod · 0.80
FetchMethod · 0.65
CloseMethod · 0.65
SetMethod · 0.65
GetMethod · 0.65
WriteHeaderMethod · 0.45

Tested by 2

TestServeBlobRef_RangeFunction · 0.68
testServeBlobRefFunction · 0.68