2010-09-28 3 views
0

En utilisant http://github.com/archiloque/rest-clientarchiloque-repos-client: changement de type de contenu à multipart/related lorsque vous posez un fichier

Lorsque vous rédigez un fichier en utilisant cette ligne, le type de contenu est défini comme

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

dans l'en-tête, par défaut.

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

J'ai essayé ceci et il fixe toujours l'en-tête multipart/form-data.

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

Est-ce que quelqu'un a essayé de régler multipart/related?

Répondre

0

Ok. Je ne pouvais pas trouver une meilleure alternative, donc fini avec l'application suivante.

Il est basé sur ce code ici. http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html

Utilisation:

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") 

Note: Ce code n'est pas prêt pour la production. C'est juste fonctionnel.

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 
Questions connexes