mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-21 01:45:45 +03:00
browse: Fix known bugs (#770)
* browse: Catch the case of a directory disappearing before having been read * browse: Revert to old pass-through behaviour PROPFIND is a request for an alternate view on a directory's contents, which response is indeed not implemented but ideally allowed to ask for. OPTIONS would ideally return (at least) what methods the requestor could use, which is an allowed request method, too. This addresses #767.
This commit is contained in:
parent
924b53eb3c
commit
2f2d357fb6
2 changed files with 23 additions and 20 deletions
|
@ -234,12 +234,11 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
for i := range b.Configs {
|
for i := range b.Configs {
|
||||||
if middleware.Path(r.URL.Path).Matches(b.Configs[i].PathScope) {
|
if middleware.Path(r.URL.Path).Matches(b.Configs[i].PathScope) {
|
||||||
bc = &b.Configs[i]
|
bc = &b.Configs[i]
|
||||||
break
|
goto inScope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bc == nil {
|
return b.Next.ServeHTTP(w, r)
|
||||||
return b.Next.ServeHTTP(w, r)
|
inScope:
|
||||||
}
|
|
||||||
|
|
||||||
// Browse works on existing directories; delegate everything else
|
// Browse works on existing directories; delegate everything else
|
||||||
requestedFilepath := filepath.Join(b.Root, r.URL.Path)
|
requestedFilepath := filepath.Join(b.Root, r.URL.Path)
|
||||||
|
@ -261,8 +260,11 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Do not reply to anything else because it might be nonsensical
|
// Do not reply to anything else because it might be nonsensical
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case http.MethodGet, http.MethodHead:
|
case http.MethodGet, http.MethodHead:
|
||||||
|
// proceed, noop
|
||||||
|
case "PROPFIND", http.MethodOptions:
|
||||||
|
return http.StatusNotImplemented, nil
|
||||||
default:
|
default:
|
||||||
return http.StatusMethodNotAllowed, nil
|
return b.Next.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Browsing navigation gets messed up if browsing a directory
|
// Browsing navigation gets messed up if browsing a directory
|
||||||
|
@ -275,19 +277,27 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Load directory contents
|
// Load directory contents
|
||||||
file, err := os.Open(requestedFilepath)
|
file, err := os.Open(requestedFilepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsPermission(err) {
|
switch {
|
||||||
|
case os.IsPermission(err):
|
||||||
return http.StatusForbidden, err
|
return http.StatusForbidden, err
|
||||||
|
case os.IsExist(err):
|
||||||
|
return http.StatusGone, err
|
||||||
|
default:
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
files, err := file.Readdir(-1)
|
files, err := file.Readdir(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsPermission(err) {
|
switch {
|
||||||
|
case os.IsPermission(err):
|
||||||
return http.StatusForbidden, err
|
return http.StatusForbidden, err
|
||||||
|
case os.IsExist(err):
|
||||||
|
return http.StatusGone, err
|
||||||
|
default:
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if user can browse up another folder
|
// Determine if user can browse up another folder
|
||||||
|
@ -302,7 +312,7 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Assemble listing of directory contents
|
// Assemble listing of directory contents
|
||||||
listing, err := directoryListing(files, r, canGoUp, b.Root, b.IgnoreIndexes, bc.Variables)
|
listing, err := directoryListing(files, r, canGoUp, b.Root, b.IgnoreIndexes, bc.Variables)
|
||||||
if err != nil { // directory isn't browsable
|
if err != nil { // directory isn't browsable
|
||||||
return http.StatusInternalServerError, err
|
return b.Next.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the query values into the Listing struct
|
// Copy the query values into the Listing struct
|
||||||
|
|
|
@ -112,8 +112,7 @@ func TestBrowseHTTPMethods(t *testing.T) {
|
||||||
|
|
||||||
b := Browse{
|
b := Browse{
|
||||||
Next: middleware.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) {
|
Next: middleware.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
t.Fatalf("Next shouldn't be called")
|
return http.StatusTeapot, nil // not t.Fatalf, or we will not see what other methods yield
|
||||||
return 0, nil
|
|
||||||
}),
|
}),
|
||||||
Root: "./testdata",
|
Root: "./testdata",
|
||||||
Configs: []Config{
|
Configs: []Config{
|
||||||
|
@ -128,14 +127,8 @@ func TestBrowseHTTPMethods(t *testing.T) {
|
||||||
for method, expected := range map[string]int{
|
for method, expected := range map[string]int{
|
||||||
http.MethodGet: http.StatusOK,
|
http.MethodGet: http.StatusOK,
|
||||||
http.MethodHead: http.StatusOK,
|
http.MethodHead: http.StatusOK,
|
||||||
http.MethodOptions: http.StatusMethodNotAllowed,
|
http.MethodOptions: http.StatusNotImplemented,
|
||||||
http.MethodPost: http.StatusMethodNotAllowed,
|
"PROPFIND": http.StatusNotImplemented,
|
||||||
http.MethodPut: http.StatusMethodNotAllowed,
|
|
||||||
http.MethodPatch: http.StatusMethodNotAllowed,
|
|
||||||
http.MethodDelete: http.StatusMethodNotAllowed,
|
|
||||||
"COPY": http.StatusMethodNotAllowed,
|
|
||||||
"MOVE": http.StatusMethodNotAllowed,
|
|
||||||
"MKCOL": http.StatusMethodNotAllowed,
|
|
||||||
} {
|
} {
|
||||||
req, err := http.NewRequest(method, "/photos/", nil)
|
req, err := http.NewRequest(method, "/photos/", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue