Example #1
0
    def test_stream_file_wrapper_without_read(self):
        from zope.interface import implementer
        from ZPublisher.HTTPResponse import WSGIResponse
        from ZPublisher.Iterators import IStreamIterator

        @implementer(IStreamIterator)
        class TestStreamIterator:
            data = "hello" * 20

            def __len__(self):
                return len(self.data)

        class Wrapper:
            def __init__(self, file):
                self.file = file

        _response = WSGIResponse()
        _response.setHeader('Content-Type', 'text/plain')
        body = _response.body = TestStreamIterator()
        environ = self._makeEnviron(**{'wsgi.file_wrapper': Wrapper})
        start_response = DummyCallable()
        _publish = DummyCallable()
        _publish._result = _response
        app_iter = self._callFUT(environ, start_response, _publish)
        # The stream iterator has no ``read`` and will not be used
        # for ``wsgi.file_wrapper``. It is returned as-is.
        self.assertTrue(app_iter is body)
        self.assertTrue(isinstance(app_iter, TestStreamIterator))
        self.assertEqual(int(_response.headers['content-length']), len(body))
        self.assertTrue(
            _response.headers['content-type'].startswith('text/plain'))
        self.assertEqual(_response.status, 200)
Example #2
0
    def testStreaming(self):
        out = BytesIO()
        response = WSGIResponse(stdout=out)
        response.write(b'datachunk1')
        response.write(b'datachunk2')

        events = self.reporter.events
        self.assertEqual(len(events), 1)
        self.assertIsInstance(events[0], PubBeforeStreaming)
        self.assertEqual(events[0].response, response)

        self.assertTrue(b'datachunk1datachunk2' in out.getvalue())
Example #3
0
    def testStreaming(self):
        out = BytesIO()
        response = WSGIResponse(stdout=out)
        response.write(b'datachunk1')
        response.write(b'datachunk2')

        events = self.reporter.events
        self.assertEqual(len(events), 1)
        self.assertIsInstance(events[0], PubBeforeStreaming)
        self.assertEqual(events[0].response, response)

        self.assertTrue(b'datachunk1datachunk2' in out.getvalue())
Example #4
0
    def test_unboundstream_file_wrapper(self):
        from ZPublisher.Iterators import IUnboundStreamIterator
        from zope.interface import implementer
        from ZPublisher.HTTPResponse import WSGIResponse

        @implementer(IUnboundStreamIterator)
        class TestUnboundStreamIterator(object):
            data = "hello"

            def __len__(self):
                return len(self.data)

        class Wrapper(object):
            def __init__(self, file):
                self.file = file

        _response = WSGIResponse()
        _response.setStatus(200)
        # UnboundStream needs Content-Length header
        _response.setHeader('Content-Length', '5')
        _response.setHeader('Content-Type', 'text/plain')
        body = _response.body = TestUnboundStreamIterator()
        environ = self._makeEnviron(**{'wsgi.file_wrapper': Wrapper})
        start_response = DummyCallable()
        _publish = DummyCallable()
        _publish._result = _response
        app_iter = self._callFUT(environ, start_response, _publish)
        self.assertTrue(app_iter.file is body)
        self.assertTrue(isinstance(app_iter, Wrapper))
        self.assertEqual(int(_response.headers['content-length']), len(body))
        self.assertTrue(
            _response.headers['content-type'].startswith('text/plain'))
        self.assertEqual(_response.status, 200)
Example #5
0
class _Request(BaseRequest):
    response = WSGIResponse()
    _hacked_path = False
    args = ()
    environ = {}

    def __init__(self, *args, **kw):
        BaseRequest.__init__(self, *args, **kw)
        self['PATH_INFO'] = self['URL'] = ''
        self.steps = []

    def traverse(self, *unused, **unused_kw):
        action = self.action
        if action.startswith('fail'):
            raise Exception(action)
        if action == 'conflict':
            raise ConflictError()
        if action == 'succeed':
            return _succeed
        else:
            raise ValueError('unknown action: %s' % action)

    def close(self):
        # override to get rid of the 'EndRequestEvent' notification
        pass
