Add python-eventlet package to MOS 8.0 repository
[packages/trusty/python-eventlet.git] / python-eventlet / eventlet / wsgi.py
similarity index 94%
rename from eventlet/eventlet/wsgi.py
rename to python-eventlet/eventlet/wsgi.py
index e69d107d49e69d593125c5c83cc22542a3312264..72582770ae9edc015ea7580a5035eb7e5d1b591e 100644 (file)
@@ -8,12 +8,13 @@ import warnings
 
 from eventlet.green import BaseHTTPServer
 from eventlet.green import socket
 
 from eventlet.green import BaseHTTPServer
 from eventlet.green import socket
-from eventlet.green import urllib
 from eventlet import greenio
 from eventlet import greenpool
 from eventlet import support
 from eventlet.support import six
 
 from eventlet import greenio
 from eventlet import greenpool
 from eventlet import support
 from eventlet.support import six
 
+from eventlet.support.six.moves import urllib
+
 
 DEFAULT_MAX_SIMULTANEOUS_REQUESTS = 1024
 DEFAULT_MAX_HTTP_VERSION = 'HTTP/1.1'
 
 DEFAULT_MAX_SIMULTANEOUS_REQUESTS = 1024
 DEFAULT_MAX_HTTP_VERSION = 'HTTP/1.1'
@@ -224,6 +225,33 @@ class HeadersTooLarge(Exception):
     pass
 
 
     pass
 
 
+def get_logger(log, debug):
+    if callable(getattr(log, 'info', None)) \
+       and callable(getattr(log, 'debug', None)):
+        return log
+    else:
+        return LoggerFileWrapper(log, debug)
+
+
+class LoggerFileWrapper(object):
+    def __init__(self, log, debug):
+        self.log = log
+        self._debug = debug
+
+    def info(self, msg, *args, **kwargs):
+        self.write(msg, *args)
+
+    def debug(self, msg, *args, **kwargs):
+        if self._debug:
+            self.write(msg, *args)
+
+    def write(self, msg, *args):
+        msg = msg + '\n'
+        if args:
+            msg = msg % args
+        self.log.write(msg)
+
+
 class FileObjectForHeaders(object):
 
     def __init__(self, fp):
 class FileObjectForHeaders(object):
 
     def __init__(self, fp):
@@ -395,24 +423,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
                 towrite.append(six.b("%x" % (len(data),)) + b"\r\n" + data + b"\r\n")
             else:
                 towrite.append(data)
                 towrite.append(six.b("%x" % (len(data),)) + b"\r\n" + data + b"\r\n")
             else:
                 towrite.append(data)
-            try:
-                _writelines(towrite)
-                length[0] = length[0] + sum(map(len, towrite))
-            except UnicodeEncodeError:
-                self.server.log_message(
-                    "Encountered non-ascii unicode while attempting to write"
-                    "wsgi response: %r" %
-                    [x for x in towrite if isinstance(x, six.text_type)])
-                self.server.log_message(traceback.format_exc())
-                _writelines(
-                    ["HTTP/1.1 500 Internal Server Error\r\n",
-                     "Connection: close\r\n",
-                     "Content-type: text/plain\r\n",
-                     "Content-length: 98\r\n",
-                     "Date: %s\r\n" % format_date_time(time.time()),
-                     "\r\n",
-                     ("Internal Server Error: wsgi application passed "
-                      "a unicode object to the server instead of a string.")])
+            _writelines(towrite)
+            length[0] = length[0] + sum(map(len, towrite))
 
         def start_response(status, response_headers, exc_info=None):
             status_code[0] = status.split()[0]
 
         def start_response(status, response_headers, exc_info=None):
             status_code[0] = status.split()[0]
@@ -456,6 +468,9 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
                 minimum_write_chunk_size = int(self.environ.get(
                     'eventlet.minimum_write_chunk_size', self.minimum_chunk_size))
                 for data in result:
                 minimum_write_chunk_size = int(self.environ.get(
                     'eventlet.minimum_write_chunk_size', self.minimum_chunk_size))
                 for data in result:
+                    if isinstance(data, six.text_type):
+                        data = data.encode('ascii')
+
                     towrite.append(data)
                     towrite_size += len(data)
                     if towrite_size >= minimum_write_chunk_size:
                     towrite.append(data)
                     towrite_size += len(data)
                     if towrite_size >= minimum_write_chunk_size:
@@ -471,8 +486,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
             except Exception:
                 self.close_connection = 1
                 tb = traceback.format_exc()
             except Exception:
                 self.close_connection = 1
                 tb = traceback.format_exc()
