-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #12384: Add a three-second timeout for RSS reader widget
- Loading branch information
1 parent
261f5e4
commit 9319cff
Showing
3 changed files
with
39 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
from urllib.parse import urlencode | ||
|
||
import feedparser | ||
import requests | ||
from django import forms | ||
from django.conf import settings | ||
from django.contrib.contenttypes.models import ContentType | ||
|
@@ -269,12 +270,9 @@ class ConfigForm(WidgetConfigForm): | |
) | ||
|
||
def render(self, request): | ||
url = self.config['feed_url'] | ||
feed = self.get_feed() | ||
|
||
return render_to_string(self.template_name, { | ||
'url': url, | ||
'feed': feed, | ||
'url': self.config['feed_url'], | ||
**self.get_feed() | ||
}) | ||
|
||
@cached_property | ||
|
@@ -286,17 +284,33 @@ def cache_key(self): | |
def get_feed(self): | ||
# Fetch RSS content from cache if available | ||
if feed_content := cache.get(self.cache_key): | ||
feed = feedparser.FeedParserDict(feed_content) | ||
else: | ||
feed = feedparser.parse( | ||
self.config['feed_url'], | ||
request_headers={'User-Agent': f'NetBox/{settings.VERSION}'} | ||
return { | ||
'feed': feedparser.FeedParserDict(feed_content), | ||
} | ||
|
||
# Fetch feed content from remote server | ||
try: | ||
response = requests.get( | ||
url=self.config['feed_url'], | ||
headers={'User-Agent': f'NetBox/{settings.VERSION}'}, | ||
proxies=settings.HTTP_PROXIES, | ||
timeout=3 | ||
) | ||
if not feed.bozo: | ||
# Cap number of entries | ||
max_entries = self.config.get('max_entries') | ||
feed['entries'] = feed['entries'][:max_entries] | ||
# Cache the feed content | ||
cache.set(self.cache_key, dict(feed), self.config.get('cache_timeout')) | ||
|
||
return feed | ||
response.raise_for_status() | ||
except requests.exceptions.RequestException as e: | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jeremystretch
Author
Member
|
||
return { | ||
'error': e, | ||
} | ||
|
||
# Parse feed content | ||
feed = feedparser.parse(response.content) | ||
if not feed.bozo: | ||
# Cap number of entries | ||
max_entries = self.config.get('max_entries') | ||
feed['entries'] = feed['entries'][:max_entries] | ||
# Cache the feed content | ||
cache.set(self.cache_key, dict(feed), self.config.get('cache_timeout')) | ||
|
||
return { | ||
'feed': feed, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For robustness, catch OSError here? (RequestException is a subclass of this).
See #12411 where OP got a http.client.RemoteDisconnected exception (a different subclass of OSError)
Possibly though, it would be better to catch OSError and Runtime error at a higher level covering all widgets. If a transient error occurs in any widget you don't want it to bring the whole of Netbox down.