Commit 2f2d357f authored by W. Mark Kubacki's avatar W. Mark Kubacki Committed by Matt Holt

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.
parent 924b53eb
......@@ -234,12 +234,11 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
for i := range b.Configs {
if middleware.Path(r.URL.Path).Matches(b.Configs[i].PathScope) {
bc = &b.Configs[i]
break
goto inScope
}
}
if bc == nil {
return b.Next.ServeHTTP(w, r)
}
inScope:
// Browse works on existing directories; delegate everything else
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
switch r.Method {
case http.MethodGet, http.MethodHead:
// proceed, noop
case "PROPFIND", http.MethodOptions:
return http.StatusNotImplemented, nil
default:
return http.StatusMethodNotAllowed, nil
return b.Next.ServeHTTP(w, r)
}
// Browsing navigation gets messed up if browsing a directory
......@@ -275,20 +277,28 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
// Load directory contents
file, err := os.Open(requestedFilepath)
if err != nil {
if os.IsPermission(err) {
switch {
case os.IsPermission(err):
return http.StatusForbidden, err
}
case os.IsExist(err):
return http.StatusGone, err
default:
return http.StatusInternalServerError, err
}
}
defer file.Close()
files, err := file.Readdir(-1)
if err != nil {
if os.IsPermission(err) {
switch {
case os.IsPermission(err):
return http.StatusForbidden, err
}
case os.IsExist(err):
return http.StatusGone, err
default:
return http.StatusInternalServerError, err
}
}
// Determine if user can browse up another folder
var canGoUp bool
......@@ -302,7 +312,7 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
// Assemble listing of directory contents
listing, err := directoryListing(files, r, canGoUp, b.Root, b.IgnoreIndexes, bc.Variables)
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
......
......@@ -112,8 +112,7 @@ func TestBrowseHTTPMethods(t *testing.T) {
b := Browse{
Next: middleware.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) {
t.Fatalf("Next shouldn't be called")
return 0, nil
return http.StatusTeapot, nil // not t.Fatalf, or we will not see what other methods yield
}),
Root: "./testdata",
Configs: []Config{
......@@ -128,14 +127,8 @@ func TestBrowseHTTPMethods(t *testing.T) {
for method, expected := range map[string]int{
http.MethodGet: http.StatusOK,
http.MethodHead: http.StatusOK,
http.MethodOptions: http.StatusMethodNotAllowed,
http.MethodPost: http.StatusMethodNotAllowed,
http.MethodPut: http.StatusMethodNotAllowed,
http.MethodPatch: http.StatusMethodNotAllowed,
http.MethodDelete: http.StatusMethodNotAllowed,
"COPY": http.StatusMethodNotAllowed,
"MOVE": http.StatusMethodNotAllowed,
"MKCOL": http.StatusMethodNotAllowed,
http.MethodOptions: http.StatusNotImplemented,
"PROPFIND": http.StatusNotImplemented,
} {
req, err := http.NewRequest(method, "/photos/", nil)
if err != nil {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment