Giter Site home page Giter Site logo

webdav's Introduction

⚠️ Disclaimer: this repository is not actively maintained. If you are interested in maintaining it, please contact me.

webdav

Build Go Report Card Version Docker Pulls

Install

Please refer to the Releases page for more information. There, you can either download the binaries or find the Docker commands to install WebDAV.

Usage

webdav command line interface is really easy to use so you can easily create a WebDAV server for your own user. By default, it runs on a random free port and supports JSON, YAML and TOML configuration. An example of a YAML configuration with the default configurations:

# Server related settings
address: 0.0.0.0
port: 0
auth: true
tls: false
cert: cert.pem
key: key.pem
prefix: /
debug: false

# Default user settings (will be merged)
scope: .
modify: true
rules: []

# CORS configuration
cors:
  enabled: true
  credentials: true
  allowed_headers:
    - Depth
  allowed_hosts:
    - http://localhost:8080
  allowed_methods:
    - GET
  exposed_headers:
    - Content-Length
    - Content-Range

users:
  - username: admin
    password: admin
    scope: /a/different/path
  - username: encrypted
    password: "{bcrypt}$2y$10$zEP6oofmXFeHaeMfBNLnP.DO8m.H.Mwhd24/TOX2MWLxAExXi4qgi"
  - username: "{env}ENV_USERNAME"
    password: "{env}ENV_PASSWORD"
  - username: basic
    password: basic
    modify:   false
    rules:
      - regex: false
        allow: false
        path: /some/file
      - path: /public/access/
        modify: true

There are more ways to customize how you run WebDAV through flags and environment variables. Please run webdav --help for more information on that.

Systemd

An example of how to use this with systemd is on webdav.service.example.

CORS

The allowed_* properties are optional, the default value for each of them will be *. exposed_headers is optional as well, but is not set if not defined. Setting credentials to true will allow you to:

  1. Use withCredentials = true in javascript.
  2. Use the username:password@host syntax.

Reverse Proxy Service

When you use a reverse proxy implementation like Nginx or Apache, please note the following fields to avoid causing 502 errors

location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

License

MIT © Henrique Dias

webdav's People

Contributors

acez avatar c35sys avatar fzoske avatar greatbody avatar hacdias avatar hormones avatar icidasset avatar lustyn avatar marcio199226 avatar mfrister avatar mikitsu avatar mohammed90 avatar pataquets avatar sartoshi-foot-dao avatar scusi avatar shunf4 avatar sxueck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webdav's Issues

Docker image: webdav exited with code 255

Hi,

I use the docker image and whenever I restart the host, the webdav container does not come up ans the logs only show webdav exited with code 255.

If I then start it manually using docker-compose up -d, it starts an everything is fine.

Is there a debug option or some kind of verbosioity settinng to figure out whats going wrong?

Option for no password

It would be nice to have an option for no passwords, to create unauthenicated read only users for instance.

IPv6 address is broken in log

Version: V4.1.0

