Help, don't know what's wrong with my HTTP multipart POST - http

POST /upload HTTP/1.1
Host: assets.drop.io
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.10) Gecko/2
009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Length: 5728
Content-Type: multipart/form-data; boundary=--------MalolHCBdarysNYMHZbIvjbD
--------MalolHCBdarysNYMHZbIvjbD
Content-Disposition: form-data; name="api_key"
0b8a12109c3a1bfc4ba94aec926e1f9cfd8bb6f0
--------MalolHCBdarysNYMHZbIvjbD
Content-Disposition: form-data; name="drop_name"
4pgvoxc
--------MalolHCBdarysNYMHZbIvjbD
Content-Disposition: form-data; name="version"
2.0
--------MalolHCBdarysNYMHZbIvjbD
Content-Disposition: form-data; name="rachel"; filename="rachel"
Content-Type: application/octet-stream
BMv¶
--------MalolHCBdarysNYMHZbIvjbD--
The response I get is: Bad Request. And in the HTML of the response there is this:
:MultiPartParseError: bad content body:
'
----------MalolHCBdarysNYMHZbIvjbD' should == '----------MalolHCBdarysNYMHZbIvjbD
'></td></tr>

The answer is in your question. The response says that the divider should be '----------MalolHCBdarysNYMHZbIvjbD ' instead of ' ----------MalolHCBdarysNYMHZbIvjbD'
Look at the leading and trailing spaces.

The schematic syntax of a multipart/form-data message is as follows:
Content-Type: multipart/form-data; boundary=boundary
--boundary
Content-Disposition: form-data; name="field 1"
data 1
--boundary
Content-Disposition: form-data; name="field 2"
data 2
⋮
--boundary
Content-Disposition: form-data; name="field N"
data N
--boundary--
So the inner part boundaries are --boundary (-- followed by the boundary value) and the last is --boundary-- (-- followed by the boundary value followed by --).
In your case you are just missing the leading --.

Related

HTTP Post multipart/form-data: Invalid Content-Disposition value

I am working on a HTTPS POST request which contains two multipart/form-data entries.
But for whatever reason I can't get it working.
This is the request I am sending:
POST /my/api/endpoint HTTP/1.0
Host: myserver.de
Content-Type: multipart/form-data; boundary=123456
Content-Length: 147
Connection: close
X-API-KEY: 123
--123456
Content-Disposition: form-data; name="edf"
EDF
--123456
Content-Disposition: form-data; name="parameters"
PARAMETERS
--123456--
What is not shown above that the string is null-terminated ('\0' after --123456--).
But the response I get is:
HTTP/1.1 400 Bad Request
Server: nginx/1.21.3
Date: Wed, 04 May 2022 06:35:34 GMT
Content-Type: application/json; charset=utf-8
Connection: close
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-0c7bdc085f3f2543aee5f677554f0568-3911d802790ef040-00","errors":{"":["Failed to read the request form. Form section has invalid Content-Disposition value: "]}}
Is someone able to determine what I am doing wrong here?
Edit:
If I remove the null termination I get
HTTP/1.1 400 Bad Request
Server: nginx/1.21.3
Date: Wed, 04 May 2022 06:44:43 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: close
122
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-504d94c952c60246b96667d6a8c2e690-d160644f50acf14a-00","errors":{"edf":["The EDF field is required."],"parameters":["The Parameters field is required."]}}
0
Do you notice the 122 and 0 numbers - where are they comming from?

Strange firefox bug triggers on reload