Example #6
0
 def test_304(self):
     env = {
         'SERVER_NAME': 'localhost',
         'SERVER_PORT': '80',
         'SERVER_PROTOCOL': 'HTTP/1.1',
         'REQUEST_METHOD': 'GET',
         'IF_MODIFIED_SINCE': '2050/12/31',
     }
     stdout = BytesIO()
     response = WSGIResponse(stdout)
     request = WSGIRequest(BytesIO(), env, response)
     path = os.path.join(os.path.dirname(App.__file__), 'www',
                         'zopelogo.png')
     image = App.ImageFile.ImageFile(path)
     result = image.index_html(request, response)
     self.assertEqual(stdout.getvalue(), b'')
     self.assertEqual(len(result), 0)
     self.assertEqual(response.getHeader('Content-Length'), '0')
Example #7
0
 def test_304(self):
     env = {
         'SERVER_NAME': 'localhost',
         'SERVER_PORT': '80',
         'SERVER_PROTOCOL': 'HTTP/1.1',
         'REQUEST_METHOD': 'GET',
         'IF_MODIFIED_SINCE': '2050/12/31',
     }
     stdout = BytesIO()
     response = WSGIResponse(stdout)
     request = WSGIRequest(BytesIO(), env, response)
     path = os.path.join(os.path.dirname(App.__file__),
                         'www', 'zopelogo.png')
     image = App.ImageFile.ImageFile(path)
     result = image.index_html(request, response)
     self.assertEqual(stdout.getvalue(), b'')
     self.assertEqual(len(result), 0)
     self.assertEqual(response.getHeader('Content-Length'), '0')
Example #8
0
 def test_index_html(self):
     env = {
         'SERVER_NAME': 'localhost',
         'SERVER_PORT': '80',
         'SERVER_PROTOCOL': 'HTTP/1.1',
         'REQUEST_METHOD': 'GET',
     }
     stdin = BytesIO()
     stdout = BytesIO()
     response = WSGIResponse(stdout)
     request = WSGIRequest(stdin, env, response)
     path = os.path.join(os.path.dirname(App.__file__), 'www',
                         'zopelogo.png')
     image = App.ImageFile.ImageFile(path)
     result = image.index_html(request, response)
     self.assertEqual(stdout.getvalue(), b'')
     self.assertIsInstance(result, io.FileIO)
     self.assertTrue(b''.join(result).startswith(b'\x89PNG\r\n'))
     self.assertEqual(len(result), image.size)
     self.assertEqual(response.getHeader('Content-Length'), str(image.size))
     result.close()
Example #9
0
 def test_index_html(self):
     env = {
         'SERVER_NAME': 'localhost',
         'SERVER_PORT': '80',
         'SERVER_PROTOCOL': 'HTTP/1.1',
         'REQUEST_METHOD': 'GET',
     }
     stdin = BytesIO()
     stdout = BytesIO()
     response = WSGIResponse(stdout)
     request = WSGIRequest(stdin, env, response)
     path = os.path.join(os.path.dirname(App.__file__),
                         'www', 'zopelogo.png')
     image = App.ImageFile.ImageFile(path)
     result = image.index_html(request, response)
     self.assertEqual(stdout.getvalue(), b'')
     self.assertIsInstance(result, io.FileIO)
     self.assertTrue(b''.join(result).startswith(b'\x89PNG\r\n'))
     self.assertEqual(len(result), image.size)
     self.assertEqual(response.getHeader('Content-Length'), str(image.size))
     result.close()
