def browser_timing_insertion(response, transaction):

    # No point continuing if header is empty. This can occur if
    # RUM is not enabled within the UI. It is assumed at this
    # point that if header is not empty, then footer will not be
    # empty. We don't want to generate the footer just yet as
    # want to do that as late as possible so that application
    # server time in footer is as accurate as possible. In
    # particular, if the response content is generated on demand
    # then the flattening of the response could take some time
    # and we want to track that. We thus generate footer below
    # at point of insertion.

    header = transaction.browser_timing_header()

    if not header:
        return response

    def html_to_be_inserted():
        return six.b(header) + six.b(transaction.browser_timing_footer())

    # Make sure we flatten any content first as it could be
    # stored as a list of strings in the response object. We
    # assign it back to the response object to avoid having
    # multiple copies of the string in memory at the same time
    # as we progress through steps below.

    result = insert_html_snippet(response.content, html_to_be_inserted)

    if result is not None:
        if transaction.settings.debug.log_autorum_middleware:
            _logger.debug(
                'RUM insertion from Django middleware '
                'triggered. Bytes added was %r.',
                len(result) - len(response.content))

        response.content = result

        if response.get('Content-Length', None):
            response['Content-Length'] = str(len(response.content))

    return response
def browser_timing_middleware(request, response):

    # Don't do anything if receive a streaming response which
    # was introduced in Django 1.5. Need to avoid this as there
    # will be no 'content' attribute. Alternatively there may be
    # a 'content' attribute which flattens the stream, which if
    # we access, will break the streaming and/or buffer what is
    # potentially a very large response in memory contrary to
    # what user wanted by explicitly using a streaming response
    # object in the first place. To preserve streaming but still
    # do RUM insertion, need to move to a WSGI middleware and
    # deal with how to update the content length.

    if hasattr(response, 'streaming_content'):
        return response

    # Need to be running within a valid web transaction.

    transaction = current_transaction()

    if not transaction:
        return response

    # Only insert RUM JavaScript headers and footers if enabled
    # in configuration and not already likely inserted.

    if not transaction.settings.browser_monitoring.enabled:
        return response

    if transaction.autorum_disabled:
        return response

    if not django_settings.browser_monitoring.auto_instrument:
        return response

    if transaction.rum_header_generated:
        return response

    # Only possible if the content type is one of the allowed
    # values. Normally this is just text/html, but optionally
    # could be defined to be list of further types. For example
    # a user may want to also perform insertion for
    # 'application/xhtml+xml'.

    ctype = response.get('Content-Type', '').lower().split(';')[0]

    if ctype not in transaction.settings.browser_monitoring.content_type:
        return response

    # Don't risk it if content encoding already set.

    if response.has_header('Content-Encoding'):
        return response

    # Don't risk it if content is actually within an attachment.

    cdisposition = response.get('Content-Disposition', '').lower()

    if cdisposition.split(';')[0].strip().lower() == 'attachment':
        return response

    # No point continuing if header is empty. This can occur if
    # RUM is not enabled within the UI. It is assumed at this
    # point that if header is not empty, then footer will not be
    # empty. We don't want to generate the footer just yet as
    # want to do that as late as possible so that application
    # server time in footer is as accurate as possible. In
    # particular, if the response content is generated on demand
    # then the flattening of the response could take some time
    # and we want to track that. We thus generate footer below
    # at point of insertion.

    header = transaction.browser_timing_header()

    if not header:
        return response

    def html_to_be_inserted():
        return six.b(header) + six.b(transaction.browser_timing_footer())

    # Make sure we flatten any content first as it could be
    # stored as a list of strings in the response object. We
    # assign it back to the response object to avoid having
    # multiple copies of the string in memory at the same time
    # as we progress through steps below.

    result = insert_html_snippet(response.content, html_to_be_inserted)

    if result is not None:
        if transaction.settings.debug.log_autorum_middleware:
            _logger.debug('RUM insertion from Django middleware '
                    'triggered. Bytes added was %r.',
                    len(result) - len(response.content))

        response.content = result
        response['Content-Length'] = str(len(response.content))

    return response
