From 52acdae90e9d4181d9cc231186e774c9d7fcc00d Mon Sep 17 00:00:00 2001
From: "Piotr S. Staszewski"
Date: Thu, 16 Apr 2020 19:39:41 +0200
Subject: [PATCH 1/2] Copy, paste and adjust from 2.6+
---
lib/evil-proxy/agentproxy.rb | 67 +++++++++++++++++++++++-------------
1 file changed, 43 insertions(+), 24 deletions(-)
diff --git a/lib/evil-proxy/agentproxy.rb b/lib/evil-proxy/agentproxy.rb
index 2652194..fe1369c 100644
--- a/lib/evil-proxy/agentproxy.rb
+++ b/lib/evil-proxy/agentproxy.rb
@@ -13,38 +13,57 @@ def fire key, *args
@mitm_server.fire key, *args, self
end
- def perform_proxy_request(req, res)
+ def perform_proxy_request(req, res, req_class, body_stream = nil)
uri = req.request_uri
path = uri.path.dup
path << "?" << uri.query if uri.query
- header = Hash.new
- choose_header(req, header)
- response = nil
+ header = setup_proxy_header(req, res)
+ upstream = setup_upstream_proxy_authentication(req, res, header)
- http = Net::HTTP.new(uri.host, uri.port)
+ body_tmp = []
+ http = Net::HTTP.new(uri.host, uri.port, upstream.host, upstream.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
- http.start do
- if @config[:ProxyTimeout]
- ################################## these issues are
- http.open_timeout = 30 # secs # necessary (maybe because
- http.read_timeout = 60 # secs # Ruby's bug, but why?)
- ##################################
- end
+ req_fib = Fiber.new do
+ http.start do
+ if @config[:ProxyTimeout]
+ ################################## these issues are
+ http.open_timeout = 30 # secs # necessary (maybe because
+ http.read_timeout = 60 # secs # Ruby's bug, but why?)
+ ##################################
+ end
+ if body_stream && req['transfer-encoding'] =~ /\bchunked\b/i
+ header['Transfer-Encoding'] = 'chunked'
+ end
+ http_req = req_class.new(path, header)
+ http_req.body_stream = body_stream if body_stream
+ http.request(http_req) do |response|
+ # Persistent connection requirements are mysterious for me.
+ # So I will close the connection in every response.
+ res['proxy-connection'] = "close"
+ res['connection'] = "close"
- response = yield(http, path, header)
+ # stream Net::HTTP::HTTPResponse to WEBrick::HTTPResponse
+ res.status = response.code.to_i
+ res.chunked = response.chunked?
+ choose_header(response, res)
+ set_cookie(response, res)
+ set_via(res)
+ response.read_body do |buf|
+ body_tmp << buf
+ Fiber.yield # wait for res.body Proc#call
+ end
+ end # http.request
+ end
+ end
+ req_fib.resume # read HTTP response headers and first chunk of the body
+ res.body = ->(socket) do
+ while buf = body_tmp.shift
+ socket.write(buf)
+ buf.clear
+ req_fib.resume # continue response.read_body
+ end
end
-
- # Persistent connection requirements are mysterious for me.
- # So I will close the connection in every response.
- res['proxy-connection'] = "close"
- res['connection'] = "close"
-
- # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPResponse
- res.status = response.code.to_i
- choose_header(response, res)
- set_cookie(response, res)
- res.body = response.body
end
def service req, res
From cf186814640d7f0e8bf3ac5dd4abc55cb8875ba9 Mon Sep 17 00:00:00 2001
From: "Piotr S. Staszewski"
Date: Thu, 16 Apr 2020 19:40:24 +0200
Subject: [PATCH 2/2] Adjust internal calls
---
lib/evil-proxy/httpproxy.rb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/evil-proxy/httpproxy.rb b/lib/evil-proxy/httpproxy.rb
index b099907..fe18e4a 100644
--- a/lib/evil-proxy/httpproxy.rb
+++ b/lib/evil-proxy/httpproxy.rb
@@ -69,25 +69,25 @@ def self.define_callback_methods callback
end
def do_PUT(req, res)
- perform_proxy_request(req, res) do |http, path, header|
+ perform_proxy_request(req, res, req.class) do |http, path, header|
http.put(path, req.body || '', header)
end
end
def do_DELETE(req, res)
- perform_proxy_request(req, res) do |http, path, header|
+ perform_proxy_request(req, res, req.class) do |http, path, header|
http.delete(path, header)
end
end
def do_PATCH(req, res)
- perform_proxy_request(req, res) do |http, path, header|
+ perform_proxy_request(req, res, req.class) do |http, path, header|
http.patch(path, req.body || '', header)
end
end
def do_OPTIONS(req, res)
- perform_proxy_request(req, res) do |http, path, header|
+ perform_proxy_request(req, res, req.class) do |http, path, header|
http.options(path, header)
end
end