【问题标题】:archiloque-rest-client: change content-type to multipart/related when posing a filearchiloque-rest-client:在提交文件时将内容类型更改为多部分/相关
【发布时间】:2010-09-28 07:05:54
【问题描述】:

使用 http://github.com/archiloque/rest-client

使用此行发布文件时,内容类型设置为

Content-Type: multipart/form-data; boundary=301405

默认情况下在标题中。

RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')

我试过了,它仍然设置标题 multipart/form-data。

RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb'), :content_type => 'multipart/related'

有人试过设置多部分/相关吗?

【问题讨论】:

    标签: ruby-on-rails rest-client


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      好的。我找不到更好的选择,所以最终选择了以下应用。

      这里基于此代码。 http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html

      用法:

      files = { File.new("myfile1","rb"), File.new("myfile2","rb")}
      mpost = Mutipart("main", "<my xml main part content which refers to file names>",files )
      mpost.post("our_url","post")
      

      注意:此代码尚未准备好用于生产。它只是功能性的。

      ---------------- multipart.rb -------------

      require 'net/http'
      require 'uri'
      require 'pp'
      require 'mime/types'
      
      class Multipart  
      
        def initialize( main_part_id, main_part_content, file_names )  
          @file_names = file_names  
          @main_part_id = main_part_id
          @main_part_content = main_part_content
        end
      
        def post( to_url, method = :post )  
          boundary = "###-------#{Time.new}-----####"
      
          parts = []  
          streams = []
          # write main part first
          parts << StringPart.new( "--" + boundary + "\r\n")
          parts << StringPart.new("Content-Disposition: name=\"#{@main_part_id}\";\"\r\n" +  
            "Content-ID: #{@main_part_id}\r\n\r\n"+
            "Content-Type: application/xml\r\n\r\n" +  
          @main_part_content + "\r\n\r\n")
          parts << StringPart.new( "\r\n--" + boundary + "\r\n")
      
          @file_names.each do |param_name, filestream|
            raise 'mutlipartsend: empty file object' if filestream.blank?
      
            filename= filestream.respond_to?(:original_path) ? filestream.original_path : filestream.path
            ctype = filestream.respond_to?(:content_type) ? filestream.content_type: nil
            fsize = filestream.respond_to?(:lstat) ? filestream.lstat.size : filestream.size
      
      
            if !ctype
              begin
                  pos = filename.rindex('/') # if filename is a path
                  fname = filename[pos + 1, filename.length - pos]
                  mm = MIME::Types.type_for(fname)
                  ctype = mm.first.content_type if !mm.blank?
              rescue Exception => e
                p e.message
              end
            end
            if !ctype
              ctype= 'application/binary'
              p "mutlipartsend: failed to determine contenttype for #{filename}. using application/binary"
            end
      
      
            parts << StringPart.new("Content-Disposition: name=\"" + param_name.to_s + "\"; filename=\"" + filename + "\"\r\n" +  
              "Content-Type: #{ctype}\r\n\r\n")
              #"Content-Type: application/binary\r\n\r\n")
            begin
              stream = File.open(filestream.path,"rb")
              streams << stream 
              parts << StreamPart.new(stream, fsize)
              parts << StringPart.new( "\r\n--" + boundary + "\r\n" )
            rescue Exception => e
              p 'failed to load filestream '+ filestream.path
              p e.message
              raise 'failed to load filestream ' + e.message
            end
      
          end
      
          post_stream = MultipartStream.new( parts )  
      
          url = URI.parse( to_url )
          req = method == :post ? Net::HTTP::Post.new(url.path) : Net::HTTP::Put.new(url.path)
          req.content_length = post_stream.size
          req.content_type = 'multipart/mixed; boundary=' + boundary
          req["myheader1"] = 'header1'
          req["myheader2"] = 'header2'
      
          req.body_stream = post_stream  
          res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }  
      
          streams.each do |stream|  
            stream.close();  
          end  
      
          res  
        end  
      
      end  
      
      class StreamPart  
        def initialize( stream, size )  
          @stream, @size = stream, size  
        end  
      
        def size  
          @size  
        end  
      
        def read( offset, how_much )  
          @stream.read( how_much )  
        end  
      end  
      
      class StringPart  
        def initialize ( str )  
          @str = str  
        end  
      
        def size  
          @str.length  
        end  
      
        def read ( offset, how_much )  
          @str[offset, how_much]  
        end  
      end  
      
      class MultipartStream  
        def initialize( parts )  
          @parts = parts  
          @part_no = 0;  
          @part_offset = 0;  
        end  
      
      
      
        def size  
          total = 0  
          @parts.each do |part|  
            total += part.size  
          end  
          total  
        end  
      
        def read ( how_much )  
          if @part_no >= @parts.size  
            return nil;  
          end  
      
          how_much_current_part = @parts[@part_no].size - @part_offset  
      
          how_much_current_part = if how_much_current_part > how_much  
            how_much  
          else  
            how_much_current_part  
          end  
      
          how_much_next_part = how_much - how_much_current_part  
      
          current_part = @parts[@part_no].read(@part_offset, how_much_current_part )  
      
          if how_much_next_part > 0  
            @part_no += 1
            @part_changed=true
            @part_offset = 0  
            next_part = read( how_much_next_part  )  
            current_part + if next_part  
              next_part  
            else  
              ''  
            end  
          else  
            @part_offset += how_much_current_part  
            current_part  
          end  
        end  
      
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-21
        • 1970-01-01
        • 2010-12-20
        • 2017-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-23
        相关资源
        最近更新 更多