Reputation: 2383
I have a Rails 4.2 app with a heavy file upload traffic.
I want to override rack.multipart.tempfile_factory
in order to provide additional behaviour associated with the temporary files Rack creates under the hood when accepting file uploads.
So where and how do I change Rack's env
hash exactly? Tried doing env['...'] = ...
inside an initializer, said env
is undefined. Changing it to ENV
raises an error saying it cannot convert a lambda to String (rack.multipart.tempfile_factory
requires a lambda so I can't just change it to a String). Using request.env
inside a controller method has no effect whatsoever. I tested the last by copy-pasting the stock Rack factory's one line of code and added writing a random number to a file with a fixed path; that file never got created in the first place after uploading a few files, so there you go.
I am looking for an official solution and don't have the intention to monkey-patch Rack. Its spec states this is possible, so how exactly should I be doing it?
Of course, if all else fails, I will resort to hacking, but I'd prefer to hear the official ways of doing it first.
(And while we're at this, can you also recommend a gemless solution to override rack.hijack_io
, with some real-world examples? Searching for that thing in particular wasn't very helpful, nobody seems to provide an end-to-end working solution, only bits & pieces).
Thank you for your consideration.
Upvotes: 1
Views: 1256
Reputation: 1496
env
You just need to override Application#call
. In config/application.rb
(or config/environments/production.rb
if you like) you add this method:
class Application < Rails::Application
...
def call(env)
env["rack.multipart.tempfile_factory"] = ->(what, now) { "lambda time" }
super(env)
end
...
end
See #call for more info on that.
ENV
ENV
is a constant in Ruby that corresponds to the shell environment. This allows you to do things in your shell script like:
$ export MY_VAR=hahahaha
...
irb> ENV['MY_VAR'] #=> "hahahaha"
It's more than a Rack variable—it's a Ruby constant!
Your error "cannot convert lambda to string" is because all ENV
values must be Strings. So even if you do
$ export MY_VAR=42
You'll get
irb> ENV['MY_VAR'] #=> "42"
where "42"
is a String, not an Integer.
Upvotes: 2