MCPcopy
hub / github.com/caddyserver/caddy / ServeHTTP

Method ServeHTTP

modules/caddyhttp/fileserver/staticfiles.go:269–596  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler)

Source from the content-addressed store, hash-verified

267}
268
269func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
270 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
271
272 if runtime.GOOS == "windows" {
273 // reject paths with Alternate Data Streams (ADS)
274 if strings.Contains(r.URL.Path, ":") {
275 return caddyhttp.Error(http.StatusBadRequest, fmt.Errorf("illegal ADS path"))
276 }
277 // reject paths with "8.3" short names
278 trimmedPath := strings.TrimRight(r.URL.Path, ". ") // Windows ignores trailing dots and spaces, sigh
279 if len(path.Base(trimmedPath)) <= 12 && strings.Contains(trimmedPath, "~") {
280 return caddyhttp.Error(http.StatusBadRequest, fmt.Errorf("illegal short name"))
281 }
282 // both of those could bypass file hiding or possibly leak information even if the file is not hidden
283 }
284
285 filesToHide := fsrv.transformHidePaths(repl)
286
287 root := repl.ReplaceAll(fsrv.Root, ".")
288 fsName := repl.ReplaceAll(fsrv.FileSystem, "")
289
290 fileSystem, ok := fsrv.fsmap.Get(fsName)
291 if !ok {
292 return caddyhttp.Error(http.StatusNotFound, fmt.Errorf("filesystem not found"))
293 }
294
295 // remove any trailing `/` as it breaks fs.ValidPath() in the stdlib
296 filename := strings.TrimSuffix(caddyhttp.SanitizedPathJoin(root, r.URL.Path), "/")
297
298 if c := fsrv.logger.Check(zapcore.DebugLevel, "sanitized path join"); c != nil {
299 c.Write(
300 zap.String("site_root", root),
301 zap.String("fs", fsName),
302 zap.String("request_path", r.URL.Path),
303 zap.String("result", filename),
304 )
305 }
306
307 // get information about the file
308 info, err := fs.Stat(fileSystem, filename)
309 if err != nil {
310 err = fsrv.mapDirOpenError(fileSystem, err, filename)
311 if errors.Is(err, fs.ErrNotExist) {
312 return fsrv.notFound(w, r, next)
313 } else if errors.Is(err, fs.ErrInvalid) {
314 return caddyhttp.Error(http.StatusBadRequest, err)
315 } else if errors.Is(err, fs.ErrPermission) {
316 return caddyhttp.Error(http.StatusForbidden, err)
317 }
318 return caddyhttp.Error(http.StatusInternalServerError, err)
319 }
320
321 // if the request mapped to a directory, see if
322 // there is an index file we can serve
323 var implicitIndexFile bool
324 if info.IsDir() && len(fsrv.IndexNames) > 0 {
325 for _, indexPage := range fsrv.IndexNames {
326 indexPage := repl.ReplaceAll(indexPage, "")

Callers 1

check_validator_headersFunction · 0.95

Calls 15

transformHidePathsMethod · 0.95
mapDirOpenErrorMethod · 0.95
notFoundMethod · 0.95
serveBrowseMethod · 0.95
openFileMethod · 0.95
getEtagFromFileMethod · 0.95
ErrorFunction · 0.92
SanitizedPathJoinFunction · 0.92
AcceptedEncodingsFunction · 0.92
fileHiddenFunction · 0.85
redirectFunction · 0.85
calculateEtagFunction · 0.85

Tested by 1

check_validator_headersFunction · 0.76