summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Yelizariev <iel@odoo.com>2021-03-12 09:03:30 +0000
committerIvan Yelizariev <iel@odoo.com>2021-03-15 14:52:36 +0000
commitbdec63cf97e6904604e9f1e0bf3b6f453b6add60 (patch)
tree45a5fd1f9f9884b95e8a1c85b3b4f0963a4c5a56
parent6737feef848dc47120cf3d2cca84e033e869c985 (diff)
[FIX] link_tracker: prevent downloading big or non-html files
link tracker tries to get title from HTML, but the url may be not an html page or too big html to process. It's a waste of bandwidth, but may also lead to a Server Memory Limit error. As a solution, make HEAD request and don't proceed to GET request if it's not an html page or it's too big. Also, limit page downloading to 50KB. STEPS: - Have a standard database with link_tracker and mass_mailing. - Create a new mass mail MM - Add a link to a large file in MM Mail Body - Click "SEND" - Go to Settings / Technical / Automation / Scheduled Actions - Open the "Process Mass Mailing Queue" or "Email Marketing: Process queue" - Click "RUN MANUALLY" --- opw-2457640 closes odoo/odoo#67785 X-original-commit: 4216dc83f134aa41232afc7b5d080a9dc93db171 Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com> Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
-rw-r--r--addons/link_tracker/models/link_tracker.py12
1 files changed, 11 insertions, 1 deletions
diff --git a/addons/link_tracker/models/link_tracker.py b/addons/link_tracker/models/link_tracker.py
index 50b00b9011f..ace848971af 100644
--- a/addons/link_tracker/models/link_tracker.py
+++ b/addons/link_tracker/models/link_tracker.py
@@ -10,6 +10,8 @@ from werkzeug import urls
from odoo import tools, models, fields, api, _
+URL_MAX_SIZE = 10 * 1024 * 1024
+
class LinkTracker(models.Model):
""" Link trackers allow users to wrap any URL into a short URL that can be
@@ -94,7 +96,15 @@ class LinkTracker(models.Model):
@api.depends('url')
def _get_title_from_url(self, url):
try:
- page = requests.get(url, timeout=5)
+ head = requests.head(url, timeout=5)
+ if (
+ int(head.headers.get('Content-Length', 0)) > URL_MAX_SIZE
+ or
+ 'text/html' not in head.headers.get('Content-Type', 'text/html')
+ ):
+ return url
+ # HTML parser can work with a part of page, so ask server to limit downloading to 50 KB
+ page = requests.get(url, timeout=5, headers={"range": "bytes=0-50000"})
p = html.fromstring(page.text.encode('utf-8'), parser=html.HTMLParser(encoding='utf-8'))
title = p.find('.//title').text
except: