Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 151 lines (131 sloc) 4.446 kB
089a01a web.py 0.2
aaronsw authored
1 """
2 HTTP Utilities
3 (from web.py)
4 """
5
6 __all__ = [
7 "expires", "lastmodified",
8 "prefixurl", "modified",
874feb3 bug fixes and web.url
anand authored
9 "changequery", "url",
bb3ab9e @anandology removed reloader from http.py. It has been moved to application.py
anandology authored
10 "profiler",
089a01a web.py 0.2
aaronsw authored
11 ]
12
13 import sys, os, threading, urllib, urlparse
14 try: import datetime
15 except ImportError: pass
16 import net, utils, webapi as web
17
18 def prefixurl(base=''):
19 """
20 Sorry, this function is really difficult to explain.
21 Maybe some other time.
22 """
23 url = web.ctx.path.lstrip('/')
24 for i in xrange(url.count('/')):
25 base += '../'
26 if not base:
27 base = './'
28 return base
29
30 def expires(delta):
31 """
32 Outputs an `Expires` header for `delta` from now.
33 `delta` is a `timedelta` object or a number of seconds.
34 """
35 if isinstance(delta, (int, long)):
36 delta = datetime.timedelta(seconds=delta)
37 date_obj = datetime.datetime.utcnow() + delta
38 web.header('Expires', net.httpdate(date_obj))
39
40 def lastmodified(date_obj):
41 """Outputs a `Last-Modified` header for `datetime`."""
42 web.header('Last-Modified', net.httpdate(date_obj))
43
44 def modified(date=None, etag=None):
d12fbe8 @aaronsw add docstring for web.modified; enhance function slightly
aaronsw authored
45 """
46 Checks to see if the page has been modified since the version in the
47 requester's cache.
48
49 When you publish pages, you can include `Last-Modified` and `ETag`
50 with the date the page was last modified and an opaque token for
51 the particular version, respectively. When readers reload the page,
52 the browser sends along the modification date and etag value for
53 the version it has in its cache. If the page hasn't changed,
54 the server can just return `304 Not Modified` and not have to
55 send the whole page again.
56
57 This function takes the last-modified date `date` and the ETag `etag`
58 and checks the headers to see if they match. If they do, it returns
e6bc8d2 @anandology raise web.notmodified instead of returning False to indicate notmodified
anandology authored
59 `True` otherwise it raises NotModified error. It also sets
60 `Last-Modified` and `ETag` output headers.
d12fbe8 @aaronsw add docstring for web.modified; enhance function slightly
aaronsw authored
61 """
5c0d10e @anandology fix python 2.3 compatibility
anandology authored
62 try:
63 from __builtin__ import set
64 except ImportError:
65 # for python 2.3
66 from sets import Set as set
67
68 n = set([x.strip('" ') for x in web.ctx.env.get('HTTP_IF_NONE_MATCH', '').split(',')])
089a01a web.py 0.2
aaronsw authored
69 m = net.parsehttpdate(web.ctx.env.get('HTTP_IF_MODIFIED_SINCE', '').split(';')[0])
70 validate = False
71 if etag:
3ccd412 @aaronsw add etag support
aaronsw authored
72 if '*' in n or etag in n:
73 validate = True
089a01a web.py 0.2
aaronsw authored
74 if date and m:
75 # we subtract a second because
76 # HTTP dates don't have sub-second precision
77 if date-datetime.timedelta(seconds=1) <= m:
78 validate = True
d12fbe8 @aaronsw add docstring for web.modified; enhance function slightly
aaronsw authored
79
4f32f8b @aaronsw fix in web.modified
aaronsw authored
80 if date: lastmodified(date)
81 if etag: web.header('ETag', '"' + etag + '"')
e6bc8d2 @anandology raise web.notmodified instead of returning False to indicate notmodified
anandology authored
82 if validate:
83 raise web.notmodified()
84 else:
85 return True
089a01a web.py 0.2
aaronsw authored
86
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored
87 def urlencode(query, doseq=0):
db64ef3 fix unicode bugs with urlencode
aaronsw authored
88 """
89 Same as urllib.urlencode, but supports unicode strings.
90
91 >>> urlencode({'text':'foo bar'})
92 'text=foo+bar'
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored
93 >>> urlencode({'x': [1, 2]}, doseq=True)
94 'x=1&x=2'
db64ef3 fix unicode bugs with urlencode
aaronsw authored
95 """
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored
96 def convert(value, doseq=False):
97 if doseq and isinstance(value, list):
98 return [convert(v) for v in value]
99 else:
100 return utils.utf8(value)
101
102 query = dict([(k, convert(v, doseq)) for k, v in query.items()])
103 return urllib.urlencode(query, doseq=doseq)
db64ef3 fix unicode bugs with urlencode
aaronsw authored
104
3962c18 changequery takes optional query argument.
anand authored
105 def changequery(query=None, **kw):
089a01a web.py 0.2
aaronsw authored
106 """
107 Imagine you're at `/foo?a=1&b=2`. Then `changequery(a=3)` will return
108 `/foo?a=3&b=2` -- the same URL but with the arguments you requested
109 changed.
110 """
3962c18 changequery takes optional query argument.
anand authored
111 if query is None:
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored
112 query = web.rawinput(method='get')
089a01a web.py 0.2
aaronsw authored
113 for k, v in kw.iteritems():
114 if v is None:
115 query.pop(k, None)
116 else:
117 query[k] = v
53fb28d fixed bugs in changequery and redirect
anand authored
118 out = web.ctx.path
089a01a web.py 0.2
aaronsw authored
119 if query:
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored
120 out += '?' + urlencode(query, doseq=True)
089a01a web.py 0.2
aaronsw authored
121 return out
122
3962c18 changequery takes optional query argument.
anand authored
123 def url(path=None, **kw):
874feb3 bug fixes and web.url
anand authored
124 """
125 Makes url by concatinating web.ctx.homepath and path and the
126 query string created using the arguments.
127 """
3962c18 changequery takes optional query argument.
anand authored
128 if path is None:
129 path = web.ctx.path
874feb3 bug fixes and web.url
anand authored
130 if path.startswith("/"):
131 out = web.ctx.homepath + path
132 else:
133 out = path
134
135 if kw:
db64ef3 fix unicode bugs with urlencode
aaronsw authored
136 out += '?' + urlencode(kw)
874feb3 bug fixes and web.url
anand authored
137
138 return out
139
089a01a web.py 0.2
aaronsw authored
140 def profiler(app):
141 """Outputs basic profiling information at the bottom of each response."""
cb2115c fix profiling bug (tx spez)
aaronsw authored
142 from utils import profile
089a01a web.py 0.2
aaronsw authored
143 def profile_internal(e, o):
144 out, result = profile(app)(e, o)
3df6a15 @anandology fix web.profiler (Bug#326633)
anandology authored
145 return list(out) + ['<pre>' + net.websafe(result) + '</pre>']
089a01a web.py 0.2
aaronsw authored
146 return profile_internal
147
148 if __name__ == "__main__":
149 import doctest
150 doctest.testmod()
Something went wrong with that request. Please try again.