]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Solve SF bug #231249: cgi.py opens too many (temporary) files.
authorGuido van Rossum <guido@python.org>
Fri, 29 Jun 2001 13:06:06 +0000 (13:06 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 29 Jun 2001 13:06:06 +0000 (13:06 +0000)
class FieldStorage: this patch changes read_lines() and co. to use a
StringIO() instead of a real file.  The write() calls are redirected
to a private method that replaces it with a real, external file only
when it gets too big (> 1000 bytes).

This avoids problems in forms using the multipart/form-data encoding
with many fields.  The original code created a temporary file for
*every* field (not just for file upload fields), thereby sometimes
exceeding the open file limit of some systems.

Note that the simpler solution "use a real file only for file uploads"
can't be used because the form field parser has no way to tell which
fields correspond to file uploads.

It's *possible* but extremely unlikely that this would break someone's
code; they would have to be stepping way outside the documented
interface for FieldStorage and use f.file.fileno(), or depend on
overriding make_file() to return a file-like object with additional
known properties.

Lib/cgi.py

index 4fa696ff1dafe4dd3ea402285af3ce011fa8aa19..35343607a7fbbc1d92a5d07978e2653ed689bced 100755 (executable)
@@ -28,7 +28,7 @@ written in Python.
 # responsible for its maintenance.
 #
 
-__version__ = "2.5"
+__version__ = "2.6"
 
 
 # Imports
@@ -633,12 +633,20 @@ class FieldStorage:
 
     def read_lines(self):
         """Internal: read lines until EOF or outerboundary."""
-        self.file = self.make_file('')
+        self.file = self.__file = StringIO()
         if self.outerboundary:
             self.read_lines_to_outerboundary()
         else:
             self.read_lines_to_eof()
 
+    def __write(self, line):
+        if self.__file is not None:
+            if self.__file.tell() + len(line) > 1000:
+                self.file = self.make_file('')
+                self.file.write(self.__file.getvalue())
+                self.__file = None
+        self.file.write(line)
+
     def read_lines_to_eof(self):
         """Internal: read lines until EOF."""
         while 1:
@@ -646,7 +654,7 @@ class FieldStorage:
             if not line:
                 self.done = -1
                 break
-            self.file.write(line)
+            self.__write(line)
 
     def read_lines_to_outerboundary(self):
         """Internal: read lines until outerboundary."""
@@ -674,7 +682,7 @@ class FieldStorage:
                 line = line[:-1]
             else:
                 delim = ""
-            self.file.write(odelim + line)
+            self.__write(odelim + line)
 
     def skip_lines(self):
         """Internal: skip lines until outer boundary if defined."""