forked from codeforamerica/git-jekyll-preview
-
Notifications
You must be signed in to change notification settings - Fork 5
/
href.py
131 lines (98 loc) · 4.71 KB
/
href.py
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from urlparse import urlparse, urljoin, urlunparse
from re import match
def get_redirect(req_part, ref_url, slash_count=3):
'''
>>> get_redirect('/style.css?q=Hi', 'http://preview.local/foo/bar/baz/')
'/foo/bar/baz/style.css?q=Hi'
>>> get_redirect('/style.css?q=Hi', 'http://preview.local/foo/bar/baz/quux.html')
'/foo/bar/baz/style.css?q=Hi'
>>> get_redirect('/quux/style.css?q=Hi', 'http://preview.local/foo/bar/baz/')
'/foo/bar/baz/quux/style.css?q=Hi'
>>> get_redirect('/style.css?q=Hi', 'http://preview.local/foo/bar/br/anch/', 4)
'/foo/bar/br/anch/style.css?q=Hi'
>>> get_redirect('/style.css?q=Hi', 'http://preview.local/foo/bar/br/anch/quux.html', 4)
'/foo/bar/br/anch/style.css?q=Hi'
>>> get_redirect('/quux/style.css?q=Hi', 'http://preview.local/foo/bar/br/anch/', 4)
'/foo/bar/br/anch/quux/style.css?q=Hi'
>>> get_redirect('/style.css?q=Hi', 'http://preview.local/foo/barbaz/', 2)
'/foo/barbaz/style.css?q=Hi'
>>> get_redirect('/style.css?q=Hi', 'http://preview.local/foo/barbaz/quux.html', 2)
'/foo/barbaz/style.css?q=Hi'
>>> get_redirect('/quux/style.css?q=Hi', 'http://preview.local/foo/barbaz/', 2)
'/foo/barbaz/quux/style.css?q=Hi'
'''
_, _, ref_path, _, _, _ = urlparse(ref_url)
pattern = r'(?P<preamble>' + (r'/[^/]+' * slash_count) + r')'
ref_git_preamble_match = match(pattern, ref_path)
return ref_git_preamble_match.group('preamble') + req_part
def needs_redirect(req_host, req_path, ref_url, slash_count=3):
'''
Don't redirect when the request and referer hosts don't match:
>>> needs_redirect('preview.local', '/style.css', 'http://example.com/foo/bar/baz/')
False
Don't redirect when the referer doesn't appear to include a git path.
>>> needs_redirect('preview.local', '/style.css', 'http://preview.local/about/')
False
Don't redirect when the referer doesn't appear to include a git path.
>>> needs_redirect('preview.local', '/style.css', 'http://preview.local/about/', 2)
False
Don't redirect when the referer doesn't appear to include a git path.
>>> needs_redirect('preview.local', '/style.css', 'http://preview.local/foo/bar/', 3)
False
Don't redirect when the referer doesn't appear to include a git path.
>>> needs_redirect('preview.local', '/style.css', 'http://preview.local/foo/bar/baz/', 4)
False
Don't redirect when the request path already includes the git preamble.
>>> needs_redirect('preview.local', '/foo/bar/baz/style.css', 'http://preview.local/foo/bar/baz/')
False
Don't redirect when the request path already includes the git preamble.
>>> needs_redirect('preview.local', '/foo/bar/br/anch/style.css', 'http://preview.local/foo/bar/br/anch/', 4)
False
Don't redirect when the request path already includes the git preamble.
>>> needs_redirect('preview.local', '/foo/barbaz/style.css', 'http://preview.local/foo/barbaz/', 2)
False
>>> needs_redirect('preview.local', '/', 'http://preview.local/foo/bar/baz/')
True
>>> needs_redirect('preview.local', '/style.css', 'http://preview.local/foo/bar/baz/')
True
>>> needs_redirect('preview.local', '/fee/fi/fo/fum/style.css', 'http://preview.local/foo/bar/baz/')
True
>>> needs_redirect('preview.local', '/', 'http://preview.local/foo/bar/br/anch/')
True
>>> needs_redirect('preview.local', '/style.css', 'http://preview.local/foo/bar/br/anch/')
True
>>> needs_redirect('preview.local', '/fee/fi/fo/fum/style.css', 'http://preview.local/foo/bar/br/anch/', 4)
True
>>> needs_redirect('preview.local', '/fee/fi/fo/fum/style.css', 'http://preview.local/foo/barbaz/', 2)
True
'''
_, ref_host, ref_path, _, _, _ = urlparse(ref_url)
#
# Don't redirect when the request and referer hosts don't match.
#
if req_host != ref_host:
return False
pattern = r'(?P<preamble>' + (r'/[^/]+' * slash_count) + r')'
ref_git_preamble_match = match(pattern, ref_path)
#
# Don't redirect when the referer doesn't appear to include a git path.
#
if not ref_git_preamble_match:
return False
#
# Don't redirect when the request path already includes the git preamble.
#
if req_path.startswith(ref_git_preamble_match.group('preamble')):
return False
return True
def absolute_url(request, location):
'''
'''
if 'X-Forwarded-Proto' not in request.headers:
return location
scheme = request.headers.get('X-Forwarded-Proto')
actual_url = urlunparse((scheme, request.host, request.path, request.query_string, None, None))
return urljoin(actual_url, location)
if __name__ == '__main__':
import doctest
doctest.testmod()