Skip to content

Commit

Permalink
Merge branch 'redirect_middleware' of git://github.com/wishdev/em-htt…
Browse files Browse the repository at this point in the history
…p-request
  • Loading branch information
igrigorik committed May 1, 2011
2 parents 483d921 + ee2e6dd commit c90c670
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/em-http/client.rb
@@ -1,4 +1,8 @@
module EventMachine

class InvalidRedirectError < StandardError
end

class HttpClient
include Deferrable
include HttpEncoding
Expand Down Expand Up @@ -82,9 +86,17 @@ def unbind
if redirect?

begin
@state = :redirecting
@conn.middleware.each do |m|
m.response(self) if m.respond_to?(:response)
end
@state = :finished
@req.followed += 1
@req.set_uri(@response_header.location)
@conn.redirect(self)
rescue EventMachine::InvalidRedirectError
@state = :finished
succeed(self)
rescue Exception => e
on_error(e.message)
end
Expand Down
53 changes: 53 additions & 0 deletions spec/redirect_spec.rb
@@ -1,5 +1,30 @@
require 'helper'

class RedirectMiddleware
class << self
attr_accessor :call_count
end

RedirectMiddleware.call_count = 0

def request(c, h, r)
RedirectMiddleware.call_count += 1
h['EM-Middleware'] = RedirectMiddleware.call_count.to_s
[h, r]
end

def response(r)
RedirectMiddleware.call_count = (r.response_header['EM_MIDDLEWARE'].to_i + 1)
end
end

class PickyRedirectMiddleware < RedirectMiddleware
def response(r)
raise EventMachine::InvalidRedirectError if r.state == :redirecting && r.response_header['LOCATION'][-1] == '3'
super
end
end

describe EventMachine::HttpRequest do

it "should follow location redirects" do
Expand Down Expand Up @@ -147,4 +172,32 @@
}
end

it "should call middleware each time it redirects" do
EventMachine.run {
conn = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/middleware_redirects_1')
conn.use RedirectMiddleware
http = conn.get :redirects => 3
http.errback { failed(http) }
http.callback {
http.response_header.status.should == 200
RedirectMiddleware.call_count.should == 6
EM.stop
}
}
end

it "should call middleware which may reject a redirection" do
EventMachine.run {
conn = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/middleware_redirects_1')
conn.use PickyRedirectMiddleware
http = conn.get :redirects => 3
http.errback { failed(http) }
http.callback {
http.response_header.status.should == 301
http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/redirect/middleware_redirects_2'
EM.stop
}
}
end

end
14 changes: 14 additions & 0 deletions spec/stallion.rb
Expand Up @@ -132,6 +132,20 @@ def self.call(env)
stable.response.status = 301
stable.response["Location"] = "/"

elsif stable.request.path_info == '/redirect/middleware_redirects_1'
stable.response.status = 301
stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
stable.response["Location"] = "/redirect/middleware_redirects_2"

elsif stable.request.path_info == '/redirect/middleware_redirects_2'
stable.response.status = 301
stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
stable.response["Location"] = "/redirect/middleware_redirects_3"

elsif stable.request.path_info == '/redirect/middleware_redirects_3'
stable.response.status = 200
stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]

elsif stable.request.path_info == '/redirect/nohost'
stable.response.status = 301
stable.response["Location"] = "http:/"
Expand Down

0 comments on commit c90c670

Please sign in to comment.