Example #10
0
    def publish(self, path, basic=None, env=None, extra=None,
                request_method='GET', stdin=None, handle_errors=True):
        '''Publishes the object at 'path' returning a response object.'''

        from io import BytesIO
        from ZPublisher.HTTPRequest import WSGIRequest as Request
        from ZPublisher.HTTPResponse import WSGIResponse
        from ZPublisher.WSGIPublisher import publish_module

        # Commit the sandbox for good measure
        transaction.commit()

        if env is None:
            env = {}
        if extra is None:
            extra = {}

        request = self.app.REQUEST

        env['SERVER_NAME'] = request['SERVER_NAME']
        env['SERVER_PORT'] = request['SERVER_PORT']
        env['SERVER_PROTOCOL'] = 'HTTP/1.1'
        env['REQUEST_METHOD'] = request_method

        p = path.split('?')
        if len(p) == 1:
            env['PATH_INFO'] = p[0]
        elif len(p) == 2:
            [env['PATH_INFO'], env['QUERY_STRING']] = p
        else:
            raise TypeError('')

        if basic:
            env['HTTP_AUTHORIZATION'] = basic_auth_encode(basic)

        if not handle_errors:
            # Tell the publisher to skip exception views
            env['x-wsgiorg.throw_errors'] = True

        if stdin is None:
            stdin = BytesIO()

        outstream = BytesIO()
        response = WSGIResponse(stdout=outstream, stderr=sys.stderr)
        request = Request(stdin, env, response)
        for k, v in extra.items():
            request[k] = v

        wsgi_headers = BytesIO()

        def start_response(status, headers):
            # Keep the fake response in-sync with the actual values
            # from the WSGI start_response call.
            response.setStatus(status.split()[0])
            for key, value in headers:
                response.setHeader(key, value)

            wsgi_headers.write(
                b'HTTP/1.1 ' + status.encode('ascii') + b'\r\n')
            headers = b'\r\n'.join([
                (k + ': ' + v).encode('ascii') for k, v in headers])
            wsgi_headers.write(headers)
            wsgi_headers.write(b'\r\n\r\n')

        publish = partial(publish_module, _request=request, _response=response)
        if handle_errors:
            publish = HTTPExceptionHandler(publish)

        wsgi_result = publish(env, start_response)

        return ResponseWrapper(response, outstream, path,
                               wsgi_result, wsgi_headers)
Example #11
0
 def _publish(request, mod_info):
     response = WSGIResponse()
     response.write(b'WRITTEN')
     response.body = b'BODY'
     return response
def http(request_string, handle_errors=True):
    """Execute an HTTP request string via the publisher

    This is used for HTTP doc tests.
    """
    from urllib.parse import unquote
    from ZPublisher.HTTPRequest import WSGIRequest as Request
    from ZPublisher.HTTPResponse import WSGIResponse
    from ZPublisher.WSGIPublisher import publish_module

    # Commit work done by previous python code.
    transaction.commit()

    # Discard leading white space to make call layout simpler
    request_string = request_string.lstrip()

    # Split off and parse the command line
    newline = request_string.find('\n')
    command_line = request_string[:newline].rstrip()
    request_string = request_string[newline + 1:]
    method, path, protocol = command_line.split()
    path = unquote(path)

    env = {
        'HTTP_HOST': 'localhost',
        'HTTP_REFERER': 'localhost',
        'REQUEST_METHOD': method,
        'SERVER_PROTOCOL': protocol,
    }

    p = path.split('?', 1)
    if len(p) == 1:
        env['PATH_INFO'] = p[0]
    elif len(p) == 2:
        [env['PATH_INFO'], env['QUERY_STRING']] = p
    else:
        raise TypeError('')

    header_output = HTTPHeaderOutput(
        protocol, ('x-content-type-warning', 'x-powered-by'))

    # With a HeaderParser the payload is always a string, Parser would create a
    # list of messages for multipart messages.
    parser = email.parser.HeaderParser()
    msg = parser.parsestr(request_string)
    headers = msg.items()
    body = msg.get_payload()

    if isinstance(body, str):
        body = body.encode('utf-8')

    # Store request body without headers
    instream = BytesIO(body)

    for name, value in headers:
        name = ('_'.join(name.upper().split('-')))
        if name not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            name = 'HTTP_' + name
        env[name] = value.rstrip()

    if 'HTTP_AUTHORIZATION' in env:
        env['HTTP_AUTHORIZATION'] = auth_header(env['HTTP_AUTHORIZATION'])

    if not handle_errors:
        # Tell the publisher to skip exception views
        env['x-wsgiorg.throw_errors'] = True

    outstream = BytesIO()
    response = WSGIResponse(stdout=outstream, stderr=sys.stderr)
    request = Request(instream, env, response)

    env['wsgi.input'] = instream
    wsgi_headers = BytesIO()

    def start_response(status, headers):
        wsgi_headers.write(
            b'HTTP/1.1 ' + status.encode('ascii') + b'\r\n')
        headers = b'\r\n'.join([
            (k + ': ' + v).encode('ascii') for k, v in headers])
        wsgi_headers.write(headers)
        wsgi_headers.write(b'\r\n\r\n')

    publish = partial(publish_module, _request=request, _response=response)
    if handle_errors:
        publish = HTTPExceptionHandler(publish)

    wsgi_result = publish(env, start_response)

    header_output.setResponseStatus(response.getStatus(), response.errmsg)
    header_output.setResponseHeaders(response.headers)
    header_output.headersl.extend(response._cookie_list())
    header_output.appendResponseHeaders(response.accumulated_headers)

    sync()

    return DocResponseWrapper(
        response, outstream, path, header_output, wsgi_result, wsgi_headers)
