diff --git a/docs/conf.py b/docs/conf.py index 723fb5e..def94ca 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,7 +28,7 @@ # The short X.Y version version = '3.0' # The full version, including alpha/beta/rc tags -release = '3.0.8' +release = '3.0.9' # -- General configuration --------------------------------------------------- diff --git a/webware/Properties.py b/webware/Properties.py index ca1f447..1d3d05c 100644 --- a/webware/Properties.py +++ b/webware/Properties.py @@ -1,6 +1,6 @@ name = 'Webware for Python' -version = (3, 0, 8) +version = (3, 0, 9) status = 'stable' diff --git a/webware/WebUtils/FieldStorage.py b/webware/WebUtils/FieldStorage.py index 9f6eb06..2c6e010 100644 --- a/webware/WebUtils/FieldStorage.py +++ b/webware/WebUtils/FieldStorage.py @@ -435,7 +435,8 @@ def read_binary(self): data = data.decode() except UnicodeDecodeError: self._binary_file = True - self.file = self.make_file() + if self.file is None: + self.file = self.make_file() self.file.write(data) todo -= len(data) diff --git a/webware/WebUtils/Tests/TestFieldStorageModified.py b/webware/WebUtils/Tests/TestFieldStorageModified.py index d55551f..6041f72 100644 --- a/webware/WebUtils/Tests/TestFieldStorageModified.py +++ b/webware/WebUtils/Tests/TestFieldStorageModified.py @@ -257,6 +257,86 @@ def testPostRequestWithNonUtf8TextData(self): self.assertEqual(fs.bytes_read, length) self.assertEqual(fs.file.read(), content) + def testPostRequestWithSmallPayloadWithContentLength(self): + length = 1000 # much smaller than buffer size + payload = 'x' * length + fs = FieldStorage( + fp=BytesIO(payload.encode()), + environ={'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'text/plain', + 'CONTENT_LENGTH': length}) + self.assertEqual(fs.headers, { + 'content-type': 'text/plain', + 'content-length': length}) + self.assertEqual(fs.type, 'text/plain') + self.assertEqual(fs.length, length) + self.assertEqual(fs.bytes_read, length) + self.assertEqual(fs.file.read(), payload) + + def testPostRequestWithLargeTextPayloadWithContentLength(self): + length = 25000 # much larger than buffer size + payload = 'x' * length + fs = FieldStorage( + fp=BytesIO(payload.encode()), + environ={'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'text/plain', + 'CONTENT_LENGTH': length}) + self.assertEqual(fs.headers, { + 'content-type': 'text/plain', + 'content-length': length}) + self.assertEqual(fs.type, 'text/plain') + self.assertEqual(fs.length, length) + self.assertEqual(fs.bytes_read, length) + self.assertEqual(fs.file.read(), payload) + + def testPostRequestWithLargeJsonPayloadWithContentLength(self): + # create JSON payload that is much larger than the buffer size + payload = {f'test{i}': str(i) * 5000 for i in range(5)} + payload = str(payload).replace("'", '"') + length = len(payload) + self.assertGreater(length, 25000) + fs = FieldStorage( + fp=BytesIO(payload.encode()), + environ={'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'application/json', + 'CONTENT_LENGTH': length}) + self.assertEqual(fs.headers, { + 'content-type': 'application/json', + 'content-length': length}) + self.assertEqual(fs.type, 'application/json') + self.assertEqual(fs.length, length) + self.assertEqual(fs.bytes_read, length) + # make sure that the original payload is preserved + self.assertEqual(fs.file.read(), payload) + + def testPostRequestWithSmallPayloadWithoutContentLength(self): + length = 1000 # much smaller than buffer size + payload = 'x' * length + fs = FieldStorage( + fp=BytesIO(payload.encode()), + environ={'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'text/plain'}) + self.assertEqual(fs.headers, { + 'content-type': 'text/plain'}) + self.assertEqual(fs.type, 'text/plain') + self.assertEqual(fs.length, -1) + self.assertEqual(fs.bytes_read, length) + self.assertEqual(fs.file.read(), payload) + + def testPostRequestWithLargePayloadWithoutContentLength(self): + length = 25000 # much larger than buffer size + payload = 'x' * length + fs = FieldStorage( + fp=BytesIO(payload.encode()), + environ={'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'text/plain'}) + self.assertEqual(fs.headers, { + 'content-type': 'text/plain'}) + self.assertEqual(fs.type, 'text/plain') + self.assertEqual(fs.length, -1) + self.assertEqual(fs.bytes_read, length) + self.assertEqual(fs.file.read(), payload) + def testIsBinaryType(self): self.assertIs(isBinaryType('application/json'), False) self.assertIs(isBinaryType('application/xml'), False)