Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 104 lines (91 sloc) 4.628 kb
8ecf49e Eric Holscher Added an NGINX SSI processing middleware. Might break yo' shit.
ericholscher authored
1 import re
7462962 Eric Holscher Removed adns dependency for pure python dnspython. Also cache dns
ericholscher authored
2
8bb2184 Eric Holscher Allow people to use any hostname while in DEBUG
ericholscher authored
3 from django.conf import settings
7462962 Eric Holscher Removed adns dependency for pure python dnspython. Also cache dns
ericholscher authored
4 from django.core.cache import cache
8ecf49e Eric Holscher Added an NGINX SSI processing middleware. Might break yo' shit.
ericholscher authored
5 from django.core.urlresolvers import get_urlconf, get_resolver, Resolver404
22c7c05 Eric Holscher Added language support to our urls/subdomains.
ericholscher authored
6 from django.http import Http404
d0b2cba Eric Holscher Added logo to uploaded html docs.
ericholscher authored
7 from django.utils.encoding import smart_unicode
8ecf49e Eric Holscher Added an NGINX SSI processing middleware. Might break yo' shit.
ericholscher authored
8
4f4d380 Eric Holscher Start storing CNAMEs seen in redis.
ericholscher authored
9 import redis
10
11
22c7c05 Eric Holscher Added language support to our urls/subdomains.
ericholscher authored
12 from projects.views.public import slug_detail, subdomain_handler
5c69fac Eric Holscher Allow for project subdomains.
ericholscher authored
13
d0b2cba Eric Holscher Added logo to uploaded html docs.
ericholscher authored
14 #Thanks to debug-toolbar for the response-replacing code.
15 _HTML_TYPES = ('text/html', 'application/xhtml+xml')
16
17 OUR_CODE = """
18 <hr> <!-- End original user content -->
19 <script type="text/javascript">
20 var _gaq = _gaq || [];
21 _gaq.push(['_setAccount', 'UA-17997319-1']);
22 _gaq.push(['_trackPageview']);
23 (function() {
24 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
25 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
26 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
27 })();
28 </script>
29
30 <style type="text/css">
31 .badge { position: fixed; display: block; bottom: 5px; height: 40px; text-indent: -9999em; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset; -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset; }
32 .badge.rtd { background: #257597 url(http://media.readthedocs.org/images/badge-rtd.png) top left no-repeat; border: 1px solid #282E32; width: 160px; right: 5px; }
33 </style>
34
35 <a href="http://readthedocs.org?fromdocs=middleware" class="badge rtd">Brought to you by Read the Docs</a>
36 """
37
38 def replace_insensitive(string, target, replacement):
39 """
40 Similar to string.replace() but is case insensitive
41 Code borrowed from: http://forums.devshed.com/python-programming-11/case-insensitive-string-replace-490921.html
42 """
43 no_case = string.lower()
44 index = no_case.rfind(target.lower())
45 if index >= 0:
46 return string[:index] + replacement + string[index + len(target):]
47 else: # no results so return the original string
48 return string
49
50
5c69fac Eric Holscher Allow for project subdomains.
ericholscher authored
51 class SubdomainMiddleware(object):
52 def process_request(self, request):
76899b5 Eric Holscher Fix middleware to query dns and generally be awesome.
ericholscher authored
53 host = request.get_host()
54 if ':' in host:
55 host = host.split(':')[0]
56 domain_parts = host.split('.')
0aec26d Eric Holscher Once more try and fix this.
ericholscher authored
57 #Google was finding crazy www.blah.readthedocs.org domains.
a795c68 Eric Holscher I should learn that whenever I touch this middleware I break stuff.
ericholscher authored
58 if len(domain_parts) > 3:
566a22b Eric Holscher Fix IP based hostnames.
ericholscher authored
59 if not settings.DEBUG:
60 raise Http404('Invalid hostname')
a795c68 Eric Holscher I should learn that whenever I touch this middleware I break stuff.
ericholscher authored
61 if len(domain_parts) == 3:
76899b5 Eric Holscher Fix middleware to query dns and generally be awesome.
ericholscher authored
62 subdomain = domain_parts[0]
9ece0e4 Eric Holscher Add slug onto request for subdomains/CNAMEs
ericholscher authored
63 request.slug = subdomain
ec7ebad Eric Holscher One more place :)
ericholscher authored
64 if not (subdomain.lower() == 'www') and 'readthedocs.org' in host:
dfe4443 Eric Holscher Make home a relative link when CNAME'd. Fixes issue #9.
ericholscher authored
65 request.subdomain = True
22c7c05 Eric Holscher Added language support to our urls/subdomains.
ericholscher authored
66 return subdomain_handler(request, subdomain, request.path.lstrip('/'))
ec00dbc Eric Holscher Let people CNAME with readthedocs subdomain.
ericholscher authored
67 if 'readthedocs.org' not in host \
7aadb96 Eric Holscher Added a super basic API with tastypie.
ericholscher authored
68 and 'localhost' not in host \
69 and 'testserver' not in host:
dfe4443 Eric Holscher Make home a relative link when CNAME'd. Fixes issue #9.
ericholscher authored
70 request.cname = True
e0009ba Eric Holscher Clean up middleware and subdomain header.
ericholscher authored
71 try:
4f4d380 Eric Holscher Start storing CNAMEs seen in redis.
ericholscher authored
72 redis_conn = redis.Redis(**settings.REDIS)
7462962 Eric Holscher Removed adns dependency for pure python dnspython. Also cache dns
ericholscher authored
73 slug = cache.get(host)
74 if not slug:
75 from dns import resolver
76 answer = [ans for ans in resolver.query(host, 'CNAME')][0]
77 domain = answer.target.to_unicode()
78 slug = domain.split('.')[0]
79 cache.set(host, slug, 60*60)
4f4d380 Eric Holscher Start storing CNAMEs seen in redis.
ericholscher authored
80 #Cache the slug -> host mapping permanently.
81 redis_conn.sadd("rtd_slug:v1:%s" % slug, host)
9ece0e4 Eric Holscher Add slug onto request for subdomains/CNAMEs
ericholscher authored
82 request.slug = slug
22c7c05 Eric Holscher Added language support to our urls/subdomains.
ericholscher authored
83 return subdomain_handler(request,
84 slug,
85 request.path.lstrip('/'))
7462962 Eric Holscher Removed adns dependency for pure python dnspython. Also cache dns
ericholscher authored
86 except:
22c7c05 Eric Holscher Added language support to our urls/subdomains.
ericholscher authored
87 #Some crazy person is CNAMEing to us. 404.
8bb2184 Eric Holscher Allow people to use any hostname while in DEBUG
ericholscher authored
88 if not settings.DEBUG:
89 raise Http404('Invalid Host Name.')
22c7c05 Eric Holscher Added language support to our urls/subdomains.
ericholscher authored
90 #Normal request.
76899b5 Eric Holscher Fix middleware to query dns and generally be awesome.
ericholscher authored
91 return None
d0b2cba Eric Holscher Added logo to uploaded html docs.
ericholscher authored
92
93 def process_response(self, request, response):
94 #Try and make this match as little as possible.
3150461 Eric Holscher Fix.
ericholscher authored
95 if response.status_code == 200 and '_static' not in request.path and '_images' not in request.path:
222b7fc Eric Holscher Make middleware not slow and crappy.
ericholscher authored
96 if getattr(request, 'add_badge', False):
1066c0b Eric Holscher Make middleware much faster.
ericholscher authored
97 response.content = replace_insensitive(
98 smart_unicode(response.content),
99 "</body>",
100 smart_unicode(OUR_CODE + "</body>"))
d0b2cba Eric Holscher Added logo to uploaded html docs.
ericholscher authored
101 if response.get('Content-Length', None):
102 response['Content-Length'] = len(response.content)
103 return response
Something went wrong with that request. Please try again.