|
Package Dropbox ::
Package web2py ::
Package gluon ::
Module http
|
|
1
2
3
4 """
5 This file is part of the web2py Web Framework
6 Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
7 License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
8 """
9
10 import re
11
12 __all__ = ['HTTP', 'redirect']
13
14 defined_status = {
15 200: 'OK',
16 201: 'CREATED',
17 202: 'ACCEPTED',
18 203: 'NON-AUTHORITATIVE INFORMATION',
19 204: 'NO CONTENT',
20 205: 'RESET CONTENT',
21 206: 'PARTIAL CONTENT',
22 301: 'MOVED PERMANENTLY',
23 302: 'FOUND',
24 303: 'SEE OTHER',
25 304: 'NOT MODIFIED',
26 305: 'USE PROXY',
27 307: 'TEMPORARY REDIRECT',
28 400: 'BAD REQUEST',
29 401: 'UNAUTHORIZED',
30 403: 'FORBIDDEN',
31 404: 'NOT FOUND',
32 405: 'METHOD NOT ALLOWED',
33 406: 'NOT ACCEPTABLE',
34 407: 'PROXY AUTHENTICATION REQUIRED',
35 408: 'REQUEST TIMEOUT',
36 409: 'CONFLICT',
37 410: 'GONE',
38 411: 'LENGTH REQUIRED',
39 412: 'PRECONDITION FAILED',
40 413: 'REQUEST ENTITY TOO LARGE',
41 414: 'REQUEST-URI TOO LONG',
42 415: 'UNSUPPORTED MEDIA TYPE',
43 416: 'REQUESTED RANGE NOT SATISFIABLE',
44 417: 'EXPECTATION FAILED',
45 422: 'UNPROCESSABLE ENTITY',
46 500: 'INTERNAL SERVER ERROR',
47 501: 'NOT IMPLEMENTED',
48 502: 'BAD GATEWAY',
49 503: 'SERVICE UNAVAILABLE',
50 504: 'GATEWAY TIMEOUT',
51 505: 'HTTP VERSION NOT SUPPORTED',
52 }
53
54
55
56
57 try:
58 BaseException
59 except NameError:
60 BaseException = Exception
61
62 regex_status = re.compile('^\d{3} \w+$')
63
64
65 -class HTTP(BaseException):
66
67 - def __init__(
68 self,
69 status,
70 body='',
71 cookies=None,
72 **headers
73 ):
74 self.status = status
75 self.body = body
76 self.headers = headers
77 self.cookies2headers(cookies)
78
80 if cookies and len(cookies) > 0:
81 self.headers['Set-Cookie'] = [
82 str(cookie)[11:] for cookie in cookies.values()]
83
84 - def to(self, responder, env=None):
85 env = env or {}
86 status = self.status
87 headers = self.headers
88 if status in defined_status:
89 status = '%d %s' % (status, defined_status[status])
90 else:
91 status = str(status)
92 if not regex_status.match(status):
93 status = '500 %s' % (defined_status[500])
94 headers.setdefault('Content-Type', 'text/html; charset=UTF-8')
95 body = self.body
96 if status[:1] == '4':
97 if not body:
98 body = status
99 if isinstance(body, str):
100 if len(body) < 512 and \
101 headers['Content-Type'].startswith('text/html'):
102 body += '<!-- %s //-->' % ('x' * 512)
103 headers['Content-Length'] = len(body)
104 rheaders = []
105 for k, v in headers.iteritems():
106 if isinstance(v, list):
107 rheaders += [(k, str(item)) for item in v]
108 elif not v is None:
109 rheaders.append((k, str(v)))
110 responder(status, rheaders)
111 if env.get('request_method', '') == 'HEAD':
112 return ['']
113 elif isinstance(body, str):
114 return [body]
115 elif hasattr(body, '__iter__'):
116 return body
117 else:
118 return [str(body)]
119
120 @property
122 """
123 compose a message describing this exception
124
125 "status defined_status [web2py_error]"
126
127 message elements that are not defined are omitted
128 """
129 msg = '%(status)d'
130 if self.status in defined_status:
131 msg = '%(status)d %(defined_status)s'
132 if 'web2py_error' in self.headers:
133 msg += ' [%(web2py_error)s]'
134 return msg % dict(status=self.status,
135 defined_status=defined_status.get(self.status),
136 web2py_error=self.headers.get('web2py_error'))
137
139 "stringify me"
140 return self.message
141
142
143 -def redirect(location='', how=303, client_side=False):
144 if location:
145 from gluon import current
146 loc = location.replace('\r', '%0D').replace('\n', '%0A')
147 if client_side and current.request.ajax:
148 raise HTTP(200, **{'web2py-redirect-location': loc})
149 else:
150 raise HTTP(how,
151 'You are being redirected <a href="%s">here</a>' % loc,
152 Location=loc)
153 else:
154 from gluon import current
155 if client_side and current.request.ajax:
156 raise HTTP(200, **{'web2py-component-command': 'window.location.reload(true)'})
157