23 |
23 |
24 """ |
24 """ |
25 |
25 |
26 __docformat__ = "restructuredtext en" |
26 __docformat__ = "restructuredtext en" |
27 |
27 |
|
28 import tempfile |
|
29 |
28 from StringIO import StringIO |
30 from StringIO import StringIO |
29 from urllib import quote |
31 from urllib import quote |
30 from urlparse import parse_qs |
32 from urlparse import parse_qs |
|
33 from warnings import warn |
31 |
34 |
32 from cubicweb.multipart import copy_file, parse_form_data |
35 from cubicweb.multipart import copy_file, parse_form_data |
33 from cubicweb.web.request import CubicWebRequestBase |
36 from cubicweb.web.request import CubicWebRequestBase |
34 from cubicweb.wsgi import pformat, normalize_header |
37 from cubicweb.wsgi import pformat, normalize_header |
35 |
38 |
37 class CubicWebWsgiRequest(CubicWebRequestBase): |
40 class CubicWebWsgiRequest(CubicWebRequestBase): |
38 """most of this code COMES FROM DJANGO |
41 """most of this code COMES FROM DJANGO |
39 """ |
42 """ |
40 |
43 |
41 def __init__(self, environ, vreg): |
44 def __init__(self, environ, vreg): |
|
45 # self.vreg is used in get_posted_data, which is called before the |
|
46 # parent constructor. |
|
47 self.vreg = vreg |
|
48 |
42 self.environ = environ |
49 self.environ = environ |
43 self.path = environ['PATH_INFO'] |
50 self.path = environ['PATH_INFO'] |
44 self.method = environ['REQUEST_METHOD'].upper() |
51 self.method = environ['REQUEST_METHOD'].upper() |
45 |
52 |
46 # content_length "may be empty or absent" |
53 # content_length "may be empty or absent" |
57 self.content.seek(0, 0) |
64 self.content.seek(0, 0) |
58 environ['wsgi.input'] = self.content |
65 environ['wsgi.input'] = self.content |
59 |
66 |
60 headers_in = dict((normalize_header(k[5:]), v) for k, v in self.environ.items() |
67 headers_in = dict((normalize_header(k[5:]), v) for k, v in self.environ.items() |
61 if k.startswith('HTTP_')) |
68 if k.startswith('HTTP_')) |
|
69 if 'CONTENT_TYPE' in environ: |
|
70 headers_in['Content-Type'] = environ['CONTENT_TYPE'] |
62 https = self.is_secure() |
71 https = self.is_secure() |
|
72 if self.path.startswith('/https/'): |
|
73 self.path = self.path[6:] |
|
74 self.environ['PATH_INFO'] = self.path |
|
75 https = True |
|
76 |
63 post, files = self.get_posted_data() |
77 post, files = self.get_posted_data() |
64 |
78 |
65 super(CubicWebWsgiRequest, self).__init__(vreg, https, post, |
79 super(CubicWebWsgiRequest, self).__init__(vreg, https, post, |
66 headers= headers_in) |
80 headers= headers_in) |
|
81 self.content = environ['wsgi.input'] |
67 if files is not None: |
82 if files is not None: |
68 for key, part in files.iteritems(): |
83 for key, part in files.iteritems(): |
69 name = None |
84 name = None |
70 if part.filename is not None: |
85 if part.filename is not None: |
71 name = unicode(part.filename, self.encoding) |
86 name = unicode(part.filename, self.encoding) |
112 post = parse_qs(self.environ.get('QUERY_STRING', '')) |
127 post = parse_qs(self.environ.get('QUERY_STRING', '')) |
113 files = None |
128 files = None |
114 if self.method == 'POST': |
129 if self.method == 'POST': |
115 forms, files = parse_form_data(self.environ, strict=True, |
130 forms, files = parse_form_data(self.environ, strict=True, |
116 mem_limit=self.vreg.config['max-post-length']) |
131 mem_limit=self.vreg.config['max-post-length']) |
117 post.update(forms) |
132 post.update(forms.dict) |
118 self.content.seek(0, 0) |
133 self.content.seek(0, 0) |
119 return post, files |
134 return post, files |
|
135 |
|
136 def setup_params(self, params): |
|
137 # This is a copy of CubicWebRequestBase.setup_params, but without |
|
138 # converting unicode strings because it is partially done by |
|
139 # get_posted_data |
|
140 self.form = {} |
|
141 if params is None: |
|
142 return |
|
143 encoding = self.encoding |
|
144 for param, val in params.iteritems(): |
|
145 if isinstance(val, (tuple, list)): |
|
146 val = [ |
|
147 unicode(x, encoding) if isinstance(x, str) else x |
|
148 for x in val] |
|
149 if len(val) == 1: |
|
150 val = val[0] |
|
151 elif isinstance(val, str): |
|
152 val = unicode(val, encoding) |
|
153 if param in self.no_script_form_params and val: |
|
154 val = self.no_script_form_param(param, val) |
|
155 if param == '_cwmsgid': |
|
156 self.set_message_id(val) |
|
157 elif param == '__message': |
|
158 warn('[3.13] __message in request parameter is deprecated (may ' |
|
159 'only be given to .build_url). Seeing this message usualy ' |
|
160 'means your application hold some <form> where you should ' |
|
161 'replace use of __message hidden input by form.set_message, ' |
|
162 'so new _cwmsgid mechanism is properly used', |
|
163 DeprecationWarning) |
|
164 self.set_message(val) |
|
165 else: |
|
166 self.form[param] = val |