Example #13
0
def http(request_string, handle_errors=True):
    """Execute an HTTP request string via the publisher

    This is used for HTTP doc tests.
    """
    import rfc822
    from io import BytesIO
    from six.moves.urllib.parse import unquote
    from ZPublisher.HTTPRequest import WSGIRequest as Request
    from ZPublisher.HTTPResponse import WSGIResponse
    from ZPublisher.WSGIPublisher import publish_module

    # Commit work done by previous python code.
    transaction.commit()

    # Discard leading white space to make call layout simpler
    request_string = request_string.lstrip()

    # Split off and parse the command line
    l = request_string.find('\n')
    command_line = request_string[:l].rstrip()
    request_string = request_string[l + 1:]
    method, path, protocol = command_line.split()
    path = unquote(path)

    instream = BytesIO(request_string)

    env = {
        'HTTP_HOST': 'localhost',
        'HTTP_REFERER': 'localhost',
        'REQUEST_METHOD': method,
        'SERVER_PROTOCOL': protocol,
    }

    p = path.split('?', 1)
    if len(p) == 1:
        env['PATH_INFO'] = p[0]
    elif len(p) == 2:
        [env['PATH_INFO'], env['QUERY_STRING']] = p
    else:
        raise TypeError('')

    header_output = HTTPHeaderOutput(
        protocol,
        ('x-content-type-warning', 'x-powered-by', 'bobo-exception-type',
         'bobo-exception-file', 'bobo-exception-value', 'bobo-exception-line'))

    headers = [
        split_header(header) for header in rfc822.Message(instream).headers
    ]

    # Store request body without headers
    instream = BytesIO(instream.read())

    for name, value in headers:
        name = ('_'.join(name.upper().split('-')))
        if name not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            name = 'HTTP_' + name
        env[name] = value.rstrip()

    if 'HTTP_AUTHORIZATION' in env:
        env['HTTP_AUTHORIZATION'] = auth_header(env['HTTP_AUTHORIZATION'])

    outstream = BytesIO()
    response = WSGIResponse(stdout=outstream, stderr=sys.stderr)
    request = Request(instream, env, response)

    env['wsgi.input'] = instream
    wsgi_headers = BytesIO()

    def start_response(status, headers):
        wsgi_headers.write('HTTP/1.1 %s\r\n' % status)
        headers = '\r\n'.join([': '.join(x) for x in headers])
        wsgi_headers.write(headers)
        wsgi_headers.write('\r\n\r\n')

    publish = partial(publish_module, _request=request, _response=response)
    if handle_errors:
        publish = HTTPExceptionHandler(publish)

    wsgi_result = publish(env, start_response)

    header_output.setResponseStatus(response.getStatus(), response.errmsg)
    header_output.setResponseHeaders(response.headers)
    header_output.headersl.extend(response._cookie_list())
    header_output.appendResponseHeaders(response.accumulated_headers)

    sync()

    return DocResponseWrapper(response, outstream, path, header_output,
                              wsgi_result, wsgi_headers)
Example #14
0
    def publish(self,
                path,
                basic=None,
                env=None,
                extra=None,
                request_method='GET',
                stdin=None,
                handle_errors=True):
        '''Publishes the object at 'path' returning a response object.'''

        from io import BytesIO
        from ZPublisher.HTTPRequest import WSGIRequest as Request
        from ZPublisher.HTTPResponse import WSGIResponse
        from ZPublisher.WSGIPublisher import publish_module

        # Commit the sandbox for good measure
        transaction.commit()

        if env is None:
            env = {}
        if extra is None:
            extra = {}

        request = self.app.REQUEST

        env['SERVER_NAME'] = request['SERVER_NAME']
        env['SERVER_PORT'] = request['SERVER_PORT']
        env['SERVER_PROTOCOL'] = 'HTTP/1.1'
        env['REQUEST_METHOD'] = request_method

        p = path.split('?')
        if len(p) == 1:
            env['PATH_INFO'] = p[0]
        elif len(p) == 2:
            [env['PATH_INFO'], env['QUERY_STRING']] = p
        else:
            raise TypeError('')

        if basic:
            env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic)

        if stdin is None:
            stdin = BytesIO()

        outstream = BytesIO()
        response = WSGIResponse(stdout=outstream, stderr=sys.stderr)
        request = Request(stdin, env, response)
        for k, v in extra.items():
            request[k] = v

        wsgi_headers = BytesIO()

        def start_response(status, headers):
            wsgi_headers.write('HTTP/1.1 %s\r\n' % status)
            headers = '\r\n'.join([': '.join(x) for x in headers])
            wsgi_headers.write(headers)
            wsgi_headers.write('\r\n\r\n')

        publish = partial(publish_module, _request=request, _response=response)
        if handle_errors:
            publish = HTTPExceptionHandler(publish)

        wsgi_result = publish(env, start_response)

        return ResponseWrapper(response, outstream, path, wsgi_result,
                               wsgi_headers)