Notice the IP address in the line 2021/07/02 09:48:11 [:guest cache will be clean.

Listening on [::1]:8888
2021/07/02 09:44:14 [::1]:36418 tried to verify account , username is [guest]
2021/07/02 09:48:11 [:guest cache will be clean

Listening on 127.0.0.1:8888
2021/07/02 09:51:29 127.0.0.1:58364 tried to verify account , username is [guest]
2021/07/02 09:53:32 127.0.0.1:guest cache will be clean

Tutorial needed.

I need a tutorial to show me the meaning of every parameters. Is there one?

Feature Request: Allow recognition of a subpath prefix

We could allow recognition and correct handling of a subpath prefix (like "/dav/") to adapt to situations such as working behind a reverse proxy dispatching query to different services by URL path prefix.

A simple modification to make it work is submitted in #31.

Questions of the config yml

  1. I run the server on Windows cmd and it print the connect info, could a log file be set to record both the connect info and operation like FileZilla Server? And other configs like connect or cache timeout are able to be setup?

  2. Found that the CRUD can take effect whether "modify" is set true or false. So how to limit users to only read, and a root only read while a subdir can write?

  3. Now I have to config a user for each path, can a user's scope contains several paths?

  4. Found a dir can't be listed entirety when there is a system dir not able to access, maybe it can be skipped rather than get the program admin right

doesn't work on Windows 10 if scope is set to Disk root e.g. D:/

works if set to subdirectories, but fails when set to disk root.

[Window Title]
Open Folder

[Content]
\\127.0.0.1@8086\DavWWWRoot is not acccessible. You might not have permission to use this network resource. Contact the administrator of this server .

Parameter Error


[Confirm]
scope: d:/
address: 0.0.0.0
port: 8086
tls: false
cert: cert.pem
key: key.pem
users:
  - username: admin
    password: admin

iOS can not connect my webdav service?

Thanks for your code first.

After deploy this service on my personal cloud server, I use finder on MacBookPro to connect.
Url is : http://mydomain.com
Everything seems ok.

But, my iPhone can not connect.
i'v tried these url:

http://mydomain.com ----> error shows: do not support this url type

mydomin.com ----> can not connect. errors shows: domain name or ip error.

mydomain.com/one_dir_in_the_root_path ----> jump to the basic auth page, and ask for my account.
after input my account and click next button, it shows only one Directory with name of "one_dir_in_the_root_path",
and the dir is readonly. I enter the dir, but found nothing files and dirs...

why...... wait for your help! thanks.

`users` property in JSON config file is not recognized

webdav claims to support JSON, YAML and TOML configuration file. But JSON support is not working as advertised. It has a weird bug.

The webdav I am using is built from tag v4.0.0.

  1. Put the following configuration into a file named config.json.
{
    "address": "0.0.0.0",
    "port": 8888,
    "auth": true,
    "scope": ".",
    "users": [
        {
            "password": "password",
            "username": "username"
        }
    ]
}
  1. Run webdav -c config.json.
  2. Try to log in from a client. The authorization will fail.
shell> http -a username:password OPTIONS localhost:8888
HTTP/1.1 401 Unauthorized
Content-Length: 15
Content-Type: text/plain; charset=utf-8
Date: Thu, 01 Jul 2021 10:11:35 GMT
Www-Authenticate: Basic realm="Restricted"
X-Content-Type-Options: nosniff

Not authorized
  1. Change the config file's name from config.json to config.yaml, then run webdav -c config.yaml.
  2. Try to log in from a client. This time the authorization will succeed.
shell> http -a username:password OPTIONS localhost:8888
HTTP/1.1 200 OK
Allow: OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND
Content-Length: 0
Date: Thu, 01 Jul 2021 10:13:24 GMT
Dav: 1, 2
Ms-Author-Via: DAV
Www-Authenticate: Basic realm="Restricted"

So users property in config.json is not recognized by webdav. But it's recognized when the config file name has the .yaml suffix.

Low speed

How improve DL/UL speed? It's limit on ~10 Mbps.

BUG in use by nplayer

The latest version will have one more directory in nplayer, and it can't be modified or deleted. The previous version will not be like this.

release for linux-mipsle

Would you add MIPS (mipsle) arch to release too ?
Many popular Router/NAS device is running a mipsle CPU (eg MT7620).

Thanks alot.

The beginning of the ~$

The beginning of the ~$
winscp has error text: XML parse error at line 1: junk after document element

The ~$ is a temporary file when Word/Excel is edited

CORS Preflight 401 Status

Thanks for this great CLI!

I stumbled upon one issue though:
The preflight request for the CORS request I'm making requires authorization.
The W3C spec states that a OPTIONS request should never require authorization.
So I can't connect through my web application in Chrome.

Docker Image not Working

Okay, so this is a multifaceted issue, and not limited to just the Docker image. The Docker image is how I found it.

Simple go build doesn't work because of the presence of the webdav/ directory while the module name is also webdav. The go build command will complain with go build: build output "webdav" already exists and is a directory. The go build command can be fooled into proceeding with the build by issuing go build -o webdav main.go, at which it'll (hilariously) create the binary inside the webdav directory as such webdav/command-line-arguments. Yes, the binary name is command-line-arguments. This wasn't an issue before c5f3907 because back then the main package was within a directory named webdav, so there was no name conflict.

Now Docker... the Dockerfile. So the Dockerfile copies the webdav to /webdav, which we now know is a directory and not a binary.

COPY webdav /webdav

Then it tries to execute it:

ENTRYPOINT [ "/webdav" ]

which causes Docker to log standard_init_linux.go:211: exec user process caused "no such file or directory". That's because it's trying to execute a directory.

Per-user paths

Would it be possible to add support so each user has their own path, without specifying each user?
E.g. with a config like this:

webdav {
    scope /users/$user
}

It'd get the user name from the auth module.

That way, if authenticated as the user "bob", it'd let him get a different path than say the user "alice".

Crash when scope is settings to root directory on mac and linux

Hi & Happy New Year...
Thanks for this great project...
The server doesn't working when scope is set to any of roots directories
I tested it on macOS Catalina and Arch Linux...

because of accessing all partitions and disks i needed to set scope to /Volumes/ on Catalina but server doesn't work , even i tried it on Arch Linux and Manjaro ( settings to /mnt/ or / ) but when scope was set to root directories it doesn't work at all , but work in sub-directories...
Thanks again

crash at high concurrency

Env: Synology DS918+
System: DSM7.0
Binary: https://github.com/hacdias/webdav/releases/download/v4.1.0/linux-386-webdav.tar.gz
command: nohup ./webdav &

Use webdav as backend cloud storage for Joplin(a open source diary), when sync many files it frequently crash.

Bellow is stack info:
2021/08/12 10:40:20 192.168.0.146:53906 tried to verify account , username is [XXXX]
fatal error: concurrent map writes
fatal error: concurrent map writes

goroutine 35 [running]:
runtime.throw(0x84c3094, 0x15)
runtime/panic.go:1116 +0x6a fp=0xa4b1c34 sp=0xa4b1c20 pc=0x807723a
runtime.mapassign_faststr(0x845ea80, 0xa49aa60, 0xa49c4a0, 0x1d, 0x87a6e60)
runtime/map_faststr.go:291 +0x358 fp=0xa4b1c70 sp=0xa4b1c34 pc=0x8057b18
github.com/hacdias/webdav/v3/lib.(*Config).ServeHTTP(0xa580ec0, 0x855a640, 0xa4e8140, 0xa4da380)
github.com/hacdias/webdav/v3/lib/webdav.go:103 +0x3c3 fp=0xa4b1d90 sp=0xa4b1c70 pc=0x82fe963
net/http.serverHandler.ServeHTTP(0xa5ae750, 0x855a640, 0xa4e8140, 0xa4da380)
net/http/server.go:2843 +0x7f fp=0xa4b1da4 sp=0xa4b1d90 pc=0x82a9ccf
net/http.(*conn).serve(0xa5de060, 0x855af20, 0xa49b740)
net/http/server.go:1925 +0x7b8 fp=0xa4b1fe0 sp=0xa4b1da4 pc=0x82a64d8
runtime.goexit()
runtime/asm_386.s:1333 +0x1 fp=0xa4b1fe4 sp=0xa4b1fe0 pc=0x80a50d1
created by net/http.(*Server).Serve
net/http/server.go:2969 +0x2b9

goroutine 1 [chan receive]:
main.main()
command-line-arguments/main.go:26 +0x104

goroutine 18 [select]:
github.com/hacdias/webdav/v3/lib.LastRequestLogIndex(0x855af20, 0xa49b220)
github.com/hacdias/webdav/v3/lib/log.go:17 +0x2a4
created by main.main
command-line-arguments/main.go:20 +0x5d

goroutine 19 [IO wait]:
internal/poll.runtime_pollWait(0xe7441f28, 0x72, 0x0)
runtime/netpoll.go:222 +0x4b
internal/poll.(*pollDesc).wait(0xa5c20b4, 0x72, 0x0, 0x0, 0x84bce69)
internal/poll/fd_poll_runtime.go:87 +0x37
internal/poll.(*pollDesc).waitRead(...)
internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xa5c20a0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
internal/poll/fd_unix.go:394 +0x1ae
net.(*netFD).accept(0xa5c20a0, 0x0, 0x87a6e60, 0xa5a8238)
net/fd_unix.go:172 +0x27
net.(*TCPListener).accept(0xa5b6230, 0xa5de100, 0x148a1400, 0x8080cfd)
net/tcpsock_posix.go:139 +0x27
net.(*TCPListener).Accept(0xa5b6230, 0xa46de1c, 0xc, 0xa4829a0, 0x82aa099)
net/tcpsock.go:261 +0x57
net/http.(*Server).Serve(0xa5ae750, 0x855a500, 0xa5b6230, 0x0, 0x0)
net/http/server.go:2937 +0x1eb
net/http.Serve(...)
net/http/server.go:2498
github.com/hacdias/webdav/v3/cmd.glob..func1(0x87a2520, 0x87bb674, 0x0, 0x0)
github.com/hacdias/webdav/v3/cmd/root.go:80 +0x33f
github.com/spf13/cobra.(*Command).execute(0x87a2520, 0xa496118, 0x0, 0x0, 0x87a2520, 0xa496118)
github.com/spf13/[email protected]/command.go:856 +0x1e0
github.com/spf13/cobra.(*Command).ExecuteC(0x87a2520, 0x0, 0x0, 0x0)
github.com/spf13/[email protected]/command.go:960 +0x297
github.com/spf13/cobra.(*Command).Execute(...)
github.com/spf13/[email protected]/command.go:897
github.com/hacdias/webdav/v3/cmd.Execute()
github.com/hacdias/webdav/v3/cmd/cmd.go:9 +0x23
created by main.main
command-line-arguments/main.go:21 +0x73

goroutine 33 [syscall]:
os/signal.signal_recv(0x0)
runtime/sigqueue.go:147 +0x12f
os/signal.loop()
os/signal/signal_unix.go:23 +0x1a
created by os/signal.Notify.func1.1
os/signal/signal.go:150 +0x33

goroutine 34 [IO wait]:
internal/poll.runtime_pollWait(0xe7441e90, 0x77, 0xffffffff)
runtime/netpoll.go:222 +0x4b
internal/poll.(*pollDesc).wait(0xa5c2104, 0x77, 0x0, 0xed06d, 0xffffffff)
internal/poll/fd_poll_runtime.go:87 +0x37
internal/poll.(*pollDesc).waitWrite(...)
internal/poll/fd_poll_runtime.go:96
internal/poll.SendFile(0xa5c20f0, 0x8, 0xed06d, 0x0, 0x0, 0x0, 0x0, 0x0)
internal/poll/sendfile_linux.go:42 +0x228
net.sendFile.func1(0x8, 0x72)
net/sendfile_linux.go:42 +0x46
internal/poll.(*FD).RawRead(0xa4b9280, 0xa49b700, 0x0, 0x0)
internal/poll/fd_unix.go:530 +0xbf
os.(*rawConn).Read(0xa497040, 0xa49b700, 0x837dd096, 0x0)
os/rawconn.go:31 +0x49
net.sendFile(0xa5c20f0, 0x8556380, 0xa496918, 0x0, 0x0, 0x0, 0x0, 0x100)
net/sendfile_linux.go:41 +0x13e
net.(*TCPConn).readFrom(0xa5845a8, 0x8556380, 0xa4a8380, 0x8000106, 0x0, 0xffffffff, 0x82a06b0)
net/tcpsock_posix.go:51 +0x72
net.(*TCPConn).ReadFrom(0xa5845a8, 0x8556380, 0xa4a8380, 0xc, 0xa4fc1cc, 0x87bb601, 0x0)
net/tcpsock.go:103 +0x3f
net/http.(*response).ReadFrom(0xa4e80a0, 0x8556380, 0xa4a8380, 0x0, 0x0, 0x0, 0x0)
net/http/server.go:615 +0x23d
io.copyBuffer(0x8556700, 0xa4e80a0, 0x8556380, 0xa4a8380, 0x0, 0x0, 0x0, 0x8050f99, 0x8469c80, 0x84ab020, ...)
io/io.go:395 +0x298
io.Copy(...)
io/io.go:368
io.CopyN(0x8556700, 0xa4e80a0, 0x85567e0, 0xa496918, 0xff0e5, 0x0, 0x0, 0x0, 0x0, 0x0)
io/io.go:344 +0x8e
net/http.serveContent(0x855a640, 0xa4e80a0, 0xa4da280, 0xa494145, 0x2a, 0x8c38f95, 0x0, 0xd8a5eea9, 0xe, 0x87a6e60, ...)
net/http/fs.go:300 +0x23f
net/http.ServeContent(0x855a640, 0xa4e80a0, 0xa4da280, 0xa494145, 0x2a, 0x8c38f95, 0x0, 0xd8a5eea9, 0xe, 0x87a6e60, ...)
net/http/fs.go:167 +0x98
golang.org/x/net/webdav.(*Handler).handleGetHeadPost(0xa582340, 0x855a640, 0xa4e80a0, 0xa4da280, 0xc8, 0x0, 0x0)
golang.org/x/[email protected]/webdav/webdav.go:219 +0x360
golang.org/x/net/webdav.(*Handler).ServeHTTP(0xa582340, 0x855a640, 0xa4e80a0, 0xa4da280)
golang.org/x/[email protected]/webdav/webdav.go:53 +0x94
github.com/hacdias/webdav/v3/lib.(*Config).ServeHTTP(0xa580ec0, 0x855a640, 0xa4e80a0, 0xa4da280)
github.com/hacdias/webdav/v3/lib/webdav.go:159 +0x61e
net/http.serverHandler.ServeHTTP(0xa5ae750, 0x855a640, 0xa4e80a0, 0xa4da280)
net/http/server.go:2843 +0x7f
net/http.(*conn).serve(0xa5de000, 0x855af20, 0xa49b280)
net/http/server.go:1925 +0x7b8
created by net/http.(*Server).Serve
net/http/server.go:2969 +0x2b9

goroutine 21 [IO wait]:
internal/poll.runtime_pollWait(0xe7441e90, 0x72, 0x85573c0)
runtime/netpoll.go:222 +0x4b
internal/poll.(*pollDesc).wait(0xa5c2104, 0x72, 0x8557300, 0x87621ac, 0x0)
internal/poll/fd_poll_runtime.go:87 +0x37
internal/poll.(*pollDesc).waitRead(...)
internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xa5c20f0, 0xa49b2ad, 0x1, 0x1, 0x0, 0x0, 0x0)
internal/poll/fd_unix.go:159 +0x170
net.(*netFD).Read(0xa5c20f0, 0xa49b2ad, 0x1, 0x1, 0x0, 0x0, 0x0)
net/fd_posix.go:55 +0x3f
net.(*conn).Read(0xa5845a8, 0xa49b2ad, 0x1, 0x1, 0x0, 0x0, 0x0)
net/net.go:182 +0x67
net/http.(*connReader).backgroundRead(0xa49b2a0)
net/http/server.go:690 +0x46
created by net/http.(*connReader).startBackgroundRead
net/http/server.go:686 +0xb0

goroutine 36 [running]:
goroutine running on other thread; stack unavailable
created by net/http.(*Server).Serve
net/http/server.go:2969 +0x2b9

goroutine 22 [runnable]:
net/http.(*connReader).backgroundRead(0xa49b760)
net/http/server.go:689
created by net/http.(*connReader).startBackgroundRead
net/http/server.go:686 +0xb0

goroutine 37 [runnable]:
net/http.(*connReader).backgroundRead(0xa5825a0)
net/http/server.go:689
created by net/http.(*connReader).startBackgroundRead
net/http/server.go:686 +0xb0

goroutine 36 [running]:
runtime.throw(0x84c3094, 0x15)
runtime/panic.go:1116 +0x6a fp=0xa5e6c34 sp=0xa5e6c20 pc=0x807723a
runtime.mapassign_faststr(0x845ea80, 0xa49aa60, 0xa5ac680, 0x1d, 0x87a6e60)
runtime/map_faststr.go:291 +0x358 fp=0xa5e6c70 sp=0xa5e6c34 pc=0x8057b18
github.com/hacdias/webdav/v3/lib.(*Config).ServeHTTP(0xa580ec0, 0x855a640, 0xa5ec000, 0xa5c6080)
github.com/hacdias/webdav/v3/lib/webdav.go:103 +0x3c3 fp=0xa5e6d90 sp=0xa5e6c70 pc=0x82fe963
net/http.serverHandler.ServeHTTP(0xa5ae750, 0x855a640, 0xa5ec000, 0xa5c6080)
net/http/server.go:2843 +0x7f fp=0xa5e6da4 sp=0xa5e6d90 pc=0x82a9ccf
net/http.(*conn).serve(0xa5de0c0, 0x855af20, 0xa582580)
net/http/server.go:1925 +0x7b8 fp=0xa5e6fe0 sp=0xa5e6da4 pc=0x82a64d8
runtime.goexit()
runtime/asm_386.s:1333 +0x1 fp=0xa5e6fe4 sp=0xa5e6fe0 pc=0x80a50d1
created by net/http.(*Server).Serve
net/http/server.go:2969 +0x2b9

Filename truncated after semicolon

I am not sure if the bug is in caddy-webdav or in this lib, but it seems that a filename with a semicolon (;) in it gets truncated at the semicolon (the semicolon is also elided) when listing files. Have you encountered this before or is it just me? 😅

Make official Docker Hub image build from source

Docker Hub allows you to create Automated Builds from source: https://docs.docker.com/docker-hub/builds/
It also allows to create different image tags from git tags & branches.
By making the image build via an AB, you give the resulting image verifiability and auditability. Also, the build is fully automatic. You can have the latest image tag build from HEAD and individual image tags from git's release tags.
Some people avoid non-verifiable (manually uploaded) images due to security & traceability reasons.

Docker search command clearly displays AB:

$ docker search hacdias
NAME                        DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
hacdias/webdav                                                              0                                       
hacdias/caddy-plugin-test                                                   0                                       
hacdias/co20                                                                0                                       
marvambass/webdav           my forked and dockerized version of github.c…   0                                       [OK]
gifteryaa/filemanager       https://github.com/hacdias/filemanager          0                                       
svlentink/filebrowser       The 'official' is not an automated build and…   0                                       [OK]

Create/Edit/Delete as separate permissions

Hello,

I have just found out about Caddy-webdav, and I am enthusiastic about it. We already have it running on some servers with excellent results.

Right now permissions can be set to access and/or change a resource.

I was wondering if it could be possible to add independent permissions? Like:

  • create only
  • change only
  • delete only

Currently we do use combinations of those permissions on some webdav shares, through NextCloud (see screenshot).

webdav-access-options

We do not need all the infrastructure NextCloud offers, and the additional complex toolchain that imposes.

It would be fantastic if Caddy-webdav could completely replace NextCloud's role as webdav server .

Thank you for making Caddy-webdav available, it is a wonderful addition to Caddy.

Blocking open files for other users.

It is very important to block open files for other user's sessions. The SMB protocol works in a similar way. The WebDAV protocol also supports a mechanism for blocking open files. Is it possible to implement file locks or configure this lock via the config file?

How to use custom config.yaml with webdav in windows10 .

I'm a new user. I run webdav in windows 10 cmd shell. the config.yaml is copyed from README.MD. in the same directory.
How could I run with my custom config.yaml ?
I tried eg:
d:\webdav\webdav -c config.yaml is same return error msg: "the environment variable is empty"
d:\webdav\webdav -c . the webdav is run but not use my config.yaml and can't login.

where could found the example ?

How to use it?

What is the default user password for this release?
Config.yml is configured under . / or / etc / WebDAV /, but it will be prompted that environment variable is not set and cannot run

https support

Https support

Thanks for great work, works like a charm!
Is that possible to add https support?

sharing whole partition

hello,

i am on windows. when i share the whole partition like this:
webdav /webdav/c/ { scope c:\ modify true }
i get httpcode 401
but when i stop caddy, change the scope to a directory
webdav /webdav/c/ { scope c:\caddy\ modify true }
and restart it, everything works smoothly. this is same for different drive letters.
whats your take on this?

missing libraries linux arm64 binary?

using the 3.0 image, I get "standard_init_linux.go:207: exec user process caused "no such file or directory". I can replicate this in alpine:

$ docker run --rm -ti alpine:latest sh
/ # uname -a
Linux dfa14c4c248a 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 Linux
/ # curl -L https://github.com/hacdias/webdav/releases/download/v3.0.0/linux-386-webdav.tar.gz | tar xzvf -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   613    0   613    0     0   3368      0 --:--:-- --:--:-- --:--:--  3368
LICENSE
README.md
webdav
100 3766k  100 3766k    0     0  1421k      0  0:00:02  0:00:02 --:--:-- 1867k.
/ # ./webdav
Listening on [::]:35261
^C
/ # curl -L https://github.com/hacdias/webdav/releases/download/v3.0.0/linux-amd64-webdav.tar.gz | tar xzvf -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615    0   615    0     0   2971      0 --:--:-- --:--:-- --:--:--  2971
LICENSE
README.md
webdav
100 3971k  100 3971k    0     0  6109k      0 --:--:-- --:--:-- --:--:-- 25.8M
/ # ./webdav
sh: ./webdav: not found

I can not replicate this issue using e.g. ubuntu:latest. Is there a library missing from the amd64 binary?

fatal error: concurrent map writes

fatal error: concurrent map writes

goroutine 3482 [running]:
runtime.throw(0x4dc12b, 0x15)
	runtime/panic.go:1116 +0x54 fp=0x4000068940 sp=0x4000068910 pc=0x411d4
runtime.mapassign_faststr(0x45e2e0, 0x400001edb0, 0x40000242a0, 0x12, 0x4000192201)
	runtime/map_faststr.go:211 +0x3c4 fp=0x40000689b0 sp=0x4000068940 pc=0x222d4
github.com/hacdias/webdav/v3/lib.(*Config).ServeHTTP(0x40001a4100, 0x57e3c0, 0x40000c6000, 0x40000fe000)
	github.com/hacdias/webdav/v3/lib/webdav.go:103 +0x388 fp=0x4000068be0 sp=0x40000689b0 pc=0x2d4c48
net/http.serverHandler.ServeHTTP(0x40001de000, 0x57e3c0, 0x40000c6000, 0x40000fe000)
	net/http/server.go:2843 +0xbc fp=0x4000068c10 sp=0x4000068be0 pc=0x279d8c
net/http.(*conn).serve(0x40004041e0, 0x57f800, 0x40001a8040)
	net/http/server.go:1925 +0x6f4 fp=0x4000068fc0 sp=0x4000068c10 pc=0x276074
runtime.goexit()
	runtime/asm_arm64.s:1136 +0x4 fp=0x4000068fc0 sp=0x4000068fc0 pc=0x72874
created by net/http.(*Server).Serve
	net/http/server.go:2969 +0x2e8

goroutine 1 [chan receive, 2544 minutes]:
main.main()
	command-line-arguments/main.go:26 +0x114

goroutine 6 [select]:
github.com/hacdias/webdav/v3/lib.LastRequestLogIndex(0x57f800, 0x4000104480)
	github.com/hacdias/webdav/v3/lib/log.go:17 +0x204
created by main.main
	command-line-arguments/main.go:20 +0x70

goroutine 7 [IO wait]:
internal/poll.runtime_pollWait(0x7f6220be88, 0x72, 0x0)
	runtime/netpoll.go:222 +0x44
internal/poll.(*pollDesc).wait(0x40001a4198, 0x72, 0x0, 0x0, 0x4d5f54)
	internal/poll/fd_poll_runtime.go:87 +0x38
internal/poll.(*pollDesc).waitRead(...)
	internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0x40001a4180, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	internal/poll/fd_unix.go:394 +0x1a0
net.(*netFD).accept(0x40001a4180, 0x0, 0x4000239b48, 0x27ab8c)
	net/fd_unix.go:172 +0x2c
net.(*TCPListener).accept(0x400019c2a0, 0x6107865e, 0x4000239b78, 0x4baf4)
	net/tcpsock_posix.go:139 +0x2c
net.(*TCPListener).Accept(0x400019c2a0, 0x4000239be0, 0x4000239be8, 0x18, 0x4000001380)
	net/tcpsock.go:261 +0x5c
net/http.(*Server).Serve(0x40001de000, 0x57e140, 0x400019c2a0, 0x0, 0x0)
	net/http/server.go:2937 +0x218
net/http.Serve(...)
	net/http/server.go:2498
github.com/hacdias/webdav/v3/cmd.glob..func1(0x816a60, 0x400019c020, 0x0, 0x2)
	github.com/hacdias/webdav/v3/cmd/root.go:80 +0x33c
github.com/spf13/cobra.(*Command).execute(0x816a60, 0x400001e190, 0x2, 0x2, 0x816a60, 0x400001e190)
	github.com/spf13/[email protected]/command.go:856 +0x1c4
github.com/spf13/cobra.(*Command).ExecuteC(0x816a60, 0x0, 0x0, 0x0)
	github.com/spf13/[email protected]/command.go:960 +0x268
github.com/spf13/cobra.(*Command).Execute(...)
	github.com/spf13/[email protected]/command.go:897
github.com/hacdias/webdav/v3/cmd.Execute()
	github.com/hacdias/webdav/v3/cmd/cmd.go:9 +0x30
created by main.main
	command-line-arguments/main.go:21 +0x84

goroutine 17 [syscall, 2544 minutes]:
os/signal.signal_recv(0x0)
	runtime/sigqueue.go:147 +0xc4
os/signal.loop()
	os/signal/signal_unix.go:23 +0x20
created by os/signal.Notify.func1.1
	os/signal/signal.go:150 +0x44

goroutine 3483 [IO wait]:
internal/poll.runtime_pollWait(0x7f6220ba00, 0x72, 0x7d04f8)
	runtime/netpoll.go:222 +0x44
internal/poll.(*pollDesc).wait(0x4000400118, 0x72, 0x576f00, 0x7d04f8, 0x0)
	internal/poll/fd_poll_runtime.go:87 +0x38
internal/poll.(*pollDesc).waitRead(...)
	internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0x4000400100, 0x40001a61c1, 0x1, 0x1, 0x0, 0x0, 0x0)
	internal/poll/fd_unix.go:159 +0x160
