MCPcopy
hub / github.com/perkeep/perkeep / ServeFile

Method ServeFile

pkg/server/download.go:300–378  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request, file blob.Ref)

Source from the content-addressed store, hash-verified

298}
299
300func (dh *DownloadHandler) ServeFile(w http.ResponseWriter, r *http.Request, file blob.Ref) {
301 ctx := r.Context()
302 if r.Method != "GET" && r.Method != "HEAD" {
303 http.Error(w, "Invalid download method", http.StatusBadRequest)
304 return
305 }
306
307 if r.Header.Get("If-Modified-Since") != "" {
308 // Immutable, so any copy's a good copy.
309 w.WriteHeader(http.StatusNotModified)
310 return
311 }
312
313 dh.r = r
314 fi, packed, err := dh.fileInfo(ctx, file)
315 if err != nil {
316 http.Error(w, "Can't serve file: "+err.Error(), http.StatusInternalServerError)
317 return
318 }
319 if !fi.mode.IsRegular() {
320 http.Error(w, "Not a regular file", http.StatusBadRequest)
321 return
322 }
323 defer fi.close()
324
325 h := w.Header()
326 h.Set("Content-Length", fmt.Sprint(fi.size))
327 h.Set("Expires", time.Now().UTC().Add(oneYear).Format(http.TimeFormat))
328 if packed {
329 h.Set("X-Camlistore-Packed", "1")
330 }
331
332 fileName := func(ext string) string {
333 if fi.name != "" {
334 return fi.name
335 }
336 return "file-" + file.String() + ext
337 }
338
339 if r.FormValue("inline") == "1" || dh.forceInline {
340 // TODO(mpl): investigate why at least text files have an incorrect MIME.
341 if fi.mime == "application/octet-stream" {
342 // Since e.g. plain text files are seen as "application/octet-stream", we force
343 // check for that, so we can have the browser display them as text if they are
344 // indeed actually text.
345 text, err := isText(fi.rs)
346 if err != nil {
347 // TODO: https://perkeep.org/issues/1060
348 httputil.ServeError(w, r, fmt.Errorf("cannot verify MIME type of file: %v", err))
349 return
350 }
351 if text {
352 fi.mime = "text/plain"
353 }
354 }
355 h.Set("Content-Disposition", "inline")
356 } else {
357 w.Header().Set("Content-Disposition", "attachment; filename="+fileName(".dat"))

Callers 4

handleGetViaSharingMethod · 0.95
ServeHTTPMethod · 0.95
serveFileDownloadMethod · 0.95
serveFileFunction · 0.80

Calls 13

fileInfoMethod · 0.95
ServeErrorFunction · 0.92
ParseFunction · 0.92
isTextFunction · 0.85
ContextMethod · 0.80
GetMethod · 0.65
SetMethod · 0.65
HashMethod · 0.65
ErrorMethod · 0.45
WriteHeaderMethod · 0.45
AddMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected