Ruby on rails archiloque rest客户端:设置文件姿势时,将内容类型更改为多部分/相关
使用 使用此行过帐文件时,内容类型设置为Ruby on rails archiloque rest客户端:设置文件姿势时,将内容类型更改为多部分/相关,ruby-on-rails,rest-client,Ruby On Rails,Rest Client,使用 使用此行过帐文件时,内容类型设置为 Content-Type: multipart/form-data; boundary=301405 默认情况下,在标题中 RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb') 我尝试了这个,但它仍然设置了头多部分/表单数据 RestClient.post '/data', :myfile => File.new("/path/to/image.
Content-Type: multipart/form-data; boundary=301405
默认情况下,在标题中
RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')
我尝试了这个,但它仍然设置了头多部分/表单数据
RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb'), :content_type => 'multipart/related'
有人试过设置多部分/相关吗?好。我找不到更好的选择,所以最终使用了以下应用程序 它基于这里的代码。 用法:
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")
files={File.new(“myfile1”、“rb”)、File.new(“myfile2”、“rb”)}
mpost=multipart(“主”、“文件”)
mpost.post(“我们的url”,“post”)
注意:此代码尚未准备好生产。它只是功能性的
----------------multipart.rb-------------
需要“net/http”
需要“uri”
需要“pp”
需要“mime/类型”
类多部分
def初始化(主部分id、主部分内容、文件名)
@文件名=文件名
@main\u part\u id=main\u part\u id
@主要部分内容=主要部分内容
结束
def post(to_url,method=:post)
boundary=“####-----#{Time.new}-----####”
部分=[]
流=[]
#先写主要部分
零件或者您可以使用全新的ish多零件车身宝石:
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