net.(*netFD).Read(0x4000400100, 0x40001a61c1, 0x1, 0x1, 0x40001cef68, 0x270b30, 0x4000104510)
	net/fd_posix.go:55 +0x44
net.(*conn).Read(0x400000e038, 0x40001a61c1, 0x1, 0x1, 0x0, 0x0, 0x0)
	net/net.go:182 +0x74
net/http.(*connReader).backgroundRead(0x40001a61b0)
	net/http/server.go:690 +0x50
created by net/http.(*connReader).startBackgroundRead
	net/http/server.go:686 +0xc4

goroutine 3523 [IO wait]:
internal/poll.runtime_pollWait(0x7f6220bae8, 0x72, 0x7d04f8)
	runtime/netpoll.go:222 +0x44
internal/poll.(*pollDesc).wait(0x4000400098, 0x72, 0x576f00, 0x7d04f8, 0x0)
	internal/poll/fd_poll_runtime.go:87 +0x38
internal/poll.(*pollDesc).waitRead(...)
	internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0x4000400080, 0x4000262041, 0x1, 0x1, 0x0, 0x0, 0x0)
	internal/poll/fd_unix.go:159 +0x160
net.(*netFD).Read(0x4000400080, 0x4000262041, 0x1, 0x1, 0x40001d3768, 0x270b30, 0x40001a8450)
	net/fd_posix.go:55 +0x44
