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) { ...@@ -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) { ...@@ -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,20 +277,28 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { ...@@ -275,20 +277,28 @@ 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
var canGoUp bool var canGoUp bool
...@@ -302,7 +312,7 @@ func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { ...@@ -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) { ...@@ -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) { ...@@ -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 {
......
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