-                self.server.log_message(tb)
-                if not headers_set:
+                self.server.log.info(tb)
+                if not headers_sent:
                     err_body = six.b(tb) if self.server.debug else b''
                     start_response("500 Internal Server Error",
                                    [('Content-type', 'text/plain'),
                     err_body = six.b(tb) if self.server.debug else b''
                     start_response("500 Internal Server Error",
                                    [('Content-type', 'text/plain'),
@@ -497,7 +512,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
                 hook(self.environ, *args, **kwargs)
 
             if self.server.log_output:
                 hook(self.environ, *args, **kwargs)
 
             if self.server.log_output:
-                self.server.log_message(self.server.log_format % {
+                self.server.log.info(self.server.log_format % {
                     'client_ip': self.get_client_ip(),
                     'client_port': self.client_address[1],
                     'date_time': self.log_date_time_string(),
                     'client_ip': self.get_client_ip(),
                     'client_port': self.client_address[1],
                     'date_time': self.log_date_time_string(),
@@ -522,7 +537,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
 
         pq = self.path.split('?', 1)
         env['RAW_PATH_INFO'] = pq[0]
 
         pq = self.path.split('?', 1)
         env['RAW_PATH_INFO'] = pq[0]
-        env['PATH_INFO'] = urllib.unquote(pq[0])
+        env['PATH_INFO'] = urllib.parse.unquote(pq[0])
         if len(pq) > 1:
             env['QUERY_STRING'] = pq[1]
 
         if len(pq) > 1:
             env['QUERY_STRING'] = pq[1]
 
@@ -616,9 +631,9 @@ class Server(BaseHTTPServer.HTTPServer):
         self.socket = socket
         self.address = address
         if log:
         self.socket = socket
         self.address = address
         if log:
-            self.log = log
+            self.log = get_logger(log, debug)
         else:
         else:
-            self.log = sys.stderr
+            self.log = get_logger(sys.stderr, debug)
         self.app = app
         self.keepalive = keepalive
         self.environ = environ
         self.app = app
         self.keepalive = keepalive
         self.environ = environ
@@ -672,12 +687,12 @@ class Server(BaseHTTPServer.HTTPServer):
         except socket.timeout:
             # Expected exceptions are not exceptional
             sock.close()
         except socket.timeout:
             # Expected exceptions are not exceptional
             sock.close()
-            if self.debug:
-                # similar to logging "accepted" in server()
-                self.log_message('(%s) timed out %r' % (self.pid, address))
+            # similar to logging "accepted" in server()
+            self.log.debug('(%s) timed out %r' % (self.pid, address))
 
     def log_message(self, message):
 
     def log_message(self, message):
-        self.log.write(message + '\n')
+        warnings.warn('server.log_message is deprecated.  Please use server.log.info instead')
+        self.log.info(message)
 
 
 try:
 
 
 try:
@@ -801,15 +816,14 @@ def server(sock, site,
             if port == ':80':
                 port = ''
 
             if port == ':80':
                 port = ''
 
-        serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % (
+        serv.log.info("(%s) wsgi starting up on %s://%s%s/" % (
             serv.pid, scheme, host, port))
         while is_accepting:
             try:
                 client_socket = sock.accept()
                 client_socket[0].settimeout(serv.socket_timeout)
             serv.pid, scheme, host, port))
         while is_accepting:
             try:
                 client_socket = sock.accept()
                 client_socket[0].settimeout(serv.socket_timeout)
-                if debug:
-                    serv.log.write("(%s) accepted %r\n" % (
-                        serv.pid, client_socket[1]))
+                serv.log.debug("(%s) accepted %r" % (
+                    serv.pid, client_socket[1]))
                 try:
                     pool.spawn_n(serv.process_request, client_socket)
                 except AttributeError:
                 try:
                     pool.spawn_n(serv.process_request, client_socket)
                 except AttributeError:
@@ -822,11 +836,11 @@ def server(sock, site,
                 if support.get_errno(e) not in ACCEPT_ERRNO:
                     raise
             except (KeyboardInterrupt, SystemExit):
                 if support.get_errno(e) not in ACCEPT_ERRNO:
                     raise
             except (KeyboardInterrupt, SystemExit):
-                serv.log.write("wsgi exiting\n")
+                serv.log.info("wsgi exiting")
                 break
     finally:
         pool.waitall()
                 break
     finally:
         pool.waitall()
-        serv.log.write("(%s) wsgi exited, is_accepting=%s\n" % (
+        serv.log.info("(%s) wsgi exited, is_accepting=%s" % (
             serv.pid, is_accepting))
         try:
             # NOTE: It's not clear whether we want this to leave the
             serv.pid, is_accepting))
         try:
             # NOTE: It's not clear whether we want this to leave the