droppy icon indicating copy to clipboard operation
droppy copied to clipboard

Support PUT-based uploads with basic auth

Open mabead opened this issue 6 years ago • 5 comments

I am running droppy under docker with this configuration:

{
  "listeners" : [
    {
      "host": ["0.0.0.0", "::"],
      "port": 8989,
      "protocol": "http"
    }
  ],
  "public": true,
  "timestamps": true,
  "linkLength": 5,
  "linkExtensions": false,
  "logLevel": 2,
  "maxFileSize": 0,
  "updateInterval": 1000,
  "pollingInterval": 0,
  "keepAlive": 20000,
  "allowFrame": false,
  "readOnly": false,
  "ignorePatterns": [],
  "watch": true
}

I then try to upload a file with curl using curl -i --upload-file foo.txt http://127.0.0.1:8989/foo.txt but it fails like this:

HTTP/1.1 100 Continue

HTTP/1.1 405 Method Not Allowed
Date: Mon, 18 Feb 2019 11:39:06 GMT
Connection: keep-alive
Content-Length: 0

Can you explain how I can upload file to droppy using curl?

mabead avatar Feb 18 '19 11:02 mabead

You'd have to replicate the POST to !/upload with multipart/form-data encoded files in the body and the multiparts themselves in a special format, not sure if this is easily possible in curl.

silverwind avatar Feb 19 '19 17:02 silverwind

I guess I would not be opposed to a PR adding support for PUT based uploads on the !/upload endpoint. Or possibly accept PUT on any URL, if the destination path is based on the URL itself (I have no idea how PUT uploads work). It could use HTTP basic auth in case the server is not public

silverwind avatar Feb 19 '19 17:02 silverwind

One should be able to tell curl to upload via POST instead of PUT - PUT is merely the default HTTP method.

https://stackoverflow.com/questions/12667797/using-curl-to-upload-post-data-with-files

katanacrimson avatar Feb 01 '20 14:02 katanacrimson

I almost got curl uploading to work, except that Basic auth does not work. Do I need to change a setting somewhere?

$ curl -v -X POST --data-binary @test.txt http://admin:<password>@droppy.example.com/\!/upload?to=test.txt
* About to connect() to droppy.example.com port 80 (#0)
*   Trying 127.0.0.1...
* Connected to droppy.example.com (127.0.0.1) port 80 (#0)
* Server auth using Basic with user 'admin'
> POST /!/upload?to=test.txt HTTP/1.1
> Authorization: Basic <base64-encoded password>
> User-Agent: curl/7.29.0
> Host: droppy.example.com
> Accept: */*
> Content-Length: 0
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 401 Unauthorized
< Server: nginx/1.15.8
< Date: Wed, 05 Feb 2020 11:31:03 GMT
< Content-Length: 0
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
* Closing connection 0

Update: with public=true, the curl command uploads the file and receives 200 OK! :) But the droppy server seems to be busy afterwards and I have to restart the container, and the uploaded file is then not actually in droppy anywhere...

Qvazar avatar Feb 05 '20 11:02 Qvazar

Don't know if you guys are still interested in this problem but this is what worked for me:

UNAUTHENTICATED (i.e. public: true in config/config.json)

Upload file /local/path/to/file

$ curl -v -X POST -F 'file=@/local/path/to/file'  'http://${hostDroppyIsRunningOn}:8989/!/upload?vId=0&to=/&rename=0'

AUTHENTICATED (i.e. public: false in config/config.json)

Login to get login cookie

$ curl -v -X POST -d '{"username": "${actualDroppyUsername}", "password": "${actualDroppyPassword}", "remember": "true", "path": "/"}' 'http://${hostDroppyIsRunningOn}:8989/!/login'
...
> POST /!/login HTTP/1.1
...
< Set-Cookie: s=${cookieValue}; path=/; expires=Wed, 23 Jun 2021 16:13:41 GMT; HttpOnly; SameSite=strict
...

Upload file /local/path/to/file

# Use cookie from earlier response
$ curl -v -X POST --cookie 's=${cookieValue}' -F 'file=@/local/path/to/file' 'http://${hostDroppyIsRunningOn}:8989/!/upload?vId=0&to=/&rename=0'

note1: the following personal notation is meant to capture the variation in values depending on how you set things up and your environment. Please replace this with your particular values:

${hostDroppyIsRunningOn} - Depends which ip address or hostname you are using for droppy in your environment.
${actualDroppyUsername} - I opted to use default account so this would of been admin.
${actualDroppyPassword} - I opted to use default account so depends on what password value was set when first logging into the browser ui.
${cookieValue} - Comes from the response of the curl login.

note2: This is for uploading a single file.

Let me know if you want me to do a PR on the README to add this documentation so people don't have to go digging through the issues like I did. I can also include how to GET a file from the server using curl without having to get the shared link from the ui. The other operation that I thought could be useful for people wanting to circumvent the ui and go through service is a DELETE but this is handled by a websocket (We can see this from the server/server.js file). I don't think curl can handle websocket requests so this would have to be handled with a different command line utility.

fgharo avatar Jun 23 '20 17:06 fgharo