-
-
Notifications
You must be signed in to change notification settings - Fork 693
Upload Service Demo Server
- How to get it and run it
- Test multipart upload with curl
- Test binary upload with curl
- Test basic auth multipart and binary uploads with curl
- Test upload with demo app
- Validate Content Length
- Use curl to simulate poor bandwidth
First of all, you need to install node.js. The following steps are described using a macOS, but they should be the same across all platforms.
-
Open a terminal, go into a directory of your choice (In this example I do everything inside
/Users/alex/temp
) andgit clone https://github.com/gotev/android-upload-service.git
-
Enter the demo server directory and download its dependencies:
cd android-upload-service/examples/server-nodejs/ && npm i
-
Run the server:
npm start
and you will see an output like this:
> nodejs-upload-server-example@1.0.0 start /Users/alex/temp/android-upload-service/examples/server-nodejs > node index.js Upload server started. Listening on all interfaces on port 3000 The following endpoints are available for upload testing: HTTP/Multipart: http://192.168.1.132:3000/upload/multipart HTTP/Multipart (Basic Auth): http://192.168.1.132:3000/upload/multipart-ba Binary: http://192.168.1.132:3000/upload/binary Binary (Basic Auth): http://192.168.1.132:3000/upload/binary-ba 401 Forbidden: http://192.168.1.132:3000/upload/forbidden Validate Content Length: http://192.168.1.132:3000/upload/validate-content-length Basic auth credentials are: {"username":"test","password":"pass"}
Remember to keep the terminal window open to make the server run. If you close the window, it will stop.
While keeping the server terminal window open, open a new terminal window and go to a directory where you have a file you want to use for upload testing.
In my case this file is called upnpresources.zip
and I also add a multipart parameter mykey=myvalue
. upload
is the parameter name for the uploaded file. You can choose your own.
Execute:
curl -v -X POST -F mykey=myvalue -F upload=@upnpresources.zip http://192.168.1.132:3000/upload/multipart
Replace http://192.168.1.132:3000/upload/multipart
with the URL of your local running demo server.
In the window where the server is running you should see something like this:
HTTP/Multipart Upload Request from: ::ffff:192.168.1.132
Received headers
----------------
host: 192.168.1.132:3000
user-agent: curl/7.64.1
accept: */*
content-length: 69164575
content-type: multipart/form-data; boundary=------------------------71581ebd6678dd8f
expect: 100-continue
Received files
--------------
[
{
fieldname: 'upload',
originalname: 'upnpresources.zip',
encoding: '7bit',
mimetype: 'application/octet-stream',
destination: './uploads/',
filename: 'upload-1602929227751-263380332',
path: 'uploads/upload-1602929227751-263380332',
size: 69164263
}
]
Received params
---------------
{
"mykey": "myvalue"
}
Upload completed
and an output like this where you ran the curl
command:
* Trying 192.168.1.132...
* TCP_NODELAY set
* Connected to 192.168.1.132 (192.168.1.132) port 3000 (#0)
> POST /upload/multipart HTTP/1.1
> Host: 192.168.1.132:3000
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 69164575
> Content-Type: multipart/form-data; boundary=------------------------71581ebd6678dd8f
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Date: Sat, 17 Oct 2020 10:07:07 GMT
< Connection: keep-alive
< Content-Length: 10
<
* Connection #0 to host 192.168.1.132 left intact
{"success":true,"message":"upload completed successfully","data":{"files":[{"fieldname":"upload","originalname":"upnpresources.zip","encoding":"7bit","mimetype":"application/octet-stream","destination":"./uploads/","filename":"upload-1602929227751-263380332","path":"upload-1602929227751-263380332","size":69164263}],"params":{"mykey":"myvalue"}}}* Closing connection 0
That means the upload was successful. To get a proof of that, you may calculate the md5 of the uploaded file and the received file. In my case:
$ md5 upnpresources.zip
MD5 (upnpresources.zip) = 41971b58bc94e7b973a7e25902dbc448
$ md5 uploads/upload-1602929227751-263380332
MD5 (uploads/upload-1602929227751-263380332) = 41971b58bc94e7b973a7e25902dbc448
so it's all good!
While keeping the server terminal window open, open a new terminal window and go to a directory where you have a file you want to use for upload testing.
In my case this file is called upnpresources.zip
and I also add a header named file-name
for the demo server to know the name of my file.
Execute:
curl -v -X POST --data-binary @upnpresources.zip -H "file-name: myfile" http://192.168.1.132:3000/upload/binary
Replace http://192.168.1.132:3000/upload/binary
with the URL of your local running demo server.
In the window where the server is running you should see something like this:
Binary Upload Request from: ::ffff:192.168.1.132
Received headers
----------------
host: 192.168.1.132:3000
user-agent: curl/7.64.1
accept: */*
file-name: myfile
content-length: 35190618
content-type: application/x-www-form-urlencoded
expect: 100-continue
Started binary upload of: myfile
Finished binary upload of: myfile
in: /Users/alex/temp/android-upload-service/examples/server-nodejs/uploads/myfile
and an output like this where you ran the curl
command:
* Trying 192.168.1.132...
* TCP_NODELAY set
* Connected to 192.168.1.132 (192.168.1.132) port 3000 (#0)
> POST /upload/binary HTTP/1.1
> Host: 192.168.1.132:3000
> User-Agent: curl/7.64.1
> Accept: */*
> file-name: myfile
> Content-Length: 35190618
> Content-Type: application/x-www-form-urlencoded
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/plain; charset=utf-8
< Content-Length: 2
< ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
< Date: Sat, 17 Oct 2020 10:26:00 GMT
< Connection: keep-alive
<
* Connection #0 to host 192.168.1.132 left intact
{"success":true,"data":{"filename":"myfile","uploadFilePath":"/Users/alex/temp/android-upload-service/examples/server-nodejs/uploads/myfile"}}* Closing connection 0
That means the upload was successful. To get a proof of that, you may calculate the md5 of the uploaded file and the received file. In my case:
$ md5 upnpresources.zip
MD5 (upnpresources.zip) = 41971b58bc94e7b973a7e25902dbc448
$ md5 uploads/myfile
MD5 (uploads/myfile) = 41971b58bc94e7b973a7e25902dbc448
so it's all good!
Everything is the same as explained in the above sections, except for two things. When you execute the curl command you have to
- add
--user test:pass
- use the endpoint with the
-ba
suffix. Somultipart-ba
orbinary-ba
curl -v -X POST --user test:pass -F mykey=myvalue -F upload=@upnpresources.zip http://192.168.1.132:3000/upload/multipart-ba
curl -v -X POST --user test:pass --data-binary @upnpresources.zip -H "file-name: myfile" http://192.168.1.132:3000/upload/binary-ba
Refer to this guide: https://github.com/gotev/android-upload-service/wiki/Upload-Service-Testbed
Use this endpoint to check if the request's declared Content-Length
header matches actual body content length.
Binary Request Example
curl -v -X POST --data-binary @upnpresources.zip -H "file-name: myfile" http://192.168.1.132:3000/upload/validate-content-length
Multipart Request Example
curl -v -X POST -F mykey=myvalue -F upload=@upnpresources.zip http://192.168.1.132:3000/upload/validate-content-length
The endpoint responds with HTTP 200 OK
if the Content-Length
is valid, otherwise HTTP 400 Bad Request
. In the response you will find also expected and actual values.
curl
is a fantastic tool. You can easily apply bandwidth limitations when you perform uploads by using (taken from man curl
):
--limit-rate <speed>
Specify the maximum transfer rate you want curl to use - for both downloads and uploads. This feature is useful if you
have a limited pipe and you'd like your transfer not to use your entire bandwidth. To make it slower than it otherwise
would be.
The given speed is measured in bytes/second, unless a suffix is appended. Appending 'k' or 'K' will count the number as
kilobytes, 'm' or 'M' makes it megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
If you also use the -Y, --speed-limit option, that option will take precedence and might cripple the rate-limiting
slightly, to help keeping the speed-limit logic working.
If this option is used several times, the last one will be used.
For example:
curl -vvv -X POST --limit-rate 1M -F mykey=myvalue -F upload=@large_test_file http://192.168.1.132:3000/upload/multipart
This will perform the upload using a maximum of 1 megabytes per second bandwidth.