2014-07-02 16 views
6

sto cercando di trovare un modo per riprodurre una richiesta HTTP che invia i dati binari nel payload così come imposta un'intestazione Content-Type: binary, come il seguente comando con l'arricciatura:Come inviare dati binari tramite una richiesta HTTP utilizzando una gemma Ruby?

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 

ho già provato utilizzando il client REST (https://github.com/rest-client/rest-client) e HTTPClient (https://github.com/nahi/httpclient), ma senza successo. Usando il codice sotto il server ha risposto con HTTP 500. Qualcuno l'ha già fatto o non è possibile per lo scopo a cui sono state progettate le gemme? Codice

Rubino:

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 

UPDATE (w/una possibile soluzione)

ho finito per correre la richiesta con il HTTParty (seguendo la direzione data dal @DemonKingPiccolo) e ha funzionato. Ecco il codice:

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 

Il corpo può anche essere scritta come suggerito da @gumbo:

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

[httparty] (https://github.com/jnunemaker/httparty) potrebbe essere in grado di farlo. – Piccolo

+0

@DemonKingPiccolo grazie per il suggerimento. Lo guarderò. –

+1

Hai detto che hai provato "senza successo", ma cosa significa? –

risposta

5

Ho appena provato questo e ha funzionato come un fascino:

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> 

ho verificato che i dati POSTed correttamente utilizzando RequestBin.

Net::HTTP è veramente approssimativo e non è molto divertente da usare (ad esempio, devi formattare manualmente le intestazioni dei cookie). Il suo principale vantaggio è che è nella libreria standard. Una gemma come RestClient o HTTParty potrebbe essere una scelta migliore, e sono abbastanza sicuro che qualcuno di loro gestirà i dati binari almeno altrettanto facilmente.

+0

Grazie a jordan per presentarmi la rete :: HTTP. Ho modificato la descrizione della domanda con altre possibili soluzioni che ho raggiunto. –

+0

Riga seguente: req = NET :: HTTP :: Post.new (uri.path) ha un refuso corretto è: req = Net :: HTTP :: Post.new (uri.path) – raskhadafi

+1

@raskhadafi Buona cattura, grazie ! –

Problemi correlati