studio-b12 / gowebdav

A golang WebDAV client library and command line tool.
BSD 3-Clause "New" or "Revised" License
309 stars 89 forks source link

File upload uploads files with 0 bytes - No error given #35

Closed RAYs3T closed 3 years ago

RAYs3T commented 4 years ago

Describe the bug I discovered a bug in the file upload that has some relation to #20. When uploading a file to Nextcloud, the command succeeds and exits without any error, but the uploaded file has a size of 0 bytes.

Software

To Reproduce

  1. checkout this project
  2. Setup your environment with the ROOT, USER and PASSWORD
  3. Pick a file you want to upload
  4. Upload the file using the command
    gowebdav -X PUT /webdav_test.png .\Chart_KAD.PNG
    Put: .\Chart_KAD.PNG -> /webdav_test.png`
  5. Look at the Nextcloud instance to see that the actual uploaded file-size is 0 bytes.

image image

Apache access log (nextcloud)

80.187.108.153 - - [12/Aug/2020:12:32:26 +0200] "PUT /remote.php/dav/files/RAYs3T/webdav_test.png HTTP/1.1" 401 557
80.187.108.153 - - [12/Aug/2020:12:32:27 +0200] "PUT /remote.php/dav/files/RAYs3T/webdav_test.png HTTP/1.1" 201 -

Expected The file should upload completly or fail with an error

Additional context I initially discovered this issue via PhotoPrism (which uses this client for the uploads). At least one other user is facing the same issue (https://github.com/photoprism/photoprism/issues/443).

chripo commented 4 years ago

thank you for the excellent bugreport. at the moment i have no time left, to do some fixes. your welcome to fix this issues.

RAYs3T commented 4 years ago

I'll dig around a little on the weekend!

chripo commented 4 years ago

sound good. if you stuck, drop me i line an i'll try to help you.

RAYs3T commented 4 years ago

Okay, so i can confirm that the call invoking the request via the HTTP client indeed includes the correct file (with content). if you look at the contents of the reader, the correct file is streamed.

image

This makes me think that this might be really an issue on Nextclouds site. But what I don't get is why the upload with cyberduck for example works. Maybe its something with the headers set...

chripo commented 4 years ago

does curl work?

chripo commented 4 years ago

@RAYs3T any progress?

RAYs3T commented 4 years ago

Sorry for the late response. It seems like this is somehow involving the reverse proxy which you're using in your setup. Since I switched my nextcloud instance from apache2 to nginx and configured some extras, it's working fine.

Here the issue description: https://trac.cyberduck.io/wiki/help/en/howto/mount/issues/fastcgi

And this is what you have to configure in nginx https://github.com/photoprism/photoprism/issues/443#issuecomment-685608490

So this isn't an issue with the client - Maybe just how the error is handled.

pojntfx commented 3 years ago

I ran into this issue and I think I got to the bottom of it as well: reverse proxies which have issues with chunked encoding. In my case however, the target WebDAV server (a Nextcloud) can't be modified/the setup can't be changed, which blocked use of this library for me.

Anyways, to fix, I've added an interceptor to Client.put:

rs, err := c.req("PUT", path, stream, func(rq *http.Request) {
        b, err := ioutil.ReadAll(rq.Body)
        if err != nil {
            panic(err)
        }

        rq.ContentLength = int64(len(b))

        rq.Body = ioutil.NopCloser(bytes.NewReader(b))
    })

Using this, the upload works fine - I'll fork it for now. I'd recommend adding a Client.SetInterceptor func(interceptor func(method string, rq *http.Request)) API - I could create a PR if this would be an acceptable solution for those like me which are stuck without chunked encoding :)

pojntfx commented 3 years ago

@chripo I've prepared a PR which resolves this issue.