diff options
author | Tiago Natel de Moura <t.nateldemoura@f5.com> | 2020-02-05 13:13:04 +0000 |
---|---|---|
committer | Tiago Natel de Moura <t.nateldemoura@f5.com> | 2020-02-05 13:13:04 +0000 |
commit | d3e218a8c379baf1af4759097d3c9c2fedb01432 (patch) | |
tree | 27c5b2c227535b7ff21ef41a16db3cb76f3f6033 /test | |
parent | 29d8b34244e24095f23f5e483f8452035fbb77aa (diff) | |
download | unit-d3e218a8c379baf1af4759097d3c9c2fedb01432.tar.gz unit-d3e218a8c379baf1af4759097d3c9c2fedb01432.tar.bz2 |
Tests: add helper for form-data and multipart.
Diffstat (limited to 'test')
-rw-r--r-- | test/test_java_application.py | 39 | ||||
-rw-r--r-- | test/unit/http.py | 73 |
2 files changed, 90 insertions, 22 deletions
diff --git a/test/test_java_application.py b/test/test_java_application.py index d2b97f88..9d873d6b 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -1,3 +1,4 @@ +import io import os import time import unittest @@ -1223,31 +1224,25 @@ class TestJavaApplication(TestApplicationJava): os.mkdir(fulldst) self.public_dir(fulldst) - body = ( - """Preamble. Should be ignored.\r -\r ---12345\r -Content-Disposition: form-data; name="file"; filename="sample.txt"\r -Content-Type: text/plain\r -\r -Data from sample file\r ---12345\r -Content-Disposition: form-data; name="destination"\r -\r -%s\r ---12345\r -Content-Disposition: form-data; name="upload"\r -\r -Upload\r ---12345--\r -\r -Epilogue. Should be ignored.""" - % fulldst - ) + fields = { + 'file': { + 'filename': 'sample.txt', + 'type': 'text/plain', + 'data': io.StringIO('Data from sample file'), + }, + 'destination': fulldst, + 'upload': 'Upload', + } + + encoded, content_type = self.multipart_encode(fields) + + preamble = 'Preamble. Should be ignored.' + epilogue = 'Epilogue. Should be ignored.' + body = "%s\r\n%s\r\n%s" % (preamble, encoded.decode(), epilogue) resp = self.post( headers={ - 'Content-Type': 'multipart/form-data; boundary=12345', + 'Content-Type': content_type, 'Host': 'localhost', 'Connection': 'close', }, diff --git a/test/unit/http.py b/test/unit/http.py index 839e91a2..c71e8f7e 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -1,3 +1,6 @@ +import binascii +import io +import os import re import time import json @@ -68,6 +71,10 @@ class TestHTTP(TestUnit): if body != b'': if isinstance(body, str): body = body.encode() + elif isinstance(body, dict): + body, content_type = self.form_encode(body) + + headers['Content-Type'] = content_type if 'Content-Length' not in headers: headers['Content-Length'] = len(body) @@ -266,3 +273,69 @@ class TestHTTP(TestUnit): sock.close() self.assertTrue(ret, 'socket connected') + + def form_encode(self, fields): + is_multipart = False + + for _, value in fields.items(): + if isinstance(value, dict): + is_multipart = True + break + + if is_multipart: + body, content_type = self.multipart_encode(fields) + + else: + body, content_type = self.form_url_encode(fields) + + return body, content_type + + def form_url_encode(self, fields): + data = "&".join("%s=%s" % (name, value) + for name, value in fields.items()).encode() + return data, 'application/x-www-form-urlencoded' + + def multipart_encode(self, fields): + boundary = binascii.hexlify(os.urandom(16)).decode('ascii') + + body = '' + + for field, value in fields.items(): + filename = '' + datatype = '' + + if isinstance(value, dict): + datatype = 'text/plain' + filename = value['filename'] + + if value.get('type'): + datatype = value['type'] + + if not isinstance(value['data'], io.IOBase): + self.fail('multipart encoding of file requires a stream.') + + data = value['data'].read() + + elif isinstance(value, str): + data = value + + else: + self.fail('multipart requires a string or stream data') + + body += ( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"" + ) % (boundary, field) + + if filename != '': + body += "; filename=\"%s\"" % filename + + body += "\r\n" + + if datatype != '': + body += "Content-Type: %s\r\n" % datatype + + body += "\r\n%s\r\n" % data + + body += "--%s--\r\n" % boundary + + return body.encode(), "multipart/form-data; boundary=%s" % boundary |