Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leaves RuntimeError (can't modify frozen Hash) when used with ActionController::Live Streaming #7

Closed
dimroc opened this issue Dec 16, 2014 · 7 comments

Comments

@dimroc
Copy link
Contributor

dimroc commented Dec 16, 2014

I actually have no need to use the csrf with a streaming controller but because the gem places an after_filter on all controllers, I encounter the crash:

Completed 500 Internal Server Error in 113ms

RuntimeError (can't modify frozen Hash):
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/action_dispatch/middleware/cookies.rb:316:in `[]='
  /Users/dimroc/workspace/angular_rails_csrf/lib/angular_rails_csrf/concern.rb:10:in `set_xsrf_token_cookie'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:427:in `block in make_lambda'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:236:in `call'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:236:in `block in halting'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:169:in `call'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:169:in `block in halting'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:92:in `call'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:92:in `_run_callbacks'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/callbacks.rb:81:in `run_callbacks'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/abstract_controller/callbacks.rb:19:in `process_action'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/action_controller/metal/rescue.rb:29:in `process_action'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/notifications.rb:164:in `block in instrument'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activesupport-4.2.0.rc3/lib/active_support/notifications.rb:164:in `instrument'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/activerecord-4.2.0.rc3/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/abstract_controller/base.rb:137:in `process'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionview-4.2.0.rc3/lib/action_view/rendering.rb:30:in `process'
  /Users/dimroc/.rvm/gems/ruby-2.1.5@loopandtie/gems/actionpack-4.2.0.rc3/lib/action_controller/metal/live.rb:278:in `block in process'

Any Controller like the one below will get an error in the after_filer:

class ServerSideEventsController < ApplicationController
  include ActionController::Live
  ...
end

Some reference on Live::Streaming
http://dius.com.au/2014/03/21/server-sent-events-rails-4-angularjs/

Could there perhaps be a way to exclude certain controllers from the after_filter?

@dimroc
Copy link
Contributor Author

dimroc commented Dec 16, 2014

Here is some good reading: https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb#L23

  # There are a few caveats with this use. You *cannot* write headers after the
  # response has been committed (Response#committed? will return truthy).
  # Calling +write+ or +close+ on the response stream will cause the response
  # object to be committed. Make sure all headers are set before calling write
  # or close on your stream.

@jsanders
Copy link
Owner

Thanks a lot for this report! I definitely hadn't tested against an application with any streaming actions. I'll take a look, but I think your suggestion of leaving out the after_filter for some actions is the right idea.

@baweaver
Copy link

Might be as simple as making this a before_filter or allowing for a protect_from_forgery except: [:action]

@sime
Copy link

sime commented Apr 16, 2015

I have just experienced this exact error with ActionController::Live though I do not use this gem. Though I am testing my new production environment behind Cloudflare and cannot reproduce it consistently.

Is it a good idea in general to protect_from_forgery except: [:action] or skip_before_action :verify_authenticity_token on streaming actions/controllers?

@baweaver
Copy link

baweaver commented Jun 4, 2015

@dimroc Might want to close this issue as well 😄

@jsanders
Copy link
Owner

jsanders commented Jun 4, 2015

Ah yeah, fixed by #10. Thanks!

@jsanders jsanders closed this as completed Jun 4, 2015
@bodrovis
Copy link
Collaborator

Due to problems with Devise #17 reverted to after_action. Still, the exclude_xsrf_token_cookie class method was introduced as suggested above. It can be added for streaming controllers to get rif of CSRF token. These changes are in master and a new version will be released soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants