def process(method, path, parameters = nil, headers = nil)
data = requestify(parameters)
path = interpret_uri(path) if path =~ %r{://}
path = "/#{path}" unless path[0] == ?/
@path = path
env = {}
if method == :get
env["QUERY_STRING"] = data
data = nil
end
env.update(
"REQUEST_METHOD" => method.to_s.upcase,
"REQUEST_URI" => path,
"HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"SERVER_PORT" => (https? ? "443" : "80"),
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
"CONTENT_LENGTH" => data ? data.length.to_s : nil,
"HTTP_COOKIE" => encode_cookies,
"HTTPS" => https? ? "on" : "off",
"HTTP_ACCEPT" => accept
)
(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
unless ActionController::Base.respond_to?(:clear_last_instantiation!)
ActionController::Base.module_eval { include ControllerCapture }
end
ActionController::Base.clear_last_instantiation!
env['rack.input'] = data.is_a?(IO) ? data : StringIO.new(data || '')
@status, @headers, result_body = ActionController::Dispatcher.new.mark_as_test_request!.call(env)
@request_count += 1
@controller = ActionController::Base.last_instantiation
@request = @controller.request
@response = @controller.response
@response.extend(TestResponseBehavior)
@html_document = nil
@headers['Status'] = @status
@status, @status_message = @status.split(/ /)
@status = @status.to_i
cgi_headers = Hash.new { |h,k| h[k] = [] }
@headers.each do |key, value|
cgi_headers[key.downcase] << value
end
cgi_headers['set-cookie'] = cgi_headers['set-cookie'].first
@headers = cgi_headers
@response.headers['cookie'] ||= []
(@headers['set-cookie'] || []).each do |cookie|
name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
@cookies[name] = value
@response.headers['cookie'] << CGI::Cookie::new("name" => name, "value" => value)
end
return status
rescue MultiPartNeededException
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"}))
return status
end