def _nr_wrapper_Compress_after_request(wrapped, instance, args, kwargs):
    def _params(response, *args, **kwargs):
        return response

    response = _params(*args, **kwargs)

    # If the response has direct_passthrough flagged, then is
    # likely to be streaming a file or other large response.
    # Leave the response alone in this situation even though
    # it looked like flask_compress doesn't honour it.

    #if getattr(response, 'direct_passthrough', None):
    #    return wrapped(*args, **kwargs)

    # Need to be running within a valid web transaction.

    transaction = current_transaction()

    if not transaction:
        return wrapped(*args, **kwargs)

    # Only insert RUM JavaScript headers and footers if enabled
    # in configuration and not already likely inserted.

    if not transaction.settings.browser_monitoring.enabled:
        return wrapped(*args, **kwargs)

    if transaction.autorum_disabled:
        return wrapped(*args, **kwargs)

    if not flask_compress_settings.browser_monitoring.auto_instrument:
        return wrapped(*args, **kwargs)

    if transaction.rum_header_generated:
        return wrapped(*args, **kwargs)

    # Only possible if the content type is one of the allowed
    # values. Normally this is just text/html, but optionally
    # could be defined to be list of further types. For example
    # a user may want to also perform insertion for
    # 'application/xhtml+xml'.

    ctype = response.mimetype.lower()

    if ctype not in transaction.settings.browser_monitoring.content_type:
        return wrapped(*args, **kwargs)


    # Don't risk it if content encoding already set.

    if 'Content-Encoding' in response.headers:
        return wrapped(*args, **kwargs)

    # Don't risk it if content is actually within an attachment.

    cdisposition = response.headers.get('Content-Disposition', '').lower()

    if cdisposition.split(';')[0].strip() == 'attachment':
        return wrapped(*args, **kwargs)

    # No point continuing if header is empty. This can occur if
    # RUM is not enabled within the UI. It is assumed at this
    # point that if header is not empty, then footer will not be
    # empty. We don't want to generate the footer just yet as
    # want to do that as late as possible so that application
    # server time in footer is as accurate as possible. In
    # particular, if the response content is generated on demand
    # then the flattening of the response could take some time
    # and we want to track that. We thus generate footer below
    # at point of insertion.

    header = transaction.browser_timing_header()

    if not header:
        return wrapped(*args, **kwargs)

    def html_to_be_inserted():
        return six.b(header) + six.b(transaction.browser_timing_footer())

    # Make sure we flatten any content first as it could be
    # stored as a list of strings in the response object. We
    # assign it back to the response object to avoid having
    # multiple copies of the string in memory at the same time
    # as we progress through steps below.

    result = insert_html_snippet(response.get_data(), html_to_be_inserted)

    if result is not None:
        if transaction.settings.debug.log_autorum_middleware:
            _logger.debug('RUM insertion from flask_compress '
                    'triggered. Bytes added was %r.',
                    len(result) - len(response.get_data()))

        response.set_data(result)
        response.headers['Content-Length'] = str(len(response.get_data()))

    return wrapped(*args, **kwargs)
Exemple #4
0
def browser_timing_middleware(request, response):

    # Don't do anything if receive a streaming response which
    # was introduced in Django 1.5. Need to avoid this as there
    # will be no 'content' attribute. Alternatively there may be
    # a 'content' attribute which flattens the stream, which if
    # we access, will break the streaming and/or buffer what is
    # potentially a very large response in memory contrary to
    # what user wanted by explicitly using a streaming response
    # object in the first place. To preserve streaming but still
    # do RUM insertion, need to move to a WSGI middleware and
    # deal with how to update the content length.

    if hasattr(response, 'streaming_content'):
        return response

    # Need to be running within a valid web transaction.

    transaction = current_transaction()

    if not transaction:
        return response

    # Only insert RUM JavaScript headers and footers if enabled
    # in configuration and not already likely inserted.

    if not transaction.settings.browser_monitoring.enabled:
        return response

    if transaction.autorum_disabled:
        return response

    if not django_settings.browser_monitoring.auto_instrument:
        return response

    if transaction.rum_header_generated:
        return response

    # Only possible if the content type is one of the allowed
    # values. Normally this is just text/html, but optionally
    # could be defined to be list of further types. For example
    # a user may want to also perform insertion for
    # 'application/xhtml+xml'.

    ctype = response.get('Content-Type', '').lower().split(';')[0]

    if ctype not in transaction.settings.browser_monitoring.content_type:
        return response

    # Don't risk it if content encoding already set.

    if response.has_header('Content-Encoding'):
        return response

    # Don't risk it if content is actually within an attachment.

    cdisposition = response.get('Content-Disposition', '').lower()

    if cdisposition.split(';')[0].strip().lower() == 'attachment':
        return response

    # No point continuing if header is empty. This can occur if
    # RUM is not enabled within the UI. It is assumed at this
    # point that if header is not empty, then footer will not be
    # empty. We don't want to generate the footer just yet as
    # want to do that as late as possible so that application
    # server time in footer is as accurate as possible. In
    # particular, if the response content is generated on demand
    # then the flattening of the response could take some time
    # and we want to track that. We thus generate footer below
    # at point of insertion.

    header = transaction.browser_timing_header()

    if not header:
        return response

    def html_to_be_inserted():
        return six.b(header) + six.b(transaction.browser_timing_footer())

    # Make sure we flatten any content first as it could be
    # stored as a list of strings in the response object. We
    # assign it back to the response object to avoid having
    # multiple copies of the string in memory at the same time
    # as we progress through steps below.

    result = insert_html_snippet(response.content, html_to_be_inserted)

    if result is not None:
        if transaction.settings.debug.log_autorum_middleware:
            _logger.debug(
                'RUM insertion from Django middleware '
                'triggered. Bytes added was %r.',
                len(result) - len(response.content))

        response.content = result

        if response.get('Content-Length', None):
            response['Content-Length'] = str(len(response.content))

    return response
