Skip to content

Commit

Permalink
refactor: single dav && index list prefixs
Browse files Browse the repository at this point in the history
Signed-off-by: 117503445 <[email protected]>
  • Loading branch information
117503445 committed Feb 17, 2024
1 parent 40d2e0b commit 7c8ac95
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 57 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,23 @@ require (
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rs/zerolog v1.32.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/studio-b12/gowebdav v0.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
Expand Down
38 changes: 37 additions & 1 deletion internal/server/server.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package server

import (
"context"
"net/http"
"os"
"strings"

"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -106,7 +108,38 @@ func NewWebDAVServer(addr string, handlerConfigs []*HandlerConfig) *WebDAVServer
handlers[cfg.Prefix] = h
}

enableSingleDavMode := false
var singleHandler *Handler
if len(handlers) == 1 {
for _, h := range handlers {
if h.prefix == "/" {
log.Debug().Msg("Enable SingleDavMode")

enableSingleDavMode = true
singleHandler = h
break
}
}
}

// create a webdav.Handler for listing all available prefixes
memFileSystem := webdav.NewMemFS()
for _, cfg := range handlerConfigs {
memFileSystem.Mkdir(context.TODO(), cfg.Prefix, os.ModeDir)
}
indexHandler := &webdav.Handler{
FileSystem: memFileSystem,
LockSystem: webdav.NewMemLS(),
Prefix: "/",
}

sMux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
log.Debug().Str("URL", req.URL.Path).Str("Method", req.Method).Msg("Request")
if enableSingleDavMode {
singleHandler.ServeHTTP(w, req)
return
}

url := req.URL.Path
for prefix, handler := range handlers {
if !strings.HasPrefix(url, prefix) {
Expand All @@ -116,7 +149,10 @@ func NewWebDAVServer(addr string, handlerConfigs []*HandlerConfig) *WebDAVServer
return
}

// TODO: list all available prefixes
if req.Method == "PROPFIND" && url == "/" {
indexHandler.ServeHTTP(w, req)
return
}
})
return &WebDAVServer{
addr: addr,
Expand Down
168 changes: 112 additions & 56 deletions tests/dav_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"time"

"GoWebDAV/internal/server"
// "github.com/rs/zerolog/log"
"github.com/stretchr/testify/assert"
"github.com/studio-b12/gowebdav"
)

Expand All @@ -20,33 +20,92 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}

const ADDR = "localhost:8081"
var file1Name = "1.txt"
var file1Content = []byte("file1")