net.(*conn).Read(0x400000e030, 0x4000262041, 0x1, 0x1, 0x0, 0x0, 0x0)
	net/net.go:182 +0x74
net/http.(*connReader).backgroundRead(0x4000262030)
	net/http/server.go:690 +0x50
created by net/http.(*connReader).startBackgroundRead
	net/http/server.go:686 +0xc4

goroutine 3481 [runnable]:
net/http.Header.Clone(0x40002620f0, 0x7e8100)
	net/http/header.go:102 +0x128
net/http.(*response).WriteHeader(0x40001de0e0, 0x195)
	net/http/server.go:1149 +0x1d4
golang.org/x/net/webdav.(*Handler).ServeHTTP(0x40001a8300, 0x57e3c0, 0x40001de0e0, 0x400019e200)
	golang.org/x/[email protected]/webdav/webdav.go:74 +0x104
github.com/hacdias/webdav/v3/lib.(*Config).ServeHTTP(0x40001a4100, 0x57e3c0, 0x40001de0e0, 0x400019e200)
	github.com/hacdias/webdav/v3/lib/webdav.go:159 +0x5f8
net/http.serverHandler.ServeHTTP(0x40001de000, 0x57e3c0, 0x40001de0e0, 0x400019e200)
	net/http/server.go:2843 +0xbc
