* Why env.object_id is different in each middleware?
@ 2009-12-09 22:59 Iñaki Baz Castillo
2009-12-09 23:15 ` Iñaki Baz Castillo
0 siblings, 1 reply; 7+ messages in thread
From: Iñaki Baz Castillo @ 2009-12-09 22:59 UTC (permalink / raw)
To: rack-devel
Hi, I've realized that env.object_id is different when inspecting it in each
middleware or final application in a Rack builder. How is possible?
In my case I use this simple builder:
---------------------------------------
::Rack::Builder.new do
use ::Clogger, ...
map "/", &::MyApp.handle_request
end
class MyApp
def self.handle_request
proc do run Proc.new { |env|
::MyApp::Request.handle(env)
} end
end
end
---------------------------------------
If I check env.object_id into Clogger call method, and also into
MyApp.ahndle_request, they have different values.
Since env is a hash I cannot understand why its object_id changes. Any
explanatuion for it?
This explains that when I change env[XXX] into my final appplication
MyApp.handle_request the change doesn't exist after calling
resp = @app.call(env)
in the first middleware.
Thanks a lot.
--
Iñaki Baz Castillo <ibc@aliax.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Why env.object_id is different in each middleware?
2009-12-09 22:59 Why env.object_id is different in each middleware? Iñaki Baz Castillo
@ 2009-12-09 23:15 ` Iñaki Baz Castillo
2010-01-04 0:50 ` Tim Carey-Smith
0 siblings, 1 reply; 7+ messages in thread
From: Iñaki Baz Castillo @ 2009-12-09 23:15 UTC (permalink / raw)
To: rack-devel
El Miércoles, 9 de Diciembre de 2009, Iñaki Baz Castillo escribió:
> Since env is a hash I cannot understand why its object_id changes. Any
> explanation for it?
> This explains that when I change env[XXX] into my final appplication
> MyApp.handle_request the change doesn't exist after calling
> resp = @app.call(env)
> in the first middleware.
If I add a env["LALA"] in the first middleware then it's visible for following
middlewares.
However if I add env["LOLO"] in the second middleware this is not visible for
first middleware after calling "@app.call(env)".
Is it the expected behavior?
Thanks.
--
Iñaki Baz Castillo <ibc@aliax.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Why env.object_id is different in each middleware?
2009-12-09 23:15 ` Iñaki Baz Castillo
@ 2010-01-04 0:50 ` Tim Carey-Smith
2010-01-04 0:58 ` Iñaki Baz Castillo
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Tim Carey-Smith @ 2010-01-04 0:50 UTC (permalink / raw)
To: rack-devel
On 10/12/2009, at 12:15 PM, Iñaki Baz Castillo wrote:
> El Miércoles, 9 de Diciembre de 2009, Iñaki Baz Castillo escribió:
>> Since env is a hash I cannot understand why its object_id changes.
>> Any
>> explanation for it?
>> This explains that when I change env[XXX] into my final appplication
>> MyApp.handle_request the change doesn't exist after calling
>> resp = @app.call(env)
>> in the first middleware.
>
> If I add a env["LALA"] in the first middleware then it's visible for
> following
> middlewares.
> However if I add env["LOLO"] in the second middleware this is not
> visible for
> first middleware after calling "@app.call(env)".
>
> Is it the expected behavior?
>
> Thanks.
Hi there,
I've hit this before. This is because you are using Rack::URLMap (via
Builder#map).
The inner app is called with a new env hash.
> diff --git a/lib/rack/urlmap.rb b/lib/rack/urlmap.rb
> index b699d35..3374535 100644
> --- a/lib/rack/urlmap.rb
> +++ b/lib/rack/urlmap.rb
> @@ -45,7 +45,7 @@ module Rack
> next unless rest.empty? || rest[0] == ?/
>
> return app.call(
> - env.merge(
> + env.merge!(
> 'SCRIPT_NAME' => (script_name + location),
> 'PATH_INFO' => rest))
> }
Is this patch useful?
Is it useful to assume that a request will only have a single env hash?
Will it make Rack::Cascade and friends behave incorrectly?
Should URLMap revert the change in an ensure to allow subsequent
requests to function?
Hope this explains the behaviour,
Tim
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Why env.object_id is different in each middleware?
2010-01-04 0:50 ` Tim Carey-Smith
@ 2010-01-04 0:58 ` Iñaki Baz Castillo
2010-01-04 19:44 ` Iñaki Baz Castillo
2010-01-05 20:57 ` Ryan Tomayko
2 siblings, 0 replies; 7+ messages in thread
From: Iñaki Baz Castillo @ 2010-01-04 0:58 UTC (permalink / raw)
To: rack-devel
El Lunes, 4 de Enero de 2010, Tim Carey-Smith escribió:
> > diff --git a/lib/rack/urlmap.rb b/lib/rack/urlmap.rb
> > index b699d35..3374535 100644
> > --- a/lib/rack/urlmap.rb
> > +++ b/lib/rack/urlmap.rb
> > @@ -45,7 +45,7 @@ module Rack
> > next unless rest.empty? || rest[0] == ?/
> >
> > return app.call(
> > - env.merge(
> > + env.merge!(
> > 'SCRIPT_NAME' => (script_name + location),
> > 'PATH_INFO' => rest))
> > }
>
> Is this patch useful?
> Is it useful to assume that a request will only have a single env hash?
> Will it make Rack::Cascade and friends behave incorrectly?
>
> Should URLMap revert the change in an ensure to allow subsequent
> requests to function?
>
> Hope this explains the behaviour,
Yes it does :)
Thanks.
--
Iñaki Baz Castillo <ibc@aliax.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Why env.object_id is different in each middleware?
2010-01-04 0:50 ` Tim Carey-Smith
2010-01-04 0:58 ` Iñaki Baz Castillo
@ 2010-01-04 19:44 ` Iñaki Baz Castillo
2010-01-05 20:57 ` Ryan Tomayko
2 siblings, 0 replies; 7+ messages in thread
From: Iñaki Baz Castillo @ 2010-01-04 19:44 UTC (permalink / raw)
To: rack-devel
El Lunes, 4 de Enero de 2010, Tim Carey-Smith escribió:
> Is this patch useful?
> Is it useful to assume that a request will only have a single env hash?
> Will it make Rack::Cascade and friends behave incorrectly?
>
> Should URLMap revert the change in an ensure to allow subsequent
> requests to function?
A workaround is creating an initial middleware (like rack-config), adding some
empty entries to env hash and latter, in other middlewares or final
application, using env["NEW_ENTRY"].replace.
Of course this is a hack as it's only valid if the new entry is a String or an
object supporting "replace".
class Init
def initialize(app)
@app = app
end
def call(env)
# Create env["REMOTE_USER"] so it can be latter replaced
# (String#replaced) by the main application and Clogger will log it.
env["REMOTE_USER"] = ""
@app.call(env)
end
end
And in config.ru:
---------------------------------
use Init
use ::Clogger, xxxxx
run MyApp.new
---------------------------------
Then in case env["REMOTE_USER"] is set into MyApp it should be set as follows:
class MyApp
def call(env)
...getting username string...
env["REMOTE_USER"].replace(username)
...
end
end
Would be any performance penalty in using env.merge! like you suggest rather
than env.merge?
Regards.
--
Iñaki Baz Castillo <ibc@aliax.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Why env.object_id is different in each middleware?
2010-01-04 0:50 ` Tim Carey-Smith
2010-01-04 0:58 ` Iñaki Baz Castillo
2010-01-04 19:44 ` Iñaki Baz Castillo
@ 2010-01-05 20:57 ` Ryan Tomayko
2010-01-05 23:47 ` Iñaki Baz Castillo
2 siblings, 1 reply; 7+ messages in thread
From: Ryan Tomayko @ 2010-01-05 20:57 UTC (permalink / raw)
To: rack-devel
On Sun, Jan 3, 2010 at 4:50 PM, Tim Carey-Smith <g@spork.in> wrote:
> On 10/12/2009, at 12:15 PM, Iñaki Baz Castillo wrote:
>
>> El Miércoles, 9 de Diciembre de 2009, Iñaki Baz Castillo escribió:
>>>
>>> Since env is a hash I cannot understand why its object_id changes. Any
>>> explanation for it?
>>> This explains that when I change env[XXX] into my final appplication
>>> MyApp.handle_request the change doesn't exist after calling
>>> resp = @app.call(env)
>>> in the first middleware.
>>
>> If I add a env["LALA"] in the first middleware then it's visible for
>> following
>> middlewares.
>> However if I add env["LOLO"] in the second middleware this is not visible
>> for
>> first middleware after calling "@app.call(env)".
>>
>> Is it the expected behavior?
>>
>> Thanks.
>
> Hi there,
>
> I've hit this before. This is because you are using Rack::URLMap (via
> Builder#map).
> The inner app is called with a new env hash.
>
>> diff --git a/lib/rack/urlmap.rb b/lib/rack/urlmap.rb
>> index b699d35..3374535 100644
>> --- a/lib/rack/urlmap.rb
>> +++ b/lib/rack/urlmap.rb
>> @@ -45,7 +45,7 @@ module Rack
>> next unless rest.empty? || rest[0] == ?/
>>
>> return app.call(
>> - env.merge(
>> + env.merge!(
>> 'SCRIPT_NAME' => (script_name + location),
>> 'PATH_INFO' => rest))
>> }
>
> Is this patch useful?
> Is it useful to assume that a request will only have a single env hash?
> Will it make Rack::Cascade and friends behave incorrectly?
>
> Should URLMap revert the change in an ensure to allow subsequent requests to
> function?
This is something I've always thought should be included in the rack
spec. Should a rack component, A, that calls another component, B, be
able to assume that env modifications made by B (or downstream) will
be visible in the env passed by A when B returns? As of right now,
there's a number of core and contrib middleware that assume: no. The
URLMap example above is a good one. A lot of middleware pass a copy of
the env downstream instead of modifying and relaying the env provided.
I see this come up fairly often but I'm not sure there's ever been a
good use case for it. It's usually a sign that you're using the env
where you should be using the response tuple. e.g., instead of putting
something in the env, put it in the response headers or convey it via
status code.
Or maybe this really is something the env could be useful for and I've
just never run into a good case. Can anyone provide real examples of
where it would be necessary?
Thanks,
Ryan
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Why env.object_id is different in each middleware?
2010-01-05 20:57 ` Ryan Tomayko
@ 2010-01-05 23:47 ` Iñaki Baz Castillo
0 siblings, 0 replies; 7+ messages in thread
From: Iñaki Baz Castillo @ 2010-01-05 23:47 UTC (permalink / raw)
To: rack-devel
El Martes, 5 de Enero de 2010, Ryan Tomayko escribió:
> Or maybe this really is something the env could be useful for and I've
> just never run into a good case. Can anyone provide real examples of
> where it would be necessary?
My real case:
I want to use Clogger to log the authenticated user ($env["REMOTE_USER"]).
Clogger expects that it runs after an authentication middleware which adds
such env entry. However in my case I need to decide the "remote_user" in the
final Rack application so I need that changes done in env by the last Rack
application are visible for previous middlewares (Clogger).
Perhaps env shouldn't be used for this purpose, but what else? adding such
info in the response headers seem a hack to me, what about if I want to pass
an object or a hash rather than a single string?
--
Iñaki Baz Castillo <ibc@aliax.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-01-05 23:47 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-09 22:59 Why env.object_id is different in each middleware? Iñaki Baz Castillo
2009-12-09 23:15 ` Iñaki Baz Castillo
2010-01-04 0:50 ` Tim Carey-Smith
2010-01-04 0:58 ` Iñaki Baz Castillo
2010-01-04 19:44 ` Iñaki Baz Castillo
2010-01-05 20:57 ` Ryan Tomayko
2010-01-05 23:47 ` Iñaki Baz Castillo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).