* 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).