PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/site-packages/django/core/servers/basehttp.py

https://gitlab.com/areema/myproject
Python | 198 lines | 190 code | 1 blank | 7 comment | 1 complexity | 06267fbe3377bb27833b6401aac01e99 MD5 | raw file
  1. """
  2. HTTP server that implements the Python WSGI protocol (PEP 333, rev 1.21).
  3. Based on wsgiref.simple_server which is part of the standard library since 2.5.
  4. This is a simple server for use in testing or debugging Django apps. It hasn't
  5. been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE!
  6. """
  7. from __future__ import unicode_literals
  8. import socket
  9. import sys
  10. from wsgiref import simple_server
  11. from django.core.exceptions import ImproperlyConfigured
  12. from django.core.handlers.wsgi import ISO_8859_1, UTF_8
  13. from django.core.management.color import color_style
  14. from django.core.wsgi import get_wsgi_application
  15. from django.utils import six
  16. from django.utils.encoding import uri_to_iri
  17. from django.utils.module_loading import import_string
  18. from django.utils.six.moves import socketserver
  19. __all__ = ('WSGIServer', 'WSGIRequestHandler')
  20. def get_internal_wsgi_application():
  21. """
  22. Loads and returns the WSGI application as configured by the user in
  23. ``settings.WSGI_APPLICATION``. With the default ``startproject`` layout,
  24. this will be the ``application`` object in ``projectname/wsgi.py``.
  25. This function, and the ``WSGI_APPLICATION`` setting itself, are only useful
  26. for Django's internal server (runserver); external WSGI servers should just
  27. be configured to point to the correct application object directly.
  28. If settings.WSGI_APPLICATION is not set (is ``None``), we just return
  29. whatever ``django.core.wsgi.get_wsgi_application`` returns.
  30. """
  31. from django.conf import settings
  32. app_path = getattr(settings, 'WSGI_APPLICATION')
  33. if app_path is None:
  34. return get_wsgi_application()
  35. try:
  36. return import_string(app_path)
  37. except ImportError as e:
  38. msg = (
  39. "WSGI application '%(app_path)s' could not be loaded; "
  40. "Error importing module: '%(exception)s'" % ({
  41. 'app_path': app_path,
  42. 'exception': e,
  43. })
  44. )
  45. six.reraise(ImproperlyConfigured, ImproperlyConfigured(msg),
  46. sys.exc_info()[2])
  47. def is_broken_pipe_error():
  48. exc_type, exc_value = sys.exc_info()[:2]
  49. return issubclass(exc_type, socket.error) and exc_value.args[0] == 32
  50. class WSGIServer(simple_server.WSGIServer, object):
  51. """BaseHTTPServer that implements the Python WSGI protocol"""
  52. request_queue_size = 10
  53. def __init__(self, *args, **kwargs):
  54. if kwargs.pop('ipv6', False):
  55. self.address_family = socket.AF_INET6
  56. super(WSGIServer, self).__init__(*args, **kwargs)
  57. def server_bind(self):
  58. """Override server_bind to store the server name."""
  59. super(WSGIServer, self).server_bind()
  60. self.setup_environ()
  61. def handle_error(self, request, client_address):
  62. if is_broken_pipe_error():
  63. sys.stderr.write("- Broken pipe from %s\n" % (client_address,))
  64. else:
  65. super(WSGIServer, self).handle_error(request, client_address)
  66. # Inheriting from object required on Python 2.
  67. class ServerHandler(simple_server.ServerHandler, object):
  68. def handle_error(self):
  69. # Ignore broken pipe errors, otherwise pass on
  70. if not is_broken_pipe_error():
  71. super(ServerHandler, self).handle_error()
  72. class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
  73. def __init__(self, *args, **kwargs):
  74. self.style = color_style()
  75. super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  76. def address_string(self):
  77. # Short-circuit parent method to not call socket.getfqdn
  78. return self.client_address[0]
  79. def log_message(self, format, *args):
  80. msg = "[%s] " % self.log_date_time_string()
  81. try:
  82. msg += "%s\n" % (format % args)
  83. except UnicodeDecodeError:
  84. # e.g. accessing the server via SSL on Python 2
  85. msg += "\n"
  86. # Utilize terminal colors, if available
  87. if args[1][0] == '2':
  88. # Put 2XX first, since it should be the common case
  89. msg = self.style.HTTP_SUCCESS(msg)
  90. elif args[1][0] == '1':
  91. msg = self.style.HTTP_INFO(msg)
  92. elif args[1] == '304':
  93. msg = self.style.HTTP_NOT_MODIFIED(msg)
  94. elif args[1][0] == '3':
  95. msg = self.style.HTTP_REDIRECT(msg)
  96. elif args[1] == '404':
  97. msg = self.style.HTTP_NOT_FOUND(msg)
  98. elif args[1][0] == '4':
  99. # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x
  100. if args[0].startswith(str('\x16\x03')):
  101. msg = ("You're accessing the development server over HTTPS, "
  102. "but it only supports HTTP.\n")
  103. msg = self.style.HTTP_BAD_REQUEST(msg)
  104. else:
  105. # Any 5XX, or any other response
  106. msg = self.style.HTTP_SERVER_ERROR(msg)
  107. sys.stderr.write(msg)
  108. def get_environ(self):
  109. # Strip all headers with underscores in the name before constructing
  110. # the WSGI environ. This prevents header-spoofing based on ambiguity
  111. # between underscores and dashes both normalized to underscores in WSGI
  112. # env vars. Nginx and Apache 2.4+ both do this as well.
  113. for k, v in self.headers.items():
  114. if '_' in k:
  115. del self.headers[k]
  116. env = super(WSGIRequestHandler, self).get_environ()
  117. path = self.path
  118. if '?' in path:
  119. path = path.partition('?')[0]
  120. path = uri_to_iri(path).encode(UTF_8)
  121. # Under Python 3, non-ASCII values in the WSGI environ are arbitrarily
  122. # decoded with ISO-8859-1. We replicate this behavior here.
  123. # Refs comment in `get_bytes_from_wsgi()`.
  124. env['PATH_INFO'] = path.decode(ISO_8859_1) if six.PY3 else path
  125. return env
  126. def handle(self):
  127. """Copy of WSGIRequestHandler, but with different ServerHandler"""
  128. self.raw_requestline = self.rfile.readline(65537)
  129. if len(self.raw_requestline) > 65536:
  130. self.requestline = ''
  131. self.request_version = ''
  132. self.command = ''
  133. self.send_error(414)
  134. return
  135. if not self.parse_request(): # An error code has been sent, just exit
  136. return
  137. handler = ServerHandler(
  138. self.rfile, self.wfile, self.get_stderr(), self.get_environ()
  139. )
  140. handler.request_handler = self # backpointer for logging
  141. handler.run(self.server.get_app())
  142. def run(addr, port, wsgi_handler, ipv6=False, threading=False):
  143. server_address = (addr, port)
  144. if threading:
  145. httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {})
  146. else:
  147. httpd_cls = WSGIServer
  148. httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
  149. if threading:
  150. # ThreadingMixIn.daemon_threads indicates how threads will behave on an
  151. # abrupt shutdown; like quitting the server by the user or restarting
  152. # by the auto-reloader. True means the server will not wait for thread
  153. # termination before it quits. This will make auto-reloader faster
  154. # and will prevent the need to kill the server manually if a thread
  155. # isn't terminating correctly.
  156. httpd.daemon_threads = True
  157. httpd.set_app(wsgi_handler)
  158. httpd.serve_forever()