author | Pierre-Yves David <pierre-yves.david@logilab.fr> |
Tue, 11 Dec 2012 17:17:40 +0100 | |
branch | stable |
changeset 8610 | b1145ad53999 |
parent 8600 | d74addac92bb |
child 8611 | 51068fe1e39a |
permissions | -rw-r--r-- |
8190
2a3c1b787688
[vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8179
diff
changeset
|
1 |
# copyright 2003-2012 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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
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:
5389
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
5423
e15abfdcce38
backport default into stable: stable is now cw 3.8
Sylvain Thénault <sylvain.thenault@logilab.fr>
diff
changeset
|
18 |
"""abstract class for http request""" |
0 | 19 |
|
20 |
__docformat__ = "restructuredtext en" |
|
21 |
||
22 |
import time |
|
23 |
import random |
|
24 |
import base64 |
|
8600
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
25 |
import urllib |
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:
7872
diff
changeset
|
26 |
from hashlib import sha1 # pylint: disable=E0611 |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
27 |
from Cookie import SimpleCookie |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
28 |
from calendar import timegm |
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
29 |
from datetime import date, datetime |
0 | 30 |
from urlparse import urlsplit |
8316
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
31 |
import httplib |
0 | 32 |
from itertools import count |
6078
c08e74b0609e
fix missing import in web.request
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
6064
diff
changeset
|
33 |
from warnings import warn |
0 | 34 |
|
35 |
from rql.utils import rqlvar_maker |
|
36 |
||
37 |
from logilab.common.decorators import cached |
|
2613
5e19c2bb370e
R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
2559
diff
changeset
|
38 |
from logilab.common.deprecation import deprecated |
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2258
diff
changeset
|
39 |
from logilab.mtconverter import xml_escape |
1801
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
40 |
|
0 | 41 |
from cubicweb.dbapi import DBAPIRequest |
6063
17a53f6dea42
[request] js is defined in uilib, not utils
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6062
diff
changeset
|
42 |
from cubicweb.uilib import remove_html_tags, js |
17a53f6dea42
[request] js is defined in uilib, not utils
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6062
diff
changeset
|
43 |
from cubicweb.utils import SizeConstrainedList, HTMLHead, make_uid |
3094
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
44 |
from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE_NOEXT |
1801
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
45 |
from cubicweb.web import (INTERNAL_FIELD_VALUE, LOGGER, NothingToEdit, |
5940
0e3ae19b181a
[uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5890
diff
changeset
|
46 |
RequestError, StatusResponse) |
8316
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
47 |
from cubicweb.web.httpcache import GMTOFFSET, get_validators |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
48 |
from cubicweb.web.http_headers import Headers, Cookie, parseDateTime |
0 | 49 |
|
662
6f867ab70e3d
move _MARKER from appobject to web.request
sylvain.thenault@logilab.fr
parents:
610
diff
changeset
|
50 |
_MARKER = object() |
6f867ab70e3d
move _MARKER from appobject to web.request
sylvain.thenault@logilab.fr
parents:
610
diff
changeset
|
51 |
|
6564
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
52 |
def build_cb_uid(seed): |
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:
7872
diff
changeset
|
53 |
sha = sha1('%s%s%s' % (time.time(), seed, random.random())) |
6564
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
54 |
return 'cb_%s' % (sha.hexdigest()) |
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
55 |
|
0 | 56 |
|
57 |
def list_form_param(form, param, pop=False): |
|
58 |
"""get param from form parameters and return its value as a list, |
|
59 |
skipping internal markers if any |
|
60 |
||
61 |
* if the parameter isn't defined, return an empty list |
|
62 |
* if the parameter is a single (unicode) value, return a list |
|
63 |
containing that value |
|
64 |
* if the parameter is already a list or tuple, just skip internal |
|
65 |
markers |
|
66 |
||
8238
087bb529035c
[spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8177
diff
changeset
|
67 |
if pop is True, the parameter is removed from the form dictionary |
0 | 68 |
""" |
69 |
if pop: |
|
70 |
try: |
|
71 |
value = form.pop(param) |
|
72 |
except KeyError: |
|
73 |
return [] |
|
74 |
else: |
|
75 |
value = form.get(param, ()) |
|
76 |
if value is None: |
|
77 |
value = () |
|
78 |
elif not isinstance(value, (list, tuple)): |
|
79 |
value = [value] |
|
80 |
return [v for v in value if v != INTERNAL_FIELD_VALUE] |
|
81 |
||
82 |
||
83 |
||
84 |
class CubicWebRequestBase(DBAPIRequest): |
|
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
85 |
"""abstract HTTP request, should be extended according to the HTTP backend |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
86 |
Immutable attributes that describe the received query and generic configuration |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
87 |
""" |
8128
0a927fe4541b
[controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8082
diff
changeset
|
88 |
ajax_request = False # to be set to True by ajax controllers |
1421
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
89 |
|
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
90 |
def __init__(self, vreg, https=False, form=None, headers={}): |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
91 |
""" |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
92 |
:vreg: Vregistry, |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
93 |
:https: boolean, s this a https request |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
94 |
:form: Forms value |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
95 |
""" |
0 | 96 |
super(CubicWebRequestBase, self).__init__(vreg) |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
97 |
#: (Boolean) Is this an https request. |
0 | 98 |
self.https = https |
8480
086cff6a306a
[book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8316
diff
changeset
|
99 |
#: User interface property (vary with https) (see :ref:`uiprops`) |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
100 |
self.uiprops = None |
8480
086cff6a306a
[book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8316
diff
changeset
|
101 |
#: url for serving datadir (vary with https) (see :ref:`resources`) |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
102 |
self.datadir_url = None |
5467
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
103 |
if https: |
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
104 |
self.uiprops = vreg.config.https_uiprops |
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
105 |
self.datadir_url = vreg.config.https_datadir_url |
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
106 |
else: |
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
107 |
self.uiprops = vreg.config.uiprops |
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
108 |
self.datadir_url = vreg.config.datadir_url |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
109 |
#: raw html headers that can be added from any view |
7762
a3f9ba4d44eb
[web] add option to make resources-concat optional (implements #1910615)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7660
diff
changeset
|
110 |
self.html_headers = HTMLHead(self) |
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
111 |
#: received headers |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
112 |
self._headers_in = Headers() |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
113 |
for k, v in headers.iteritems(): |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
114 |
self._headers_in.addRawHeader(k, v) |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
115 |
#: form parameters |
0 | 116 |
self.setup_params(form) |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
117 |
#: dictionary that may be used to store request data that has to be |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
118 |
#: shared among various components used to publish the request (views, |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
119 |
#: controller, application...) |
0 | 120 |
self.data = {} |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
121 |
#: search state: 'normal' or 'linksearch' (eg searching for an object |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
122 |
#: to create a relation with another) |
1426 | 123 |
self.search_state = ('normal',) |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
124 |
#: page id, set by htmlheader template |
0 | 125 |
self.pageid = None |
3816
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
126 |
self._set_pageid() |
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
127 |
# prepare output header |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
128 |
#: Header used for the final response |
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
129 |
self.headers_out = Headers() |
8312
6c2119509fac
[web] Move request handling logic into cubicweb application. (closes #2200684)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8309
diff
changeset
|
130 |
#: HTTP status use by the final response |
6c2119509fac
[web] Move request handling logic into cubicweb application. (closes #2200684)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8309
diff
changeset
|
131 |
self.status_out = 200 |
3816
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
132 |
|
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
133 |
def _set_pageid(self): |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
134 |
"""initialize self.pageid |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
135 |
if req.form provides a specific pageid, use it, otherwise build a |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
136 |
new one. |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
137 |
""" |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
138 |
pid = self.form.get('pageid') |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
139 |
if pid is None: |
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
140 |
pid = make_uid(id(self)) |
7374
3c9850d929e5
[web request] don't define pageid js variable when one is found in form parameters (eg, page ajax call)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7268
diff
changeset
|
141 |
self.html_headers.define_var('pageid', pid, override=False) |
3816
37b376bb4088
[web] set pageid at request instanciation rather than in htmlheader template
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3275
diff
changeset
|
142 |
self.pageid = pid |
0 | 143 |
|
8155
c075950cc929
[bw compat] json_request setter is necessary for some cubes which has json_request (eg preview)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8128
diff
changeset
|
144 |
def _get_json_request(self): |
8128
0a927fe4541b
[controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8082
diff
changeset
|
145 |
warn('[3.15] self._cw.json_request is deprecated, use self._cw.ajax_request instead', |
0a927fe4541b
[controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8082
diff
changeset
|
146 |
DeprecationWarning, stacklevel=2) |
0a927fe4541b
[controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8082
diff
changeset
|
147 |
return self.ajax_request |
8155
c075950cc929
[bw compat] json_request setter is necessary for some cubes which has json_request (eg preview)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8128
diff
changeset
|
148 |
def _set_json_request(self, value): |
c075950cc929
[bw compat] json_request setter is necessary for some cubes which has json_request (eg preview)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8128
diff
changeset
|
149 |
warn('[3.15] self._cw.json_request is deprecated, use self._cw.ajax_request instead', |
c075950cc929
[bw compat] json_request setter is necessary for some cubes which has json_request (eg preview)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8128
diff
changeset
|
150 |
DeprecationWarning, stacklevel=2) |
c075950cc929
[bw compat] json_request setter is necessary for some cubes which has json_request (eg preview)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8128
diff
changeset
|
151 |
self.ajax_request = value |
c075950cc929
[bw compat] json_request setter is necessary for some cubes which has json_request (eg preview)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8128
diff
changeset
|
152 |
json_request = property(_get_json_request, _set_json_request) |
8128
0a927fe4541b
[controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8082
diff
changeset
|
153 |
|
8309
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
154 |
def base_url(self, secure=None): |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
155 |
"""return the root url of the instance |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
156 |
|
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
157 |
secure = False -> base-url |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
158 |
secure = None -> https-url if req.https |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
159 |
secure = True -> https if it exist |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
160 |
""" |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
161 |
if secure is None: |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
162 |
secure = self.https |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
163 |
base_url = None |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
164 |
if secure: |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
165 |
base_url = self.vreg.config.get('https-url') |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
166 |
if base_url is None: |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
167 |
base_url = super(CubicWebRequestBase, self).base_url() |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
168 |
return base_url |
48ef505aa9f9
[request] gather all base_url logic in a single place (closes #2200756)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8271
diff
changeset
|
169 |
|
2792
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
170 |
@property |
6581
4a3b264589dc
[dbapi] enhanced web compatible request when using dbapi
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6564
diff
changeset
|
171 |
def authmode(self): |
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
172 |
"""Authentification mode of the instance |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
173 |
|
8480
086cff6a306a
[book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8316
diff
changeset
|
174 |
(see :ref:`WebServerConfig`)""" |
6581
4a3b264589dc
[dbapi] enhanced web compatible request when using dbapi
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6564
diff
changeset
|
175 |
return self.vreg.config['auth-mode'] |
4a3b264589dc
[dbapi] enhanced web compatible request when using dbapi
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6564
diff
changeset
|
176 |
|
8271
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
177 |
# Various variable generator. |
3bd9b317b1d8
[req, doc] add some documentation of CubicWebRequestBase attributes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8239
diff
changeset
|
178 |
|
6581
4a3b264589dc
[dbapi] enhanced web compatible request when using dbapi
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6564
diff
changeset
|
179 |
@property |
2801
7ef4c1c9266b
fix syntax error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2792
diff
changeset
|
180 |
def varmaker(self): |
4366
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
181 |
"""the rql varmaker is exposed both as a property and as the |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
182 |
set_varmaker function since we've two use cases: |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
183 |
|
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
184 |
* accessing the req.varmaker property to get a new variable name |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
185 |
|
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
186 |
* calling req.set_varmaker() to ensure a varmaker is set for later ajax |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
187 |
calls sharing our .pageid |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
188 |
""" |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
189 |
return self.set_varmaker() |
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
190 |
|
7266
f625097d1e99
[request] don't init tabindex unnecessarily, since it's added to page data which will makes an ajax call to unload_page_data necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7070
diff
changeset
|
191 |
def next_tabindex(self): |
6259
c3d98e4bee12
[request] memoize tabindex across ajax calls (on pageid) to avoid ui confusion
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6108
diff
changeset
|
192 |
nextfunc = self.get_page_data('nexttabfunc') |
c3d98e4bee12
[request] memoize tabindex across ajax calls (on pageid) to avoid ui confusion
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6108
diff
changeset
|
193 |
if nextfunc is None: |
c3d98e4bee12
[request] memoize tabindex across ajax calls (on pageid) to avoid ui confusion
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6108
diff
changeset
|
194 |
nextfunc = count(1).next |
c3d98e4bee12
[request] memoize tabindex across ajax calls (on pageid) to avoid ui confusion
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6108
diff
changeset
|
195 |
self.set_page_data('nexttabfunc', nextfunc) |
7266
f625097d1e99
[request] don't init tabindex unnecessarily, since it's added to page data which will makes an ajax call to unload_page_data necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7070
diff
changeset
|
196 |
return nextfunc() |
6259
c3d98e4bee12
[request] memoize tabindex across ajax calls (on pageid) to avoid ui confusion
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6108
diff
changeset
|
197 |
|
4366
d51f28ba9399
fif inlined relation forms pb w/ new ajax forms.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4277
diff
changeset
|
198 |
def set_varmaker(self): |
2792
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
199 |
varmaker = self.get_page_data('rql_varmaker') |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
200 |
if varmaker is None: |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
201 |
varmaker = rqlvar_maker() |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
202 |
self.set_page_data('rql_varmaker', varmaker) |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
203 |
return varmaker |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
204 |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
205 |
def set_session(self, session, user=None): |
0 | 206 |
"""method called by the session handler when the user is authenticated |
207 |
or an anonymous connection is open |
|
208 |
""" |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
209 |
super(CubicWebRequestBase, self).set_session(session, user) |
2245
7463e1a748dd
new set_session_props method exposed by the repository, use it to be sure session language is in sync the request language
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2202
diff
changeset
|
210 |
# set request language |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
211 |
vreg = self.vreg |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
212 |
if self.user: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
213 |
try: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
214 |
# 1. user specified language |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
215 |
lang = vreg.typed_value('ui.language', |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
216 |
self.user.properties['ui.language']) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
217 |
self.set_language(lang) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
218 |
return |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
219 |
except KeyError: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
220 |
pass |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
221 |
if vreg.config['language-negociation']: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
222 |
# 2. http negociated language |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
223 |
for lang in self.header_accept_language(): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
224 |
if lang in self.translations: |
0 | 225 |
self.set_language(lang) |
226 |
return |
|
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
227 |
# 3. default language |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
228 |
self.set_default_language(vreg) |
1426 | 229 |
|
0 | 230 |
def set_language(self, lang): |
3275
5247789df541
[gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3094
diff
changeset
|
231 |
gettext, self.pgettext = self.translations[lang] |
5247789df541
[gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3094
diff
changeset
|
232 |
self._ = self.__ = gettext |
0 | 233 |
self.lang = lang |
234 |
self.debug('request language: %s', lang) |
|
5244
5467674ad101
[web] put a fake object that raise Unauthorized on any attribute access as req.cnx and req._user, so we are properly asked to authenticated on any view that tries to do something with one of those attributes (instead of doing defensive programming everywhere we're doing that)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5223
diff
changeset
|
235 |
if self.cnx: |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
236 |
self.cnx.set_session_props(lang=lang) |
1426 | 237 |
|
0 | 238 |
# input form parameters management ######################################## |
1426 | 239 |
|
0 | 240 |
# common form parameters which should be protected against html values |
241 |
# XXX can't add 'eid' for instance since it may be multivalued |
|
242 |
# dont put rql as well, if query contains < and > it will be corrupted! |
|
1426 | 243 |
no_script_form_params = set(('vid', |
244 |
'etype', |
|
0 | 245 |
'vtitle', 'title', |
246 |
'__message', |
|
247 |
'__redirectvid', '__redirectrql')) |
|
1426 | 248 |
|
0 | 249 |
def setup_params(self, params): |
250 |
"""WARNING: we're intentionaly leaving INTERNAL_FIELD_VALUE here |
|
251 |
||
1426 | 252 |
subclasses should overrides to |
0 | 253 |
""" |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
254 |
self.form = {} |
0 | 255 |
if params is None: |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
256 |
return |
0 | 257 |
encoding = self.encoding |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
258 |
for param, val in params.iteritems(): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
259 |
if isinstance(val, (tuple, list)): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
260 |
val = [unicode(x, encoding) for x in val] |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
261 |
if len(val) == 1: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
262 |
val = val[0] |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
263 |
elif isinstance(val, str): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
264 |
val = unicode(val, encoding) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
265 |
if param in self.no_script_form_params and val: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
266 |
val = self.no_script_form_param(param, val) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
267 |
if param == '_cwmsgid': |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
268 |
self.set_message_id(val) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
269 |
elif param == '__message': |
7432
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
270 |
warn('[3.13] __message in request parameter is deprecated (may ' |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
271 |
'only be given to .build_url). Seeing this message usualy ' |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
272 |
'means your application hold some <form> where you should ' |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
273 |
'replace use of __message hidden input by form.set_message, ' |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
274 |
'so new _cwmsgid mechanism is properly used', |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
275 |
DeprecationWarning) |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
276 |
self.set_message(val) |
0 | 277 |
else: |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
278 |
self.form[param] = val |
1426 | 279 |
|
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
280 |
def no_script_form_param(self, param, value): |
0 | 281 |
"""ensure there is no script in a user form param |
282 |
||
283 |
by default return a cleaned string instead of raising a security |
|
284 |
exception |
|
285 |
||
286 |
this method should be called on every user input (form at least) fields |
|
287 |
that are at some point inserted in a generated html page to protect |
|
288 |
against script kiddies |
|
289 |
""" |
|
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
290 |
# safety belt for strange urls like http://...?vtitle=yo&vtitle=yo |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
291 |
if isinstance(value, (list, tuple)): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
292 |
self.error('no_script_form_param got a list (%s). Who generated the URL ?', |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
293 |
repr(value)) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
294 |
value = value[0] |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
295 |
return remove_html_tags(value) |
1426 | 296 |
|
0 | 297 |
def list_form_param(self, param, form=None, pop=False): |
298 |
"""get param from form parameters and return its value as a list, |
|
299 |
skipping internal markers if any |
|
1426 | 300 |
|
0 | 301 |
* if the parameter isn't defined, return an empty list |
302 |
* if the parameter is a single (unicode) value, return a list |
|
303 |
containing that value |
|
304 |
* if the parameter is already a list or tuple, just skip internal |
|
305 |
markers |
|
306 |
||
8238
087bb529035c
[spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8177
diff
changeset
|
307 |
if pop is True, the parameter is removed from the form dictionary |
0 | 308 |
""" |
309 |
if form is None: |
|
310 |
form = self.form |
|
1426 | 311 |
return list_form_param(form, param, pop) |
312 |
||
0 | 313 |
def reset_headers(self): |
314 |
"""used by AutomaticWebTest to clear html headers between tests on |
|
315 |
the same resultset |
|
316 |
""" |
|
7762
a3f9ba4d44eb
[web] add option to make resources-concat optional (implements #1910615)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7660
diff
changeset
|
317 |
self.html_headers = HTMLHead(self) |
0 | 318 |
return self |
319 |
||
320 |
# web state helpers ####################################################### |
|
1426 | 321 |
|
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
322 |
@property |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
323 |
def message(self): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
324 |
try: |
7432
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
325 |
return self.session.data.pop(self._msgid, u'') |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
326 |
except AttributeError: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
327 |
try: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
328 |
return self._msg |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
329 |
except AttributeError: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
330 |
return None |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
331 |
|
0 | 332 |
def set_message(self, msg): |
333 |
assert isinstance(msg, unicode) |
|
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
334 |
self._msg = msg |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
335 |
|
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
336 |
def set_message_id(self, msgid): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
337 |
self._msgid = msgid |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
338 |
|
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
339 |
@cached |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
340 |
def redirect_message_id(self): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
341 |
return make_uid() |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
342 |
|
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
343 |
def set_redirect_message(self, msg): |
7432
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
344 |
# TODO - this should probably be merged with append_to_redirect_message |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
345 |
assert isinstance(msg, unicode) |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
346 |
msgid = self.redirect_message_id() |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
347 |
self.session.data[msgid] = msg |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
348 |
return msgid |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
349 |
|
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
350 |
def append_to_redirect_message(self, msg): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
351 |
msgid = self.redirect_message_id() |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
352 |
currentmsg = self.session.data.get(msgid) |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
353 |
if currentmsg is not None: |
7432
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
354 |
currentmsg = u'%s %s' % (currentmsg, msg) |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
355 |
else: |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
356 |
currentmsg = msg |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
357 |
self.session.data[msgid] = currentmsg |
4897
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
358 |
return msgid |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
359 |
|
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
360 |
def reset_message(self): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
361 |
if hasattr(self, '_msg'): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
362 |
del self._msg |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
363 |
if hasattr(self, '_msgid'): |
e402e0b32075
[web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4851
diff
changeset
|
364 |
del self._msgid |
1426 | 365 |
|
0 | 366 |
def update_search_state(self): |
367 |
"""update the current search state""" |
|
368 |
searchstate = self.form.get('__mode') |
|
5244
5467674ad101
[web] put a fake object that raise Unauthorized on any attribute access as req.cnx and req._user, so we are properly asked to authenticated on any view that tries to do something with one of those attributes (instead of doing defensive programming everywhere we're doing that)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5223
diff
changeset
|
369 |
if not searchstate and self.cnx: |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
370 |
searchstate = self.session.data.get('search_state', 'normal') |
0 | 371 |
self.set_search_state(searchstate) |
372 |
||
373 |
def set_search_state(self, searchstate): |
|
374 |
"""set a new search state""" |
|
375 |
if searchstate is None or searchstate == 'normal': |
|
376 |
self.search_state = (searchstate or 'normal',) |
|
377 |
else: |
|
378 |
self.search_state = ('linksearch', searchstate.split(':')) |
|
379 |
assert len(self.search_state[-1]) == 4 |
|
5244
5467674ad101
[web] put a fake object that raise Unauthorized on any attribute access as req.cnx and req._user, so we are properly asked to authenticated on any view that tries to do something with one of those attributes (instead of doing defensive programming everywhere we're doing that)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5223
diff
changeset
|
380 |
if self.cnx: |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
381 |
self.session.data['search_state'] = searchstate |
0 | 382 |
|
1173
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
383 |
def match_search_state(self, rset): |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
384 |
"""when searching an entity to create a relation, return True if entities in |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
385 |
the given rset may be used as relation end |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
386 |
""" |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
387 |
try: |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
388 |
searchedtype = self.search_state[1][-1] |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
389 |
except IndexError: |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
390 |
return False # no searching for association |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
391 |
for etype in rset.column_types(0): |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
392 |
if etype != searchedtype: |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
393 |
return False |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
394 |
return True |
8f123fd081f4
forgot to add that expected method (was a function in view.__init__)
sylvain.thenault@logilab.fr
parents:
1013
diff
changeset
|
395 |
|
0 | 396 |
def update_breadcrumbs(self): |
397 |
"""stores the last visisted page in session data""" |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
398 |
searchstate = self.session.data.get('search_state') |
0 | 399 |
if searchstate == 'normal': |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
400 |
breadcrumbs = self.session.data.get('breadcrumbs') |
0 | 401 |
if breadcrumbs is None: |
402 |
breadcrumbs = SizeConstrainedList(10) |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
403 |
self.session.data['breadcrumbs'] = breadcrumbs |
4864
e77d3e95872d
[web req] check latest url in breadcrumbs is not the same as the current one to keep more valuable information
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
404 |
breadcrumbs.append(self.url()) |
e77d3e95872d
[web req] check latest url in breadcrumbs is not the same as the current one to keep more valuable information
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
405 |
else: |
e77d3e95872d
[web req] check latest url in breadcrumbs is not the same as the current one to keep more valuable information
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
406 |
url = self.url() |
4974
025a491bad0c
take care to empty breadcrumbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4868
diff
changeset
|
407 |
if breadcrumbs and breadcrumbs[-1] != url: |
4864
e77d3e95872d
[web req] check latest url in breadcrumbs is not the same as the current one to keep more valuable information
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
408 |
breadcrumbs.append(url) |
0 | 409 |
|
410 |
def last_visited_page(self): |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
411 |
breadcrumbs = self.session.data.get('breadcrumbs') |
0 | 412 |
if breadcrumbs: |
413 |
return breadcrumbs.pop() |
|
414 |
return self.base_url() |
|
415 |
||
6062
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
416 |
def user_rql_callback(self, rqlargs, *args, **kwargs): |
7793
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
417 |
"""register a user callback to execute some rql query, and return a URL |
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
418 |
to call that callback which can be inserted in an HTML view. |
6062
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
419 |
|
7793
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
420 |
`rqlargs` should be a tuple containing argument to give to the execute function. |
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
421 |
|
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
422 |
The first argument following rqlargs must be the message to be |
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
423 |
displayed after the callback is called. |
6062
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
424 |
|
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
425 |
For other allowed arguments, see :meth:`user_callback` method |
2792
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
426 |
""" |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
427 |
def rqlexec(req, rql, args=None, key=None): |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
428 |
req.execute(rql, args, key) |
6062
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
429 |
return self.user_callback(rqlexec, rqlargs, *args, **kwargs) |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
430 |
|
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
431 |
def user_callback(self, cb, cbargs, *args, **kwargs): |
7793
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
432 |
"""register the given user callback and return a URL which can |
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
433 |
be inserted in an HTML view. When the URL is accessed, the |
8032
bcb87336c7d2
[doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7990
diff
changeset
|
434 |
callback function will be called (as 'cb(req, \*cbargs)', and a |
7793
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
435 |
message will be displayed in the web interface. The third |
8a330017ca4d
[doc] add some documentation in cubicweb.web.action
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
7660
diff
changeset
|
436 |
positional argument must be 'msg', containing the message. |
2792
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
437 |
|
6062
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
438 |
You can specify the underlying js function to call using a 'jsfunc' |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
439 |
named args, to one of :func:`userCallback`, |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
440 |
':func:`userCallbackThenUpdateUI`, ':func:`userCallbackThenReloadPage` |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
441 |
(the default). Take care arguments may vary according to the used |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
442 |
function. |
2792
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
443 |
""" |
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
444 |
self.add_js('cubicweb.ajax.js') |
6062
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
445 |
jsfunc = kwargs.pop('jsfunc', 'userCallbackThenReloadPage') |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
446 |
if 'msg' in kwargs: |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
447 |
warn('[3.10] msg should be given as positional argument', |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
448 |
DeprecationWarning, stacklevel=2) |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
449 |
args = (kwargs.pop('msg'),) + args |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
450 |
assert not kwargs, 'dunno what to do with remaining kwargs: %s' % kwargs |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
451 |
cbname = self.register_onetime_callback(cb, *cbargs) |
f1a550102f5c
[request] enhanced user[_rql]_callback method, allowing to call other js variant, eg one of userCallback, userCallbackThenUpdateUI, userCallbackThenReloadPage (the default). Also benefit from the new magic js object.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
452 |
return "javascript: %s" % getattr(js, jsfunc)(cbname, *args) |
2792
135580d15d42
rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2788
diff
changeset
|
453 |
|
0 | 454 |
def register_onetime_callback(self, func, *args): |
6564
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
455 |
cbname = build_cb_uid(func.__name__) |
0 | 456 |
def _cb(req): |
457 |
try: |
|
7990
a673d1d9a738
[diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7894
diff
changeset
|
458 |
return func(req, *args) |
a673d1d9a738
[diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7894
diff
changeset
|
459 |
finally: |
a673d1d9a738
[diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7894
diff
changeset
|
460 |
self.unregister_callback(self.pageid, cbname) |
0 | 461 |
self.set_page_data(cbname, _cb) |
462 |
return cbname |
|
1426 | 463 |
|
0 | 464 |
def unregister_callback(self, pageid, cbname): |
465 |
assert pageid is not None |
|
466 |
assert cbname.startswith('cb_') |
|
467 |
self.info('unregistering callback %s for pageid %s', cbname, pageid) |
|
468 |
self.del_page_data(cbname) |
|
469 |
||
470 |
def clear_user_callbacks(self): |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
471 |
if self.session is not None: # XXX |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
472 |
for key in self.session.data.keys(): |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
473 |
if key.startswith('cb_'): |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
474 |
del self.session.data[key] |
1426 | 475 |
|
0 | 476 |
# web edition helpers ##################################################### |
1426 | 477 |
|
0 | 478 |
@cached # so it's writed only once |
479 |
def fckeditor_config(self): |
|
7277
acd7f0e9f276
[etwist] Generates apache's mod_concat-like urls for js and css
Quentin Roquefort <roquefort.quentin@gmail.com>
parents:
7273
diff
changeset
|
480 |
fckeditor_url = self.build_url('fckeditor/fckeditor.js') |
acd7f0e9f276
[etwist] Generates apache's mod_concat-like urls for js and css
Quentin Roquefort <roquefort.quentin@gmail.com>
parents:
7273
diff
changeset
|
481 |
self.add_js(fckeditor_url, localfile=False) |
0 | 482 |
self.html_headers.define_var('fcklang', self.lang) |
483 |
self.html_headers.define_var('fckconfigpath', |
|
7070
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
484 |
self.data_url('cubicweb.fckcwconfig.js')) |
1013
948a3882c94a
add a use_fckeditor method on http request
sylvain.thenault@logilab.fr
parents:
940
diff
changeset
|
485 |
def use_fckeditor(self): |
948a3882c94a
add a use_fckeditor method on http request
sylvain.thenault@logilab.fr
parents:
940
diff
changeset
|
486 |
return self.vreg.config.fckeditor_installed() and self.property_value('ui.fckeditor') |
0 | 487 |
|
488 |
def edited_eids(self, withtype=False): |
|
489 |
"""return a list of edited eids""" |
|
490 |
yielded = False |
|
491 |
# warning: use .keys since the caller may change `form` |
|
492 |
form = self.form |
|
493 |
try: |
|
494 |
eids = form['eid'] |
|
495 |
except KeyError: |
|
4155
80cc9c6ddcf0
NothingToEdit is not a ValidationError, simplify
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4154
diff
changeset
|
496 |
raise NothingToEdit(self._('no selected entities')) |
0 | 497 |
if isinstance(eids, basestring): |
498 |
eids = (eids,) |
|
499 |
for peid in eids: |
|
500 |
if withtype: |
|
501 |
typekey = '__type:%s' % peid |
|
502 |
assert typekey in form, 'no entity type specified' |
|
503 |
yield peid, form[typekey] |
|
504 |
else: |
|
505 |
yield peid |
|
506 |
yielded = True |
|
507 |
if not yielded: |
|
4155
80cc9c6ddcf0
NothingToEdit is not a ValidationError, simplify
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4154
diff
changeset
|
508 |
raise NothingToEdit(self._('no selected entities')) |
0 | 509 |
|
510 |
# minparams=3 by default: at least eid, __type, and some params to change |
|
511 |
def extract_entity_params(self, eid, minparams=3): |
|
512 |
"""extract form parameters relative to the given eid""" |
|
513 |
params = {} |
|
514 |
eid = str(eid) |
|
515 |
form = self.form |
|
516 |
for param in form: |
|
517 |
try: |
|
518 |
name, peid = param.split(':', 1) |
|
519 |
except ValueError: |
|
7639
5c9e94a09e97
[web form] avoid mis-formated warning for _cw_fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7536
diff
changeset
|
520 |
if not param.startswith('__') and param not in ('eid', '_cw_fields'): |
6079 | 521 |
self.warning('param %s mis-formatted', param) |
0 | 522 |
continue |
523 |
if peid == eid: |
|
524 |
value = form[param] |
|
525 |
if value == INTERNAL_FIELD_VALUE: |
|
526 |
value = None |
|
527 |
params[name] = value |
|
528 |
params['eid'] = eid |
|
529 |
if len(params) < minparams: |
|
530 |
raise RequestError(self._('missing parameters for entity %s') % eid) |
|
531 |
return params |
|
1426 | 532 |
|
4277
35cd057339b2
turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
533 |
# XXX this should go to the GenericRelationsField. missing edition cancel protocol. |
0 | 534 |
|
535 |
def remove_pending_operations(self): |
|
536 |
"""shortcut to clear req's pending_{delete,insert} entries |
|
537 |
||
538 |
This is needed when the edition is completed (whether it's validated |
|
539 |
or cancelled) |
|
540 |
""" |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
541 |
self.session.data.pop('pending_insert', None) |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
542 |
self.session.data.pop('pending_delete', None) |
0 | 543 |
|
544 |
def cancel_edition(self, errorurl): |
|
545 |
"""remove pending operations and `errorurl`'s specific stored data |
|
546 |
""" |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
547 |
self.session.data.pop(errorurl, None) |
0 | 548 |
self.remove_pending_operations() |
1426 | 549 |
|
0 | 550 |
# high level methods for HTTP headers management ########################## |
551 |
||
552 |
# must be cached since login/password are popped from the form dictionary |
|
553 |
# and this method may be called multiple times during authentication |
|
554 |
@cached |
|
555 |
def get_authorization(self): |
|
556 |
"""Parse and return the Authorization header""" |
|
557 |
if self.authmode == "cookie": |
|
558 |
try: |
|
559 |
user = self.form.pop("__login") |
|
560 |
passwd = self.form.pop("__password", '') |
|
561 |
return user, passwd.encode('UTF8') |
|
562 |
except KeyError: |
|
563 |
self.debug('no login/password in form params') |
|
564 |
return None, None |
|
565 |
else: |
|
566 |
return self.header_authorization() |
|
1426 | 567 |
|
0 | 568 |
def get_cookie(self): |
569 |
"""retrieve request cookies, returns an empty cookie if not found""" |
|
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
570 |
# XXX use http_headers implementation |
0 | 571 |
try: |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
572 |
return SimpleCookie(self.get_header('Cookie')) |
0 | 573 |
except KeyError: |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
574 |
return SimpleCookie() |
0 | 575 |
|
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
576 |
def set_cookie(self, name, value, maxage=300, expires=None, secure=False): |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
577 |
"""set / update a cookie |
0 | 578 |
|
579 |
by default, cookie will be available for the next 5 minutes. |
|
580 |
Give maxage = None to have a "session" cookie expiring when the |
|
581 |
client close its browser |
|
582 |
""" |
|
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
583 |
if isinstance(name, SimpleCookie): |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
584 |
warn('[3.13] set_cookie now takes name and value as two first ' |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
585 |
'argument, not anymore cookie object and name', |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
586 |
DeprecationWarning, stacklevel=2) |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
587 |
secure = name[value]['secure'] |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
588 |
name, value = value, name[value].value |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
589 |
if maxage: # don't check is None, 0 may be specified |
7858
f91255a3b2c2
[web request] fix stupid error that gone through the review
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7855
diff
changeset
|
590 |
assert expires is None, 'both max age and expires cant be specified' |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
591 |
expires = maxage + time.time() |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
592 |
elif expires: |
8176
eff4fe02ec64
[req cookie] fix remove_cookie expires which was leading to expires computed to 0 in set_cookie and the Cookie class interpret that has no expires. Closes #2154654
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8081
diff
changeset
|
593 |
# we don't want to handle times before the EPOCH (cause bug on |
eff4fe02ec64
[req cookie] fix remove_cookie expires which was leading to expires computed to 0 in set_cookie and the Cookie class interpret that has no expires. Closes #2154654
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8081
diff
changeset
|
594 |
# windows). Also use > and not >= else expires == 0 and Cookie think |
eff4fe02ec64
[req cookie] fix remove_cookie expires which was leading to expires computed to 0 in set_cookie and the Cookie class interpret that has no expires. Closes #2154654
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8081
diff
changeset
|
595 |
# that means no expire... |
eff4fe02ec64
[req cookie] fix remove_cookie expires which was leading to expires computed to 0 in set_cookie and the Cookie class interpret that has no expires. Closes #2154654
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8081
diff
changeset
|
596 |
assert expires + GMTOFFSET > date(1970, 1, 1) |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
597 |
expires = timegm((expires + GMTOFFSET).timetuple()) |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
598 |
else: |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
599 |
expires = None |
0 | 600 |
# make sure cookie is set on the correct path |
7870
1a1e04163cde
[test] unicode name/value in cookie makes tests failing (SimpleCookie then suppose it's a dict...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7858
diff
changeset
|
601 |
cookie = Cookie(str(name), str(value), self.base_url_path(), |
1a1e04163cde
[test] unicode name/value in cookie makes tests failing (SimpleCookie then suppose it's a dict...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7858
diff
changeset
|
602 |
expires=expires, secure=secure) |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
603 |
self.headers_out.addHeader('Set-cookie', cookie) |
0 | 604 |
|
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
605 |
def remove_cookie(self, name, bwcompat=None): |
0 | 606 |
"""remove a cookie by expiring it""" |
7855
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
607 |
if bwcompat is not None: |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
608 |
warn('[3.13] remove_cookie now take only a name as argument', |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
609 |
DeprecationWarning, stacklevel=2) |
54283a5b7afc
[web request] fix cookie 'expires' formating (closes #1953945)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7793
diff
changeset
|
610 |
name = bwcompat |
8176
eff4fe02ec64
[req cookie] fix remove_cookie expires which was leading to expires computed to 0 in set_cookie and the Cookie class interpret that has no expires. Closes #2154654
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8081
diff
changeset
|
611 |
self.set_cookie(name, '', maxage=0, expires=date(2000, 1, 1)) |
0 | 612 |
|
613 |
def set_content_type(self, content_type, filename=None, encoding=None): |
|
614 |
"""set output content type for this request. An optional filename |
|
615 |
may be given |
|
616 |
""" |
|
6353
b622602f8e9d
don't add another encoding if already present in content-type
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
6259
diff
changeset
|
617 |
if content_type.startswith('text/') and ';charset=' not in content_type: |
0 | 618 |
content_type += ';charset=' + (encoding or self.encoding) |
619 |
self.set_header('content-type', content_type) |
|
620 |
if filename: |
|
8600
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
621 |
header = ['attachment'] |
8610
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
622 |
unicode_filename = None |
8600
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
623 |
try: |
8610
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
624 |
ascii_filename = filename.encode('ascii') |
8600
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
625 |
except UnicodeEncodeError: |
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
626 |
# fallback filename for very old browser |
8610
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
627 |
unicode_filename = filename |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
628 |
ascii_filename = filename.encode('ascii', 'ignore') |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
629 |
# escape " and \ |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
630 |
# see http://greenbytes.de/tech/tc2231/#attwithfilenameandextparamescaped |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
631 |
ascii_filename = ascii_filename.replace('\x5c', r'\\').replace('"', r'\"') |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
632 |
header.append('filename="%s"' % ascii_filename) |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
633 |
if unicode_filename is not None: |
8600
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
634 |
# encoded filename according RFC5987 |
8610
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
635 |
urlquoted_filename = urllib.quote(unicode_filename.encode('utf-8'), '') |
b1145ad53999
[downloadable] fix filename HTTP header for simple name with space (closes #2535715)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8600
diff
changeset
|
636 |
header.append("filename*=utf-8''" + urlquoted_filename) |
8600
d74addac92bb
[downloadable] fix filename in HTTP header (closes #2522325, #2522324)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8480
diff
changeset
|
637 |
self.set_header('content-disposition', ';'.join(header)) |
0 | 638 |
|
639 |
# high level methods for HTML headers management ########################## |
|
640 |
||
2258
79bc598c6411
when request is a json request, bind on 'ajax-loaded' instead of document.ready()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2255
diff
changeset
|
641 |
def add_onload(self, jscode): |
4851
e55bdd10421e
remove deprecation warning introduced by add_onload api change
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4719
diff
changeset
|
642 |
self.html_headers.add_onload(jscode) |
2258
79bc598c6411
when request is a json request, bind on 'ajax-loaded' instead of document.ready()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2255
diff
changeset
|
643 |
|
0 | 644 |
def add_js(self, jsfiles, localfile=True): |
8032
bcb87336c7d2
[doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7990
diff
changeset
|
645 |
"""specify a list of JS files to include in the HTML headers. |
bcb87336c7d2
[doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7990
diff
changeset
|
646 |
|
0 | 647 |
:param jsfiles: a JS filename or a list of JS filenames |
648 |
:param localfile: if True, the default data dir prefix is added to the |
|
649 |
JS filename |
|
650 |
""" |
|
651 |
if isinstance(jsfiles, basestring): |
|
652 |
jsfiles = (jsfiles,) |
|
653 |
for jsfile in jsfiles: |
|
654 |
if localfile: |
|
7070
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
655 |
jsfile = self.data_url(jsfile) |
0 | 656 |
self.html_headers.add_js(jsfile) |
657 |
||
4860
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
658 |
def add_css(self, cssfiles, media=u'all', localfile=True, ieonly=False, |
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
659 |
iespec=u'[if lt IE 8]'): |
0 | 660 |
"""specify a CSS file to include in the HTML headers |
5290
15846058378b
[doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4984
diff
changeset
|
661 |
|
8032
bcb87336c7d2
[doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7990
diff
changeset
|
662 |
:param cssfiles: a CSS filename or a list of CSS filenames. |
0 | 663 |
:param media: the CSS's media if necessary |
664 |
:param localfile: if True, the default data dir prefix is added to the |
|
665 |
CSS filename |
|
4860
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
666 |
:param ieonly: True if this css is specific to IE |
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
667 |
:param iespec: conditional expression that will be used around |
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
668 |
the css inclusion. cf: |
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
669 |
http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx |
0 | 670 |
""" |
671 |
if isinstance(cssfiles, basestring): |
|
672 |
cssfiles = (cssfiles,) |
|
673 |
if ieonly: |
|
674 |
if self.ie_browser(): |
|
4860
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
675 |
extraargs = [iespec] |
0 | 676 |
add_css = self.html_headers.add_ie_css |
677 |
else: |
|
678 |
return # no need to do anything on non IE browsers |
|
679 |
else: |
|
4860
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
680 |
extraargs = [] |
0 | 681 |
add_css = self.html_headers.add_css |
682 |
for cssfile in cssfiles: |
|
683 |
if localfile: |
|
7070
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
684 |
cssfile = self.data_url(cssfile) |
4860
cedb6afdb7da
[web] fix #736332: iespec functionality for add_css
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4719
diff
changeset
|
685 |
add_css(cssfile, media, *extraargs) |
1426 | 686 |
|
5713
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
687 |
@deprecated('[3.9] use ajax_replace_url() instead, naming rql and vid arguments') |
1801
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
688 |
def build_ajax_replace_url(self, nodeid, rql, vid, replacemode='replace', |
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
689 |
**extraparams): |
5713
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
690 |
return self.ajax_replace_url(nodeid, replacemode, rql=rql, vid=vid, |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
691 |
**extraparams) |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
692 |
|
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
693 |
def ajax_replace_url(self, nodeid, replacemode='replace', **extraparams): |
5290
15846058378b
[doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4984
diff
changeset
|
694 |
"""builds an ajax url that will replace nodeid's content |
15846058378b
[doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4984
diff
changeset
|
695 |
|
1801
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
696 |
:param nodeid: the dom id of the node to replace |
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
697 |
:param replacemode: defines how the replacement should be done. |
5290
15846058378b
[doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4984
diff
changeset
|
698 |
|
5713
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
699 |
Possible values are : |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
700 |
- 'replace' to replace the node's content with the generated HTML |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
701 |
- 'swap' to replace the node itself with the generated HTML |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
702 |
- 'append' to append the generated HTML to the node's content |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
703 |
|
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
704 |
Arbitrary extra named arguments may be given, they will be included as |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
705 |
parameters of the generated url. |
1801
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
706 |
""" |
6564
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
707 |
# define a function in headers and use it in the link to avoid url |
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
708 |
# unescaping pb: browsers give the js expression to the interpreter |
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
709 |
# after having url unescaping the content. This may make appear some |
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
710 |
# quote or other special characters that will break the js expression. |
5713
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
711 |
extraparams.setdefault('fname', 'view') |
605f571198eb
[web] ajax_replace_url superseed build_ajax_replace_url, more generic and relying on the json controller (closes #750090)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5685
diff
changeset
|
712 |
url = self.build_url('json', **extraparams) |
6564
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
713 |
cbname = build_cb_uid(url[:50]) |
7515
e1ba23fdcf2d
closes #1484510: ajax_replace_url should propagate page id (until an underlying api does it automatically
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7411
diff
changeset
|
714 |
# think to propagate pageid. XXX see https://www.cubicweb.org/ticket/1753121 |
7660
a1506b5306cc
closes #1826543: error on some ajax_replace_url call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7639
diff
changeset
|
715 |
jscode = u'function %s() { $("#%s").%s; }' % ( |
7515
e1ba23fdcf2d
closes #1484510: ajax_replace_url should propagate page id (until an underlying api does it automatically
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7411
diff
changeset
|
716 |
cbname, nodeid, js.loadxhtml(url, {'pageid': self.pageid}, |
e1ba23fdcf2d
closes #1484510: ajax_replace_url should propagate page id (until an underlying api does it automatically
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7411
diff
changeset
|
717 |
'get', replacemode)) |
6564
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
718 |
self.html_headers.add_post_inline_script(jscode) |
ff9f7c566464
[request] fix ajax_replace_url which breaks if the url contains some quotes (that will be properly quoted but unquoted by the browser, breaking the js expression) by using a separated js function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6543
diff
changeset
|
719 |
return "javascript: %s()" % cbname |
1801
672acc730ce5
ajax_replace_url becomes obsolete, req.build_ajax_replace_url should be used instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1718
diff
changeset
|
720 |
|
0 | 721 |
# urls/path management #################################################### |
1426 | 722 |
|
7432
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
723 |
def build_url(self, *args, **kwargs): |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
724 |
"""return an absolute URL using params dictionary key/values as URL |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
725 |
parameters. Values are automatically URL quoted, and the |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
726 |
publishing method to use may be specified or will be guessed. |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
727 |
""" |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
728 |
if '__message' in kwargs: |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
729 |
msg = kwargs.pop('__message') |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
730 |
kwargs['_cwmsgid'] = self.set_redirect_message(msg) |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
731 |
return super(CubicWebRequestBase, self).build_url(*args, **kwargs) |
cab99ccdb774
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents:
7412
diff
changeset
|
732 |
|
0 | 733 |
def url(self, includeparams=True): |
734 |
"""return currently accessed url""" |
|
735 |
return self.base_url() + self.relative_path(includeparams) |
|
736 |
||
737 |
def selected(self, url): |
|
738 |
"""return True if the url is equivalent to currently accessed url""" |
|
739 |
reqpath = self.relative_path().lower() |
|
740 |
baselen = len(self.base_url()) |
|
741 |
return (reqpath == url[baselen:].lower()) |
|
742 |
||
743 |
def base_url_prepend_host(self, hostname): |
|
744 |
protocol, roothost = urlsplit(self.base_url())[:2] |
|
745 |
if roothost.startswith('www.'): |
|
746 |
roothost = roothost[4:] |
|
747 |
return '%s://%s.%s' % (protocol, hostname, roothost) |
|
748 |
||
749 |
def base_url_path(self): |
|
750 |
"""returns the absolute path of the base url""" |
|
751 |
return urlsplit(self.base_url())[2] |
|
1426 | 752 |
|
7070
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
753 |
def data_url(self, relpath): |
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
754 |
"""returns the absolute path for a data resouce""" |
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
755 |
return self.datadir_url + relpath |
5f8e52d722c5
[web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
6581
diff
changeset
|
756 |
|
0 | 757 |
@cached |
758 |
def from_controller(self): |
|
759 |
"""return the id (string) of the controller issuing the request""" |
|
760 |
controller = self.relative_path(False).split('/', 1)[0] |
|
2650
18aec79ec3a3
R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2613
diff
changeset
|
761 |
registered_controllers = self.vreg['controllers'].keys() |
0 | 762 |
if controller in registered_controllers: |
763 |
return controller |
|
764 |
return 'view' |
|
1426 | 765 |
|
0 | 766 |
def validate_cache(self): |
8316
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
767 |
"""raise a `StatusResponse` exception if a cached page along the way |
0 | 768 |
exists and is still usable. |
769 |
||
770 |
calls the client-dependant implementation of `_validate_cache` |
|
771 |
""" |
|
8316
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
772 |
modified = True |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
773 |
if self.get_header('Cache-Control') not in ('max-age=0', 'no-cache'): |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
774 |
# Here, we search for any invalid 'not modified' condition |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
775 |
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3 |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
776 |
validators = get_validators(self._headers_in) |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
777 |
if validators: # if we have no |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
778 |
modified = any(func(val, self.headers_out) for func, val in validators) |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
779 |
# Forge expected response |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
780 |
if modified: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
781 |
if 'Expires' not in self.headers_out: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
782 |
# Expires header seems to be required by IE7 -- Are you sure ? |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
783 |
self.add_header('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT') |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
784 |
if self.http_method() == 'HEAD': |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
785 |
raise StatusResponse(200, '') |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
786 |
# /!\ no raise, the function returns and we keep processing the request) |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
787 |
else: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
788 |
# overwrite headers_out to forge a brand new not-modified response |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
789 |
self.headers_out = self._forge_cached_headers() |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
790 |
if self.http_method() in ('HEAD', 'GET'): |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
791 |
raise StatusResponse(httplib.NOT_MODIFIED) |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
792 |
else: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
793 |
raise StatusResponse(httplib.PRECONDITION_FAILED) |
1426 | 794 |
|
0 | 795 |
# abstract methods to override according to the web front-end ############# |
1426 | 796 |
|
0 | 797 |
def http_method(self): |
798 |
"""returns 'POST', 'GET', 'HEAD', etc.""" |
|
799 |
raise NotImplementedError() |
|
800 |
||
8316
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
801 |
def _forge_cached_headers(self): |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
802 |
# overwrite headers_out to forge a brand new not-modified response |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
803 |
headers = Headers() |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
804 |
for header in ( |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
805 |
# Required from sec 10.3.5: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
806 |
'date', 'etag', 'content-location', 'expires', |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
807 |
'cache-control', 'vary', |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
808 |
# Others: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
809 |
'server', 'proxy-authenticate', 'www-authenticate', 'warning'): |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
810 |
value = self._headers_in.getRawHeaders(header) |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
811 |
if value is not None: |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
812 |
headers.setRawHeaders(header, value) |
d5b1b75805dd
[cache] factorize _validate_cache() logic implemented in wsgi and twisted handlers
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
8314
diff
changeset
|
813 |
return headers |
1426 | 814 |
|
0 | 815 |
def relative_path(self, includeparams=True): |
816 |
"""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:
2315
diff
changeset
|
817 |
to the instance's root, but some other normalization may be needed |
0 | 818 |
so that the returned path may be used to compare to generated urls |
819 |
||
820 |
:param includeparams: |
|
821 |
boolean indicating if GET form parameters should be kept in the path |
|
822 |
""" |
|
823 |
raise NotImplementedError() |
|
824 |
||
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
825 |
# http headers ############################################################ |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
826 |
|
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
827 |
### incoming headers |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
828 |
|
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
829 |
def get_header(self, header, default=None, raw=True): |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
830 |
"""return the value associated with the given input header, raise |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
831 |
KeyError if the header is not set |
0 | 832 |
""" |
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
833 |
if raw: |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
834 |
return self._headers_in.getRawHeaders(header, [default])[0] |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
835 |
return self._headers_in.getHeader(header, default) |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
836 |
|
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
837 |
def header_accept_language(self): |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
838 |
"""returns an ordered list of preferred languages""" |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
839 |
acceptedlangs = self.get_header('Accept-Language', raw=False) or {} |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
840 |
for lang, _ in sorted(acceptedlangs.iteritems(), key=lambda x: x[1], |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
841 |
reverse=True): |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
842 |
lang = lang.split('-')[0] |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
843 |
yield lang |
0 | 844 |
|
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
845 |
def header_if_modified_since(self): |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
846 |
"""If the HTTP header If-modified-since is set, return the equivalent |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
847 |
date time value (GMT), else return None |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
848 |
""" |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
849 |
mtime = self.get_header('If-modified-since', raw=False) |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
850 |
if mtime: |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
851 |
# :/ twisted is returned a localized time stamp |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
852 |
return datetime.fromtimestamp(mtime) + GMTOFFSET |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
853 |
return None |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
854 |
|
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
855 |
### outcoming headers |
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
856 |
def set_header(self, header, value, raw=True): |
0 | 857 |
"""set an output HTTP header""" |
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
858 |
if raw: |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
859 |
# adding encoded header is important, else page content |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
860 |
# will be reconverted back to unicode and apart unefficiency, this |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
861 |
# may cause decoding problem (e.g. when downloading a file) |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
862 |
self.headers_out.setRawHeaders(header, [str(value)]) |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
863 |
else: |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
864 |
self.headers_out.setHeader(header, value) |
0 | 865 |
|
866 |
def add_header(self, header, value): |
|
867 |
"""add an output HTTP header""" |
|
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
868 |
# adding encoded header is important, else page content |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
869 |
# will be reconverted back to unicode and apart unefficiency, this |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
870 |
# may cause decoding problem (e.g. when downloading a file) |
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
871 |
self.headers_out.addRawHeader(header, str(value)) |
1426 | 872 |
|
0 | 873 |
def remove_header(self, header): |
874 |
"""remove an output HTTP header""" |
|
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
4984
diff
changeset
|
875 |
self.headers_out.removeHeader(header) |
1426 | 876 |
|
0 | 877 |
def header_authorization(self): |
878 |
"""returns a couple (auth-type, auth-value)""" |
|
879 |
auth = self.get_header("Authorization", None) |
|
880 |
if auth: |
|
881 |
scheme, rest = auth.split(' ', 1) |
|
882 |
scheme = scheme.lower() |
|
883 |
try: |
|
884 |
assert scheme == "basic" |
|
885 |
user, passwd = base64.decodestring(rest).split(":", 1) |
|
886 |
# XXX HTTP header encoding: use email.Header? |
|
887 |
return user.decode('UTF8'), passwd |
|
888 |
except Exception, ex: |
|
889 |
self.debug('bad authorization %s (%s: %s)', |
|
890 |
auth, ex.__class__.__name__, ex) |
|
891 |
return None, None |
|
892 |
||
1716
b12d9e22bac3
basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents:
1560
diff
changeset
|
893 |
def parse_accept_header(self, header): |
7164
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
894 |
"""returns an ordered list of accepted values""" |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
895 |
try: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
896 |
value_parser, value_sort_key = ACCEPT_HEADER_PARSER[header.lower()] |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
897 |
except KeyError: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
898 |
value_parser = value_sort_key = None |
1716
b12d9e22bac3
basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents:
1560
diff
changeset
|
899 |
accepteds = self.get_header(header, '') |
7164
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
900 |
values = _parse_accept_header(accepteds, value_parser, value_sort_key) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
901 |
return (raw_value for (raw_value, parsed_value, score) in values) |
0 | 902 |
|
3094
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
903 |
def demote_to_html(self): |
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
904 |
"""helper method to dynamically set request content type to text/html |
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
905 |
|
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
906 |
The global doctype and xmldec must also be changed otherwise the browser |
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
907 |
will display '<[' at the beginning of the page |
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
908 |
""" |
8063
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
909 |
if not self.vreg.config['force-html-content-type']: |
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
910 |
if not hasattr(self, 'main_stream'): |
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
911 |
raise Exception("Can't demote to html from an ajax context. You " |
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
912 |
"should change force-html-content-type to yes " |
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
913 |
"in the instance configuration file.") |
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
914 |
self.set_content_type('text/html') |
1b2a05c9b71c
[html, ajax] demote_to_html don't crash anymore if force-html-content-type is activated. Closes #712309
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7879
diff
changeset
|
915 |
self.main_stream.set_doctype(TRANSITIONAL_DOCTYPE_NOEXT) |
7187
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
916 |
|
8314
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
917 |
# xml doctype ############################################################# |
cfd6ab461849
[Web-Request] Use rich header (closes #2204164)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
8312
diff
changeset
|
918 |
|
7187
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
919 |
def set_doctype(self, doctype, reset_xmldecl=True): |
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
920 |
"""helper method to dynamically change page doctype |
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
921 |
|
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
922 |
:param doctype: the new doctype, e.g. '<!DOCTYPE html>' |
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
923 |
:param reset_xmldecl: if True, remove the '<?xml version="1.0"?>' |
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
924 |
declaration from the page |
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
925 |
""" |
496f51b92154
[views] extend HTMLStream API to be able to change doctype / xmldecl
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7164
diff
changeset
|
926 |
self.main_stream.set_doctype(doctype, reset_xmldecl) |
3094
978ed8c2c0e4
[googlemap] #344872 set request content-type to text/html
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2650
diff
changeset
|
927 |
|
0 | 928 |
# page data management #################################################### |
929 |
||
930 |
def get_page_data(self, key, default=None): |
|
5683
ca2badf54858
[request] fix typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5505
diff
changeset
|
931 |
"""return value associated to `key` in current page data""" |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
932 |
page_data = self.session.data.get(self.pageid) |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
933 |
if page_data is None: |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
934 |
return default |
0 | 935 |
return page_data.get(key, default) |
1426 | 936 |
|
0 | 937 |
def set_page_data(self, key, value): |
938 |
"""set value associated to `key` in current page data""" |
|
939 |
self.html_headers.add_unload_pagedata() |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
940 |
page_data = self.session.data.setdefault(self.pageid, {}) |
0 | 941 |
page_data[key] = value |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
942 |
self.session.data[self.pageid] = page_data |
1426 | 943 |
|
0 | 944 |
def del_page_data(self, key=None): |
945 |
"""remove value associated to `key` in current page data |
|
946 |
if `key` is None, all page data will be cleared |
|
947 |
""" |
|
948 |
if key is None: |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
949 |
self.session.data.pop(self.pageid, None) |
0 | 950 |
else: |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
951 |
try: |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
952 |
del self.session.data[self.pageid][key] |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
953 |
except KeyError: |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5155
diff
changeset
|
954 |
pass |
0 | 955 |
|
956 |
# user-agent detection #################################################### |
|
957 |
||
958 |
@cached |
|
959 |
def useragent(self): |
|
960 |
return self.get_header('User-Agent', None) |
|
961 |
||
962 |
def ie_browser(self): |
|
963 |
useragent = self.useragent() |
|
964 |
return useragent and 'MSIE' in useragent |
|
1426 | 965 |
|
0 | 966 |
def xhtml_browser(self): |
2558
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
967 |
"""return True if the browser is considered as xhtml compatible. |
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
968 |
|
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
969 |
If the instance is configured to always return text/html and not |
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
970 |
application/xhtml+xml, this method will always return False, even though |
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
971 |
this is semantically different |
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
972 |
""" |
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
973 |
if self.vreg.config['force-html-content-type']: |
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
974 |
return False |
0 | 975 |
useragent = self.useragent() |
1421
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
976 |
# * MSIE/Konqueror does not support xml content-type |
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
977 |
# * Opera supports xhtml and handles namespaces properly but it breaks |
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
978 |
# jQuery.attr() |
495
f8b1edfe9621
[#80966] Opera supports xhtml and handles namespaces properly but it breaks jQuery.attr(), so xhtml_browser return False if the webbrowser is opera
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents:
0
diff
changeset
|
979 |
if useragent and ('MSIE' in useragent or 'KHTML' in useragent |
f8b1edfe9621
[#80966] Opera supports xhtml and handles namespaces properly but it breaks jQuery.attr(), so xhtml_browser return False if the webbrowser is opera
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents:
0
diff
changeset
|
980 |
or 'Opera' in useragent): |
0 | 981 |
return False |
982 |
return True |
|
983 |
||
1421
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
984 |
def html_content_type(self): |
2558
81c8b5312f9c
move test on force-html-content-type to xhtml_browser method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2556
diff
changeset
|
985 |
if self.xhtml_browser(): |
1421
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
986 |
return 'application/xhtml+xml' |
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
987 |
return 'text/html' |
77ee26df178f
doc type handling refactoring: do the ext substitution at the module level
sylvain.thenault@logilab.fr
parents:
1173
diff
changeset
|
988 |
|
2559
46859078c866
[R xhtml] remove xhtml_wrap* function, use instead a single req.document_surrounding_div method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2558
diff
changeset
|
989 |
def document_surrounding_div(self): |
46859078c866
[R xhtml] remove xhtml_wrap* function, use instead a single req.document_surrounding_div method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2558
diff
changeset
|
990 |
if self.xhtml_browser(): |
4454
aba1b563705b
[request] add a note about the encoding mgmt (or lack thereof)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4212
diff
changeset
|
991 |
return (u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE + # XXX encoding ? |
2559
46859078c866
[R xhtml] remove xhtml_wrap* function, use instead a single req.document_surrounding_div method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2558
diff
changeset
|
992 |
u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">') |
46859078c866
[R xhtml] remove xhtml_wrap* function, use instead a single req.document_surrounding_div method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2558
diff
changeset
|
993 |
return u'<div>' |
46859078c866
[R xhtml] remove xhtml_wrap* function, use instead a single req.document_surrounding_div method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2558
diff
changeset
|
994 |
|
5467
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
995 |
@deprecated('[3.9] use req.uiprops[rid]') |
5444
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
996 |
def external_resource(self, rid, default=_MARKER): |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
997 |
"""return a path to an external resource, using its identifier |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
998 |
|
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
999 |
raise `KeyError` if the resource is not defined |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1000 |
""" |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1001 |
try: |
5467
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5444
diff
changeset
|
1002 |
return self.uiprops[rid] |
5444
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1003 |
except KeyError: |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1004 |
if default is _MARKER: |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1005 |
raise |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1006 |
return default |
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1007 |
|
f7fdb5dd82f6
[webconfig] introduce property sheets. Use them to replace external_resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5426
diff
changeset
|
1008 |
|
7164
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1009 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1010 |
## HTTP-accept parsers / utilies ############################################## |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1011 |
def _mimetype_sort_key(accept_info): |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1012 |
"""accepted mimetypes must be sorted by : |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1013 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1014 |
1/ highest score first |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1015 |
2/ most specific mimetype first, e.g. : |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1016 |
- 'text/html level=1' is more specific 'text/html' |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1017 |
- 'text/html' is more specific than 'text/*' |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1018 |
- 'text/*' itself more specific than '*/*' |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1019 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1020 |
""" |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1021 |
raw_value, (media_type, media_subtype, media_type_params), score = accept_info |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1022 |
# FIXME: handle '+' in media_subtype ? (should xhtml+xml have a |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1023 |
# higher precedence than xml ?) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1024 |
if media_subtype == '*': |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1025 |
score -= 0.0001 |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1026 |
if media_type == '*': |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1027 |
score -= 0.0001 |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1028 |
return 1./score, media_type, media_subtype, 1./(1+len(media_type_params)) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1029 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1030 |
def _charset_sort_key(accept_info): |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1031 |
"""accepted mimetypes must be sorted by : |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1032 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1033 |
1/ highest score first |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1034 |
2/ most specific charset first, e.g. : |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1035 |
- 'utf-8' is more specific than '*' |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1036 |
""" |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1037 |
raw_value, value, score = accept_info |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1038 |
if value == '*': |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1039 |
score -= 0.0001 |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1040 |
return 1./score, value |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1041 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1042 |
def _parse_accept_header(raw_header, value_parser=None, value_sort_key=None): |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1043 |
"""returns an ordered list accepted types |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1044 |
|
7273
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1045 |
:param value_parser: a function to parse a raw accept chunk. If None |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1046 |
is provided, the function defaults to identity. If a function is provided, |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1047 |
it must accept 2 parameters ``value`` and ``other_params``. ``value`` is |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1048 |
the value found before the first ';', `other_params` is a dictionary |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1049 |
built from all other chunks after this first ';' |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1050 |
|
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1051 |
:param value_sort_key: a key function to sort values found in the accept |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1052 |
header. This function will be passed a 3-tuple |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1053 |
(raw_value, parsed_value, score). If None is provided, the default |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1054 |
sort_key is 1./score |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1055 |
|
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1056 |
:return: a list of 3-tuple (raw_value, parsed_value, score), |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1057 |
ordered by score. ``parsed_value`` will be the return value of |
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1058 |
``value_parser(raw_value)`` |
7164
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1059 |
""" |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1060 |
if value_sort_key is None: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1061 |
value_sort_key = lambda infos: 1./infos[-1] |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1062 |
values = [] |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1063 |
for info in raw_header.split(','): |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1064 |
score = 1.0 |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1065 |
other_params = {} |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1066 |
try: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1067 |
value, infodef = info.split(';', 1) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1068 |
except ValueError: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1069 |
value = info |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1070 |
else: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1071 |
for info in infodef.split(';'): |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1072 |
try: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1073 |
infokey, infoval = info.split('=') |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1074 |
if infokey == 'q': # XXX 'level' |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1075 |
score = float(infoval) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1076 |
continue |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1077 |
except ValueError: |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1078 |
continue |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1079 |
other_params[infokey] = infoval |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1080 |
parsed_value = value_parser(value, other_params) if value_parser else value |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1081 |
values.append( (value.strip(), parsed_value, score) ) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1082 |
values.sort(key=value_sort_key) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1083 |
return values |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1084 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1085 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1086 |
def _mimetype_parser(value, other_params): |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1087 |
"""return a 3-tuple |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1088 |
(type, subtype, type_params) corresponding to the mimetype definition |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1089 |
e.g. : for 'text/*', `mimetypeinfo` will be ('text', '*', {}), for |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1090 |
'text/html;level=1', `mimetypeinfo` will be ('text', '*', {'level': '1'}) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1091 |
""" |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1092 |
try: |
7273
a949fc438029
[etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7187
diff
changeset
|
1093 |
media_type, media_subtype = value.strip().split('/', 1) |
7164
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1094 |
except ValueError: # safety belt : '/' should always be present |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1095 |
media_type = value.strip() |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1096 |
media_subtype = '*' |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1097 |
return (media_type, media_subtype, other_params) |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1098 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1099 |
|
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1100 |
ACCEPT_HEADER_PARSER = { |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1101 |
'accept': (_mimetype_parser, _mimetype_sort_key), |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1102 |
'accept-charset': (None, _charset_sort_key), |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1103 |
} |
93a19c1831aa
[http] implement 1587305: provide better implementation of Accept header parsing + tests
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
7070
diff
changeset
|
1104 |
|
0 | 1105 |
from cubicweb import set_log_methods |
1106 |
set_log_methods(CubicWebRequestBase, LOGGER) |