Skip to content

Inspect headers for correct syntax #128

Open

Description

@wosc

In a similar vein as #119 there is another difference between WebTest and a real WSGI server: WebTest passes HTTP headers through as-is, but HTTP has syntactical rules that need to be obeyed. I noticed this when I tried to base64-encode a (somewhat lengthy) header value -- the result can contain newlines, which (when not escaped) do not survive a transport through HTTP.

Here is an example:

from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
import json
import requests
import threading
import unittest
import webtest


class Test(unittest.TestCase):

    HEADERS = {'X-Foo': 'Bar\nBaz\n'}

    def test_real_http_truncates_header_on_newline(self):
        server = WSGIServer(('localhost', 0), WSGIRequestHandler)
        port = server.server_port
        server.set_app(echo_header_app)
        thread = threading.Thread(target=server.serve_forever)
        thread.daemon = True
        thread.start()

        r = requests.get('http://localhost:%s/' % port, headers=self.HEADERS)
        # This is the expected truncated result.
        self.assertEqual('Bar', r.json()['HTTP_X_FOO'])

        server.shutdown()
        thread.join()

    def test_webtest_should_not_pass_header_through_unchecked(self):
        app = webtest.TestApp(echo_header_app)
        r = app.get('/', headers=self.HEADERS)
        # This fails, actual value is 'Bar\nBaz\n'
        self.assertEqual('Bar', json.loads(r.body)['HTTP_X_FOO'])


def echo_header_app(env, start_response):
    status = '200 OK'
    headers = [('Content-type', 'application/json')]
    start_response(status, headers)

    return [json.dumps(
        {key: value for key, value in env.items() if key.startswith('HTTP_')})]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions