Exemplo n.º 1
0
    def force_type(cls, response, environ=None):
        """Enforce that the WSGI response is a response object of the current
        type.  Werkzeug will use the `BaseResponse` internally in many
        situations like the exceptions.  If you call `get_response` on an
        exception you will get back a regular `BaseResponse` object, even if
        you are using a custom subclass.

        This method can enforce a given response type, and it will also
        convert arbitrary WSGI callables into response objects if an environ
        is provided::

            # convert a Werkzeug response object into an instance of the
            # MyResponseClass subclass.
            response = MyResponseClass.force_type(response)

            # convert any WSGI application into a response object
            response = MyResponseClass.force_type(response, environ)

        This is especially useful if you want to post-process responses in
        the main dispatcher and use functionality provided by your subclass.

        Keep in mind that this will modify response objects in place if
        possible!
        """
        if not isinstance(response, BaseResponse):
            if environ is None:
                raise TypeError('cannot convert WSGI application into '
                                'response objects without an environ')
            response = BaseResponse(*run_wsgi_app(response, environ))
        response.__class__ = cls
        return response
Exemplo n.º 2
0
 def from_app(cls, app, environ, buffered=False):
     """Create a new response object from an application output.  This
     works best if you pass it an application that returns a generator all
     the time.  Sometimes applications may use the `write()` callable
     returned by the `start_response` function.  This tries to resolve such
     edge cases automatically.  But if you don't get the expected output
     you should set `buffered` to `True` which enforces buffering.
     """
     return cls(*run_wsgi_app(app, environ, buffered))
Exemplo n.º 3
0
 def from_app(cls, app, environ, buffered=False):
     """
     Create a new response object from an application output.  This works
     best if you pass it an application that returns a generator all the
     time.  Sometimes applications may use the `write()` callable returned
     by the `start_response` function.  This tries to resolve such edge
     cases automatically.  But if you don't get the expected output you
     should set `buffered` to `True` which enforces buffering.
     """
     return cls(*run_wsgi_app(app, environ, buffered))
Exemplo n.º 4
0
    def open(self, path='/', base_url=None, query_string=None, method='GET',
             data=None, input_stream=None, content_type=None,
             content_length=0, errors_stream=None, multithread=False,
             multiprocess=False, run_once=False, environ_overrides=None):
        """
        Open a page for the application.  This function takes similar
        arguments as the `create_environ` method from the utils module.  If
        the first argument is an environ or request object it is used as
        the environment for the request.
        """
        if input_stream is None and data and method in ('PUT', 'POST'):
            need_multipart = False
            if isinstance(data, basestring):
                assert content_type is not None, 'content type required'
            else:
                for key, value in data.iteritems():
                    if isinstance(value, basestring):
                        if isinstance(value, unicode):
                            data[key] = str(value)
                        continue
                    need_multipart = True
                    if isinstance(value, tuple):
                        data[key] = File(*value)
                    elif isinstance(value, dict):
                        data[key] = File(**value)
                    elif not isinstance(value, File):
                        data[key] = File(value)
                if need_multipart:
                    boundary, data = encode_multipart(data)
                    if content_type is None:
                        content_type = 'multipart/form-data; boundary=' + \
                            boundary
                else:
                    data = urlencode(data)
                    if content_type is None:
                        content_type = 'application/x-www-form-urlencoded'
            content_length = len(data)
            input_stream = StringIO(data)

        if hasattr(path, 'environ'):
            environ = path.environ
        elif isinstance(path, dict):
            environ = path
        else:
            environ = create_environ(path, base_url, query_string, method,
                                     input_stream, content_type, content_length,
                                     errors_stream, multithread,
                                     multiprocess, run_once)
        if environ_overrides:
            environ.update(environ_overrides)
        rv = run_wsgi_app(self.application, environ)
        return self.response_wrapper(*rv)
