Usage:
Literal value, use default timeout {% geturl "http://example.com/path/to/content/" %}
Variable value, literal timeout {% geturl object.urlfield 5 %}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | @register.simple_tag
def geturl(url, timeout=None):
"""
Usage: {% geturl url [timeout] %}
Examples:
{% geturl "http://example.com/path/to/content/" %}
{% geturl object.urlfield 1 %}
"""
import socket
from urllib2 import urlopen
socket_default_timeout = socket.getdefaulttimeout()
if timeout is not None:
try:
socket_timeout = float(timeout)
except ValueError:
raise template.TemplateSyntaxError, "timeout argument of geturl tag, if provided, must be convertible to a float"
try:
socket.setdefaulttimeout(socket_timeout)
except ValueError:
raise template.TemplateSyntaxError, "timeout argument of geturl tag, if provided, cannot be less than zero"
try:
try:
content = urlopen(url).read()
finally: # reset socket timeout
if timeout is not None:
socket.setdefaulttimeout(socket_default_timeout)
except:
content = ''
return content
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
This screams xss-vulnerability. Do you have control over the urls you include?
#
The intention is similar to the <c:import/> tag of the JavaServer Pages Standard Tag Library (JSTL). It's up to the developer to use trusted sources. :)
#
Updated to use template.Variable class from Django dev version. Also switched to urllib2 b/c urllib2.urlopen raises urllib2.HTTPError on 404, whereas urllib.urlopen simply returns 404 page content (bad).
#
Updated to use the simple_tag shortcut. :)
#
If you use this in production there are a few things to be wary of (we've done something similar for trusted URLs at my job).
From what I can tell, the way to set a timeout is: import socket; socket.setdefaulttimeout(seconds)
#
Good point on the timeout issue. Caching, of course, can be handled using the {% cache %} template tag.
#
Updated to deal with timeout issue. I have a minimal understanding of sockets and threads, so I played it safe by getting current default socket timeout at the outset and resetting the default at the end.
#
Please login first before commenting.