Django template tag to force https URL references

I needed a hack to munge some included HTML content so that <img>, <input>, <link> and <script> tags to that URL references (href and src attributes in those tags) used https. Here’s what I came up with. It’s not bullet-proof, but seems good enough for the need of the moment. Note that <a> hrefs are not altered since I only care about avoiding mixed https/http requests that prompt alarms in some browsers and indicate to users that the page might not be secure.

import re
from django import template

register = template.Library()

HTTP_RE = re.compile(r"""(<(link\s+[^>]*\bhref|(img|input|script)\s+[^>]*\bsrc)\s*=\s*["'])http://""", re.I)

class ForceHttpsNode(template.Node):

    def __init__(self, nodelist):
        self.nodelist = nodelist

    def render(self, context):
        output = self.nodelist.render(context)
        if context.has_key('request') and context['request'].is_secure():
            output = HTTP_RE.sub(r'\1https://', output)
        return output

@register.tag
def forcehttps(parser, token):
    """
    Re-writes ``http://`` URL references in ``<link>``, ``<img>``, ``<input>`` 
    and ``<script>`` tags to ``https://``, if the request is HTTPS.

    Outputs rendered content as-is if request is HTTP.

    Usage example::

        {% forcehttps %}
          <link href="http://example.com/example.css" rel=stylesheet" type="text/css"/>
        {% endforcehttps %}

    If the request is HTTPS, the output should be::

        <link href="https://example.com/example.css" rel=stylesheet" type="text/css"/>

    .. note:: https:// URLs are not checked for validity.

    """
    nodelist = parser.parse(('endforcehttps',))
    parser.delete_first_token()
    return ForceHttpsNode(nodelist)
Advertisements

,