I noticed a bug in an old version of firefox, that was shipped with my os.
These were the sympthoms:
Guile web server failed to serve the request when data was reposted.
I came up with a minimal example to show the problem.
Steps to reproduce:
start the server script
load localhost:8080
select the test.csv file for upload, and upload it
hit the refresh button in the browser
answer yes to resend post data dialog.
test.scm:
(use-modules (web server)
(rnrs bytevectors))
(define (handler request body)
(if body
(display (utf8->string body)))
(values '((content-type . (text/html)))
(string-append "<html><body>"
"<form action=\"do\" method=\"POST\" enctype=\"multipart/form-dat\
a\">"
"<input type=\"file\" name=\"x\">"
"<input type=\"submit\">")))
(run-server handler)
test.csv:
a,b
Expected result: no error displayed on the console.
Actual result:
-----------------------------18912432064747206221264673165
Content-Disposition: form-data; name="x"; filename="test.csv"
Content-Type: text/csv
In ice-9/boot-9.scm:
841:4 4 (with-throw-handler _ _ _)
In web/server/http.scm:
127:28 3 (_)
In web/request.scm:
205:31 2 (read-request #<closed: file 5559bbcb82a0> _)
In web/http.scm:
1141:6 1 (read-request-line _)
In ice-9/boot-9.scm:
752:25 0 (dispatch-exception _ _ _)
Bad request: Bad Request-Line: "a,b"
What am I doing wrong here?
Some additional information:
on a whireshark capture it turns out, that the following is sent on resend:
POST /do HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: hu-HU,hu;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/do
Content-Type: multipart/form-data; boundary=---------------------------121791188820701943592108452984
Content-Length: 150
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
-----------------------------121791188820701943592108452984
Content-Disposition: form-data; name="x"; filename="test.csv"
Content-Type: text/csv
POST /do HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: hu-HU,hu;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/do
Content-Type: multipart/form-data; boundary=---------------------------121791188820701943592108452984
Content-Length: 150
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
-----------------------------121791188820701943592108452984
Content-Disposition: form-data; name="x"; filename="test.csv"
Content-Type: text/csv
a,b
-----------------------------121791188820701943592108452984--
I will check the http spec if it has anything to say about this. The first http request is partial, followed by a well formed request.
UPDATE:
It turned out that guile webserver threw the error completely legitimately.
Answering my own question:
This is actually this firfox bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=1434553
Fixed in firefox62.

sending different 'Content-Type' for each single input param one file and other data params

Is there any way to send each different 'Content-Type' in the multipart-form data for each single input param
e.g.
Content-Type: multipart/form-data;boundary=q235Ht2tTWJhuFmC8sJxbQ7YGU7FwQafcZd8B
Accept-Charset: utf-8
"Content-Disposition: form-data; name="creative_id"
"Content-Type: text/plain;charset=ISO-8859-1”
…
"Content-Disposition: form-data; name=“file_role""
"Content-Type: text/plain;charset=ISO-8859-1”
…
"Content-Disposition: form-data; name="Filename""
"Content-Type: text/plain;charset=ISO-8859-1
"Content-Disposition: form-data; name="file"; filename="advertise_A.png"
"Content-Type: image/x-png"
For the whole request, the header will be
Content-Type: multipart/form-data;
but for its params like creative_id and file_role,
I would like to send Content-Type: text/plain;charset=ISO-8859-1
and for the file itself Content-Type: image/x-png
I tried this in two ways, but it doesnt work:
headers = {'Content-Type':'text/plain;charset=ISO-8859-1'}
files = {'file': open(asset_file, 'rb')}
and then in POST (url, files=files, headers=headers, params=values)
OR
files = {'file1': (open(asset_file, 'rb'), 'image/x-png'), 'creative_id': (1727968, 'text/plain;charset=ISO-8859-1'), 'file_role': ('PRIMARY', 'text/plain;charset=ISO-8859-1')}
and then in POST (url, files=files)
You're really close with the second example. If you provide a dict with tuples as its value, the tuples have this form:
(filename, file object or content, [content type], [headers])
where the content type and headers fields are optional.
This means you want to do this:
files = {'file': ('advertise_A.png', open(asset_file, 'rb'), 'image/x-png'), 'creative_id': ('', '1727968', 'text/plain;charset=ISO-8859-1'), 'file_role': ('', 'PRIMARY', 'text/plain;charset=ISO-8859-1'), 'Filename': ('', 'advertise_A.png', 'text/plain;charset=ISO-8859-1')}
r = requests.post(url, files=files)
Doing the above with a file that contains only the string basic_test, I get the following result:
Content-Type: multipart/form-data; boundary=82c444831d6a450ba5c4ced2e1cc7866
--82c444831d6a450ba5c4ced2e1cc7866
Content-Disposition: form-data; name="creative_id"
Content-Type: text/plain;charset=ISO-8859-1
1727968
--82c444831d6a450ba5c4ced2e1cc7866
Content-Disposition: form-data; name="file_role"
Content-Type: text/plain;charset=ISO-8859-1
PRIMARY
--82c444831d6a450ba5c4ced2e1cc7866
Content-Disposition: form-data; name="file"; filename="advertise_A.png"
Content-Type: image/x-png
basic_test
--82c444831d6a450ba5c4ced2e1cc7866
Content-Disposition: form-data; name="Filename"
Content-Type: text/plain;charset=ISO-8859-1
advertise_A.png
--82c444831d6a450ba5c4ced2e1cc7866--

curl send file as post request

I have file with request data:
POST /exampleUrl HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 57907
Content-Type: multipart/form-data; boundary=--
Accept: */*
---
Content-Type: application/octet-stream
Content-Disposition: form-data; name='wanted'; filename=NameOfFile
Content-Transfer-Encoding: binary
[DATA]
---
Content-Type: application/octet-stream
Content-Disposition: form-data; filename=ID1
Content-Transfer-Encoding: binary
[DATA]
-----
How can i send it through curl as post request?

Calculating Content Length in multipart HTTP bodies

I am creating a HTTP POST message, and I have a dobut regarding the content length value.
Say my body is as shown below:
POST http://somelink HTTP/1.1
Date: Mon, 22 Feb 1857 12:27:07 GMT
Content-Length: 21797487
Content-Type: multipart/form-data; boundary=---------------------------boundary
-----------------------------boundary
Content-Type: text/plain
Content-Disposition: form-data; name="tid"
someid
-----------------------------boundary
Content-Type: image/jpeg
Content-Disposition: form-data; filename="image.jpeg"; name="File"
SomeRandomtext
-----------------------------boundary--
Should the content length include the \r\n after boundary-- or it should end at boundary--
From the protocol point of view, the payload type doesn't matter. The content length is the length of the message that follows the header block, that's it.

Resources