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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
module ActionDispatch
module Test
class MockRequest < Rack::MockRequest
MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
class << self
def env_for(path, opts)
headers = opts.delete(:headers)
method = (opts[:method] || opts["REQUEST_METHOD"]).to_s.upcase
opts[:method] = opts["REQUEST_METHOD"] = method
path = "/#{path}" unless path[0] == ?/
uri = URI.parse(path)
uri.host ||= "example.org"
if URI::HTTPS === uri
opts.update("SERVER_PORT" => "443", "HTTPS" => "on")
end
if method == "POST" && !opts.has_key?(:input)
opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
multipart = opts[:params].respond_to?(:any?) && opts[:params].any? { |k, v| UploadedFile === v }
if multipart
opts[:input] = multipart_body(opts.delete(:params))
opts["CONTENT_LENGTH"] ||= opts[:input].length.to_s
opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}"
else
params = opts.delete(:params)
opts[:input] = case params
when Hash then requestify(params)
when nil then ""
else params
end
end
end
params = opts[:params] || {}
if params.is_a?(String)
if method == "GET"
uri.query = params
else
opts[:input] = params
end
else
params.update(::Rack::Utils.parse_query(uri.query))
uri.query = requestify(params)
end
env = ::Rack::MockRequest.env_for(uri.to_s, opts)
(headers || {}).each do |key, value|
key = key.to_s.upcase.gsub(/-/, "_")
key = "HTTP_#{key}" unless env.has_key?(key) || key =~ /^HTTP_/
env[key] = value
end
env
end
private
def requestify(value, prefix = nil)
case value
when Array
value.map do |v|
requestify(v, "#{prefix}[]")
end.join("&")
when Hash
value.map do |k, v|
requestify(v, prefix ? "#{prefix}[#{::Rack::Utils.escape(k)}]" : ::Rack::Utils.escape(k))
end.join("&")
else
"#{prefix}=#{::Rack::Utils.escape(value)}"
end
end
def multipart_requestify(params, first=true)
p = Hash.new
params.each do |key, value|
k = first ? key.to_s : "[#{key}]"
if Hash === value
multipart_requestify(value, false).each do |subkey, subvalue|
p[k + subkey] = subvalue
end
else
p[k] = value
end
end
return p
end
def multipart_body(params)
multipart_requestify(params).map do |key, value|
if value.respond_to?(:original_filename)
::File.open(value.path, "rb") do |f|
f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
<<-EOF
--#{MULTIPART_BOUNDARY}\r
Content-Disposition: form-data; name="#{key}"; filename="#{::Rack::Utils.escape(value.original_filename)}"\r
Content-Type: #{value.content_type}\r
Content-Length: #{::File.stat(value.path).size}\r
\r
#{f.read}\r
EOF
end
else
<<-EOF
--#{MULTIPART_BOUNDARY}\r
Content-Disposition: form-data; name="#{key}"\r
\r
#{value}\r
EOF
end
end.join("")+"--#{MULTIPART_BOUNDARY}--\r"
end
end
end
end
end
|