net/http.(*conn).serve(0x40004040a0, 0x57f800, 0x4000104000)
	net/http/server.go:1925 +0x6f4
created by net/http.(*Server).Serve
	net/http/server.go:2969 +0x2e8

goroutine 3510 [IO wait]:
internal/poll.runtime_pollWait(0x7f6220bcb8, 0x72, 0x7d04f8)
	runtime/netpoll.go:222 +0x44
internal/poll.(*pollDesc).wait(0x4000400018, 0x72, 0x576f00, 0x7d04f8, 0x0)
	internal/poll/fd_poll_runtime.go:87 +0x38
internal/poll.(*pollDesc).waitRead(...)
	internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0x4000400000, 0x400001e881, 0x1, 0x1, 0x0, 0x0, 0x0)
	internal/poll/fd_unix.go:159 +0x160
net.(*netFD).Read(0x4000400000, 0x400001e881, 0x1, 0x1, 0x40001d3f68, 0x270b30, 0x400031e110)
	net/fd_posix.go:55 +0x44
net.(*conn).Read(0x400000e028, 0x400001e881, 0x1, 0x1, 0x0, 0x0, 0x0)
	net/net.go:182 +0x74
net/http.(*connReader).backgroundRead(0x400001e870)
	net/http/server.go:690 +0x50
