Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file_upload fails with aptly-cli, but works with curl #152

Closed
kristianronningen opened this issue Jan 8, 2019 · 11 comments
Closed

file_upload fails with aptly-cli, but works with curl #152

kristianronningen opened this issue Jan 8, 2019 · 11 comments

Comments

@kristianronningen
Copy link

I'm having trouble getting file_upload to work, and I can't find any obvious errors anywhere. Suspecting some kind of bug. Uploading a file by accessing the aptly API using curl works. Other aptly-cli commands work, such as file_list, repo_upload and publish_update.

My aptly-cli server is Debian 9.6, Ruby 2.3.3, aptly_cli 0.4.1.
My aptly api server is Debian 9.6, aptly 1.3.0.

File to upload:

# ls -l aptly-test-file.txt 
-rw-r--r-- 1 root root 22 Jan  8 09:33 aptly-test-file.txt

# cat aptly-test-file.txt
1234567890
abcdefghij

Uploading the file using aptly-cli causes the directory to be created on the server, but the file is not uploaded. The response also does not contain the filename as expected:

# aptly-cli file_upload --trace --upload aptly-test-file.txt --directory /testfile
opening connection to my.aptly.server:443...
opened
starting SSL for my.aptly.server:443...
SSL established
<- "POST /api/files/testfile HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: multipart/form-data; boundary=-----------RubyMultipartPost\r\nContent-Length: 447\r\nAuthorization: Basic <redacted>\r\nConnection: close\r\nHost: my.aptly.server\r\n\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Server: nginx/1.14.1\r\n"
-> "Date: Tue, 08 Jan 2019 08:42:46 GMT\r\n"
-> "Content-Type: application/json; charset=utf-8\r\n"
-> "Content-Length: 2\r\n"
-> "Connection: close\r\n"
-> "Strict-Transport-Security: max-age=15768000\r\n"
-> "\r\n"
reading 2 bytes...
-> "[]"
read 2 bytes
Conn close

My /etc/aptly-cli.conf looks like this:

# cat /etc/aptly-cli.conf 
---
:proto: https
:server: my.aptly.server
:port: 443
:username: aptlyuser
:password: <redacted>
:debug: true

Using curl to upload the same file works, and shows a significant difference in the reported Content-Length of the upload. I'm not sure exactly how this is calculated:

