def __init__(self, request): self.request = request self.data = data = {} attrs = request.__dict__.copy() # environ is displayed separately del attrs['environ'] if 'response' in attrs: attrs['response'] = repr(attrs['response']) if 'session' in attrs: self.process_session_attr(self, attrs['session']) del attrs['session'] else: # only process the session if it's accessed callback_on_load(request, 'session', self.process_session_attr) data.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': [(k, saferepr(v)) for k, v in request.POST.items()], 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'environ': dictrepr(request.environ), 'extracted_attributes': {}, 'attrs': dictrepr(attrs), 'session': None, })
def content(self): vars = {} request = self.request attr_dict = request.__dict__.copy() # environ is displayed separately del attr_dict['environ'] if 'response' in attr_dict: attr_dict['response'] = repr(attr_dict['response']) vars.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': [(k, [saferepr(p) for p in request.POST.getall(k)]) for k in request.POST], 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'attrs': dictrepr(attr_dict), 'environ': dictrepr(request.environ), }) if hasattr(self.request, 'session'): vars.update({ 'session': dictrepr(self.request.session), }) return self.render( 'pyramid_debugtoolbar.panels:templates/request_vars.dbtmako', vars, request=self.request)
def content(self): vars = {} request = self.request attr_dict = request.__dict__.copy() # environ is displayed separately del attr_dict['environ'] if 'response' in attr_dict: attr_dict['response'] = repr(attr_dict['response']) vars.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': [(k, [saferepr(p) for p in request.POST.getall(k)]) for k in request.POST], 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'attrs': dictrepr(attr_dict), 'environ': dictrepr(request.environ), }) if hasattr(self.request, 'session'): vars.update({ 'session': dictrepr(self.request.session), }) return self.render( 'pyramid_debugtoolbar.panels:templates/request_vars.mako', vars, request=self.request)
def process_response(self, response): """ ``Response`` | "egress" Only process the ``Response``` if the panel is active OR if the session was accessed, as processing the ``Response`` requires opening the session. """ if self._request is None: # this scenario can happen if there is an error in the toolbar return data = self.data session = None if self.is_active or ("session" in self._request.__dict__): try: # if we installed a wrapped load, accessing the session now # will trigger the "main" marker. to handle this, check the # current version of the marker then access the session # and then reset the marker _accessed_main = data["session_accessed"]["main"] session = self._request.session except AttributeError: # the session is not configured pass if session is not None: data["session_accessed"]["main"] = _accessed_main for k, v in dictrepr(session): data["session_data"]["egress"][k] = v data["session_data"]["keys"].add(k) if (k not in data["session_data"]["ingress"]) or ( data["session_data"]["ingress"][k] != v): data["session_data"]["changed"].add(k)
def _process_session_accessed(_session): # The wrapper updates out information dict about how the # ``Session`` was accessed and notes the ingress values. data["session_accessed"]["main"] = True # process the inbound session data for k, v in dictrepr(_session): data["session_data"]["ingress"][k] = v data["session_data"]["keys"].add(k) return _session
def __init__(self, request): self.data = data = {} attr_dict = request.__dict__.copy() # environ is displayed separately del attr_dict['environ'] if 'response' in attr_dict: attr_dict['response'] = repr(attr_dict['response']) data.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': [(k, saferepr(v)) for k, v in request.POST.items()], 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'attrs': dictrepr(attr_dict), 'environ': dictrepr(request.environ), }) if hasattr(request, 'session'): data.update({ 'session': dictrepr(request.session), })
def __init__(self, request): self.data = data = {} attr_dict = request.__dict__.copy() # environ is displayed separately del attr_dict["environ"] if "response" in attr_dict: attr_dict["response"] = repr(attr_dict["response"]) data.update( { "get": [(k, request.GET.getall(k)) for k in request.GET], "post": [(k, saferepr(v)) for k, v in request.POST.items()], "cookies": [(k, request.cookies.get(k)) for k in request.cookies], "attrs": dictrepr(attr_dict), "environ": dictrepr(request.environ), } ) if hasattr(request, "session"): data.update({"session": dictrepr(request.session)})
def __init__(self, request): self.data = data = {} attr_dict = request.__dict__.copy() # environ is displayed separately del attr_dict['environ'] if 'response' in attr_dict: attr_dict['response'] = repr(attr_dict['response']) data.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': [(k, [saferepr(p) for p in request.POST.getall(k)]) for k in request.POST], 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'attrs': dictrepr(attr_dict), 'environ': dictrepr(request.environ), }) if hasattr(request, 'session'): data.update({ 'session': dictrepr(request.session), })
def __init__(self, request): self.request = request self.data = data = {} attrs = request.__dict__.copy() # environ is displayed separately del attrs['environ'] if 'response' in attrs: attrs['response'] = repr(attrs['response']) if 'session' in attrs: self.process_session_attr(self, attrs['session']) del attrs['session'] else: # only process the session if it's accessed wrap_load( request, 'session', self.process_session_attr, reify=True, ) for attr_, is_dict in lazy_request_attributes: wrap_load( request, attr_, lambda v: self.process_lazy_attr(attr_, is_dict, v), ) data.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': [(k, saferepr(v)) for k, v in request.POST.items()], 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'environ': dictrepr(request.environ), 'extracted_attributes': {}, 'attrs': dictrepr(attrs), 'session': None, })
def process_beforerender(self, event): if not self.renderings: self.renderings = [] name = event["renderer_info"].name if name and name.startswith("pyramid_debugtoolbar"): return val = getattr(event, "rendering_val", "<unknown>") try: val = repr(val) except: # crazyass code raises an exception during __repr__ (formish) val = "<unknown>" self.renderings.append(dict(name=name, system=dictrepr(event), val=text_(val, "utf-8")))
def process_beforerender(self, event): if not self.renderings: self.renderings = [] name = event['renderer_info'].name if name and name.startswith('pyramid_debugtoolbar'): return val = getattr(event, 'rendering_val', '<unknown>') try: val = repr(val) except: # crazyass code raises an exception during __repr__ (formish) val = '<unknown>' self.renderings.append(dict(name=name, system=dictrepr(event), val=val))
def process_session_attr(self, session): self.data.update({ 'session': dictrepr(session), }) return session
def __init__(self, request): self.request = request self.data = data = {} attrs = request.__dict__.copy() # environ is displayed separately del attrs['environ'] if 'response' in attrs: attrs['response'] = repr(attrs['response']) if 'session' in attrs: self.process_session_attr(attrs['session']) del attrs['session'] else: # only process the session if it's accessed wrap_load( request, 'session', self.process_session_attr, reify=True, ) for attr_, is_dict in lazy_request_attributes: wrap_load( request, attr_, lambda v: self.process_lazy_attr(attr_, is_dict, v), ) # safely displaying the POST information is a bit tedious post_variables = None post_body_info = { 'size': len(request.body), 'preview_bytes': None, } try: # PY2 # iterating request.POST in webob-1.8.1 will trigger an # exception here which will kill the `response` object and break # at-least the headers panel # `curl -d "@/path/to/file.jpg" -X POST http://app` # PY3: # the info seems decoded, but we can have 1400 items post_variables = [(saferepr(k), saferepr(v)) for k, v in request.POST.items()] except Exception: pass if not post_variables and request.body: # try to convert the POST data if it is text... try: _post_converted = request.text except Exception: _post_converted = "[... %s bytes (%s) ...]" % ( request.content_length, request.content_type, ) _post_preview_bytes = (_post_converted[:4096] if _post_converted else None) post_body_info['preview_bytes'] = _post_preview_bytes data.update({ 'get': [(k, request.GET.getall(k)) for k in request.GET], 'post': post_variables, 'post_body_info': post_body_info, 'cookies': [(k, request.cookies.get(k)) for k in request.cookies], 'environ': dictrepr(request.environ), 'extracted_attributes': {}, 'attrs': dictrepr(attrs), 'session': None, })
def wrap_handler(self, handler): """ ``wrap_handler`` allows us to monitor the entire lifecycle of the ``Request``. Instead of using this hook to create a new wrapped handler, we can just do the required analysis right here, and then invoke the original handler. Request | "ingress" Pre-process the ``Request`` if the panel is active, or if the ``Session`` has already been accessed, as the ``Request`` requires activating the ``Session`` interface. If pre-processing does not happen, the ``.session`` property will be replaced with a wrapped function which will invoke the ingress processing if the session is accessed. """ data = self.data if self.is_active: # not known on `.__init__` due to the toolbar's design. # no problem, it can be updated on `.wrap_handler` data["is_active"] = True if "session" in self._request.__dict__: # mark the ``Session`` as already accessed. # This can happen in two situations: # * The panel is activated by the user for extended logging # * The ``Session`` was accessed by another panel or higher tween data["session_accessed"]["pre"] = True if self.is_active or ("session" in self._request.__dict__): """ This block handles two situations: * The panel is activated by the user for extended logging * The ``Session`` was accessed by another panel or higher tween This uses a two-phased analysis, because we may trigger a generic ``AttributeError`` when accessing the ``Session`` if no ``ISessionFactory`` was configured. """ session = None try: session = self._request.session if not data["session_accessed"]["pre"]: data["session_accessed"]["panel_setup"] = True except AttributeError: # the ``ISession`` interface is not configured pass if session is not None: for k, v in dictrepr(session): data["session_data"]["ingress"][k] = v data["session_data"]["keys"].add(k) # Delete the loaded ``.session`` from the ``Request``; # it will be replaced with the wrapper function below. # note: This approach preserves the already-loaded # ``Session``, we are just wrapping it within # a function. if "session" in self._request.__dict__: del self._request.__dict__["session"] # If the ``Session`` was not already loaded, then we may have # just loaded it. This presents a problem for tracking, as we # will not know if the ``Session`` was accessed during the # request. # To handle this scenario, replace ``request.session`` with a # function to update the accessed marker and return the # already loaded session. def _session_accessed(self): # This function updates the ``self.data`` information dict, # and then returns the exact same ``Session`` we just # deleted from the ``Request``. data["session_accessed"]["main"] = True return session # Replace the existing ``ISession`` interface with the function. self._request.set_property(_session_accessed, name="session", reify=True) else: """ This block handles the default situation: * The ``Session`` has not been already accessed and the Panel is not enabled """ def _process_session_accessed(_session): # The wrapper updates out information dict about how the # ``Session`` was accessed and notes the ingress values. data["session_accessed"]["main"] = True # process the inbound session data for k, v in dictrepr(_session): data["session_data"]["ingress"][k] = v data["session_data"]["keys"].add(k) return _session # only process the session if it's accessed wrap_load( self._request, 'session', _process_session_accessed, reify=True, ) return handler