Skip to content

Commit

Permalink
add respond! action to return arbitrary status/contents as response
Browse files Browse the repository at this point in the history
Also fix response to return message/contents as string in array, not bare string.
  • Loading branch information
joshsusser committed Dec 23, 2009
1 parent 62da8b0 commit c6238a6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
15 changes: 15 additions & 0 deletions README.md
Expand Up @@ -40,6 +40,10 @@ Refraction can be installed in a Rails application as a plugin.

$ script/plugin install git://github.com/pivotal/refraction.git

It can also be used as a gem:

$ gem install refraction

In `environments/production.rb`, add Refraction at or near the top of your middleware stack.

config.middleware.insert_before(::Rack::Lock, ::Refraction, {})
Expand Down Expand Up @@ -102,6 +106,17 @@ The `found!` method tells Refraction to return a response with a `302 Found` sta
URL for the Location header. Like `#rewrite!` it can take either a string or hash argument to set
the URL or some of its components.

### `RequestContext#respond!(status, headers, content)`

Use `respond!` to return an arbitrary response to the request. This is useful for responding with
the contents of a static file. For example:

req.respond!(503, {'Content-Type' => 'text/html'}, File.read(MAINTENANCE_PATH))

The args are largely the same as the contents of a standard Rack response array with the exceptions
that you don't need to wrap the content in an array, and the Content-Length header is generated so it
should not be supplied.

### URL components

The request object provides the following components of the URL for matching requests: `scheme`,
Expand Down
18 changes: 11 additions & 7 deletions lib/refraction.rb
Expand Up @@ -26,12 +26,9 @@ def initialize(env)
end

def response
headers = {
'Location' => location,
'Content-Type' => 'text/plain',
'Content-Length' => message.length.to_s
}
[status, headers, message]
headers = @headers || { 'Location' => location, 'Content-Type' => 'text/plain' }
headers['Content-Length'] = message.length.to_s
[status, headers, [message]]
end

# URI part accessors
Expand Down Expand Up @@ -95,6 +92,13 @@ def found!(options)
@message = "moved to #{@uri}"
end

def respond!(status, headers, content)
@action = :respond
@status = status
@headers = headers
@message = content
end

def location
@uri.to_s
end
Expand Down Expand Up @@ -124,7 +128,7 @@ def call(env)
self.rules.call(context)

case context.action
when :permanent, :found
when :permanent, :found, :respond
context.response
when :rewrite
env["rack.url_scheme"] = context.scheme
Expand Down
18 changes: 18 additions & 0 deletions spec/refraction_spec.rb
Expand Up @@ -173,6 +173,24 @@
end
end

describe "generate arbitrary response" do
before(:each) do
Refraction.configure do |req|
req.respond!(503, {'Content-Type' => 'text/plain'}, "Site down for maintenance.")
end
end

it "should respond with status, headers and content" do
env = Rack::MockRequest.env_for('http://example.com', :method => 'get')
app = mock('app')
response = Refraction.new(app).call(env)
response[0].should == 503
response[1]['Content-Length'].to_i.should == "Site down for maintenance.".length
response[1]['Content-Type'].should == "text/plain"
response[2].should == ["Site down for maintenance."]
end
end

describe "environment" do
before(:each) do
Refraction.configure do |req|
Expand Down

0 comments on commit c6238a6

Please sign in to comment.