[英]How are people testing rails 3.1 + force_ssl?
The force_ssl function in rails 3.1 is hardcoded to ignore the development environment, but not test. rails 3.1中的force_ssl函数是硬编码的,以忽略开发环境,但不进行测试。 This is giving me redirect errors in my (minitest) tests. 这给了我(minitest)测试中的重定向错误。 Is the solution to set up my test server to support ssl (if so, how?). 解决方案是设置我的测试服务器以支持ssl(如果是这样,如何?)。 If not, should I monkey patch force_ssl to ignore requests in test? 如果没有,我应该修补force_ssl来忽略测试中的请求吗?
def force_ssl(options = {})
host = options.delete(:host)
before_filter(options) do
if !request.ssl? && !Rails.env.development?
redirect_options = {:protocol => 'https://', :status => :moved_permanently}
redirect_options.merge!(:host => host) if host
flash.keep
redirect_to redirect_options
end
end
end
EDIT Found this chain, which confirms other people think this an issue, but doesn't look like there's a committed fix yet: https://github.com/rails/rails/pull/2630 编辑找到这个链,这证实了其他人认为这是一个问题,但看起来还没有一个承诺修复: https : //github.com/rails/rails/pull/2630
Another option instead of monkey patching the entire application is to just override force_ssl
in your test suite alone. 另一个选择而不是猴子修补整个应用程序只是仅在您的测试套件中覆盖force_ssl
。 For example, in test/test_helper.rb
you can add this: 例如,在test/test_helper.rb
您可以添加:
# We don't want SSL redirects in our test suite
module ActionController::ForceSSL::ClassMethods
def force_ssl(options = {})
# noop
end
end
Here's another approach, if you don't want to mess with monkey-patching... you can use a before filter. 这是另一种方法,如果你不想搞乱猴子修补......你可以使用前过滤器。 This is rspec, not minitest syntax, but you get the idea: 这是rspec,而不是最小的语法,但你明白了:
before(:each) do
request.env["rack.url_scheme"] = "https"
end
This convinces your controller that it got an SSL request. 这使您的控制器确信它收到了SSL请求。
A benefit of taking this approach is that you can actually write a test to ensure your controller requires SSL. 采用这种方法的好处是您可以实际编写测试以确保您的控制器需要SSL。 :) :)
If you are interested in testing with varying SSL, I did this on the setup of the functional test. 如果您对使用不同的SSL进行测试感兴趣,我会在功能测试的设置上做到这一点。
def setup
@request.env['HTTPS'] = 'on'
end
That's what I ended up doing after recently upgrading to Rails 3.1 and switching to the force_ssl
filter. 这是我最近升级到Rails 3.1并切换到force_ssl
过滤器后最终做的事情。 Monkey patch to the rescue! 猴子补丁救援!
In a new file at config/initializers/ignore_force_ssl_in_test.rb
在config/initializers/ignore_force_ssl_in_test.rb
的新文件中
module ActionController
module ForceSSL
module ClassMethods
def force_ssl(options = {})
before_filter(options) do
if !request.ssl? && !Rails.env.development? && !Rails.env.test?
redirect_to :protocol => 'https://', :status => :moved_permanently
end
end
end
end
end
end
What worked for me is similar to Kelly Sutton's . 对我有用的是与Kelly Sutton相似的 。 I monkey patches force_ssl
to ignore ssl requests in test environment, otherwise use the original rails implementation: 我在测试环境中使用补丁force_ssl
来忽略ssl请求,否则使用原来的rails实现:
module ActionController
module ForceSSL
module ClassMethods
alias_method :original_force_ssl, :force_ssl
def force_ssl(options = {})
unless Rails.env.test?
original_force_ssl(options)
end
end
end
end
end
This approach of Simon Carletti's works nicely: http://www.simonecarletti.com/blog/2011/05/configuring-rails-3-https-ssl/ Simon Carletti的这种方法非常有效: http : //www.simonecarletti.com/blog/2011/05/configuring-rails-3-https-ssl/
# config/application.rb
module MyApp
class Application < Rails::Application
config.force_ssl = true
end
end
# config/environments/test.rb
MyApp::Application.configure do
config.force_ssl = false
end
If you are looking for an answer in 2013. You can simply do: 如果您正在寻找2013年的答案。您可以这样做:
force_ssl if: :ssl_configured?
def ssl_configured?
!Rails.env.test?
end
Source: http://edgeapi.rubyonrails.org/classes/ActionController/ForceSSL/ClassMethods.html 资料来源: http : //edgeapi.rubyonrails.org/classes/ActionController/ForceSSL/ClassMethods.html
force_ssl unless Rails.env.test?
You can make test calls to app using ssl! 您可以使用ssl对应用程序进行测试调用!
https://eample.org/my/route/here
in get 'https://eample.org/my/route/here'
使用完整的uri与协议https://eample.org/my/route/here
get 'https://eample.org/my/route/here'
or use https!(true)
and https!(false)
to dynamically change behavior in INTEGRATION TEST 或使用https!(true)
和https!(false)
动态更改INTEGRATION TEST中的行为
https!(true) get "/users" https!(false)
For CONTROLLER you do not have to use SSL, because (I think) they directly call action as method, without routing and other transfer stuff. 对于CONTROLLER,您不必使用SSL,因为(我认为)他们直接将action视为方法,而不需要路由和其他传输。
Rails docs recommend using if: ssl_configured? Rails文档建议使用if:ssl_configured? with the force_ssl call. 使用force_ssl调用。 You can then do: 然后你可以这样做:
def ssl_configured?
!Rails.env.development? && !Rails.env.test?
end
Without having to monkey patch as official answer indicates. 正如官方答案所示,无需猴子补丁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.