def finalize_response(self, response, record_request=True):
        """Handle and persist analytics data.

        @param {object} response: The Werkzeug Response object.
        @param {bool} record_request: Should this request be persisted?
        @returns {object}: A WSGI callable response object.

        If a 'bid' cookie (browser id) has not been set on this browser, we record
        the new browser in the datastore and set a bid cookie on this browser for
        future use. If the response is not an HTTP error, we set the cookie to expire
        a year from now.

        If `record_request` is True, we persist this request meta data in the datastore and
        reset the 'rid' (request id) cookie on the browser; which will expire at the end of
        the browser session.

        The cache header is set to tell the browser to cache the returned page for
        4 days and keep an ETag for it. Lastly, we conditionally return a response
        body only if the ETag is not a match.
        """
        browser_id = self.request.cookies.get("bid")
        browser = None
        request = None
        user_agent = None
        status = response.status_code
        status_ok = status >= 200 and status < 300 or status is 304

        # Used to avoid datastore writes during automated testing.
        no_persist = self.no_persist

        response = self.set_default_headers(response)

        # TODO
        # if not browser_id:
        # We also send the browser_id as an ETag in some cases
        # etags = self.request.if_none_match
        # etag = len(etags) and etags.pop() or None
        # If ETag length > 32 (md5) it is a browser key and not a real ETag
        # browser_id = len(etag) > 32 and etag or None
        if not browser_id:
            user_agent = self.user_agent_repr
            browser = dstore.Browser(
                user_agent=user_agent,
                init_path=self.request.path,
                init_referrer=self.request.referrer,
                init_address=self.request.remote_addr,
            )
            browser.put()
            browser_id = dstore.browser_key(browser)

        # Reset the browser id cookie
        if status_ok:
            response.set_cookie("bid", value=browser_id, expires=(int(time.time()) + 31556926))  # Exp in 1 year.

        if record_request:
            user_agent = user_agent or self.user_agent_repr
            request = dstore.Request(
                browser=browser_id,
                user_agent=user_agent,
                path=self.request.path,
                referrer=self.request.referrer,
                address=self.request.remote_addr,
                status=(response.status_code or 0),
            )
            k = request.put()
            if status_ok:
                response.set_cookie("rid", value=str(k))

        # Delete during automated testing.
        if browser and no_persist:
            browser.delete()
        if request and no_persist:
            request.delete()

        # Caching is private since we're always setting a cookie.
        response.headers["Cache-Control"] = "private, max-age=%d" % (86400 * 4)

        # Do this last for an accurate conditional response.
        response.add_etag()

        # Only send a response body if the E-Tag does not match.
        return response.make_conditional(self.request)
Ejemplo n.º 2
0
  def finalize_response(self, response, record_request=True):
    browser_id = self.request.cookies.get('bid')
    browser = None
    request = None
    user_agent = None
    status = response.status_code 
    status_ok = status >= 200 and status < 300 or status is 304

    # Used to avoid datastore writes during automated testing.
    no_persist = self.no_persist

    response = set_common_headers(response)

    # TODO
    #if not browser_id:
      # We also send the browser_id as an ETag in some cases
      #etags = self.request.if_none_match
      #etag = len(etags) and etags.pop() or None
      # If ETag length > 32 (md5) it is a browser key and not a real ETag
      #browser_id = len(etag) > 32 and etag or None
    if not browser_id:
      user_agent = self.persist_user_agent
      browser = dstore.Browser(user_agent=user_agent
                             , init_path=self.request.path
                             , init_referrer=self.request.referrer
                             , init_address=self.request.remote_addr)
      browser.put()
      browser_id = dstore.browser_key(browser)

    # Reset the browser id cookie
    if status_ok:
      response.set_cookie('bid',
                          value=browser_id,
                          expires=(int(time.time()) + 31556926)) # Exp in 1 year.

    if record_request:
      user_agent = user_agent or self.persist_user_agent
      request = dstore.Request(browser=browser_id
                             , user_agent=user_agent
                             , path=self.request.path
                             , referrer=self.request.referrer
                             , address=self.request.remote_addr
                             , status=(response.status_code or 0))
      k = request.put()
      if status_ok:
        response.set_cookie('rid', value=str(k))

    # Delete during automated testing.
    if browser and no_persist:
      browser.delete()
    if request and no_persist:
      request.delete()

    # Caching is private since we're always setting a cookie.
    response.headers['Cache-Control'] = 'private, max-age=%d' % (86400 * 4)

    # Do this last for an accurate conditional response.
    response.add_etag()

    # Only send a response body if the E-Tag does not match.
    return response.make_conditional(self.request)