Example #15
0
def http(request_string, handle_errors=True):
    """Execute an HTTP request string via the publisher

    This is used for HTTP doc tests.
    """
    from six.moves.urllib.parse import unquote
    from ZPublisher.HTTPRequest import WSGIRequest as Request
    from ZPublisher.HTTPResponse import WSGIResponse
    from ZPublisher.WSGIPublisher import publish_module

    # Commit work done by previous python code.
    transaction.commit()

    # Discard leading white space to make call layout simpler
    request_string = request_string.lstrip()

    # Split off and parse the command line
    newline = request_string.find('\n')
    command_line = request_string[:newline].rstrip()
    request_string = request_string[newline + 1:]
    method, path, protocol = command_line.split()
    path = unquote(path)

    env = {
        'HTTP_HOST': 'localhost',
        'HTTP_REFERER': 'localhost',
        'REQUEST_METHOD': method,
        'SERVER_PROTOCOL': protocol,
    }

    p = path.split('?', 1)
    if len(p) == 1:
        env['PATH_INFO'] = p[0]
    elif len(p) == 2:
        [env['PATH_INFO'], env['QUERY_STRING']] = p
    else:
        raise TypeError('')

    header_output = HTTPHeaderOutput(
        protocol, ('x-content-type-warning', 'x-powered-by'))

    # With a HeaderParser the payload is always a string, Parser would create a
    # list of messages for multipart messages.
    parser = email.parser.HeaderParser()
    msg = parser.parsestr(request_string)
    headers = msg.items()
    body = msg.get_payload()

    if isinstance(body, text_type):
        body = body.encode('utf-8')

    # Store request body without headers
    instream = BytesIO(body)

    for name, value in headers:
        name = ('_'.join(name.upper().split('-')))
        if name not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            name = 'HTTP_' + name
        env[name] = value.rstrip()

    if 'HTTP_AUTHORIZATION' in env:
        env['HTTP_AUTHORIZATION'] = auth_header(env['HTTP_AUTHORIZATION'])

    if not handle_errors:
        # Tell the publisher to skip exception views
        env['x-wsgiorg.throw_errors'] = True

    outstream = BytesIO()
    response = WSGIResponse(stdout=outstream, stderr=sys.stderr)
    request = Request(instream, env, response)

    env['wsgi.input'] = instream
    wsgi_headers = BytesIO()

    def start_response(status, headers):
        wsgi_headers.write(
            b'HTTP/1.1 ' + status.encode('ascii') + b'\r\n')
        headers = b'\r\n'.join([
            (k + ': ' + v).encode('ascii') for k, v in headers])
        wsgi_headers.write(headers)
        wsgi_headers.write(b'\r\n\r\n')

    publish = partial(publish_module, _request=request, _response=response)
    if handle_errors:
        publish = HTTPExceptionHandler(publish)

    wsgi_result = publish(env, start_response)

    header_output.setResponseStatus(response.getStatus(), response.errmsg)
    header_output.setResponseHeaders(response.headers)
    header_output.headersl.extend(response._cookie_list())
    header_output.appendResponseHeaders(response.accumulated_headers)

    sync()

    return DocResponseWrapper(
        response, outstream, path, header_output, wsgi_result, wsgi_headers)
Example #16
0
 def _publish(request, mod_info):
     response = WSGIResponse()
     response.write(b'WRITTEN')
     response.body = b'BODY'
     return response