diff options
| -rw-r--r-- | caddytest/integration/caddyfile_adapt/file_server_status.txt | 112 | ||||
| -rw-r--r-- | modules/caddyhttp/fileserver/caddyfile.go | 12 | ||||
| -rw-r--r-- | modules/caddyhttp/fileserver/staticfiles.go | 16 | 
3 files changed, 140 insertions, 0 deletions
diff --git a/caddytest/integration/caddyfile_adapt/file_server_status.txt b/caddytest/integration/caddyfile_adapt/file_server_status.txt new file mode 100644 index 0000000..ede1f4a --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/file_server_status.txt @@ -0,0 +1,112 @@ +localhost + +root * /srv + +handle /nope* { +	file_server { +		status 403 +	} +} + +handle /custom-status* { +	file_server { +		status {env.CUSTOM_STATUS} +	} +} +---------- +{ +	"apps": { +		"http": { +			"servers": { +				"srv0": { +					"listen": [ +						":443" +					], +					"routes": [ +						{ +							"match": [ +								{ +									"host": [ +										"localhost" +									] +								} +							], +							"handle": [ +								{ +									"handler": "subroute", +									"routes": [ +										{ +											"handle": [ +												{ +													"handler": "vars", +													"root": "/srv" +												} +											] +										}, +										{ +											"group": "group2", +											"handle": [ +												{ +													"handler": "subroute", +													"routes": [ +														{ +															"handle": [ +																{ +																	"handler": "file_server", +																	"hide": [ +																		"./Caddyfile" +																	], +																	"status_code": "{env.CUSTOM_STATUS}" +																} +															] +														} +													] +												} +											], +											"match": [ +												{ +													"path": [ +														"/custom-status*" +													] +												} +											] +										}, +										{ +											"group": "group2", +											"handle": [ +												{ +													"handler": "subroute", +													"routes": [ +														{ +															"handle": [ +																{ +																	"handler": "file_server", +																	"hide": [ +																		"./Caddyfile" +																	], +																	"status_code": 403 +																} +															] +														} +													] +												} +											], +											"match": [ +												{ +													"path": [ +														"/nope*" +													] +												} +											] +										} +									] +								} +							], +							"terminal": true +						} +					] +				} +			} +		} +	} +}
\ No newline at end of file diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go index 2ba53f2..447f481 100644 --- a/modules/caddyhttp/fileserver/caddyfile.go +++ b/modules/caddyhttp/fileserver/caddyfile.go @@ -40,6 +40,7 @@ func init() {  //        index         <files...>  //        browse        [<template_file>]  //        precompressed <formats...> +//        status        <status>  //    }  //  func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { @@ -65,21 +66,25 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)  				if len(fsrv.Hide) == 0 {  					return nil, h.ArgErr()  				} +  			case "index":  				fsrv.IndexNames = h.RemainingArgs()  				if len(fsrv.IndexNames) == 0 {  					return nil, h.ArgErr()  				} +  			case "root":  				if !h.Args(&fsrv.Root) {  					return nil, h.ArgErr()  				} +  			case "browse":  				if fsrv.Browse != nil {  					return nil, h.Err("browsing is already configured")  				}  				fsrv.Browse = new(Browse)  				h.Args(&fsrv.Browse.TemplateFile) +  			case "precompressed":  				var order []string  				for h.NextArg() { @@ -100,6 +105,13 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)  					order = append(order, h.Val())  				}  				fsrv.PrecompressedOrder = order + +			case "status": +				if !h.NextArg() { +					return nil, h.ArgErr() +				} +				fsrv.StatusCode = caddyhttp.WeakString(h.Val()) +  			default:  				return nil, h.Errf("unknown subdirective '%s'", h.Val())  			} diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index c670788..660e1d1 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -75,6 +75,12 @@ type FileServer struct {  	// remove trailing slash from URIs for files. Default is true.  	CanonicalURIs *bool `json:"canonical_uris,omitempty"` +	// Override the status code written when successfully serving a file. +	// Particularly useful when explicitly serving a file as display for +	// an error, like a 404 page. A placeholder may be used. By default, +	// the status code will typically be 200, or 206 for partial content. +	StatusCode caddyhttp.WeakString `json:"status_code,omitempty"` +  	// If pass-thru mode is enabled and a requested file is not found,  	// it will invoke the next handler in the chain instead of returning  	// a 404 error. By default, this is false (disabled). @@ -345,6 +351,16 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c  		return nil  	} +	// if a status code override is configured, write the status code +	// before serving the file +	if codeStr := fsrv.StatusCode.String(); codeStr != "" { +		intVal, err := strconv.Atoi(repl.ReplaceAll(codeStr, "")) +		if err != nil { +			return caddyhttp.Error(http.StatusInternalServerError, err) +		} +		w.WriteHeader(intVal) +	} +  	// let the standard library do what it does best; note, however,  	// that errors generated by ServeContent are written immediately  	// to the response, so we cannot handle them (but errors there  | 
