Пример сервера и клиента для вопросов о Rack Hijack Proxy - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть пример приложения для прокси-сервера Hijack

io_lambda = lambda{ |io|
      3.times do |i|
        puts i
        io.write "David\r\n"
      end
      io.close
    }

run lambda{ |req|
      [
        200,
        [ [ "rack.hijack", io_lambda ] ],
        [""]
      ]
    }

и запуска его

rackup config.ru -p 3000

Теперь я пытаюсь написать для него код клиента.Во-первых, просто сверните его:

curl http://localhost:3000 -vv

и получите следующий клиентский вывод:

* Rebuilt URL to: http://localhost:3000/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
<
David
David
* transfer closed with outstanding read data remaining
* stopped the pause stream!
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining

сейчас, с httparty:

require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)

response = HTTParty.get('http://localhost:3000')
puts response.body, response.code, response.message, response.headers.inspect

Я получаю:

→ ruby httparty-client.rb
Traceback (most recent call last):
    18: from httparty-client.rb:5:in `<main>'
    17: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:627:in `get'
    16: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:508:in `get'
    15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:594:in `perform_request'
    14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty/request.rb:145:in `perform'
    13: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1470:in `request'
    12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
    11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1472:in `block in request'
    10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
     9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
     8: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:166:in `reading_body'
     7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:229:in `body'
     6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
     5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
     4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
     3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
     2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:321:in `read_chunked'
     1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
    19: from httparty-client.rb:5:in `<main>'
    18: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:627:in `get'
    17: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:508:in `get'
    16: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:594:in `perform_request'
    15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty/request.rb:145:in `perform'
    14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1470:in `request'
    13: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
    12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1472:in `block in request'
    11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
    10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
     9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:166:in `reading_body'
     8: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:229:in `body'
     7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
     6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
     5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
     4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
     3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `read_chunked'
     2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `ensure in read_chunked'
     1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)

последняя попытка с net / http:

require 'net/http'

streamURL = 'http://localhost:3000'

uri = URI.parse(streamURL)

Net::HTTP.start(uri.host, uri.port) do |http|
  request = Net::HTTP::Get.new uri.request_uri

  http.request request do |response|
    response.read_body do |chunk|
       #We get the data here chunk-by-chunk
       puts chunk
    end
  end
end

Я получаю:

→ ruby net-http-client.rb
David
David
David
David
Traceback (most recent call last):
    15: from net-http-client.rb:7:in `<main>'
    14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:605:in `start'
    13: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
    12: from net-http-client.rb:10:in `block in <main>'
    11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
    10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
     9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:165:in `reading_body'
     8: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1518:in `block in transport_request'
     7: from net-http-client.rb:11:in `block (2 levels) in <main>'
     6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
     5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
     4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
     3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
     2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:321:in `read_chunked'
     1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
    16: from net-http-client.rb:7:in `<main>'
    15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:605:in `start'
    14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
    13: from net-http-client.rb:10:in `block in <main>'
    12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
    11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
    10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:165:in `reading_body'
     9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1518:in `block in transport_request'
     8: from net-http-client.rb:11:in `block (2 levels) in <main>'
     7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
     6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
     5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
     4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
     3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `read_chunked'
     2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `ensure in read_chunked'
     1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)

Может кто-нибудь объяснить мне:

1) Зачем возвращать скручиваниеDavid x2, httparty - ничего и net / http - David x4, а сервер отправил 5?Также мне любопытно, почему результаты httparty и net / http различаются, потому что один использует другой под капотом.

2) Почему во всех случаях мы имеем ошибку (transfer closed with outstanding read data remaining и end of file reached (EOFError))?

...