webdav: fix mixed property statuses in multi-status responses
This PR fixes a bug in the WebDAV backend where directories or files could randomly "disappear" from listings due to strict and fragile multi-status code parsing. Co-authored-by: bright <nako_ruru@sina.com>
This commit is contained in:
@@ -98,21 +98,19 @@ func (p *Prop) Code() int {
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatusOK examines the Status and returns an OK flag
|
// Parse a status of the form "HTTP/1.1 2xx"
|
||||||
|
var parseStatus2XX = regexp.MustCompile(`^HTTP/[\d.]+\s+2\d{2}`)
|
||||||
|
|
||||||
|
// StatusOK returns true if there is at least one 2XX response.
|
||||||
func (p *Prop) StatusOK() bool {
|
func (p *Prop) StatusOK() bool {
|
||||||
// Fetch status code as int
|
|
||||||
c := p.Code()
|
|
||||||
|
|
||||||
// Assume OK if no statuses received
|
// Assume OK if no statuses received
|
||||||
if c == -1 {
|
if len(p.Status) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if c == 0 {
|
for _, statusStr := range p.Status {
|
||||||
return false
|
if parseStatus2XX.MatchString(statusStr) {
|
||||||
}
|
return true
|
||||||
if c >= 200 && c < 300 {
|
}
|
||||||
return true
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPropStatusOK(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
status []string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"Empty status", []string{}, true},
|
||||||
|
{"Single 200 OK", []string{"HTTP/1.1 200 OK"}, true},
|
||||||
|
{"Single 404 Not Found", []string{"HTTP/1.1 404 Not Found"}, false},
|
||||||
|
{"Mixed status with 404 first", []string{"HTTP/1.1 404 Not Found", "HTTP/1.1 200 OK"}, true},
|
||||||
|
{"Mixed status with 200 first", []string{"HTTP/1.1 200 OK", "HTTP/1.1 404 Not Found"}, true},
|
||||||
|
{"Multiple non-2xx statuses", []string{"HTTP/1.1 404 Not Found", "HTTP/1.1 403 Forbidden"}, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
p := &Prop{Status: tt.status}
|
||||||
|
if got := p.StatusOK(); got != tt.want {
|
||||||
|
t.Errorf("Prop.StatusOK() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user