golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.96k stars 17.53k forks source link

x/net/webdav: PROPFIND fails on OpenBSD if the directory has a unix domain socket in it #18843

Open magisterquis opened 7 years ago

magisterquis commented 7 years ago

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

1.7.4

What operating system and processor architecture are you using (go env)?

openbsd/amd64 GOARCH="amd64" GOBIN="" GOEXE="" GOHOSTARCH="amd64" GOHOSTOS="openbsd" GOOS="openbsd" GOPATH="/home/stuart/go" GORACE="" GOROOT="/home/stuart/.goroot" GOTOOLDIR="/home/stuart/.goroot/pkg/tool/openbsd_amd64" CC="gcc" GOGCCFLAGS="-fPIC -m64 -fmessage-length=0" CXX="g++" CGO_ENABLED="0"

What did you do?

If possible, provide a recipe for reproducing the error.

  1. Make a unix domain socket in a temporary directory
  2. Serve the directory with x/net/webdav
  3. Try to list the directory with the socket

Code used to serve directory. http://play.golang.org/p/ClPtJ4beK4

For the socket, socat unix-listen:testpipe - & pkill -9 socat works.

What did you expect to see?

A listing of the directory contents.

What did you see instead?

dav:/> ls
Listing collection `/': failed:
XML parse error at line 1: junk after document element

The problem seems to be in the function props in /x/net/webdav/prop.go. It opens every file to get its dead properties. Unfortunately, on OpenBSD, opening a unix socket (as opposed to connecting to it), returns EOPNOTSUPP.

bradfitz commented 7 years ago

/cc @mdempsky

ertw commented 6 years ago

I'm able to reproduce this issue with Go 1.9 on current distributions of Linux (Ubuntu), OpenBSD, Dragonfly BSD, and MacOS. What I see using cadaver and curl is that the XML returned is almost valid, except 'internal server error' is appended after the last closing tag, making it junk.

izcet commented 6 years ago

I tested against other webdav servers (I used apache with the dav mod), and found that in the same conditions the broken pipe is silently ignored by the dav server.

For example, in the local /webdav:

user:/webdav$ ls
normal-file
testpipe

And in cadaver:

dav:/webdav/ ls
normal-file

Analyzing the order of function calls and overall functionality, I also noticed the server logs and an extra error: 2017/10/13 19:01:00 http: multiple response.WriteHeader calls in addition to the 2017/10/13 19:01:00 PROPFIND /: open testpipe: no such device or address

(both a 200 and also a 500, which are passed up to webdav.go)

Edit: This also breaks if the dav server tries to host a file with no permissions touch examplefile ; chmod 000 examplefile