Exemplo n.º 5
0
    def open(self, path='/', base_url=None, query_string=None, method='GET',
             data=None, input_stream=None, content_type=None,
             content_length=0, errors_stream=None, multithread=False,
             multiprocess=False, run_once=False, environ_overrides=None,
             as_tuple=False, buffered=False):
        """Takes the same arguments as the `create_environ` function from the
        utility module with some additions.

        The first parameter should be the path of the request which defaults to
        '/'.  The second one can either be a absolute path (in that case the url
        host is localhost:80) or a full path to the request with scheme,
        netloc port and the path to the script.

        If the `path` contains a query string it will be used, even if the
        `query_string` parameter was given.  If it does not contain one
        the `query_string` parameter is used as querystring.  In that case
        it can either be a dict, MultiDict or string.

        The following options exist:

        `method`
            The request method.  Defaults to `GET`

        `input_stream`
            The input stream.  Defaults to an empty read only stream.

        `data`
            The data you want to transmit.  You can set this to a string and
            define a content type instead of specifying an input stream.
            Additionally you can pass a dict with the form data.  The values
            could then be strings (no unicode objects!) which are then url
            encoded or file objects.

            A file object for this method is either a file descriptor with
            an additional `name` attribute (like a file descriptor returned
            by the `open` / `file` function), a tuple in the form
            ``(fd, filename, mimetype)`` (all arguments except fd optional)
            or as dict with those keys and values.

            Additionally you can instanciate the `werkzeug.test.File` object
            (or a subclass of it) and pass it as value.

        `content_type`
            The content type for this request.  Default is an empty content
            type.

        `content_length`
            The value for the content length header.  Defaults to 0.

        `errors_stream`
            The wsgi.errors stream.  Defaults to `sys.stderr`.

        `multithread`
            The multithreaded flag for the WSGI Environment.  Defaults to
            `False`.

        `multiprocess`
            The multiprocess flag for the WSGI Environment.  Defaults to
            `False`.

        `run_once`
            The run_once flag for the WSGI Environment.  Defaults to `False`.

        `buffered`
            Set this to true to buffer the application run.  This will
            automatically close the application for you as well.
        """
        if input_stream is None and data is not None and method in ('PUT', 'POST'):
            need_multipart = False
            if isinstance(data, basestring):
                assert content_type is not None, 'content type required'
            else:
                for key, value in data.iteritems():
                    if isinstance(value, basestring):
                        if isinstance(value, unicode):
                            data[key] = str(value)
                        continue
                    need_multipart = True
                    if isinstance(value, tuple):
                        data[key] = File(*value)
                    elif isinstance(value, dict):
                        data[key] = File(**value)
                    elif not isinstance(value, File):
                        data[key] = File(value)
                if need_multipart:
                    boundary, data = encode_multipart(data)
                    if content_type is None:
                        content_type = 'multipart/form-data; boundary=' + \
                            boundary
                else:
                    data = urlencode(data)
                    if content_type is None:
                        content_type = 'application/x-www-form-urlencoded'
            content_length = len(data)
            input_stream = StringIO(data)

        if hasattr(path, 'environ'):
            environ = path.environ
        elif isinstance(path, dict):
            environ = path
        else:
            environ = create_environ(path, base_url, query_string, method,
                                     input_stream, content_type, content_length,
                                     errors_stream, multithread,
                                     multiprocess, run_once)
        if environ_overrides:
            environ.update(environ_overrides)
        rv = run_wsgi_app(self.application, environ, buffered=buffered)
        response = self.response_wrapper(*rv)
        if as_tuple:
            return environ, response
        return response
Exemplo n.º 6
0
def run_app(app, path='/'):
    env = create_environ(path, SECRET_KEY)
    return run_wsgi_app(app, env)
Exemplo n.º 7
0
def run_app(app, path='/'):
    env = create_environ(path, SECRET_KEY)
    return run_wsgi_app(app, env)
Exemplo n.º 8
0
    def open(self, *args, **kwargs):
        """Takes the same arguments as the :class:`EnvironBuilder` class with
        some additions:  You can provide a :class:`EnvironBuilder` or a WSGI
        environment as only argument instead of the :class:`EnvironBuilder`
        arguments and two optional keyword arguments (`as_tuple`, `buffered`)
        that change the type of the return value or the way the application is
        executed.

        .. versionchanged:: 0.5
           If a dict is provided as file in the dict for the `data` parameter
           the content type has to be called `content_type` now instead of
           `mimetype`.  This change was made for consistency with
           :class:`werkzeug.FileWrapper`.

            The `follow_redirects` parameter was added to :func:`open`.

        Additional parameters:

        :param as_tuple: Returns a tuple in the form ``(environ, result)``
        :param buffered: Set this to true to buffer the application run.
                         This will automatically close the application for
                         you as well.
        :param follow_redirects: Set this to True if the `Client` should
                                 follow HTTP redirects.
        """
        as_tuple = kwargs.pop('as_tuple', False)
        buffered = kwargs.pop('buffered', False)
        follow_redirects = kwargs.pop('follow_redirects', False)
        environ = None
        if not kwargs and len(args) == 1:
            if isinstance(args[0], EnvironBuilder):
                environ = args[0].get_environ()
            elif isinstance(args[0], dict):
                environ = args[0]
        if environ is None:
            builder = EnvironBuilder(*args, **kwargs)
            try:
                environ = builder.get_environ()
            finally:
                builder.close()

        if self.cookie_jar is not None:
            self.cookie_jar.inject_wsgi(environ)
        rv = run_wsgi_app(self.application, environ, buffered=buffered)
        if self.cookie_jar is not None:
            self.cookie_jar.extract_wsgi(environ, rv[2])

        # handle redirects
        redirect_chain = []
        status_code = int(rv[1].split(None, 1)[0])
        while status_code in (301, 302, 303, 305, 307) and follow_redirects:
            redirect = dict(rv[2])['Location']
            host = get_host(create_environ('/', redirect))
            if get_host(environ).split(':', 1)[0] != host:
                raise RuntimeError('%r does not support redirect to '
                                   'external targets' % self.__class__)

            scheme, netloc, script_root, qs, anchor = urlparse.urlsplit(redirect)
            redirect_chain.append((redirect, status_code))

            kwargs.update({
                'base_url':         urlparse.urlunsplit((scheme, host,
                                    script_root, '', '')).rstrip('/') + '/',
                'query_string':     qs,
                'as_tuple':         as_tuple,
                'buffered':         buffered,
                'follow_redirects': False
            })
            rv = self.open(*args, **kwargs)
            status_code = int(rv[1].split(None, 1)[0])

            # Prevent loops
            if redirect_chain[-1] in redirect_chain[0:-1]:
                break

        response = self.response_wrapper(*rv)
        if as_tuple:
            return environ, response
        return response