general: move publisher pre-redirects to middleware (#18035)
This commit is contained in:
parent
a44a3c8fb0
commit
016bfc78e9
|
@ -3722,3 +3722,27 @@ def test_backoffice_formdata_named_wscall(pub):
|
|||
|
||||
resp = app.get('/backoffice/submission/test/')
|
||||
assert '<p class="comment-field ">XbarY</p>' in resp.body
|
||||
|
||||
def test_backoffice_session_var(pub):
|
||||
open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w').write('''[options]
|
||||
query_string_allowed_vars = foo,bar
|
||||
''')
|
||||
|
||||
user = create_user(pub)
|
||||
create_environment(pub)
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.backoffice_submission_roles = user.roles[:]
|
||||
formdef.fields = [
|
||||
fields.CommentField(id='7', label='X[session_var_foo]Y', type='comment'),
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
app = login(get_app(pub))
|
||||
|
||||
resp = app.get('/backoffice/submission/test/?session_var_foo=bar')
|
||||
assert resp.location == 'http://example.net/backoffice/submission/test/'
|
||||
resp = resp.follow()
|
||||
assert '<p class="comment-field ">XbarY</p>' in resp.body
|
||||
|
|
|
@ -175,6 +175,7 @@ class CompatWcsPublisher(WcsPublisher):
|
|||
self._set_request(request)
|
||||
try:
|
||||
self.parse_request(request)
|
||||
self.init_publish(request)
|
||||
output = self.try_publish(request)
|
||||
except PublishError, exc:
|
||||
output = self.finish_interrupted_request(exc)
|
||||
|
@ -210,20 +211,13 @@ class CompatWcsPublisher(WcsPublisher):
|
|||
quixote_lock = Lock()
|
||||
|
||||
def quixote(request):
|
||||
#with quixote_lock:
|
||||
if True:
|
||||
pub = get_publisher()
|
||||
compat_request = CompatHTTPRequest(request)
|
||||
return pub.process_request(compat_request)
|
||||
pub = get_publisher()
|
||||
return pub.process_request(pub.get_request())
|
||||
|
||||
|
||||
@contextmanager
|
||||
def request(request):
|
||||
pub = get_publisher()
|
||||
compat_request = CompatHTTPRequest(request)
|
||||
pub.init_publish(compat_request)
|
||||
pub._set_request(compat_request)
|
||||
compat_request.process_inputs()
|
||||
yield
|
||||
pub._clear_request()
|
||||
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
|
||||
import thread
|
||||
import threading
|
||||
import urllib
|
||||
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
from quixote import get_publisher
|
||||
from .qommon.publisher import ImmediateRedirectException
|
||||
from .qommon.http_response import HTTPResponse
|
||||
from .compat import CompatHTTPRequest, CompatWcsPublisher
|
||||
|
||||
|
@ -29,10 +33,65 @@ class PublisherInitialisationMiddleware(object):
|
|||
if not pub:
|
||||
pub = CompatWcsPublisher.create_publisher()
|
||||
compat_request = CompatHTTPRequest(request)
|
||||
pub.init_publish(compat_request)
|
||||
try:
|
||||
pub.init_publish(compat_request)
|
||||
except ImmediateRedirectException as e:
|
||||
return HttpResponseRedirect(e.location)
|
||||
|
||||
pub._set_request(compat_request)
|
||||
pub.parse_request(compat_request)
|
||||
request._publisher = pub
|
||||
|
||||
# if a ?toggle-mobile query string is passed, we explicitely set the
|
||||
# mode and reload the current page.
|
||||
if compat_request.get_query() == 'toggle-mobile':
|
||||
response = HttpResponseRedirect(compat_request.get_path())
|
||||
if pub.config.session_cookie_path:
|
||||
path = pub.config.session_cookie_path
|
||||
else:
|
||||
path = compat_request.get_environ('SCRIPT_NAME')
|
||||
if not path.endswith('/'):
|
||||
path += '/'
|
||||
if compat_request.response.page_template_key == 'mobile':
|
||||
response.set_cookie('mobile', 'false', path=path)
|
||||
else:
|
||||
response.set_cookie('mobile', 'true', path=path)
|
||||
return response
|
||||
|
||||
# handle session_var_<xxx> in query strings, add them to session and
|
||||
# redirect to same URL without the parameters
|
||||
if compat_request.get_method() == 'GET' and compat_request.form:
|
||||
query_string_allowed_vars = pub.get_site_option(
|
||||
'query_string_allowed_vars') or ''
|
||||
query_string_allowed_vars = [x.strip() for x in
|
||||
query_string_allowed_vars.split(',')]
|
||||
had_session_variables = False
|
||||
session_variables = {}
|
||||
for k, v in compat_request.form.items():
|
||||
if k.startswith('session_var_'):
|
||||
had_session_variables = True
|
||||
session_variable = str(k[len('session_var_'):])
|
||||
# only add variable to session if it's a string, this
|
||||
# handles the case of repeated parameters producing a
|
||||
# list of values (by ignoring those parameters altogether).
|
||||
if session_variable in query_string_allowed_vars and (
|
||||
isinstance(v, str)):
|
||||
session_variables[session_variable] = v
|
||||
del compat_request.form[k]
|
||||
if had_session_variables:
|
||||
pub.start_request() # creates session
|
||||
compat_request.session.add_extra_variables(**session_variables)
|
||||
pub.finish_successful_request() # commits session
|
||||
new_query_string = ''
|
||||
if compat_request.form:
|
||||
new_query_string = '?' + urllib.urlencode(compat_request.form)
|
||||
response = HttpResponseRedirect(compat_request.get_path() + new_query_string)
|
||||
for name, value in compat_request.response.generate_headers():
|
||||
if name == 'Content-Length':
|
||||
continue
|
||||
response[name] = value
|
||||
return response
|
||||
|
||||
|
||||
class AfterJobsMiddleware(object):
|
||||
ASYNC = True
|
||||
|
|
|
@ -25,6 +25,7 @@ from http_response import HTTPResponse
|
|||
|
||||
class HTTPRequest(quixote.http_request.HTTPRequest):
|
||||
signed = False
|
||||
parsed = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
quixote.http_request.HTTPRequest.__init__(self, *args, **kwargs)
|
||||
|
@ -106,6 +107,8 @@ class HTTPRequest(quixote.http_request.HTTPRequest):
|
|||
return "\n".join(result)
|
||||
|
||||
def process_inputs(self):
|
||||
if self.parsed:
|
||||
return
|
||||
quixote.http_request.HTTPRequest.process_inputs(self)
|
||||
ctype = self.environ.get("CONTENT_TYPE")
|
||||
if ctype == 'application/json':
|
||||
|
@ -121,6 +124,7 @@ class HTTPRequest(quixote.http_request.HTTPRequest):
|
|||
self.form = dict(
|
||||
(str(k), v.encode(self.charset) if isinstance(v, unicode) else v)
|
||||
for k, v in self.form.items())
|
||||
self.parsed = True
|
||||
|
||||
def is_json(self):
|
||||
if self.is_json_marker:
|
||||
|
|
|
@ -41,6 +41,7 @@ except ImportError:
|
|||
raven = None
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
from django.utils import translation
|
||||
from django.utils.translation import gettext, ngettext
|
||||
|
||||
|
@ -503,7 +504,7 @@ class QommonPublisher(Publisher, object):
|
|||
if self.missing_appdir_redirect:
|
||||
raise ImmediateRedirectException(self.missing_appdir_redirect)
|
||||
else:
|
||||
raise errors.TraversalError()
|
||||
raise Http404()
|
||||
try:
|
||||
os.makedirs(self.app_dir)
|
||||
except OSError, e:
|
||||
|
@ -531,11 +532,7 @@ class QommonPublisher(Publisher, object):
|
|||
|
||||
def init_publish(self, request):
|
||||
self.substitutions.reset()
|
||||
try:
|
||||
self.set_app_dir(request)
|
||||
except ImmediateRedirectException, e:
|
||||
self._set_request(request)
|
||||
return redirect(e.location)
|
||||
self.set_app_dir(request)
|
||||
|
||||
from vendor import pystatsd
|
||||
self.statsd = pystatsd.Client(
|
||||
|
@ -578,53 +575,9 @@ class QommonPublisher(Publisher, object):
|
|||
# direction, we will use the mobile theme variant
|
||||
request.response.page_template_key = 'mobile'
|
||||
|
||||
# if a ?toggle-mobile query string is passed, we explicitely set the
|
||||
# mode and reload the current page.
|
||||
if request.get_query() == 'toggle-mobile':
|
||||
if self.config.session_cookie_path:
|
||||
path = self.config.session_cookie_path
|
||||
else:
|
||||
path = request.get_environ('SCRIPT_NAME')
|
||||
if not path.endswith('/'):
|
||||
path += '/'
|
||||
if request.response.page_template_key == 'mobile':
|
||||
request.response.set_cookie('mobile', 'false', path=path)
|
||||
else:
|
||||
request.response.set_cookie('mobile', 'true', path=path)
|
||||
return redirect(request.get_path())
|
||||
|
||||
if request.get_environ('QOMMON_PAGE_TEMPLATE_KEY'):
|
||||
request.response.page_template_key = request.get_environ('QOMMON_PAGE_TEMPLATE_KEY')
|
||||
|
||||
# handle session_var_<xxx> in query strings, add them to session and
|
||||
# redirect to same URL without the parameters
|
||||
if request.get_method() == 'GET' and request.form:
|
||||
query_string_allowed_vars = self.get_site_option(
|
||||
'query_string_allowed_vars') or ''
|
||||
query_string_allowed_vars = [x.strip() for x in
|
||||
query_string_allowed_vars.split(',')]
|
||||
had_session_variables = False
|
||||
session_variables = {}
|
||||
for k, v in request.form.items():
|
||||
if k.startswith('session_var_'):
|
||||
had_session_variables = True
|
||||
session_variable = str(k[len('session_var_'):])
|
||||
# only add variable to session if it's a string, this
|
||||
# handles the case of repeated parameters producing a
|
||||
# list of values (by ignoring those parameters altogether).
|
||||
if session_variable in query_string_allowed_vars and (
|
||||
isinstance(v, str)):
|
||||
session_variables[session_variable] = v
|
||||
del request.form[k]
|
||||
if had_session_variables:
|
||||
self.start_request() # creates session
|
||||
request.session.add_extra_variables(**session_variables)
|
||||
self.finish_successful_request() # commits session
|
||||
new_query_string = ''
|
||||
if request.form:
|
||||
new_query_string = '?' + urllib.urlencode(request.form)
|
||||
return redirect(request.get_path() + new_query_string)
|
||||
|
||||
request.language = self.get_site_language()
|
||||
self.install_lang(request)
|
||||
self.substitutions.feed(self)
|
||||
|
@ -632,10 +585,6 @@ class QommonPublisher(Publisher, object):
|
|||
for extra_source in self.extra_sources:
|
||||
self.substitutions.feed(extra_source(self, request))
|
||||
|
||||
def try_publish(self, request):
|
||||
self.init_publish(request)
|
||||
return Publisher.try_publish(self, request)
|
||||
|
||||
def get_site_language(self):
|
||||
lang = self.cfg.get('language', {}).get('language', None)
|
||||
if lang == 'HTTP':
|
||||
|
|
Loading…
Reference in New Issue