Example #1
0
def test_middleware_preserves_file_wrapper(wsgi_env, start_response, context,
                                           tmpdir):
    path = tmpdir.join('filecontent')
    path.write('CONTENT')

    def app(environ, _start_response):
        _start_response('200 OK', [('Content-Type', 'text/plain')])
        return environ['wsgi.file_wrapper'](open(str(path)))

    mw = wsgi.TaliskerMiddleware(app, {}, {})
    wsgi_env['wsgi.file_wrapper'] = wsgiref.util.FileWrapper

    with freeze_time() as frozen:
        respiter = mw(wsgi_env, start_response)
        context.assert_not_log(msg='GET /')
        frozen.tick(1.0)
        respiter.close()

    assert isinstance(respiter, wsgiref.util.FileWrapper)
    context.assert_log(
        msg='GET /',
        extra=dict([
            ('method', 'GET'),
            ('path', '/'),
            ('status', 200),
            ('duration_ms', 1000.0),
            ('ip', '127.0.0.1'),
            ('proto', 'HTTP/1.0'),
            ('length', len('CONTENT')),
            ('filepath', str(path)),
        ]),
    )
Example #2
0
def test_middleware_basic(wsgi_env, start_response, context):
    def app(environ, _start_response):
        _start_response('200 OK', [('Content-Type', 'text/plain')])
        return [b'OK']

    extra_env = {'ENV': 'VALUE'}
    extra_headers = {'Some-Header': 'value'}
    wsgi_env['HTTP_X_REQUEST_ID'] = 'ID'

    mw = wsgi.TaliskerMiddleware(app, extra_env, extra_headers)
    output = b''.join(mw(wsgi_env, start_response))

    assert output == b'OK'
    assert wsgi_env['ENV'] == 'VALUE'
    assert wsgi_env['REQUEST_ID'] == 'ID'
    assert start_response.status == '200 OK'
    assert start_response.headers == [
        ('Content-Type', 'text/plain'),
        ('Some-Header', 'value'),
        ('X-Request-Id', 'ID'),
    ]

    context.assert_log(
        name='talisker.wsgi',
        msg='GET /',
        extra={'request_id': 'ID'},
    )
Example #3
0
def test_middleware_debug_invalid_ip(wsgi_env, start_response, context):

    def app(environ, _start_response):
        _start_response('200 OK', [('Content-Type', 'text/plain')])
        return [b'OK']

    wsgi_env['HTTP_X_DEBUG'] = '1'
    wsgi_env['REMOTE_ADDR'] = '1.2.3.4'
    mw = wsgi.TaliskerMiddleware(app, {}, {})
    output = b''.join(mw(wsgi_env, start_response))

    assert output == b'OK'
    assert start_response.status == '200 OK'

    if talisker.sentry.enabled:
        assert len(context.sentry) == 0

    context.assert_log(
        level='warning',
        msg='X-Debug header set but not trusted IP address',
        extra={
            'access_route': '1.2.3.4',
            'x_debug': '1',
        },
    )
Example #4
0
def test_middleware_debug(wsgi_env, start_response, context):
    def app(environ, _start_response):
        _start_response('200 OK', [('Content-Type', 'text/plain')])
        return [b'OK']

    wsgi_env['HTTP_X_DEBUG'] = '1'
    mw = wsgi.TaliskerMiddleware(app, {}, {})
    output = b''.join(mw(wsgi_env, start_response))

    assert output == b'OK'
    assert start_response.status == '200 OK'

    if talisker.sentry.enabled:
        msg = context.sentry[0]
        assert msg['message'] == 'Debug: /'
        assert msg['level'] == 'debug'
Example #5
0
def test_middleware_debug_middleware_no_content(wsgi_env, start_response,
                                                context):
    from werkzeug.debug import DebuggedApplication

    # DebuggedApplication turns any WSGI app into a super lazy version
    def app(environ, start_response):
        start_response('304 Not Modified', [])
        # no content
        return []

    mw = wsgi.TaliskerMiddleware(DebuggedApplication(app), {}, {})

    output = b''.join(mw(wsgi_env, start_response))

    assert start_response.status == '304 Not Modified'
    assert output == b''
