有没有办法使用 set_form 方法在多部分请求中设置内容类型?
Is there a way to set Content-type in multipart request with set_form method?
我需要使用 net/http class 方法 "set_form" 将 Content-type = "application/pdf"
设置为请求的参数,但它总是显示 Content-Type = "application/octet-stream".
我已经查看了 documentation for set_form 但我不知道如何正确设置 Content-Type。
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new("#{path}")
request.set_form([
["parameter1","#{parameter1}"],
["parameter2","#{parameter2}"],
["attachment", File.new("/home/name.pdf", "rb")]
], 'multipart/form-data')
response = http.request(request)
我已经尝试使用此代码来设置类似文档的 opt hash,但我收到了相同的回复:
uri = URI.parse("#{host}")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new("#{path}")
request.set_form([
["parameter1","#{parameter1}"],
["parameter2","#{parameter2}"],
["attachment", File.new("/home/name.pdf", "rb"), { "Content-Type" => "application/pdf" }]
], 'multipart/form-data')
response = http.request(request)
实际输出还是Content-Type: application/octet-stream
但我需要:
... Content-Disposition: form-data; name=\"attachment\"; filename=\"name.pdf\"\r\nContent-Type: application/pdf\r\n\r\n%PDF-1.5\r%\xE2\xE ...
在我看来,这对于多部分请求是不可能的,正如您在 code for the set_form
method 中看到的那样,当设置不同的内容类型时,它应该会引发错误。
# File net/http/header.rb, line 452
def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
@body_data = params
@body = nil
@body_stream = nil
@form_option = formopt
case enctype
when /\Aapplication\/x-www-form-urlencoded\z/i,
/\Amultipart\/form-data\z/i
self.content_type = enctype
else
raise ArgumentError, "invalid enctype: #{enctype}"
end
end
肯定有我的其他答案中的解决方法,或者您可以简单地使用不同的 http 客户端,如 HTTParty,它支持多部分请求的不同内容类型,开始阅读 the example here and continue in the source code on Github。我还没有找到更好的文档。
我找到了这个 (https://dradisframework.com/blog/2017/04/dradis-attachments-api-using-ruby/),不确定是否有帮助。
此代码为请求构建单独的正文部分。
require 'net/http'
uri = URI('http://dradis.ip/pro/api/nodes/18/attachments')
Net::HTTP.start(uri.host, uri.port) do |http|
# Read attachments associated to a specific node:
get_request = Net::HTTP::Get.new uri
get_request['Authorization'] = 'Token token="iOEFCQDR-miTHNTjiBxObjWC"'
get_request['Dradis-Project-Id'] = '8'
get_response = http.request(get_request)
puts get_response.body
# Attach some other files to that node:
BOUNDARY = "AaB03x"
file1 = '/your/local/path/image1.png'
file2 = '/your/local/path/image2.png'
post_body = []
post_body << "--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data; name=\"files[]\"; filename=\"#{File.basename(file1)}\"\r\n"
post_body << "Content-Type: image/png\r\n"
post_body << "\r\n"
post_body << File.read(file1)
post_body << "\r\n--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data; name=\"files[]\"; filename=\"#{File.basename(file2)}\"\r\n"
post_body << "Content-Type: image/png\r\n"
post_body << "\r\n"
post_body << File.read(file2)
post_body << "\r\n--#{BOUNDARY}--\r\n"
post_request = Net::HTTP::Post.new uri
post_request['Authorization'] = 'Token token="iOEFCQDR-miTHNTjiBxObjWC"'
post_request['Dradis-Project-Id'] = '8'
post_request.body = post_body.join
post_request["Content-Type"] = "multipart/form-data, boundary=#{BOUNDARY}"
post_response = http.request(post_request)
puts post_response.body
end
对于那些仍在寻找如何使用 Net::HTTP 进行操作的人,您应该这样做:
request.set_form(
[
['attachment', File.open('myfile.pdf'), content_type: 'application/pdf', filename: 'my-better-filename.pdf']
],
'multipart/form-data'
)
选项 content_type
和 filename
是可选的。默认情况下,内容类型为 application/octet-stream
,文件名是您要打开的文件的名称。
我需要使用 net/http class 方法 "set_form" 将 Content-type = "application/pdf"
设置为请求的参数,但它总是显示 Content-Type = "application/octet-stream".
我已经查看了 documentation for set_form 但我不知道如何正确设置 Content-Type。
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new("#{path}")
request.set_form([
["parameter1","#{parameter1}"],
["parameter2","#{parameter2}"],
["attachment", File.new("/home/name.pdf", "rb")]
], 'multipart/form-data')
response = http.request(request)
我已经尝试使用此代码来设置类似文档的 opt hash,但我收到了相同的回复:
uri = URI.parse("#{host}")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new("#{path}")
request.set_form([
["parameter1","#{parameter1}"],
["parameter2","#{parameter2}"],
["attachment", File.new("/home/name.pdf", "rb"), { "Content-Type" => "application/pdf" }]
], 'multipart/form-data')
response = http.request(request)
实际输出还是Content-Type: application/octet-stream
但我需要:
... Content-Disposition: form-data; name=\"attachment\"; filename=\"name.pdf\"\r\nContent-Type: application/pdf\r\n\r\n%PDF-1.5\r%\xE2\xE ...
在我看来,这对于多部分请求是不可能的,正如您在 code for the set_form
method 中看到的那样,当设置不同的内容类型时,它应该会引发错误。
# File net/http/header.rb, line 452
def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
@body_data = params
@body = nil
@body_stream = nil
@form_option = formopt
case enctype
when /\Aapplication\/x-www-form-urlencoded\z/i,
/\Amultipart\/form-data\z/i
self.content_type = enctype
else
raise ArgumentError, "invalid enctype: #{enctype}"
end
end
肯定有我的其他答案中的解决方法,或者您可以简单地使用不同的 http 客户端,如 HTTParty,它支持多部分请求的不同内容类型,开始阅读 the example here and continue in the source code on Github。我还没有找到更好的文档。
我找到了这个 (https://dradisframework.com/blog/2017/04/dradis-attachments-api-using-ruby/),不确定是否有帮助。
此代码为请求构建单独的正文部分。
require 'net/http'
uri = URI('http://dradis.ip/pro/api/nodes/18/attachments')
Net::HTTP.start(uri.host, uri.port) do |http|
# Read attachments associated to a specific node:
get_request = Net::HTTP::Get.new uri
get_request['Authorization'] = 'Token token="iOEFCQDR-miTHNTjiBxObjWC"'
get_request['Dradis-Project-Id'] = '8'
get_response = http.request(get_request)
puts get_response.body
# Attach some other files to that node:
BOUNDARY = "AaB03x"
file1 = '/your/local/path/image1.png'
file2 = '/your/local/path/image2.png'
post_body = []
post_body << "--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data; name=\"files[]\"; filename=\"#{File.basename(file1)}\"\r\n"
post_body << "Content-Type: image/png\r\n"
post_body << "\r\n"
post_body << File.read(file1)
post_body << "\r\n--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data; name=\"files[]\"; filename=\"#{File.basename(file2)}\"\r\n"
post_body << "Content-Type: image/png\r\n"
post_body << "\r\n"
post_body << File.read(file2)
post_body << "\r\n--#{BOUNDARY}--\r\n"
post_request = Net::HTTP::Post.new uri
post_request['Authorization'] = 'Token token="iOEFCQDR-miTHNTjiBxObjWC"'
post_request['Dradis-Project-Id'] = '8'
post_request.body = post_body.join
post_request["Content-Type"] = "multipart/form-data, boundary=#{BOUNDARY}"
post_response = http.request(post_request)
puts post_response.body
end
对于那些仍在寻找如何使用 Net::HTTP 进行操作的人,您应该这样做:
request.set_form(
[
['attachment', File.open('myfile.pdf'), content_type: 'application/pdf', filename: 'my-better-filename.pdf']
],
'multipart/form-data'
)
选项 content_type
和 filename
是可选的。默认情况下,内容类型为 application/octet-stream
,文件名是您要打开的文件的名称。