[FIX] base: serve_fallback infinite redirection
Create an attachment with an URL to a static file that does not exists, e.g. '/web/static/idontexist.png'. Inside your browser try to access that file, open <localhost:8069/web/static/idontexist.png>. The browser fails with a "Too Many Redirections" error. When a path is not found, nor in the static files, nor in the controllers, `_serve_fallback` kicks in and attempt to find a resource outside of the router that matches the URL. In case it finds an attachment with a matching URL, it'll deliver it. In this specific case, it finds our attachment and return a redirection to it's URL, which is the same URL as the request hence it loops back. Don't deliver URL attachments via `_serve_fallback`, only deliver stored files. closes odoo/odoo#156323 X-original-commit: d2bea592db6a66d531b83437d42b273606f629f1 Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
This commit is contained in:
@@ -240,7 +240,7 @@ class IrHttp(models.AbstractModel):
|
||||
def _serve_fallback(cls):
|
||||
model = request.env['ir.attachment']
|
||||
attach = model.sudo()._get_serve_attachment(request.httprequest.path)
|
||||
if attach:
|
||||
if attach and (attach.store_fname or attach.db_datas):
|
||||
return Stream.from_attachment(attach).get_response()
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -6,6 +6,7 @@ from http import HTTPStatus
|
||||
from os.path import basename, join as opj
|
||||
from unittest.mock import patch
|
||||
from freezegun import freeze_time
|
||||
from urllib3.util import parse_url
|
||||
|
||||
import odoo
|
||||
from odoo.tests import new_test_user, tagged, RecordCapturer
|
||||
@@ -311,6 +312,22 @@ class TestHttpStatic(TestHttpStaticCommon):
|
||||
self.assertFalse(att.checksum)
|
||||
self.assertDownloadGizeh(f'/web/image/{att.id}')
|
||||
|
||||
def test_static19_fallback_redirection_loop(self):
|
||||
bad_path = '/test_http/static/idontexist.png'
|
||||
self.assertRaises(FileNotFoundError, file_open, bad_path[1:])
|
||||
|
||||
self.env['ir.attachment'].create({
|
||||
'name': 'idontexist.png',
|
||||
'mimetype': 'image/png',
|
||||
'url': bad_path,
|
||||
'public': True,
|
||||
})
|
||||
|
||||
res = self.url_open(bad_path, allow_redirects=False)
|
||||
location = parse_url(res.headers.get('Location', ''))
|
||||
self.assertNotEqual(location.path, bad_path, "loop detected")
|
||||
self.assertEqual(res.status_code, 404)
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestHttpStaticLogo(TestHttpStaticCommon):
|
||||
|
||||
Reference in New Issue
Block a user