Created
January 5, 2013 19:11
-
-
Save raggi/4463147 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Safeware | |
def initialize(app) | |
@app = app | |
end | |
# This dup pattern is used frequently to avoid race conditions on state stored | |
# inside this middleware. It's not foolproof, but if you're just using | |
# single-reference instance variables (instance variables with primitive | |
# values (not data structures)) then it works well. | |
def call(env) | |
dup._call(env) | |
end | |
def _call(env) | |
# before actions | |
status, headers, body = @app.call(env) | |
# after actions | |
return status, headers, body | |
ensure | |
# If we're raising an exception, then the body from the app will not be | |
# passed on to the server or any parent middleware. In order to conform to | |
# the body close specification, we therefore must close it here under that | |
# condition. n.b. it's possible that an exception occurs before body is set, | |
# so we check for body first. | |
body.close if body && body.respond_to?(:close) && $! | |
end | |
# TODO before and after action breakouts for the non-rack async api, with proc | |
# wrappers in env. | |
# TODO logging / errors integration | |
# TODO input rewind example | |
# ... | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
❤️ ❤️
Thanks for descriptive comments!