# curl -v -F file=@aptly-test-file.txt https://aptlyuser:<redacted>@my.aptly.server/api/files/testfile
*   Trying ip.of.my.aptly.server...
* TCP_NODELAY set
* Connected to my.aptly.server (ip.of.my.aptly.server) port 443 (#0)
[..handshake lines removed..]
> POST /api/files/testfile HTTP/1.1
> Host: my.aptly.server
> Authorization: Basic <redacted>
> User-Agent: curl/7.52.1
> Accept: */*
> Content-Length: 219
> Content-Type: multipart/form-data; boundary=------------------------61a6064b8ba6fb9f
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< server: nginx/1.14.1
< date: Tue, 08 Jan 2019 08:46:08 GMT
< content-type: application/json; charset=utf-8
< content-length: 32
< strict-transport-security: max-age=15768000
<
* Curl_http_done: called premature == 0
* Connection #0 to host my.aptly.server left intact
["testfile/aptly-test-file.txt"]

These requests are, as you can see, all done through Nginx, but I have tried to also talk directly to the aptly API on port 8080, which gives me the exact same results.

For completeness, this is the relevant part in the Nginx config that handles requests to /api/:

location /api/ {
  client_max_body_size 100M;
  auth_basic "Restricted";
  auth_basic_user_file /etc/nginx/.htpasswd.aptly;
  proxy_redirect	off;
  proxy_pass	http://localhost:8080/api/;
  proxy_redirect	http://localhost:8080/api/ /api;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header Host $http_host;
  proxy_set_header Origin "";
}

And this is the supervisor config, used to start the aptly api serve:

[program:aptly]
command=/usr/bin/aptly api serve -no-lock
directory=/home/aptly
user=aptly
stdout_logfile=/var/log/supervisor/aptly-stdout.log
stderr_logfile=/var/log/supervisor/aptly-stderr.log
@kristianronningen
Copy link
Author

Forgot to mention that in the /var/log/supervisor/aptly-stdout.log there is only a single line, for both failed uploads using aptly-cli and successful uploads using curl. There is nothing in the stderr log.

[GIN] 2019/01/08 - 09:46:08 | 200 |   16.266322ms |    ip.of.my.aptly-cli.server |  POST     /api/files/testfile

@sepulworld
Copy link
Owner

Can you try removing the initial '/' for the directory? and try with a new file name.

aptly-cli file_upload --trace --upload aptly-test-file2.txt --directory testfile

@kristianronningen
Copy link
Author

The / prefix is necessary, because it becomes part of the URL, so without it, the result is a 404:

# aptly-cli file_upload --trace --upload aptly-test-file2.txt --directory testfile2
opening connection to my.aptly.server:443...
opened
starting SSL for my.aptly.server:443...
SSL established
<- "POST /api/filestestfile2 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: multipart/form-data; boundary=-----------RubyMultipartPost\r\nContent-Length: 449\r\nAuthorization: Basic <redacted>\r\nConnection: close\r\nHost: my.aptly.server\r\n\r\n"
-> "HTTP/1.1 404 Not Found\r\n"
-> "Server: nginx/1.14.1\r\n"
-> "Date: Mon, 14 Jan 2019 09:54:06 GMT\r\n"
-> "Content-Type: text/plain\r\n"
-> "Content-Length: 18\r\n"
-> "Connection: close\r\n"
-> "\r\n"
reading 18 bytes...
-> "404 page not found"
read 18 bytes
Conn close
404 page not found

@sepulworld
Copy link
Owner

sepulworld commented Jan 14, 2019 via email

@sepulworld
Copy link
Owner

Can you please try with providing the relative path to the local file that needs to be uploaded?

aptly-cli file_upload --trace --upload ./aptly-test-file3.txt --directory /testfile

@kristianronningen
Copy link
Author

It seems to make no difference:

# aptly-cli file_upload --trace --upload ./aptly-test-file3.txt --directory /testfile3
opening connection to my.aptly.server:443...
opened
starting SSL for my.aptly.server:443...
SSL established
<- "POST /api/files/testfile3 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: multipart/form-data; boundary=-----------RubyMultipartPost\r\nContent-Length: 451\r\nAuthorization: Basic <redacted>\r\nConnection: close\r\nHost: my.aptly.server\r\n\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Server: nginx/1.14.1\r\n"
-> "Date: Wed, 23 Jan 2019 09:20:41 GMT\r\n"
-> "Content-Type: application/json; charset=utf-8\r\n"
-> "Content-Length: 2\r\n"
-> "Connection: close\r\n"
-> "Strict-Transport-Security: max-age=15768000\r\n"
-> "\r\n"
reading 2 bytes...
-> "[]"
read 2 bytes
Conn close

I have also tried using the full static path (/path/to/thefile) which yields the same results.

@sepulworld
Copy link
Owner

Hmm, I’m thinking it is a bug with the httpmultiparty gem (which is unmaintained). I just took a look and httparty gen now supports multipart upload. I think we need to switch over to httparty for uploads.

@kristianronningen
Copy link
Author

kristianronningen commented Jan 24, 2019

Yeah, I saw the unmaintained notice for that gem as well, when trying to dive into the code. I didn't dive deeper into it though. Bad ruby skills and not enough time. :)

@sepulworld
Copy link
Owner

sepulworld commented Jan 26, 2019

@kristianronningen I was able to replicate the issue. And I have discovered the issue. The lastest version of HTTParty breaks aptly-cli. I need to put in some work to move to HTTParty from HTTPMultiParty. Until then, you can downgrade your httparty gem to '0.13.7'

gem install httparty --version=0.13.7 (you may need to uninstall the newer version of httparty, I didn't though)

I'm also releasing a new version of aptly-cli that will require this version upon install.

Can you tell me what version of httparty you have installed? Then try to downgrade to 0.13.7 and let me know if it works

@kristianronningen
Copy link
Author

The version was:

# gem list | grep ^httparty
httparty (0.16.3)

Then I installed 0.13.7 and uninstalled 0.16.3 (they both ended up being installed, and aptly-cli still failed):

# gem install httparty --version=0.13.7
# gem uninstall httparty --version=0.16.3
# gem list | grep ^httparty
httparty (0.13.7)

And now it works:

# aptly-cli file_upload --trace --upload aptly-test-file3.txt --directory /testfile3
opening connection to my.aptly.server:443...
opened
starting SSL for my.aptly.server:443...
SSL established
<- "POST /api/files/testfile3 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: multipart/form-data; boundary=-----------RubyMultipartPost\r\nContent-Length: 371\r\nAuthorization: Basic <redacted>\r\nConnection: close\r\nHost: my.aptly.server\r\n\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Server: nginx/1.14.1\r\n"
-> "Date: Sat, 26 Jan 2019 10:55:53 GMT\r\n"
-> "Content-Type: application/json; charset=utf-8\r\n"
-> "Content-Length: 34\r\n"
-> "Connection: close\r\n"
-> "Strict-Transport-Security: max-age=15768000\r\n"
-> "\r\n"
reading 34 bytes...
-> "[\"testfile3/aptly-test-file3.txt\"]"
read 34 bytes
Conn close
testfile3/aptly-test-file3.txt

Thanks!

@sepulworld
Copy link
Owner

sepulworld commented Jan 26, 2019

Thanks for reporting the issue! Sorry it took me a few days to gear up. Glad we figured it out! ⭐️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants