我有一个中间件,用于使用Bonjour在本地网络应用程序上宣布我的应用程序,但是当从rake或通过控制台调用Rails时,它也会宣布该服务.
我想排除这些情况,并且只在Rails作为服务器运行时使用Bonjour中间件.
中间件配置接受proc以在某些条件下使用以下内容排除中间件proc:
config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env|
env['HTTPS'] != 'on'
}
Run Code Online (Sandbox Code Playgroud)
但是,如何确定是从CLI,控制台还是作为服务器调用Rails?
我经常在Ruby on Rails的上下文中听到"中间件"这个术语.究竟是什么?你能提供具体的例子吗?
我写了一些Rack-Middleware,现在我正试着用Rspec测试它.但所有Rack-Middleware都使用'app'参数进行实例化,该参数代表Rails应用程序本身.你们怎么在Rspec嘲笑这个?
例如,
describe MyMiddleWare do
let(:app) { # How do I mock a Rails app object here? }
subject { MyMiddleWare.new(app: app) }
it 'should blah blah blah' do
# a bunch of tests go here
end
end
Run Code Online (Sandbox Code Playgroud) 最近我碰巧在Ruby代码中看到这个词use,当我正在浏览一些与goliath,middleware等相关的代码时.看起来它与include/ extend,和require.
有人可以解释为什么这个use关键字存在,以及它与include/有require什么不同?它是如何工作的,什么时候使用它?
由于不同的宝石如何在我的系统中相互作用,我将引擎安装到导轨应用程序上.我最近开始研究一种提供一些中间件功能的新gem.
有点像:
BaseApp
\
Engine
\
NewMiddlewareEngine
# BaseApp/Gemfile
gem 'Engine'
# Engine/Gemfile
gem 'NewMiddlewareEngine'
# rake middleware output:
user@laptop[BaseApp]$ bundle exec rake middleware
use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x6ebf30e1>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use CatchJsonParseErrors
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run BaseApp::Application.routes
Run Code Online (Sandbox Code Playgroud)
但是,我似乎无法让NewMiddlewareEngine显示在中间件中.我测试了这个:
BaseApp
\
NewMiddlewareEngine
# BaseApp/Gemfile …Run Code Online (Sandbox Code Playgroud) 我有一个Rails 4示例项目(博客),我创建了一个名为'request_timer'的简单中间件 config/initializers/request_timer.rb
#config/initializers/request_timer.rb
class RequestTimer
def initialize(app)
@app = app
end
def call(env)
start_time = Time.now
status, headers, response = @app.call(env)
stop_time = Time.now
[status, headers, response.body]
end
end
Run Code Online (Sandbox Code Playgroud)
我config/application.rb以两种方式添加了我的中间件
1)添加为常量
#config/application.rb
module Blog
class Application < Rails::Application
config.middleware.use RequestTimer
end
end
Run Code Online (Sandbox Code Playgroud)
这样当我尝试运行我的rails应用程序时,我收到了错误
/Users/sameera/workspace/ruby-rack/blog/config/application.rb:9:in `require': cannot load such file -- request_timer (LoadError)
from /Users/sameera/workspace/ruby-rack/blog/config/application.rb:9:in `<top (required)>'
from /Users/sameera/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.2/lib/rails/commands.rb:74:in `require'
from /Users/sameera/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.2/lib/rails/commands.rb:74:in `block in <top (required)>'
from /Users/sameera/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.2/lib/rails/commands.rb:71:in `tap'
from /Users/sameera/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.2/lib/rails/commands.rb:71:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in …Run Code Online (Sandbox Code Playgroud) 我有一个带有中间件的rails 4应用程序位于lib/some/middleware.rb,它当前通过初始化器注入到堆栈中,如下所示:
MyApp::Application.configure.do |config|
config.middleware.use 'Some::Middleware'
end
Run Code Online (Sandbox Code Playgroud)
不幸的是,每当我改变一些东西,我需要重新启动服务器.如何在开发模式下的每个请求上重新加载它?我已经看到类似的问题,在to_prepare块中使用自动加载或包装代码重新加载lib代码,但我不确定如何在这种情况下应用它.
谢谢, - FJM
更新#1
如果我尝试删除中间件,然后在to_prepare块中重新添加它,我会收到错误"无法修改冻结的数组".
对于最新版本的Ruby on Rails(在提出这个问题时有4个),实现修改请求/响应的代码(如身份验证机制)的首选方法是什么.我看到很多站点和教程都提倡Rack中间件,而似乎可以通过Action Controller过滤器方法实现相同的功能.
除了讨论首选方法之外,还可以比较每种方法的优缺点吗?在我的初步调查中,似乎动作控制器过滤器方法更紧密地集成到RoR应用程序中,这样您就可以绕过在某些控制器端点上运行某些过滤器,而中间件似乎无法具有该级别的控制.像这样的细节会很棒.谢谢!
ruby ruby-on-rails actioncontroller rack-middleware ruby-on-rails-4
每当针对我的仅使用API的Rails 5.x应用程序发送格式错误的JSON时,我都会收到异常,并且Rails将整个堆栈跟踪作为JSON返回.显然,我想回答一个很好的,自定义的,格式化的错误.
=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.6.0 (ruby 2.3.0-p0), codename: Sleepy Sunday Serenity
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
Started POST "/api/v1/identities/" for ::1 at 2016-10-26 18:42:32 +0200
ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
Error occurred while parsing request parameters.
Contents:
{
"whatever": …Run Code Online (Sandbox Code Playgroud) 我已经安装了rack-timeout gem并在初始化器中创建了rack_timeout.rb.我在Rack_timeout.rb中设置了Rack :: Timeout.service_timeout = 1.我想限制rack-timeout以在执行器超出控制器超时时停止执行api内部的控制器只能停止.我已经在lib里面创建了一个名为my_middleware.rb的自定义中间件.
class MyMiddleware < Rack::Timeout
def initialize(app, options = {})
@app = app
@exclude = options[:exclude]
end
def call(env)
if env['PATH_INFO'].include? "api"
super(env)
else
@app.call(env)
end
end
end
Run Code Online (Sandbox Code Playgroud)
配置/ development.rb
config.middleware.use "MyMiddleware"
Run Code Online (Sandbox Code Playgroud)
但它没有工作.机架超时是在发生超时时抛出异常.