如何使用Ruby gem通过HTTP请求发送二进制数据?

 Ww不孤单_584 发布于 2023-01-06 16:44

我试图找到一种方法来重现在有效负载中发送二进制数据的HTTP请求以及设置Content-Type: binary标头,如下面的cURL命令:

echo -e '\x14\x00\x00\x00\x70\x69\x6e\x67\x00\x00' | curl -X POST \
-H 'Content-Type: binary' \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip,deflate,sdch' \
-H 'Accept-Language: en-US,en;q=0.8,pt;q=0.6' \
-H 'Cookie: JSESSIONID=m1q1hkaptxcqjuvruo5qugpf' \
--data-binary @- \
--url 'http://202.12.53.123' \
--trace-ascii /dev/stdout

我已经尝试过使用REST客户端(https://github.com/rest-client/rest-client)和HTTPClient(https://github.com/nahi/httpclient),但没有成功.使用下面的代码服务器使用HTTP 500进行响应.有没有人在之前完成它,或者它不可能用于设计宝石的目的?

Ruby代码:

require 'rest-client'
request = RestClient::Request.new(
  :method => :post, 
  :url => 'http://202.12.53.123', 
  :payload => %w[14 00 00 00 70 69 6e 67 00 00], 
  :headers => {
    :content_type => :binary,
    :accept => '*/*',
    :accept_encoding => 'gzip,deflate,sdch',
    :accept_language => 'en-US,en;q=0.8,pt;q=0.6',
    :cookies => {'JSESSIONID' => 'm1q1hkaptxcqjuvruo5qugpf'}
  }
)
request.execute

更新(有一个可能的解决方案)

我最终用HTTParty运行请求(遵循@DemonKingPiccolo给出的指示)并且它有效.这是代码:

require 'httparty'
hex_data = "14 00 00 00 70 69 6e 67 00 00"
response = HTTParty.post(
  'http://202.12.53.123', 
  :headers => {
    'Content-Type' => 'binary',
    'Accept-Encoding' => 'gzip,deflate,sdch',
    'Accept-Language' => 'en-US,en;q=0.8,pt;q=0.6'
  },
  :cookies => {'JSESSIONID' => 'm1q1hkaptxcqjuvruo5qugpf'},
  :body => [hex_data.gsub(/\s+/,'')].pack('H*').force_encoding('ascii-8bit')
)
puts response.body, response.code, response.message, response.headers.inspect

身体也可以按照@gumbo的建议书写:

%w[14 00 00 00 70 69 6e 67 00 00].map { |h| h.to_i(16) }.map(&:chr).join

Jordan Runni.. 6

我只是尝试了这个,它就像一个魅力:

require "net/http"

uri = URI("http://example.com/")

http = Net::HTTP.new(uri.host, uri.port)

req = Net::HTTP::Post.new(uri.path)
req.body = "\x14\x00\x00\x00\x70\x69\x6e\x67\x00\x00"
req.content_type = "application/octet-stream"

http.request(req)
# => #

我验证了使用RequestBin正确发布的数据.

Net :: HTTP非常粗糙,使用起来并不是很有趣(例如,您必须手动格式化Cookie标头).它的主要好处是它在标准库中.像RestClient或HTTParty这样的宝石可能是更好的选择,而且我很确定它们中的任何一个都至少可以轻松处理二进制数据.

1 个回答
  • 我只是尝试了这个,它就像一个魅力:

    require "net/http"
    
    uri = URI("http://example.com/")
    
    http = Net::HTTP.new(uri.host, uri.port)
    
    req = Net::HTTP::Post.new(uri.path)
    req.body = "\x14\x00\x00\x00\x70\x69\x6e\x67\x00\x00"
    req.content_type = "application/octet-stream"
    
    http.request(req)
    # => #<Net::HTTPOK 200 OK readbody=true>
    

    我验证了使用RequestBin正确发布的数据.

    Net :: HTTP非常粗糙,使用起来并不是很有趣(例如,您必须手动格式化Cookie标头).它的主要好处是它在标准库中.像RestClient或HTTParty这样的宝石可能是更好的选择,而且我很确定它们中的任何一个都至少可以轻松处理二进制数据.

    2023-01-06 16:46 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有