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.
Related
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?
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--
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?
The Zend\Mvc\Controller\AbstractRestfulController#requestHasContentType(...) checks the content using $request->getHeaders()->get('content-type');.
Now I'm sending a cURL request like this:
# curl -i http://project.dev/seminars/1 -H 'Accept: allication/xml'
HTTP/1.1 200 OK
Date: Fri, 14 Jun 2013 16:06:33 GMT
Server: Apache/2.2.16 (Debian)
X-Powered-By: PHP/5.3.3-7+squeeze15
Vary: Accept-Encoding
Content-Length: 1108
Content-Type: text/html
So, the content type is text/html. But the output, I'm getting is false:
$test = $this->getRequest()->getHeaders()->get('content-type');
var_dump($test);
// output: bool(false)
What I'm doing wrongly and how should I do, in order to get the contetn type of the REST request?
My bad -- I was expecting the Accept value from $request->getHeaders()->get('content-type'). Instead of it I should use $this->getRequest()->getHeaders()->get('Accept').
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 --.