created by net/http.(*connReader).startBackgroundRead
	net/http/server.go:686 +0xc4

goroutine 3461 [IO wait, 266 minutes]:
internal/poll.runtime_pollWait(0x7f6220bbd0, 0x72, 0x7d04f8)
	runtime/netpoll.go:222 +0x44
internal/poll.(*pollDesc).wait(0x4000400298, 0x72, 0x576f00, 0x7d04f8, 0x0)
	internal/poll/fd_poll_runtime.go:87 +0x38
internal/poll.(*pollDesc).waitRead(...)
	internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0x4000400280, 0x4000318000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	internal/poll/fd_unix.go:159 +0x160
net.(*netFD).Read(0x4000400280, 0x4000318000, 0x1000, 0x1000, 0x40000b1768, 0x270e68, 0x0)
	net/fd_posix.go:55 +0x44
net.(*conn).Read(0x400018c048, 0x4000318000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	net/net.go:182 +0x74
net/http.(*connReader).Read(0x40002636e0, 0x4000318000, 0x1000, 0x1000, 0x40000b1848, 0x4b5b0, 0x40000b18e8)
	net/http/server.go:798 +0x244
bufio.(*Reader).fill(0x40002ebec0)
	bufio/bufio.go:101 +0xf8
bufio.(*Reader).ReadSlice(0x40002ebec0, 0x1c60a, 0x400019ea00, 0x100, 0xf8, 0x4c6040, 0x40000b18d8)
	bufio/bufio.go:360 +0x38
bufio.(*Reader).ReadLine(0x40002ebec0, 0x400019ea00, 0x81f580, 0x4000080000, 0x0, 0x81fb00, 0x400000e901)
	bufio/bufio.go:389 +0x30
net/textproto.(*Reader).readLineSlice(0x40004020c0, 0x400019ea00, 0x4000400280, 0xd7500, 0x40000b19c8, 0x6d9ec)
	net/textproto/reader.go:58 +0x60
net/textproto.(*Reader).ReadLine(...)
	net/textproto/reader.go:39
net/http.readRequest(0x40002ebec0, 0x0, 0x400019ea00, 0x0, 0x0)
	net/http/request.go:1012 +0x74
net/http.(*conn).readRequest(0x4000404140, 0x57f800, 0x400031e080, 0x0, 0x0, 0x0)
	net/http/server.go:984 +0x150
net/http.(*conn).serve(0x4000404140, 0x57f800, 0x400031e080)
	net/http/server.go:1851 +0x5ac
created by net/http.(*Server).Serve
	net/http/server.go:2969 +0x2e8

goroutine 3480 [runnable]:
net/http.Header.Clone(0x400001f1d0, 0x7e8100)
	net/http/header.go:104 +0x1d0
net/http.(*response).WriteHeader(0x40001500e0, 0x195)
	net/http/server.go:1149 +0x1d4
golang.org/x/net/webdav.(*Handler).ServeHTTP(0x40001a8300, 0x57e3c0, 0x40001500e0, 0x4000020400)
	golang.org/x/[email protected]/webdav/webdav.go:74 +0x104
github.com/hacdias/webdav/v3/lib.(*Config).ServeHTTP(0x40001a4100, 0x57e3c0, 0x40001500e0, 0x4000020400)
	github.com/hacdias/webdav/v3/lib/webdav.go:159 +0x5f8
net/http.serverHandler.ServeHTTP(0x40001de000, 0x57e3c0, 0x40001500e0, 0x4000020400)
	net/http/server.go:2843 +0xbc
net/http.(*conn).serve(0x4000404000, 0x57f800, 0x400031e000)
	net/http/server.go:1925 +0x6f4
created by net/http.(*Server).Serve
	net/http/server.go:2969 +0x2e8

Feature Request: allow/deny modification permissions for specific paths

Currently, we can grant someone permissions to modify everything they have access to, but we can't really restrict that to certain paths. We could, for example, want the whole webdav to be readonly for everyone except the admin but there could be an upload directory anyone could upload to.

A sample caddyfile excerpt could look like:

basicauth / admin admin

webdav {
scope /home/webdav
modify false # Normal users can't modify
allow /upload modify # but they can modify in /upload
block /tmp # Normal users can't access/tmp

admin
modify true # Admin can modify everything
allow /tmp nomodify # Admin can read in tmp but it's still protected from accidental modification.

Basically the idea is to add an optional third argument to the allow and allow_r directives that could either be true/false or modify/nomodify, that would grant or deny modification privileges for that path with no regard to the modify property on the user.
The modify property could even be removed or its use discouraged, because you could write allow / modify or allow / nomodify instead and optionally add exceptions to specific paths.
Another idea is to change the modify directive itself to accept a third, optional argument that defaults to / and restricts the directive to a specific path.
Will you accept a pull request implementing this? @hacdias what approach would you consider to be the best?

Webdav fails when it encounters a socket file

When using this Caddyfile for testing, I encountered an error:

localhost {

  webdav /webdav {
    scope /tmp
  }

}

I have a socket file unter /tmp/, this is what caddy returned:

<?xml version="1.0" encoding="UTF-8"?><D:multistatus xmlns:D="DAV:">[...]</D:multistatus>Internal Server Error

Note: I snipped out the content and replaced it with [...]

Interestingly, it did send a valid xml, but with Internet Server Error attached.
The xml of course only included records until it (presumably) hit the socket file, at which point it failed.

Sorry for the simple issue. I'll gladly do more testing and look into the source myself later.

Trying to get in touch regarding a security issue

Hi there,

I couldn't find a SECURITY.md in your repository and am not sure how to best contact you privately to disclose a security issue.

Can you add a SECURITY.md file with an e-mail to your repository, so that our system can send you the vulnerability details? GitHub suggests that a security policy is the best way to make sure security issues are responsibly disclosed.

Once you've done that, you should receive an e-mail within the next hour with more info.

Thanks! (cc @huntr-helper)

Feature Request - NTLM Authentication

It would be really awesome if this project supported NTLM authentication. I've been trying to get it to work by adding the required pieces to lib/webdav.go, but I think more base changes are needed. I can get the Type 1 message incoming, parse it and send the Type 2 message back, but unfortunately it doesn't get the Type 3 message back. Still investigating why that might be. I'm relatively new to Golang so this might be outside of my abilities.

Feature request: create backup

I use webdav with Tiddlywiki

https://tiddlywiki.com

It is a single file self contain html one can edit it over the http.
When you save a modified file webdav save it correctly!
I wish to be able to create a backup file when I save the file.

In other words

Having test.html open and modify using webdav! how can I make a backup
on every save?

Start: webdav --config webdav.config isn't reading the config file

I'm testing webdav on my centos 7.6 Linux VM.
Startup with options is working, sample:
$ ./webdav -p 8080 --auth=false --tls=false
Listening on [::]:8080
So i can connect via Win explorer.

Startup with webdav.config isn't reading the config file, sample:
$ ./webdav --config ./webdav.config
Listening on [::]:42106

webdav.config

Server related settings

address: 10.116.7.161
port: 80
auth: false
tls: false
cert: cert.pem
key: key.pem
prefix: /

Default user settings (will be merged)

scope: .
modify: true
rules: []

CORS configuration

cors:
enabled: true
credentials: true
allowed_headers:
- Depth
allowed_hosts:
- http://localhost:80
allowed_methods:
- GET
exposed_headers:
- Content-Length
- Content-Range

users:

  • username: admin
    password: admin
    scope: /a/different/path
  • username: encrypted
    password: "{bcrypt}$2y$10$zEP6oofmXFeHaeMfBNLnP.DO8m.H.Mwhd24/TOX2MWLxAExXi4qgi"
  • username: "{env}ENV_USERNAME"
    password: "{env}ENV_PASSWORD"
  • username: basic
    password: basic
    modify: false
    rules:
    • regex: false
      allow: false
      path: /some/file
    • path: /public/access/
      modify: true

can not run on OpenWrt built with musl

linux-amd64 release can't be run on OpenWrt and alpinelinux. i can run weddav on alpinelinux after installed glibc,but i can't find a glibc package available for OpenWrt.

bug in variable type

I set the password to number type(like 123456),it will report an error when I log in.
It is recommended to change to string type when getting parameters(like username,password)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.