I have a Rails 6 API-only application and I'm using Nginx and passenger.
When I try to do GET or POST in the Postman application or other places, I get only cached responses.
For instance, if I try to get user 1, movies, I'll get the correct ones, but if I change the JWT to user 2, I still see the previous response which was for user 1.
I have tried a few options such as:
In production.rb I added:
config.action_controller.perform_caching = false
config.cache_store = :null_store
I have also tried the controller level by adding: expires_now which in the header shows no-cache and also with expires_in 5.seconds, public: false which shows max-age=5, private as the header, but I still get the same response for any user.
you can use a command to disable cache in rails app: rails dev:cache
Related
Having server issues with an app in Rails 5.0.0.beta2 trying to use ActionCable.
Using localhost:3000 works fine, as that is what most of ActionCable defaults to. But if I try to run the rails server on port 3001, it gives me Request origin not allowed: http://localhost:3001
The ActionCable docs mention using something like ActionCable.server.config.allowed_request_origins = ['http://localhost:3001'] which does work for me if I put it in config.ru
But that seems like a really weird place to put it. I feel like it should be able to go in an initializer file, or my development.rb environment config file.
To further prove my point that it should be allowed to go in there, the setting ActionCable.server.config.disable_request_forgery_protection = true works to ignore request origin, even when I include it in development.rb.
Why would ActionCable.server.config.disable_request_forgery_protection work in development.rb, but ActionCable.server.config.allowed_request_origins doesn't (but does work in config.ru)?
Not a pressing issue, since I have several options as a work around. I just want to know if I'm missing something obvious about how I imagine this should be working.
You can put
Rails.application.config.action_cable.allowed_request_origins = ['http://localhost:3001'] in your development.rb
See https://github.com/rails/rails/tree/master/actioncable#allowed-request-origins for more informations
For my flutter app, request origin was nil. So, needed to add nil in the list.
I have added this code in config/environments/development.rb, and it works!
config.action_cable.allowed_request_origins = [/http:\/\/*/, /https:\/\/*/, /file:\/\/*/, 'file://', nil]
From this answer, you can also add the following code to config/environments/development.rb to allow requests from both http and https:
Rails.application.configure do
# ...
config.action_cable.allowed_request_origins = [%r{https?://\S+}]
end
config.action_cable.allowed_request_origins accepts an array of strings or regular expressions as the documentation states:
Action Cable will only accept requests from specified origins, which
are passed to the server config as an array. The origins can be
instances of strings or regular expressions, against which a check for
the match will be performed.
The regex listed below will match both http and https urls from any domain so be careful when using them. It is just a matter of preference which one to use.
[%r{https?://\S+}] # Taken from this answer
[%r{http[s]?://\S+}]
[%r{http://*}, %r{https://*}]
[/http:\/\/*/, /https:\/\/*/]
as you now, in development mode the "perform_caching" configuration in action_controller is set to false by default. this configuration is in config/environments/development.rb:
config.action_controller.perform_caching = false
i tried a bunch of difference views(both html and json) and after a refresh, the requests were all 304(cached). so what is perform_caching doing here exactly?
by the way, i didn't use any caching method such as (cache , stale , cache_page , cache_action , ...) and maybe this is why perform_caching is not working. so how is this caching implemented?
My understanding was that to use http caching in Rails 3, all I had to do was add something like this to the action
expires_in(10.seconds, :public => true)
but when I do this, it tries to write to tmp/cache in addition to performing http caching in the browser (same user request for that action doesn't ever hit the server, as expected)
Why is this? How do I stop Rails from writing to the cache directory for http caching?
PS: I'm using nginx+passenger
The things that writes to /tmp/cache is Rack::Cache::FileStore that is configurable via config.cache_store; It's a rails3 native proxy-cache;
if you want to disable it:
config.action_dispatch.rack_cache = nil
Another solution is to not use the :public => true setting in expires_in. It appears that this setting is the reason why Rack::Cache writes the response to cache. If you set it to private => true (the default), this doesn't happen
Given that Heroku Cedar doesn't have http caching provided by Varnish I would like to use Rack::Cache.
I have been told that rails 3.1.1 have Rack::Cache active by default, I just need to make sure to have in the configuration:
config.action_controller.perform_caching = true
and I need to pick a cache store, for this experiment I'm using:
config.cache_store = :memory_store
In the action of the page I want to cache I've added the following lines:
response.header['Cache-Control'] = 'public, max-age=300'
response.header['Expires'] = CGI.rfc1123_date(Time.now + 300)
This code used to work fine with Varnish, the first request would return a 200 and the subsequent (for 5 mins) would return a 304.
This doesn't happen with Rails 3.1 and Heroku Cedar Stack.
I do get those headers in the response but subsequent requests returns 200 instead of 304.
What am I doing wrong? Thank you.
As you noted, the Cedar stack doesn't use Varnish. That means a web request will always hit the ruby server.
With that in mind, Rack::Cache will respect your headers and serve the cached content.
However, since the request is actually going past the http layer into the rails app, the response will always be 200 since the cache doesn't happen at the http layer anymore.
To confirm this is true, insert this in one of your cached actions:
<%= Time.now.to_i %>
Then, reload the page several times and you'll notice the timestamp won't change.
This is probably very simple but I can't figure out why I get no error pages.
First off, I'm using Heroku for hosting, so it's definitely in production mode.
If I set the line "config.action_controller.consider_all_requests_local" set to true, I get a detailed error message but otherwise, I get a completely 100% blank screen. If I view the source, also blank.
All my 404,422,500.html files are in public and I haven't touched them.
And they seem to work on my local machine if I start in production mode there. So it must have to do with Heroku? Any ideas?
The logs tell me nothing useful.
Below is the details of the production.rb file
config.cache_classes = true
#ActionMailer::Base.delivery_method = :sendmail
Paperclip.options[:command_path] = "/usr/bin/"
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# set delivery method to :smtp, :sendmail or :test
config.action_mailer.delivery_method = :smtp
# Full error reports are disabled and caching is turned on
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.action_view.cache_template_loading = true
I don't think Heroku uses the .html files like Passenger or Mongrel do. You may need to catch and handle your own exceptions through two basic mechanisms:
Create an exception handler with rescue_from in your ApplicationController for anything that might explode, both specifically and up to and including Object.
Create a default route to catch anything that isn't otherwise routed.
If you bust out of your routing table, or trigger a "500" error, it's because of exceptions. These need to be handled or you'll get a blank screen unless the web server is configured otherwise.
Apache can be configured to do this with the ErrorDocument directive.