2017-03-12 3 views
0

Je suis au courant de l'existence des bibliothèques qui renvoient des réponses HTTP comme struct s:retour ipv4 GET repsonse binaire brut en élixir

> HTTPoison.get!("http://httpbin.org/get") 
> %HTTPoison.Response{body: "{\n \"args\": {}, \n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"User-Agent\": \"hackney/1.6.6\"\n }, \n \"origin\": \"86.30.176.31\", \n \"url\": \"http://httpbin.org/get\"\n}\n", headers: [{"Server", "nginx"}, {"Date", "Sun, 12 Mar 2017 06:05:29 GMT"},{"Content-Type", "application/json"}, {"Content-Length", "165"}, {"Connection", "keep-alive"}, {"Access-Control-Allow-Origin", "*"}, {"Access-Control-Allow-Credentials", "true"}], status_code: 200} 

Mais comment puis-je obtenir la forme binary brute d'un paquet de réponse HTTP ipv4 en élixir?

Selon la suggestion de Dogbert, j'ai essayé d'utiliser gen_tcp, mais on m'a donné les éléments suivants:

iex(1)> {:ok, port} = :gen_tcp.connect('httpbin.org',80,[:binary, active: 
false, packet: :http]) 
{:ok, #Port<0.6531>} 
iex(2)> :gen_tcp.send(port, "GET /get HTTP/1.1\r\nHost: httpbin.org\r\n") 
:ok 
iex(3)> :gen_tcp.recv(port,0) 
{:error, :closed} 

ce que je fais mal ici?

+0

Si la demande est un simple GET, vous pouvez utiliser 'gen_tcp' directement. Si c'est plus complexe, je crois que ['hackney'] (https://github.com/benoitc/hackney) doit avoir une option pour obtenir la réponse brute mais je n'arrive pas à la trouver. – Dogbert

+0

Si c'est juste pour déboguer, peut-être que [Wireshark] (https://www.wireshark.org/) serait une bonne option pour vous? –

+0

@PatrickOscity - essayé, mais je cherche quelque chose que je peux reproduire dans Elixir. – category

Répondre

0

Se débarrasser de l'option packet: :http dans gen_tcp.connect et en ajoutant un autre \r\n à la fin du texte HTTP résolu le problème:

iex(3)> {:ok, packet_binary} = :gen_tcp.recv(port,0) 
{:ok, {:http_response, {1, 1}, 200, 'OK'}} 

iex(4)> {:ok, port} = :gen_tcp.connect('httpbin.org',80,[:binary, active: false])    
{:ok, #Port<0.6706>} 

iex(5)> :gen_tcp.send(port, "GET /get HTTP/1.1\r\nHost: httpbin.org\r\n\r\n")  
:ok 

iex(6)> {:ok, packet_binary} = :gen_tcp.recv(port,0)        
{:ok, 
"HTTP/1.1 200 OK\r\nServer: nginx\r\nDate: Sun, 12 Mar 2017 14:01:05 GMT\r\nContent-Type: application/json\r\nContent-Length: 129\r\nConnection: keep-alive\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\n\r\n{\n \"args\": {}, \n \"headers\": {\n \"Host\": \"httpbin.org\"\n }, \n \"origin\": \"86.30.176.31\", \n \"url\": \"http://httpbin.org/get\"\n}\n"} 

iex(7)> IO.puts(packet_binary) 
HTTP/1.1 200 OK 
Server: nginx 
Date: Sun, 12 Mar 2017 14:01:05 GMT 
Content-Type: application/json 
Content-Length: 129 
Connection: keep-alive 
Access-Control-Allow-Origin: * 
Access-Control-Allow-Credentials: true 

{ 
    "args": {}, 
    "headers": { 
    "Host": "httpbin.org" 
    }, 
    "origin": "86.30.176.31", 
    "url": "http://httpbin.org/get" 
} 

:ok 

iex(8)> is_binary(packet_binary) 
true 
+0

hmmm effectivement je ne suis pas sûr à ce sujet - je dois vérifier que c'est un paquet ipv4 - ne semble pas correspondre à la spécification ipv4. – category