def _nr_wrapper_Compress_after_request(wrapped, instance, args, kwargs):
    def _params(response, *args, **kwargs):
        return response

    response = _params(*args, **kwargs)

    # If the response has direct_passthrough flagged, then is
    # likely to be streaming a file or other large response.
    # Leave the response alone in this situation even though
    # it looked like flask_compress doesn't honour it.

    #if getattr(response, 'direct_passthrough', None):
    #    return wrapped(*args, **kwargs)

    # Need to be running within a valid web transaction.

    transaction = current_transaction()

    if not transaction:
        return wrapped(*args, **kwargs)

    # Only insert RUM JavaScript headers and footers if enabled
    # in configuration and not already likely inserted.

    if not transaction.settings.browser_monitoring.enabled:
        return wrapped(*args, **kwargs)

    if transaction.autorum_disabled:
        return wrapped(*args, **kwargs)

    if not flask_compress_settings.browser_monitoring.auto_instrument:
        return wrapped(*args, **kwargs)

    if transaction.rum_header_generated:
        return wrapped(*args, **kwargs)

    # Only possible if the content type is one of the allowed
    # values. Normally this is just text/html, but optionally
    # could be defined to be list of further types. For example
    # a user may want to also perform insertion for
    # 'application/xhtml+xml'.

    ctype = response.mimetype.lower()

    if ctype not in transaction.settings.browser_monitoring.content_type:
        return wrapped(*args, **kwargs)

    # Don't risk it if content encoding already set.

    if 'Content-Encoding' in response.headers:
        return wrapped(*args, **kwargs)

    # Don't risk it if content is actually within an attachment.

    cdisposition = response.headers.get('Content-Disposition', '').lower()

    if cdisposition.split(';')[0].strip() == 'attachment':
        return wrapped(*args, **kwargs)

    # No point continuing if header is empty. This can occur if
    # RUM is not enabled within the UI. It is assumed at this
    # point that if header is not empty, then footer will not be
    # empty. We don't want to generate the footer just yet as
    # want to do that as late as possible so that application
    # server time in footer is as accurate as possible. In
    # particular, if the response content is generated on demand
    # then the flattening of the response could take some time
    # and we want to track that. We thus generate footer below
    # at point of insertion.

    header = transaction.browser_timing_header()

    if not header:
        return wrapped(*args, **kwargs)

    def html_to_be_inserted():
        return six.b(header) + six.b(transaction.browser_timing_footer())

    # Make sure we flatten any content first as it could be
    # stored as a list of strings in the response object. We
    # assign it back to the response object to avoid having
    # multiple copies of the string in memory at the same time
    # as we progress through steps below.

    result = insert_html_snippet(response.get_data(), html_to_be_inserted)

    if result is not None:
        if transaction.settings.debug.log_autorum_middleware:
            _logger.debug(
                'RUM insertion from flask_compress '
                'triggered. Bytes added was %r.',
                len(result) - len(response.get_data()))

        response.set_data(result)
        response.headers['Content-Length'] = str(len(response.get_data()))

    return wrapped(*args, **kwargs)