I'm trying to upload static HTML+friends content to a raw Nexus 3 repository. As far as the documentation goes, the only way to upload files is using HTTP PUT. Sure enough,
curl -v --user 'user:pw' --upload-file my_file.html \
http://my.nexus/repository/my-raw-repo/my_file.html
works as expected and the file can be accessed at http://my.nexus/repository/my-raw-repo/index.html
Adding this deployment to my Rake process has turned out to be hasslesome, though. Here are some things I have tried.
With net/http
:
require 'net/http'
uri = URI("http://my.nexus/repository/my-raw-repo")
file = "index.html"
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Put.new "#{repo_url}/#{file}"
request.basic_auth(user, pw)
<snip>
response = http.request request
raise "Upload failed: #{response.code} #{response.message}\n#{response.body}" \
unless response.is_a?(Net::HTTPSuccess)
end
I tried several variants for <snip>
.
Set body to file content as string:
request.body = File.read("#{file}")`
Request completes without error but Nexus shows file size 0 bytes.
Send form data to file content as stream:
request.set_form([['upload', File.open("#{file}")]], 'multipart/form-data')
That one is kind of obvious: multi-part gutter is added which Nexus does not remove:
With rest-client
:
require 'rest-client'
file = "index.html"
begin
RestClient::Request.execute(
method: :put,
url: "http://my.nexus/repository/my-raw-repo/#{file}",
<snip>
user: user,
password: pw
)
rescue RestClient::ExceptionWithResponse => e
raise "Upload failed: #{e.response}"
end
And for <snip>
(guessing around the less than clear documentation):
body: File.read("#{file}")
payload: File.read("#{file}")
payload: { file: File.new("#{file}") }
payload: { multipart: false, file: File.new("#{file}") }
I think I tried several combination more which I don't remember, with similar results.
Note bene: I've left out the parts related to SSL with a self-signed certificate because that should be unrelated.
How can I tell either library (or any other) to do PUT with data but without multi-part? Or if that's not the issue, what am I doing wrong?
I want to use an all-Ruby solution (i.e. not delegate to system curl
) so that the build can be (as) portable (as possible).
With net/http
, set the request body to the file content as stream:
request.body_stream = File.open("#{file}")
request.content_length = File.size("#{file}")
request.content_type = "text/plain" # ?!
Determining the proper MIME type from the file alone is an adventure in itself.