wsgi/request.py
author Anthony Truchet <anthony.truchet@logilab.fr>
Thu, 25 Apr 2013 10:16:25 +0200
changeset 10016 984505da8b89
parent 10000 4352b7ccde04
child 10080 bc7c3b0f439b
permissions -rw-r--r--
[forms] closes #2437859 - Detect and prevent concurrent edition of the same entity. Add the timestamp of form generation to each entity's meta-information fields. On form validation, check that no concurrent change is overwritten and raises a ValidationError in case of concurrent change. A nicer handling with a message and a link to the new version of the entity would be a good thing...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
"""WSGI request adapter for cubicweb
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
NOTE: each docstring tagged with ``COME FROM DJANGO`` means that
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
the code has been taken (or adapted) from Djanco source code :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
  http://www.djangoproject.com/
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
9942
4b99196102f0 [wsgi] Add missing import
Christophe de Vienne <christophe@unlish.com>
parents: 9941
diff changeset
    28
import tempfile
4b99196102f0 [wsgi] Add missing import
Christophe de Vienne <christophe@unlish.com>
parents: 9941
diff changeset
    29
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
from StringIO import StringIO
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
from urllib import quote
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    32
from urlparse import parse_qs
9944
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
    33
from warnings import warn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
9995
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
    35
from cubicweb.multipart import (
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
    36
    copy_file, parse_form_data, MultipartError, parse_options_header)
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
    37
from cubicweb.web import RequestError
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
from cubicweb.web.request import CubicWebRequestBase
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    39
from cubicweb.wsgi import pformat, normalize_header
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
class CubicWebWsgiRequest(CubicWebRequestBase):
8752
e19f4bba89cd Add CubicWebRequestBase.content (closes #2742453)
Julien Cristau <julien.cristau@logilab.fr>
parents: 8316
diff changeset
    43
    """most of this code COMES FROM DJANGO
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    """
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
    45
8309
48ef505aa9f9 [request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7879
diff changeset
    46
    def __init__(self, environ, vreg):
9943
a4aeee690bff [wsgi] Set self.vreg
Christophe de Vienne <christophe@unlish.com>
parents: 9942
diff changeset
    47
        # self.vreg is used in get_posted_data, which is called before the
a4aeee690bff [wsgi] Set self.vreg
Christophe de Vienne <christophe@unlish.com>
parents: 9942
diff changeset
    48
        # parent constructor.
a4aeee690bff [wsgi] Set self.vreg
Christophe de Vienne <christophe@unlish.com>
parents: 9942
diff changeset
    49
        self.vreg = vreg
a4aeee690bff [wsgi] Set self.vreg
Christophe de Vienne <christophe@unlish.com>
parents: 9942
diff changeset
    50
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        self.environ = environ
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        self.path = environ['PATH_INFO']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
        self.method = environ['REQUEST_METHOD'].upper()
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    54
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    55
        # content_length "may be empty or absent"
9563
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    56
        try:
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    57
            length = int(environ['CONTENT_LENGTH'])
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    58
        except (KeyError, ValueError):
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    59
            length = 0
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    60
        # wsgi.input is not seekable, so copy the request contents to a temporary file
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    61
        if length < 100000:
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    62
            self.content = StringIO()
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    63
        else:
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    64
            self.content = tempfile.TemporaryFile()
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    65
        copy_file(environ['wsgi.input'], self.content, maxread=length)
9563
48f0ff3e2a32 [wsgi] make sure request.content is available for consumption
Julien Cristau <julien.cristau@logilab.fr>
parents: 8752
diff changeset
    66
        self.content.seek(0, 0)
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    67
        environ['wsgi.input'] = self.content
8314
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
    68
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
    69
        headers_in = dict((normalize_header(k[5:]), v) for k, v in self.environ.items()
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
    70
                          if k.startswith('HTTP_'))
9939
46a8ed48636f [wsgi] Honor the 'CONTENT_TYPE' wsgi variable
Christophe de Vienne <christophe@unlish.com>
parents: 9735
diff changeset
    71
        if 'CONTENT_TYPE' in environ:
46a8ed48636f [wsgi] Honor the 'CONTENT_TYPE' wsgi variable
Christophe de Vienne <christophe@unlish.com>
parents: 9735
diff changeset
    72
            headers_in['Content-Type'] = environ['CONTENT_TYPE']
9737
c6f47e635845 [wsgi] look at wsgi.url_scheme to decide if we're on https
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    73
        https = self.is_secure()
9941
8dc1c96d29f1 [wsgi] Fix https detection
Christophe de Vienne <christophe@unlish.com>
parents: 9940
diff changeset
    74
        if self.path.startswith('/https/'):
8dc1c96d29f1 [wsgi] Fix https detection
Christophe de Vienne <christophe@unlish.com>
parents: 9940
diff changeset
    75
            self.path = self.path[6:]
8dc1c96d29f1 [wsgi] Fix https detection
Christophe de Vienne <christophe@unlish.com>
parents: 9940
diff changeset
    76
            self.environ['PATH_INFO'] = self.path
8dc1c96d29f1 [wsgi] Fix https detection
Christophe de Vienne <christophe@unlish.com>
parents: 9940
diff changeset
    77
            https = True
8dc1c96d29f1 [wsgi] Fix https detection
Christophe de Vienne <christophe@unlish.com>
parents: 9940
diff changeset
    78
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
        post, files = self.get_posted_data()
8314
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
    80
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
    81
        super(CubicWebWsgiRequest, self).__init__(vreg, https, post,
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
    82
                                                  headers= headers_in)
9940
292f786009ba [wsgi] Re-set the request content after calling the inherited constructor.
Christophe de Vienne <christophe@unlish.com>
parents: 9939
diff changeset
    83
        self.content = environ['wsgi.input']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
        if files is not None:
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
    85
            for key, part in files.iteritems():
9988
623707a0c404 [wsgi] Fix posted files filename reading
Christophe de Vienne <christophe@unlish.com>
parents: 9944
diff changeset
    86
                self.form[key] = (part.filename, part.file)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
    87
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
        # Since this is called as part of error handling, we need to be very
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
        # robust against potentially malformed input.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
        form = pformat(self.form)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        meta = pformat(self.environ)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        return '<CubicWebWsgiRequest\FORM:%s,\nMETA:%s>' % \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
            (form, meta)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
    ## cubicweb request interface ################################################
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
    97
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    def http_method(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        """returns 'POST', 'GET', 'HEAD', etc."""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
        return self.method
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   101
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    def relative_path(self, includeparams=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
        """return the normalized path of the request (ie at least relative
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   104
        to the instance's root, but some other normalization may be needed
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
        so that the returned path may be used to compare to generated urls
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
        :param includeparams:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
           boolean indicating if GET form parameters should be kept in the path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        path = self.environ['PATH_INFO']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        path = path[1:] # remove leading '/'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        if includeparams:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
            qs = self.environ.get('QUERY_STRING')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
            if qs:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
                return '%s?%s' % (path, qs)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   116
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        return path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
    ## wsgi request helpers ###################################################
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
   120
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
    def is_secure(self):
9741
b6cc9da206df [wsgi] the spec says wsgi.url_scheme *must* be provided
Julien Cristau <julien.cristau@logilab.fr>
parents: 9737
diff changeset
   122
        return self.environ['wsgi.url_scheme'] == 'https'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
    def get_posted_data(self):
8314
cfd6ab461849 [Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8309
diff changeset
   125
        # The WSGI spec says 'QUERY_STRING' may be absent.
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
   126
        post = parse_qs(self.environ.get('QUERY_STRING', ''))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        files = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        if self.method == 'POST':
9995
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   129
            content_type = self.environ.get('CONTENT_TYPE')
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   130
            if not content_type:
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   131
                raise RequestError("Missing Content-Type")
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   132
            content_type, options = parse_options_header(content_type)
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   133
            if content_type in (
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   134
                    'multipart/form-data',
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   135
                    'application/x-www-form-urlencoded',
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   136
                    'application/x-url-encoded'):
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   137
                forms, files = parse_form_data(
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   138
                    self.environ, strict=True,
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   139
                    mem_limit=self.vreg.config['max-post-length'])
c9f1111e0ee8 [wsgi] If multipart cannot parse the POST content, let it pass.
Christophe de Vienne <christophe@unlish.com>
parents: 9988
diff changeset
   140
                post.update(forms.dict)
9735
b71158815bc8 [wsgi] avoid reading the entire request body in memory
Julien Cristau <julien.cristau@logilab.fr>
parents: 9563
diff changeset
   141
        self.content.seek(0, 0)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        return post, files
9944
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   143
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   144
    def setup_params(self, params):
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   145
        # This is a copy of CubicWebRequestBase.setup_params, but without
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   146
        # converting unicode strings because it is partially done by
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   147
        # get_posted_data
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   148
        self.form = {}
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   149
        if params is None:
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   150
            return
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   151
        encoding = self.encoding
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   152
        for param, val in params.iteritems():
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   153
            if isinstance(val, (tuple, list)):
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   154
                val = [
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   155
                    unicode(x, encoding) if isinstance(x, str) else x
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   156
                    for x in val]
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   157
                if len(val) == 1:
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   158
                    val = val[0]
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   159
            elif isinstance(val, str):
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   160
                val = unicode(val, encoding)
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   161
            if param in self.no_script_form_params and val:
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   162
                val = self.no_script_form_param(param, val)
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   163
            if param == '_cwmsgid':
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   164
                self.set_message_id(val)
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   165
            elif param == '__message':
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   166
                warn('[3.13] __message in request parameter is deprecated (may '
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   167
                     'only be given to .build_url). Seeing this message usualy '
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   168
                     'means your application hold some <form> where you should '
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   169
                     'replace use of __message hidden input by form.set_message, '
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   170
                     'so new _cwmsgid mechanism is properly used',
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   171
                     DeprecationWarning)
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   172
                self.set_message(val)
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   173
            else:
9b3b21b7ff3e [wsgi] Fix multiple variables reading in params
Christophe de Vienne <christophe@unlish.com>
parents: 9943
diff changeset
   174
                self.form[param] = val