Example #6
0
def test_middleware_sets_header_deadline(wsgi_env, start_response, config):
    config['TALISKER_REQUEST_TIMEOUT'] = 2000

    contexts = []

    def app(environ, _start_response):
        contexts.append(Context.current())
        _start_response('200 OK', [('Content-Type', 'text/plain')])
        return [b'OK']

    ts = datetime.utcnow() + timedelta(seconds=10)
    wsgi_env['HTTP_X_REQUEST_DEADLINE'] = ts.isoformat() + 'Z'
    mw = wsgi.TaliskerMiddleware(app, {}, {})
    list(mw(wsgi_env, start_response))

    assert contexts[0].deadline == datetime_to_timestamp(ts)
Example #7
0
def test_middleware_sets_deadlines(wsgi_env, start_response, config):
    config['TALISKER_SOFT_REQUEST_TIMEOUT'] = 1000
    config['TALISKER_REQUEST_TIMEOUT'] = 2000

    contexts = []

    def app(environ, _start_response):
        contexts.append(Context.current())
        _start_response('200 OK', [('Content-Type', 'text/plain')])
        return [b'OK']

    mw = wsgi.TaliskerMiddleware(app, {}, {})
    list(mw(wsgi_env, start_response))

    assert contexts[0].soft_timeout == 1000
    assert contexts[0].deadline == contexts[0].start_time + 2.0
Example #8
0
def test_middleware_error_after_start_response(
        exc_type, wsgi_env, start_response, sentry_id, context):

    def app(wsgi_env, _start_response):
        _start_response('200 OK', [('Content-Type', 'application/json')])
        raise exc_type('error')

    extra_env = {'ENV': 'VALUE'}
    extra_headers = {'Some-Header': 'value'}
    wsgi_env['HTTP_X_REQUEST_ID'] = 'ID'
    wsgi_env['HTTP_ACCEPT'] = 'application/json'

    mw = wsgi.TaliskerMiddleware(app, extra_env, extra_headers)
    output = b''.join(mw(wsgi_env, start_response))
    error = json.loads(output.decode('utf8'))

    assert error['title'] == 'Server Error: ' + exc_type.__name__
    assert wsgi_env['ENV'] == 'VALUE'
    assert wsgi_env['REQUEST_ID'] == 'ID'
    assert start_response.status == '500 Internal Server Error'
    assert start_response.headers[:4] == [
        ('Content-Type', 'application/json'),
        ('Some-Header', 'value'),
        ('X-Request-Id', 'ID'),
        ('X-Sentry-Id', 'SENTRY_ID')
    ]

    extra = {
        'status': 500,
        'exc_type': exc_type.__name__,
    }

    if exc_type is wsgi.RequestTimeout:
        extra['timeout'] = True

    context.assert_log(
        name='talisker.wsgi',
        msg='GET /',
        extra=extra,
    )

    if talisker.sentry.enabled:
        msg = context.sentry[0]
        assert msg['event_id'] == 'SENTRY_ID'
        assert msg['message'] == '{}: {}'.format(
            exc_type.__name__, 'error'
        )
Example #9
0
def test_middleware_debug_middleware(wsgi_env, start_response, context):
    from werkzeug.debug import DebuggedApplication

    # DebuggedApplication turns any WSGI app into a super lazy version
    def app(environ, start_response):
        start_response('302 Found', [('Location', '/other')])
        yield b''

    mw = wsgi.TaliskerMiddleware(DebuggedApplication(app), {}, {})

    wsgi_env['HTTP_X_REQUEST_ID'] = 'ID'
    output = b''.join(mw(wsgi_env, start_response))

    assert start_response.status == '302 Found'
    assert output == b''
    assert start_response.headers == [
        ('Location', '/other'),
        ('X-Request-Id', 'ID'),
    ]
Example #10
0
def test_middleware_debug_middleware_error(wsgi_env, start_response, context):
    from werkzeug.debug import DebuggedApplication

    def app(environ, _):
        raise Exception('error')

    mw = wsgi.TaliskerMiddleware(DebuggedApplication(app), {}, {})

    wsgi_env['HTTP_X_REQUEST_ID'] = 'ID'
    list(mw(wsgi_env, start_response))

    assert start_response.status == '500 INTERNAL SERVER ERROR'
    assert start_response.headers == [
        ('Content-Type', 'text/html; charset=utf-8'),
        ('X-XSS-Protection', '0'),
        ('X-Request-Id', 'ID'),
    ]

    context.assert_log(name='talisker.wsgi', msg='GET /')