通过HTTP PUT上载数据而无需多部分装订线

时间:2019-05-13 12:41:40

标签: ruby http put rest-client net-http

我正在尝试将静态HTML + friends内容上传到原始Nexus 3存储库。就the documentation goes而言,上传文件的唯一方法是使用HTTP PUT。果然,

curl -v --user 'user:pw' --upload-file my_file.html  \
    http://my.nexus/repository/my-raw-repo/my_file.html

按预期工作,可以在http://my.nexus/repository/my-raw-repo/index.html上访问文件

不过,将这个部署添加到我的Rake流程中确实很麻烦。这是我尝试过的一些东西。

  1. 使用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
    

    我为<snip>尝试了几种变体。

    1. 将正文设置为字符串形式的文件内容:

      request.body = File.read("#{file}")`
      

      请求已成功完成,但Nexus显示的文件大小为0个字节。

    2. 将表单数据作为流发送到文件内容:

      request.set_form([['upload', File.open("#{file}")]], 'multipart/form-data')
      

      这很明显:添加了由Nexus无法删除的多部分装订线:

      enter image description here

  2. 使用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
    

    对于<snip>(猜测不够清晰的文档):

    1. body: File.read("#{file}")
       -> 0个字节。
    2. payload: File.read("#{file}")
       -> 0个字节。
    3. payload: { file: File.new("#{file}") }
      ->保留多部分装订线。
    4. payload: { multipart: false, file: File.new("#{file}") }
      ->保留多部分装订线。

    我想我尝试了几种我不记得的组合,结果相似。

注意事项:我省略了与SSL相关的带有自签名证书的部分,因为那应该是不相关的。

我如何告诉一个库(或任何其他库)对数据进行PUT,但没有多部分内容?或如果这不是问题,那我在做什么错了?

我想使用全Ruby解决方案(即不委托给系统curl),以便构建(可以)(尽可能)可移植。

1 个答案:

答案 0 :(得分:0)

使用net/http,将请求正文设置为流的文件内容:

request.body_stream = File.open("#{file}")
request.content_length = File.size("#{file}")
request.content_type = "text/plain" # ?!

仅从文件确定正确的MIME类型本身就是一种冒险。

相关问题