MCPcopy
hub / github.com/cortesi/devd / serveContent

Function serveContent

fileserver/fileserver.go:96–159  ·  view source on GitHub ↗

if name is empty, filename is unknown. (used for mime type, before sniffing) if modtime.IsZero(), modtime is unknown. content must be seeked to the beginning of the file. The sizeFunc is called at most once. Its error, if any, is sent in the HTTP response.

(ci inject.CopyInject, w http.ResponseWriter, r *http.Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker)

Source from the content-addressed store, hash-verified

94// content must be seeked to the beginning of the file.
95// The sizeFunc is called at most once. Its error, if any, is sent in the HTTP response.
96func serveContent(ci inject.CopyInject, w http.ResponseWriter, r *http.Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) error {
97 if checkLastModified(w, r, modtime) {
98 return nil
99 }
100 done := checkETag(w, r)
101 if done {
102 return nil
103 }
104
105 code := http.StatusOK
106
107 // If Content-Type isn't set, use the file's extension to find it, but
108 // if the Content-Type is unset explicitly, do not sniff the type.
109 ctypes, haveType := w.Header()["Content-Type"]
110 var ctype string
111 if !haveType {
112 ctype = mime.TypeByExtension(filepath.Ext(name))
113 if ctype == "" {
114 // read a chunk to decide between utf-8 text and binary
115 var buf [sniffLen]byte
116 n, _ := io.ReadFull(content, buf[:])
117 ctype = http.DetectContentType(buf[:n])
118 _, err := content.Seek(0, os.SEEK_SET) // rewind to output whole file
119 if err != nil {
120 http.Error(w, "seeker can't seek", http.StatusInternalServerError)
121 return err
122 }
123 }
124 w.Header().Set("Content-Type", ctype)
125 } else if len(ctypes) > 0 {
126 ctype = ctypes[0]
127 }
128
129 injector, err := ci.Sniff(content, ctype)
130 if err != nil {
131 http.Error(w, err.Error(), http.StatusInternalServerError)
132 return err
133 }
134
135 size, err := sizeFunc()
136 if err != nil {
137 http.Error(w, err.Error(), http.StatusInternalServerError)
138 return err
139 }
140
141 if injector.Found() {
142 size = size + int64(injector.Extra())
143 }
144
145 if size >= 0 {
146 if w.Header().Get("Content-Encoding") == "" {
147 w.Header().Set("Content-Length", strconv.FormatInt(size, 10))
148 }
149 }
150
151 w.WriteHeader(code)
152 if r.Method != "HEAD" {
153 _, err := injector.Copy(w)

Callers 3

ServeContentFunction · 0.85
serveNotFoundFileMethod · 0.85
serveFileMethod · 0.85

Calls 8

checkLastModifiedFunction · 0.85
checkETagFunction · 0.85
HeaderMethod · 0.80
SniffMethod · 0.80
WriteHeaderMethod · 0.80
FoundMethod · 0.65
ExtraMethod · 0.65
CopyMethod · 0.65

Tested by 1

ServeContentFunction · 0.68