diff --git a/dothttp/__init__.py b/dothttp/__init__.py index d1938c6..1495db2 100644 --- a/dothttp/__init__.py +++ b/dothttp/__init__.py @@ -648,7 +648,11 @@ def _load_payload(self): elif files_wrap := self.http.payload.fileswrap: files = [] for multipart_file in files_wrap.files: - multipart_content = self.get_updated_content(multipart_file.path) + if multipart_file.path.triple: + multipart_file_path = multipart_file.path.triple[3:-3] + else: + multipart_file_path = multipart_file.path.str + multipart_content = self.get_updated_content(multipart_file_path) multipart_key = self.get_updated_content(multipart_file.name) mimetype = self.get_updated_content(multipart_file.type) if multipart_file.type else None if os.path.exists(multipart_content): # probably check valid path, then check for exists diff --git a/dothttp/__version__.py b/dothttp/__version__.py index 77e0d8f..2d614d8 100644 --- a/dothttp/__version__.py +++ b/dothttp/__version__.py @@ -1 +1 @@ -__version__ = '0.0.42.a5' +__version__ = '0.0.42.a6' diff --git a/dothttp/http.tx b/dothttp/http.tx index 8509cd5..3249906 100644 --- a/dothttp/http.tx +++ b/dothttp/http.tx @@ -136,8 +136,8 @@ FILES: FILETYPE: ( - '(' name=DotString ',' path=DotString (',' (type=DotString)?)? ')' - | name=DotString ('<' | ':') path=DotString (';' (type=DotString)?)? + '(' name=DotString ',' path=TRIPLE_OR_DOUBLE_STRING (',' (type=DotString)?)? ')' + | name=DotString ('<' | ':') path=TRIPLE_OR_DOUBLE_STRING (';' (type=DotString)?)? ) ; diff --git a/test/core/payload/multipartfiles4.http b/test/core/payload/multipartfiles4.http new file mode 100644 index 0000000..7e02e6a --- /dev/null +++ b/test/core/payload/multipartfiles4.http @@ -0,0 +1,5 @@ +POST "https://httpbin.org/post" +files( + "resume" < "something else", + "content2"< """this is text part""" +) \ No newline at end of file diff --git a/test/core/test_payload.py b/test/core/test_payload.py index 67c0178..b36ca62 100644 --- a/test/core/test_payload.py +++ b/test/core/test_payload.py @@ -13,6 +13,7 @@ class PayLoadTest(TestBase): + def test_json_payload(self): req = self.get_request(f"{base_dir}/jsonpayload.http") self.assertEqual("https://dothttp.azurewebsites.net/", req.url, @@ -27,44 +28,73 @@ def test_json_payload2(self): self.assertEqual("POST", req.method, "incorrect method") self.assertEqual( b'{"string": "simple", "list": ["dothttp", "azure"], "null": null, "bool": false, "bool2": true, "float": 1.121212, "float2": 1}', - req.body, - "incorrect method") + req.body, "incorrect method") def test_json_payload3(self): req = self.get_request(f"{base_dir}/jsonpayload3.http") self.assertEqual("https://dothttp.azurewebsites.net/", req.url, "incorrect url computed") self.assertEqual("POST", req.method, "incorrect method") - self.assertEqual({"menu": { - "header": "SVG Viewer", - "items": [ - {"id": "Open"}, - {"id": "OpenNew", "label": "Open New"}, - None, - {"id": "ZoomIn", "label": "Zoom In"}, - {"id": "ZoomOut", "label": "Zoom Out"}, - {"id": "OriginalView", "label": "Original View"}, - None, - {"id": "Quality"}, - {"id": "Pause"}, - {"id": "Mute"}, - None, - {"id": "Find", "label": "Find..."}, - {"id": "FindAgain", "label": "Find Again"}, - {"id": "Copy"}, - {"id": "CopyAgain", "label": "Copy Again"}, - {"id": "CopySVG", "label": "Copy SVG"}, - {"id": "ViewSVG", "label": "View SVG"}, - {"id": "ViewSource", "label": "View Source"}, - {"id": "SaveAs", "label": "Save As"}, - None, - {"id": "Help"}, - {"id": "About", "label": "About Adobe CVG Viewer..."} - ] - }}, json.loads(req.body), "json Payload parsed wrong") + self.assertEqual( + { + "menu": { + "header": + "SVG Viewer", + "items": [{ + "id": "Open" + }, { + "id": "OpenNew", + "label": "Open New" + }, None, { + "id": "ZoomIn", + "label": "Zoom In" + }, { + "id": "ZoomOut", + "label": "Zoom Out" + }, { + "id": "OriginalView", + "label": "Original View" + }, None, { + "id": "Quality" + }, { + "id": "Pause" + }, { + "id": "Mute" + }, None, { + "id": "Find", + "label": "Find..." + }, { + "id": "FindAgain", + "label": "Find Again" + }, { + "id": "Copy" + }, { + "id": "CopyAgain", + "label": "Copy Again" + }, { + "id": "CopySVG", + "label": "Copy SVG" + }, { + "id": "ViewSVG", + "label": "View SVG" + }, { + "id": "ViewSource", + "label": "View Source" + }, { + "id": "SaveAs", + "label": "Save As" + }, None, { + "id": "Help" + }, { + "id": "About", + "label": "About Adobe CVG Viewer..." + }] + } + }, json.loads(req.body), "json Payload parsed wrong") def test_root_array(self): - req = self.get_request(f"{base_dir}/jsonpayload4.http", target="root_array") + req = self.get_request(f"{base_dir}/jsonpayload4.http", + target="root_array") self.assertEqual("https://httpbin.org/post", req.url, "incorrect url computed") self.assertEqual("POST", req.method, "incorrect method") @@ -77,28 +107,31 @@ def test_json_payload_complex(self): self.assertEqual("https://dothttp.azurewebsites.net/", req.url, "incorrect url computed") self.assertEqual("POST", req.method, "incorrect method") - self.assertEqual({ - "glossary": { - "title": "example glossary", - "GlossDiv": { - "title": "S", - "GlossList": { - "GlossEntry": { - "ID": "SGML", - "SortAs": "SGML", - "GlossTerm": "Standard Generalized Markup Language", - "Acronym": "SGML", - "Abbrev": "ISO 8879:1986", - "GlossDef": { - "para": "A meta-markup language, used to create markup languages such as DocBook.", - "GlossSeeAlso": ["GML", "XML"] - }, - "GlossSee": "markup" + self.assertEqual( + { + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": + "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": + "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } } } } - } - }, json.loads(req.body), "json Payload parsed wrong") + }, json.loads(req.body), "json Payload parsed wrong") self.assertEqual('application/json', req.headers['content-type']) def test_payload(self): @@ -120,8 +153,9 @@ def test_smileys_or_special(self): def test_payload2(self): req = self.get_request(f"{base_dir}/payload2.http") - self.assertEqual("https://dothttp.azurewebsites.net/?key3=value3&key1=value1&key2=value2", req.url, - "incorrect url computed") + self.assertEqual( + "https://dothttp.azurewebsites.net/?key3=value3&key1=value1&key2=value2", + req.url, "incorrect url computed") self.assertEqual("POST", req.method, "incorrect method") self.assertEqual("{this is bad}", req.body, "incorrect method") @@ -152,7 +186,8 @@ def file_payload_test(self, param): def test_data_json_payload(self): req = self.get_request(f"{base_dir}/dataasformpayload.http") self.assertEqual("hi=prasanth", req.body) - self.assertEqual('application/x-www-form-urlencoded', req.headers.get("content-type")) + self.assertEqual('application/x-www-form-urlencoded', + req.headers.get("content-type")) def test_multipart_payload(self): loadfile = tempfile.NamedTemporaryFile(delete=False) @@ -160,17 +195,18 @@ def test_multipart_payload(self): loadfile.write(test) loadfile.flush() data = f"this is text part" - req = self.get_request(f"{base_dir}/multipartfiles.http", properties= - [f"filename={loadfile.name}", - f"data={data}" - ]) + req = self.get_request( + f"{base_dir}/multipartfiles.http", + properties=[f"filename={loadfile.name}", f"data={data}"]) self.assertIn(test, req.body) self.assertIn(data.encode("utf-8"), req.body) # including integration test here - self.func_multipart_syntax_test(f"{base_dir}/multipartfiles2.http", loadfile, data) - self.func_multipart_syntax_test(f"{base_dir}/multipartfiles3.http", loadfile, data) + self.func_multipart_syntax_test(f"{base_dir}/multipartfiles2.http", + loadfile, data) + self.func_multipart_syntax_test(f"{base_dir}/multipartfiles3.http", + loadfile, data) loadfile.close() try: os.unlink(loadfile.name) @@ -178,10 +214,8 @@ def test_multipart_payload(self): pass def func_multipart_syntax_test(self, param, loadfile, data): - req2 = self.get_request(param, properties= - [f"filename={loadfile.name}", - f"data={data}" - ]) + req2 = self.get_request( + param, properties=[f"filename={loadfile.name}", f"data={data}"]) resp = session.send(req2).json() self.assertEqual(resp['files'], {'resume': 'test'}) @@ -189,34 +223,77 @@ def func_multipart_syntax_test(self, param, loadfile, data): def test_data_multi_payload(self): req = self.get_request(f"{base_dir}/quoted.http") - self.assertEqual(""" + self.assertEqual( + """ "'this can have quotes with escape sequence'" """, req.body) + def test_data_multi_payload_triple(self): + req = self.get_req_comp(f"{base_dir}/multipartfiles4.http") + req.load_def() + self.assertEqual([("resume", (None, "something else", "text/plain")), + ("content2", + (None, "this is text part", "text/plain"))], + req.httpdef.payload.files) + def test_data_multi2_payload(self): req = self.get_request(f"{base_dir}/quoted2.http") - self.assertEqual(""" + self.assertEqual( + """ "'this can have quotes with escape sequence'" """, req.body) def test_multi_in_json_payload(self): - self.assertEqual(b'{"simple": "test"}', self.get_request(f"{base_dir}/multilinejson.http", target='1').body) - self.assertEqual(b'{"simple": "test"}', self.get_request(f"{base_dir}/multilinejson.http", target="2").body) - self.assertEqual(b'{"simple": "\\ntest\\n\\"simple 1\\"\\n\'simple 2\'\\n\'\'simple 3\'\'\\n' - b'\\"\\"simple 4\\"\\"\\n\\n"}', - self.get_request(f"{base_dir}/multilinejson.http", target="3").body) - self.assertEqual(b'{"simple": "\\ntest\\n\\"simple 1\\"\\n\'simple 2\'\\n\'\'simple 3\'\'\\n' - b'\\"\\"simple 4\\"\\"\\n\\n"}', - self.get_request(f"{base_dir}/multilinejson.http", target="4").body) + self.assertEqual( + b'{"simple": "test"}', + self.get_request(f"{base_dir}/multilinejson.http", + target='1').body) + self.assertEqual( + b'{"simple": "test"}', + self.get_request(f"{base_dir}/multilinejson.http", + target="2").body) + self.assertEqual( + b'{"simple": "\\ntest\\n\\"simple 1\\"\\n\'simple 2\'\\n\'\'simple 3\'\'\\n' + b'\\"\\"simple 4\\"\\"\\n\\n"}', + self.get_request(f"{base_dir}/multilinejson.http", + target="3").body) + self.assertEqual( + b'{"simple": "\\ntest\\n\\"simple 1\\"\\n\'simple 2\'\\n\'\'simple 3\'\'\\n' + b'\\"\\"simple 4\\"\\"\\n\\n"}', + self.get_request(f"{base_dir}/multilinejson.http", + target="4").body) def test_payload_with_breaks(self): - self.assertEqual("simple string", self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='1').body) - self.assertEqual("simple string", self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='2').body) - self.assertEqual("simple string", self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='3').body) - self.assertEqual("simple string", self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='4').body) - self.assertEqual("simple string", self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='5').body) - self.assertEqual("simple string", self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='6').body) - self.assertEqual('simple' ' triple' ' break' ' string', - self.get_request(f"{base_dir}/datapayloadwithbreaks.http", target='7').body) + self.assertEqual( + "simple string", + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='1').body) + self.assertEqual( + "simple string", + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='2').body) + self.assertEqual( + "simple string", + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='3').body) + self.assertEqual( + "simple string", + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='4').body) + self.assertEqual( + "simple string", + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='5').body) + self.assertEqual( + "simple string", + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='6').body) + self.assertEqual( + 'simple' + ' triple' + ' break' + ' string', + self.get_request(f"{base_dir}/datapayloadwithbreaks.http", + target='7').body)