[FIX] http: convert DEFAULT_SESSION as a function get_default_session

This commit avoid to have a dict by reference that will be global.
Now get_default_session return a new dict each time for the context key.
From this way the session.context['lang'] is not shared between several
users on the same worker.

To reproduce the bug, restart the server with 2 workers, make request in
lang A on these 2 workers. DEFAULT_SESSION['context']['lang'] now is set
to this lang A.
Now, make request to an url without lang in path and without cookies and
withtout session, you should be redirected to lang B (preferred lang
from the request header) but you will be redirect to lang A due to the
dict session.context that is shared for the worker...
When we initialize the new Session, we get the wrong lang A as value for
context.lang, so we don't recompute the expected lang for the end user.

X-original-commit: 62179de74862210fe2a055d15b367b1850c24263

fwd-port of #100102

closes odoo/odoo#100910

X-original-commit: 42e46b2d89dde276f796b980f29e33cc216e7cb2
Signed-off-by: Jérémy Kersten <jke@odoo.com>
This commit is contained in:
Jeremy Kersten
2022-09-23 09:21:38 +02:00
parent bc6c8255a9
commit 5490fcc27f
5 changed files with 21 additions and 22 deletions
+1 -1
View File
@@ -101,7 +101,7 @@ def ensure_db(redirect='/web/database/selector'):
# always switch the session to the computed db
if db != request.session.db:
request.session = http.root.session_store.new()
request.session.update(http.DEFAULT_SESSION, db=db)
request.session.update(http.get_default_session(), db=db)
request.session.context['lang'] = request.default_lang()
werkzeug.exceptions.abort(request.redirect(request.httprequest.url, 302))
+1 -1
View File
@@ -12,7 +12,7 @@ class TestWebLoginCommon(HttpCase):
def login(self, username, password):
"""Log in with provided credentials and return response to POST request or raises for status."""
self.session = http.root.session_store.new()
self.session.update(http.DEFAULT_SESSION, db=get_db_name())
self.session.update(http.get_default_session(), db=get_db_name())
self.opener = Opener(self.env.cr)
self.opener.cookies.set('session_id', self.session.sid, domain=HOST, path='/')
+1 -1
View File
@@ -46,7 +46,7 @@ def MockRequest(
params={},
redirect=env['ir.http']._redirect,
session=DotDict(
odoo.http.DEFAULT_SESSION,
odoo.http.get_default_session(),
geoip={'country_code': country_code},
sale_order_id=sale_order_id,
website_sale_current_pl=website_sale_current_pl,
+17 -18
View File
@@ -208,20 +208,19 @@ CSRF_TOKEN_SALT = 60 * 60 * 24 * 365
DEFAULT_LANG = 'en_US'
# The dictionnary to initialise a new session with.
DEFAULT_SESSION = {
'context': {
#'lang': request.default_lang() # must be set at runtime
},
'db': None,
'debug': '',
'login': None,
'uid': None,
'session_token': None,
# profiling
'profile_session': None,
'profile_collectors': None,
'profile_params': None,
}
def get_default_session():
return {
'context': {}, # 'lang': request.default_lang() # must be set at runtime
'db': None,
'debug': '',
'login': None,
'uid': None,
'session_token': None,
# profiling
'profile_session': None,
'profile_collectors': None,
'profile_params': None,
}
# The request mimetypes that transport JSON in their body.
JSON_MIMETYPES = ('application/json', 'application/json-rpc')
@@ -957,10 +956,10 @@ class Session(collections.abc.MutableMapping):
})
def logout(self, keep_db=False):
db = self.db if keep_db else DEFAULT_SESSION['db'] # None
db = self.db if keep_db else get_default_session()['db'] # None
debug = self.debug
self.clear()
self.update(DEFAULT_SESSION, db=db, debug=debug)
self.update(get_default_session(), db=db, debug=debug)
self.context['lang'] = request.default_lang() if request else DEFAULT_LANG
self.should_rotate = True
@@ -1115,7 +1114,7 @@ class Request:
session.sid = sid # in case the session was not persisted
session.is_explicit = is_explicit
for key, val in DEFAULT_SESSION.items():
for key, val in get_default_session().items():
session.setdefault(key, val)
if not session.context.get('lang'):
session.context['lang'] = self.default_lang()
@@ -1258,7 +1257,7 @@ class Request:
return consteq(hm, hm_expected)
def default_context(self):
return dict(DEFAULT_SESSION['context'], lang=self.default_lang())
return dict(get_default_session()['context'], lang=self.default_lang())
def default_lang(self):
"""Returns default user language according to request specification
+1 -1
View File
@@ -1726,7 +1726,7 @@ class HttpCase(TransactionCase):
odoo.http.root.session_store.delete(self.session)
self.session = session = odoo.http.root.session_store.new()
session.update(odoo.http.DEFAULT_SESSION, db=get_db_name())
session.update(odoo.http.get_default_session(), db=get_db_name())
session.context['lang'] = odoo.http.DEFAULT_LANG
if user: # if authenticated