PageRenderTime 51ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/gluon/http.py

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