2010-07-20 19 views
9

J'écris un composant middleware rack pour une application rails qui devra conditionnellement mettre en place des cookies. J'essaie actuellement de trouver des cookies. De googler autour, il semble que cela devrait fonctionner:Comment définir un cookie avec un composant middleware (ruby) rack?

class RackApp 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    @status, @headers, @response = @app.call(env) 
    @response.set_cookie("foo", {:value => "bar", :path => "/", :expires => Time.now+24*60*60}) 
    [@status, @headers, @response] 
    end 
end 

qui ne donne pas d'erreurs, mais ne fixe pas un cookie soit. Qu'est-ce que je fais mal?

Répondre

23

Si vous souhaitez utiliser la classe Response, vous devez l'instancier à partir des résultats de l'appel de la couche de middleware plus bas dans la pile. En outre, vous n'avez pas besoin variables d'instance pour un middleware comme celui-ci et probablement ne veulent pas les utiliser de cette façon (@ statut, etc. resterait autour de l'instance middleware après signification de la demande)

class RackApp 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    status, headers, body = @app.call(env) 
    # confusingly, response takes its args in a different order 
    # than rack requires them to be passed on 
    # I know it's because most likely you'll modify the body, 
    # and the defaults are fine for the others. But, it still bothers me. 

    response = Rack::Response.new body, status, headers 

    response.set_cookie("foo", {:value => "bar", :path => "/", :expires => Time.now+24*60*60}) 
    response.finish # finish writes out the response in the expected format. 
    end 
end 

Si vous savez ce que vous faites, vous pouvez directement modifier l'en-tête du cookie, si vous ne souhaitez pas instancier un nouvel objet.

+0

Impressionnant. Cela fonctionne parfaitement pour moi. L'exemple le plus clair que j'ai vu jusqu'ici. – phaedryx

+0

Merci! Cinq ans plus tard, cet extrait était exactement ce que je cherchais. – Anurag

+0

@BaroqueBobcat Ce serait vraiment utile si vous aviez inclus comment vous pourriez directement modifier le cookie. Merci pour la bonne réponse! – thesecretmaster

13

Vous pouvez également utiliser la bibliothèque Rack::Utils pour définir et supprimer des en-têtes sans créer d'objet Rack :: Response.

class RackApp 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    status, headers, body = @app.call(env) 

    Rack::Utils.set_cookie_header!(headers, "foo", {:value => "bar", :path => "/"}) 

    [status, headers, body] 
    end 
end