/
net_http.rb
executable file
·110 lines (91 loc) · 3.75 KB
/
net_http.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
require 'net/http'
require 'net/https'
require 'stringio'
module Net #:nodoc: all
class BufferedIO
def initialize_with_fredo(io, debug_output = nil)
@read_timeout = 60
@rbuf = ''
@debug_output = debug_output
@io = case io
when Socket, OpenSSL::SSL::SSLSocket, IO
io
when String
if !io.include?("\0") && File.exists?(io) && !File.directory?(io)
File.open(io, "r")
else
StringIO.new(io)
end
end
raise "Unable to create local socket" unless @io
end
alias_method :initialize_without_fredo, :initialize
alias_method :initialize, :initialize_with_fredo
end
class HTTP
# class << self
# def socket_type_with_fredo
# Fredo::StubSocket
# end
# alias_method :socket_type_without_fredo, :socket_type
# alias_method :socket_type, :socket_type_with_fredo
# end
def request_with_fredo(request, body = nil, &block)
request_body = body
case request_body
when nil then body = StringIO.new
when String then body = StringIO.new(body)
when File then body
else
body = StringIO.new(body.to_s)
end
uri = URI.parse(request.path)
protocol = use_ssl? ? "https" : "http"
full_path = "#{protocol}://#{self.address}:#{self.port}#{request.path}"
# It's for testing, we care about all the headers
request_headers = request.instance_variable_get :@header
request_headers = Hash[*request_headers.map {|k,v| [String(k).upcase.gsub(%r{[^_0-9A-Z]},"_"),v]}.flatten]
rack_env =request_headers.merge({'REQUEST_METHOD' => request.method,
'SCRIPT_NAME' => '',
'PATH_INFO' => uri.path,
'QUERY_STRING' => (uri.query || ''),
'SERVER_NAME' => self.address,
'SERVER_PORT' => self.port,
'rack.version' => [1,1],
'rack.url_scheme' => protocol,
'rack.input' => body,
'rack.errors' => $stderr,
'rack.multithread' => true,
'rack.multiprocess' => true,
'rack.run_once' => false})
# @socket = Net::HTTP.socket_type.new
# Perform the request
status, headers, body = Fredo.call(rack_env)
response = Net::HTTPResponse.send(:response_class, "#{status}").new("1.0", "#{status}", body)
response.instance_variable_set(:@body, body)
headers.each { |name, value| response[name] = value }
response.instance_variable_set(:@read, true)
def response.read_body(*args, &block)
yield @body.join("\n") if block_given?
@body.join("\n")
end
yield response if block_given?
response
rescue Fredo::NotFound
raise Fredo::NetConnectNotAllowedError.new(full_path) unless Fredo.allow_net_connect?
connect_without_fredo
return request_without_fredo(request, request_body, &block)
end
alias_method :request_without_fredo, :request
alias_method :request, :request_with_fredo
def connect_with_fredo
unless @@alredy_checked_for_net_http_replacement_libs ||= false
# Fredo::Utility.puts_warning_for_net_http_replacement_libs_if_needed
@@alredy_checked_for_net_http_replacement_libs = true
end
nil
end
alias_method :connect_without_fredo, :connect
alias_method :connect, :connect_with_fredo
end
end