func TestPublicWrite(t *testing.T) {
dirData := "./data/public-writeable"
os.Mkdir(dirData, 0755)
var file2Name = "2.txt"
var file2Content = []byte("file2")

func untilConnected(assert *assert.Assertions, client *gowebdav.Client) {
maxTries := 10
for {
err := client.Connect()
if err == nil {
break
}
time.Sleep(100 * time.Millisecond)
maxTries--
if maxTries == 0 {
assert.FailNow("", "Failed to connect to the server")
}
}
}

func TestDAV(t *testing.T) {
var err error
// Create a directory for the server
// readOnlyAPITest tests the following:
// 1. Read the file
// 2. Read the directory
// before test, the client should be connected to the server and one file should be created
func readOnlyAPITest(assert *assert.Assertions, client *gowebdav.Client) {
downloadContent, err := client.Read("/1.txt")
assert.Nil(err)

if string(downloadContent) != string(file1Content) {
assert.FailNow("Failed to download the file")
}

files, err := client.ReadDir("/")
assert.Nil(err)
if len(files) != 1 {
assert.FailNowf("files number not equal to 1", "len(files) != 1, got %d", len(files))
}
}

// apiTest tests the following:
// 1. Create a directory
// 2. Write a file to the directory
// 3. Read the directory
// 4. Read the file
// 5. Remove the file
// before test, the client should be connected to the server and one file should be created
func apiTest(assert *assert.Assertions, client *gowebdav.Client) {
readOnlyAPITest(assert, client)

assert.Nil(client.Mkdir("/dir", os.ModePerm))
client.Write("/dir/"+file2Name, file2Content, 0644)

files, err := client.ReadDir("/dir")
assert.Nil(err)
if len(files) != 1 {
assert.FailNowf("files number not equal to 1", "len(files) != 1, got %d", len(files))
}

downloadContent, err := client.Read("/dir/2.txt")
assert.Nil(err)
if string(downloadContent) != string(file2Content) {
assert.FailNow("Failed to download the file")
}

assert.Nil(client.Remove("/dir/2.txt"))

files, err = client.ReadDir("/dir")
assert.Nil(err)
if len(files) != 0 {
assert.FailNowf("files number not equal to 0", "len(files) != 0, got %d", len(files))
}
}

func TestMultiDav(t *testing.T) {
const ADDR = "localhost:8081"
assert := assert.New(t)

dirPublicWriteable := "./data/public-writeable"
dirPublicReadonly := "./data/public-readonly"
dirAuthWriteable := "./data/auth-writeable"

file1Name := "1.txt"
file1Content := []byte("file1")

dirs := []string{dirPublicWriteable, dirPublicReadonly, dirAuthWriteable}
for _, dir := range dirs {
if err = os.Mkdir(dir, 0755); err != nil {
t.Fatal(err)
}

if err = os.WriteFile(dir+"/"+file1Name, file1Content, 0644); err != nil {
t.Fatal(err)
}
assert.Nil(os.Mkdir(dir, 0755))
assert.Nil(os.WriteFile(dir+"/"+file1Name, file1Content, 0644))
}

server := server.NewWebDAVServer(ADDR, []*server.HandlerConfig{
Expand Down Expand Up @@ -78,49 +137,46 @@ func TestDAV(t *testing.T) {
publicReadonlyClient := gowebdav.NewClient("http://"+ADDR+"/public-readonly", "", "")
authWriteableClient := gowebdav.NewClient("http://"+ADDR+"/auth-writeable", "user", "pass")

untilConnected := func(t *testing.T, client *gowebdav.Client) {
maxTries := 10
for {
err := client.Connect()
if err == nil {
break
}
time.Sleep(100 * time.Millisecond)
maxTries--
if maxTries == 0 {
t.Fatal("Failed to connect to the server")
}
}
untilConnected(assert, publicWriteableClient)
untilConnected(assert, publicReadonlyClient)
untilConnected(assert, authWriteableClient)

apiTest(assert, publicWriteableClient)
readOnlyAPITest(assert, publicReadonlyClient)
apiTest(assert, authWriteableClient)

indexClient := gowebdav.NewClient("http://"+ADDR+"/", "", "")
untilConnected(assert, indexClient)

files, err := indexClient.ReadDir("/")
assert.Nil(err)
if len(files) != 3 {
assert.FailNowf("files number not equal to 3", "len(files) != 3, got %d", len(files))
}
}

untilConnected(t, publicWriteableClient)
untilConnected(t, publicReadonlyClient)
untilConnected(t, authWriteableClient)
func TestSingleDav(t *testing.T) {
const ADDR = "localhost:8082"
assert := assert.New(t)

readOnlyAPITest := func(t *testing.T, client *gowebdav.Client) {
downloadContent, err := client.Read("/1.txt")
if err != nil {
t.Fatal(err)
}
if string(downloadContent) != string(file1Content) {
t.Fatal("Failed to download the file")
}
dir := "./data/single-dav"
os.Mkdir(dir, 0755)

files, err := client.ReadDir("/")
if err != nil {
t.Fatal(err)
}
if len(files) != 1 {
t.Fatal("len(files) != 1, got", len(files))
}
assert.Nil(os.WriteFile(dir+"/"+file1Name, file1Content, 0644))

}
server := server.NewWebDAVServer(ADDR, []*server.HandlerConfig{
{
Prefix: "/",
PathDir: dir,
Username: "",
Password: "",
ReadOnly: false,
},
})
go server.Run()

apiTest := func(t *testing.T, client *gowebdav.Client) {
readOnlyAPITest(t, client)
}
client := gowebdav.NewClient("http://"+ADDR+"/", "", "")
untilConnected(assert, client)

apiTest(t, publicWriteableClient)
readOnlyAPITest(t, publicReadonlyClient)
apiTest(t, authWriteableClient)
apiTest(assert, client)
}

0 comments on commit 7c8ac95

Please sign in to comment.