index.wsgi 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # CMS WSGI wrapper
  5. #
  6. # Copyright (C) 2011-2016 Michael Buesch <m@bues.ch>
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. import sys
  21. import atexit
  22. try:
  23. from urllib.parse import parse_qs
  24. except ImportError:
  25. from cgi import parse_qs
  26. try:
  27. sys.path.append("/var/cms") # workaround for old WSGI
  28. from cms import *
  29. except ImportError as e:
  30. raise Exception("Failed to import cms.py. Wrong python-path in WSGIDaemonProcess?:\n" + str(e))
  31. cms = None
  32. maxPostContentLength = 0
  33. def __initCMS(environ):
  34. global cms
  35. global maxPostContentLength
  36. if cms:
  37. return # Already initialized
  38. try:
  39. domain = environ["cms.domain"]
  40. cmsBase = environ["cms.cmsBase"]
  41. wwwBase = environ["cms.wwwBase"]
  42. except KeyError as e:
  43. raise Exception("WSGI environment %s not set" % str(e))
  44. debug = False
  45. try:
  46. debug = stringBool(environ["cms.debug"])
  47. except KeyError as e:
  48. pass
  49. try:
  50. maxPostContentLength = int(environ["cms.maxPostContentLength"], 10)
  51. except (KeyError, ValueError) as e:
  52. pass
  53. # Initialize the CMS module
  54. cms = CMS(dbPath = cmsBase + "/db",
  55. wwwPath = wwwBase,
  56. domain = domain,
  57. debug = debug)
  58. atexit.register(cms.shutdown)
  59. def __recvBody(environ):
  60. try:
  61. body_len = int(environ["CONTENT_LENGTH"], 10)
  62. except (ValueError, KeyError) as e:
  63. body_len = 0
  64. try:
  65. body_type = environ["CONTENT_TYPE"]
  66. except KeyError as e:
  67. body_type = "text/plain"
  68. if body_len < 0 or \
  69. (maxPostContentLength >= 0 and\
  70. body_len > maxPostContentLength):
  71. body = body_type = None
  72. else:
  73. body = environ["wsgi.input"].read(body_len)
  74. return body, body_type
  75. #post_env = env.copy()
  76. #post_env['QUERY_STRING'] = ''
  77. #post = cgi.FieldStorage(
  78. # fp=env['wsgi.input'],
  79. # environ=post_env,
  80. # keep_blank_values=True
  81. # )
  82. def application(environ, start_response):
  83. __initCMS(environ)
  84. if cms.debug:
  85. startStamp = datetime.now()
  86. status = "200 OK"
  87. additional_headers = []
  88. method = environ["REQUEST_METHOD"].upper()
  89. path = environ["PATH_INFO"]
  90. query = parse_qs(environ["QUERY_STRING"])
  91. protocol = environ["wsgi.url_scheme"].lower()
  92. try:
  93. if method == "GET":
  94. response_body, response_mime = cms.get(path, query, protocol)
  95. elif method == "POST":
  96. body, body_type = __recvBody(environ)
  97. if body is None:
  98. response_body, response_mime, status = (
  99. b"POSTed data is too long\n",
  100. "text/plain",
  101. "405 Method Not Allowed"
  102. )
  103. else:
  104. response_body, response_mime = cms.post(path, query,
  105. body, body_type,
  106. protocol)
  107. else:
  108. response_body, response_mime, status = (
  109. b"INVALID REQUEST_METHOD\n",
  110. "text/plain",
  111. "405 Method Not Allowed"
  112. )
  113. except (CMSException) as e:
  114. status = e.httpStatus
  115. response_body, response_mime, additional_headers = cms.getErrorPage(e, protocol)
  116. if cms.debug and response_mime.startswith("text/html"):
  117. delta = datetime.now() - startStamp
  118. sec = float(delta.seconds) + float(delta.microseconds) / 1000000
  119. response_body += ("\n<!-- generated in %.3f seconds -->" % sec).encode("UTF-8")
  120. response_headers = [ ('Content-Type', response_mime),
  121. ('Content-Length', str(len(response_body))) ]
  122. response_headers.extend(additional_headers)
  123. start_response(status, response_headers)
  124. return (response_body,)