Skip to content

Commit

Permalink
multipart with triple quotes (#159)
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric05 authored Dec 22, 2022
1 parent e711a2f commit dc8161d
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 84 deletions.
6 changes: 5 additions & 1 deletion dothttp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion dothttp/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.42.a5'
__version__ = '0.0.42.a6'
4 changes: 2 additions & 2 deletions dothttp/http.tx
Original file line number Diff line number Diff line change
Expand Up @@ -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)?)?
)
;

Expand Down
5 changes: 5 additions & 0 deletions test/core/payload/multipartfiles4.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
POST "https://httpbin.org/post"
files(
"resume" < "something else",
"content2"< """this is text part"""
)
237 changes: 157 additions & 80 deletions test/core/test_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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")
Expand All @@ -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):
Expand All @@ -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")

Expand Down Expand Up @@ -152,71 +186,114 @@ 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)
test = b"test"
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)
except:
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'})
self.assertEqual(resp['form'], {'content2': 'this is text part'})

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)

0 comments on commit dc8161d

Please sign in to comment.