Skip to content

Instantly share code, notes, and snippets.

@jvanasco
Created February 8, 2012 16:58
Show Gist options
  • Save jvanasco/1771046 to your computer and use it in GitHub Desktop.
Save jvanasco/1771046 to your computer and use it in GitHub Desktop.
Pyramid Event Subscribers to migrate cookie data across redirects
def main(global_config,**settings):
...
config.add_subscriber(\
'myApp.subscribers.cookiexfer_new_request',
'pyramid.events.NewRequest')
config.add_subscriber(\
'myApp.subscribers.cookiexfer_new_response',
'pyramid.events.NewResponse')
...
import logging
log = logging.getLogger(__name__)
from pyramid.httpexceptions import HTTPException
import re
_cookiexfer_redirect_add_headers= True
_cookiexfer_redirect_add_headers__unique= True
_cookiexfer_redirect_session_save= True
_cookiexfer_redirect_session_save__unique = True
_cookiexfer_re_excludes= re.compile("^/(css|img|js|deform|_debug_toolbar)")
def cookiexfer_new_request(event):
"""cookiexfer_new_request(event) ; if there is a @cookie-xfer value in the session, will set the headers and then delete it"""
if re.match( _cookiexfer_re_excludes , event.request.path_info ):
return
log.debug('@cookie-xfer cookiexfer_new_request')
if _cookiexfer_redirect_session_save:
if '@cookie-xfer' in event.request.session:
log.debug("@cookie-xfer - migrating cookies FROM session")
event.request.response.headers.extend(event.request.session['@cookie-xfer'])
del event.request.session['@cookie-xfer']
def cookiexfer_new_response(event):
"""cookiexfer_new_response(event) ; migrates headers or saves cookies. NOTE you must either RETURN the exception , or RAISE it and include headers """
if re.match( _cookiexfer_re_excludes , event.request.path_info ):
return
if isinstance( event.response , HTTPException ):
log.debug('@cookie-xfer cookiexfer_new_response')
# cookies_request is populated if the exception is RETURNed
# cookies_request is not populated if the exception is RAISEd
cookies_request= [ (k,v) for (k,v) in event.request.response.headers.iteritems() if k == 'Set-Cookie']
# cookies_response is populated if the exception is created with headers specified
cookies_response= [ (k,v) for (k,v) in event.response.headers.iteritems() if k == 'Set-Cookie']
if cookies_request or cookies_response:
log.debug("@cookie-xfer - migrating cookies INTO session")
# make a var stash
headers_cookies_all= []
headers_cookies_unique= []
session_cookies_all= []
session_cookies_unique= []
# then precalculate how we'll save the cookies
if not _cookiexfer_redirect_add_headers__unique or not _cookiexfer_redirect_session_save__unique :
# headers only need migrated cookies
headers_cookies_all = cookies_request
# session needs to save cookies
session_cookies_all = cookies_request + cookies_response
if _cookiexfer_redirect_add_headers__unique or _cookiexfer_redirect_session_save__unique :
# do a 'seen' dict
_cookies_unique__seen= {}
# first we should favor the items that we specifically set in the response
# headers stay empty
headers_cookies_unique= []
# session should favor items from the resposne
session_cookies_unique = cookies_response
# and log them all as seen
# don't add them to the cookies_unique, because they're already in the object
for (k,v) in cookies_response:
_v= v.split(';')
if _v[0] not in _cookies_unique__seen:
_cookies_unique__seen[_v[0]]= True
# now add in new cookies
for (k,v) in cookies_request:
_v= v.split(';')
if _v[0] not in _cookies_unique__seen:
_cookies_unique__seen[_v[0]]= True
headers_cookies_unique.append( (k,v) )
session_cookies_unique.append( (k,v) )
# now start sending
if _cookiexfer_redirect_add_headers:
if _cookiexfer_redirect_add_headers__unique :
event.response.headers.extend( headers_cookies_unique )
else:
event.response.headers.extend( headers_cookies_all )
if _cookiexfer_redirect_session_save :
if _cookiexfer_redirect_session_save__unique:
event.request.session['@cookie-xfer']= session_cookies_unique
else:
event.request.session['@cookie-xfer']= session_cookies_all
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment