Robert Brewer avatar Robert Brewer committed 7b4e22c

Merge from trunk for today's fixes [2072] to [2080].

Comments (0)

Files changed (11)

cherrypy/__init__.py

     def __len__(self):
         child = getattr(serving, self.__attrname__)
         return len(child)
+    
+    def __nonzero__(self):
+        child = getattr(serving, self.__attrname__)
+        return bool(child)
 
 
 # Create request and response object (the same objects will be used

cherrypy/lib/safemime.py

 def safe_multipart(flash_only=False):
     """Wrap request.rfile in a reader that won't crash on no trailing CRLF."""
     h = cherrypy.request.headers
-    if not h.get('Content-Type').startswith('multipart/'):
+    if not h.get('Content-Type','').startswith('multipart/'):
         return
     if flash_only and not 'Shockwave Flash' in h.get('User-Agent', ''):
         return

cherrypy/test/test_conn.py

                     
                     # Make another request on the same connection, which should error.
                     self.assertRaises(httplib.NotConnected, self.getPage, "/")
+                
+                # Try HEAD. See http://www.cherrypy.org/ticket/864.
+                self.getPage("/stream", method='HEAD')
+                self.assertStatus('200 OK')
+                self.assertBody('')
+                self.assertNoHeader("Transfer-Encoding")
         else:
             self.PROTOCOL = "HTTP/1.0"
             

cherrypy/test/test_http.py

         # will hang. Verify that CP times out the socket and responds
         # with 411 Length Required.
         if self.scheme == "https":
-            c = httplib.HTTPSConnection("127.0.0.1:%s" % self.PORT)
+            c = httplib.HTTPSConnection('%s:%s' % (self.interface(), self.PORT))
         else:
-            c = httplib.HTTPConnection("127.0.0.1:%s" % self.PORT)
+            c = httplib.HTTPConnection('%s:%s' % (self.interface(), self.PORT))
         c.request("POST", "/")
         self.assertEqual(c.getresponse().status, 411)
     
         
         # post file
         if self.scheme == 'https':
-            c = httplib.HTTPS('127.0.0.1:%s' % self.PORT)
+            c = httplib.HTTPS('%s:%s' % (self.interface(), self.PORT))
         else:
-            c = httplib.HTTP('127.0.0.1:%s' % self.PORT)
+            c = httplib.HTTP('%s:%s' % (self.interface(), self.PORT))
         c.putrequest('POST', '/post_multipart')
         c.putheader('Content-Type', content_type)
         c.putheader('Content-Length', str(len(body)))
         
         # Test missing version in Request-Line
         if self.scheme == 'https':
-            c = httplib.HTTPSConnection('127.0.0.1:%s' % self.PORT)
+            c = httplib.HTTPSConnection('%s:%s' % (self.interface(), self.PORT))
         else:
-            c = httplib.HTTPConnection('127.0.0.1:%s' % self.PORT)
+            c = httplib.HTTPConnection('%s:%s' % (self.interface(), self.PORT))
         c._output('GET /')
         c._send_output()
         response = c.response_class(c.sock, strict=c.strict, method='GET')

cherrypy/test/test_logging.py

         self.assertBody('content')
         self.assertStatus(200)
         
-        host = self.HOST
-        if host == '0.0.0.0':
-            # INADDR_ANY, which should respond on localhost.
-            host = "127.0.0.1"
-        if host == '::':
-            # IN6ADDR_ANY, which should respond on localhost.
-            host = "::1"
-        intro = '%s - - [' % host
+        intro = '%s - - [' % self.interface()
         
         self.assertLog(-1, intro)
         
         self.assertBody('content')
         self.assertStatus(200)
         
-        host = self.HOST
-        if host == '0.0.0.0':
-            # INADDR_ANY, which should respond on localhost.
-            host = "127.0.0.1"
-        if host == '::':
-            # IN6ADDR_ANY, which should respond on localhost.
-            host = "::1"
-        intro = '%s - - [' % host
+        intro = '%s - - [' % self.interface()
         
         self.assertLog(-1, intro)
         if [k for k, v in self.headers if k.lower() == 'content-length']:

cherrypy/test/test_objectmapping.py

         self.script_name = ""
         
         # Test absoluteURI's in the Request-Line
-        self.getPage('http://127.0.0.1/')
+        self.getPage('http://%s:%s/' % (self.interface(), self.PORT))
         self.assertBody('world')
         
         # Test that the "isolated" app doesn't leak url's into the root app.

cherrypy/test/test_refleaks.py

         success = []
         
         def getpage():
-            host = '%s:%s' % (self.HOST, self.PORT)
+            host = '%s:%s' % (self.interface(), self.PORT)
             if self.scheme == 'https':
                 c = httplib.HTTPSConnection(host)
             else:

cherrypy/test/test_session.py

         
         def request(index):
             if self.scheme == 'https':
-                c = httplib.HTTPSConnection('127.0.0.1:%s' % self.PORT)
+                c = httplib.HTTPSConnection('%s:%s' % (self.interface(), self.PORT))
             else:
-                c = httplib.HTTPConnection('127.0.0.1:%s' % self.PORT)
+                c = httplib.HTTPConnection('%s:%s' % (self.interface(), self.PORT))
             for i in xrange(request_count):
                 c.putrequest('GET', '/')
                 for k, v in cookies:

cherrypy/test/test_xmlrpc.py

         except AttributeError:
             pass
         
-        host = self.HOST
-        if host == '0.0.0.0':
-            # INADDR_ANY, which should respond on localhost.
-            host = "127.0.0.1"
-        if host == '::':
-            # IN6ADDR_ANY, which should respond on localhost.
-            host = "::1"
-        
         if scheme == "https":
-            url = 'https://%s:%s/xmlrpc/' % (host, self.PORT)
+            url = 'https://%s:%s/xmlrpc/' % (self.interface(), self.PORT)
             proxy = xmlrpclib.ServerProxy(url, transport=HTTPSTransport())
         else:
-            url = 'http://%s:%s/xmlrpc/' % (host, self.PORT)
+            url = 'http://%s:%s/xmlrpc/' % (self.interface(), self.PORT)
             proxy = xmlrpclib.ServerProxy(url)
         
         # begin the tests ...

cherrypy/test/webtest.py

         self.set_persistent(on)
     persistent = property(_get_persistent, _set_persistent)
     
+    def interface(self):
+        """Return an IP address for a client connection.
+        
+        If the server is listening on '0.0.0.0' (INADDR_ANY)
+        or '::' (IN6ADDR_ANY), this will return the proper localhost."""
+        host = self.HOST
+        if host == '0.0.0.0':
+            # INADDR_ANY, which should respond on localhost.
+            return "127.0.0.1"
+        if host == '::':
+            # IN6ADDR_ANY, which should respond on localhost.
+            return "::1"
+        return host
+    
     def getPage(self, url, headers=None, method="GET", body=None, protocol=None):
         """Open the url with debugging support. Return status, headers, body."""
         ServerError.on = False

cherrypy/wsgiserver/__init__.py

             if status < 200 or status in (204, 205, 304):
                 pass
             else:
-                if self.response_protocol == 'HTTP/1.1':
+                if (self.response_protocol == 'HTTP/1.1'
+                    and self.environ["REQUEST_METHOD"] != 'HEAD'):
                     # Use the chunked transfer-coding
                     self.chunked_write = True
                     self.outheaders.append(("Transfer-Encoding", "chunked"))
                 try:
                     return self._sock.recv(size)
                 except socket.error, e:
-                    if e.args[0] not in socket_errors_nonblocking:
+                    if (e.args[0] not in socket_errors_nonblocking
+                        and e.args[0] not in socket_error_eintr):
                         raise
 
         def read(self, size=-1):
                 try:
                     return self._sock.recv(size)
                 except socket.error, e:
-                    if e.args[0] not in socket_errors_nonblocking:
+                    if (e.args[0] not in socket_errors_nonblocking
+                        and e.args[0] not in socket_error_eintr):
                         raise
 
         def read(self, size=-1):
             ctx.use_certificate_file(self.ssl_certificate)
             self.socket = SSLConnection(ctx, self.socket)
             self.populate_ssl_environ()
+            
+            # If listening on the IPV6 any address ('::' = IN6ADDR_ANY),
+            # activate dual-stack. See http://www.cherrypy.org/ticket/871.
+            if (not isinstance(self.bind_addr, basestring)
+                and self.bind_addr[0] == '::' and family == socket.AF_INET6):
+                try:
+                    self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
+                except (AttributeError, socket.error):
+                    # Apparently, the socket option is not available in
+                    # this machine's TCP stack
+                    pass
+        
         self.socket.bind(self.bind_addr)
     
     def tick(self):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.