Skip to content
Newer
Older
100644 151 lines (131 sloc) 4.35 KB
089a01a web.py 0.2
aaronsw authored May 20, 2006
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 Feb 17, 2007
9 "changequery", "url",
bb3ab9e @anandology removed reloader from http.py. It has been moved to application.py
anandology authored Nov 10, 2008
10 "profiler",
089a01a web.py 0.2
aaronsw authored May 20, 2006
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 Nov 19, 2008
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
d9f0cc6 @anandology correct docstring
anandology authored Feb 18, 2010
59 `True`, or otherwise it raises NotModified error. It also sets
e6bc8d2 @anandology raise web.notmodified instead of returning False to indicate notmodified
anandology authored Feb 18, 2010
60 `Last-Modified` and `ETag` output headers.
d12fbe8 @aaronsw add docstring for web.modified; enhance function slightly
aaronsw authored Nov 20, 2008
61 """
5c0d10e @anandology fix python 2.3 compatibility
anandology authored Jan 6, 2009
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 May 20, 2006
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 Oct 22, 2008
72 if '*' in n or etag in n:
73 validate = True
089a01a web.py 0.2
aaronsw authored May 20, 2006
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 Nov 20, 2008
79
4f32f8b @aaronsw fix in web.modified
aaronsw authored Dec 11, 2008
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 Feb 18, 2010
82 if validate:
83 raise web.notmodified()
84 else:
85 return True
089a01a web.py 0.2
aaronsw authored May 20, 2006
86
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored Oct 23, 2009
87 def urlencode(query, doseq=0):
db64ef3 fix unicode bugs with urlencode
aaronsw authored Jul 16, 2007
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 Oct 23, 2009
93 >>> urlencode({'x': [1, 2]}, doseq=True)
94 'x=1&x=2'
db64ef3 fix unicode bugs with urlencode
aaronsw authored Jul 16, 2007
95 """
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored Oct 23, 2009
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 Jul 16, 2007
104
3962c18 changequery takes optional query argument.
anand authored Aug 15, 2007
105 def changequery(query=None, **kw):
089a01a web.py 0.2
aaronsw authored May 20, 2006
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 Aug 15, 2007
111 if query is None:
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored Oct 23, 2009
112 query = web.rawinput(method='get')
089a01a web.py 0.2
aaronsw authored May 20, 2006
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 Jun 25, 2007
118 out = web.ctx.path
089a01a web.py 0.2
aaronsw authored May 20, 2006
119 if query:
0cae750 @anandology fix changequery to make it work correctly even when the input has mul…
anandology authored Oct 23, 2009
120 out += '?' + urlencode(query, doseq=True)
089a01a web.py 0.2
aaronsw authored May 20, 2006
121 return out
122
3962c18 changequery takes optional query argument.
anand authored Aug 15, 2007
123 def url(path=None, **kw):
874feb3 bug fixes and web.url
anand authored Feb 17, 2007
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 Aug 15, 2007
128 if path is None:
129 path = web.ctx.path
874feb3 bug fixes and web.url
anand authored Feb 17, 2007
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 Jul 16, 2007
136 out += '?' + urlencode(kw)
874feb3 bug fixes and web.url
anand authored Feb 17, 2007
137
138 return out
139
089a01a web.py 0.2
aaronsw authored May 20, 2006
140 def profiler(app):
141 """Outputs basic profiling information at the bottom of each response."""
cb2115c fix profiling bug (tx spez)
aaronsw authored Nov 10, 2006
142 from utils import profile
089a01a web.py 0.2
aaronsw authored May 20, 2006
143 def profile_internal(e, o):
144 out, result = profile(app)(e, o)
3df6a15 @anandology fix web.profiler (Bug#326633)
anandology authored Feb 25, 2009
145 return list(out) + ['<pre>' + net.websafe(result) + '</pre>']
089a01a web.py 0.2
aaronsw authored May 20, 2006
146 return profile_internal
147
148 if __name__ == "__main__":
149 import doctest
150 doctest.testmod()
Something went wrong with that request. Please try again.