JMeter Multipart JSON Request Form Data - jmeter

I am trying to construct a HTTP Request through JMeter that uses a multipart data body.
I have a HTTP Header Manager that has COntent-Type set to multipart/form-data; boundary=AaB03x. I selected 'Use multipart/form-data for POST'.
I then have a data body created as,
`-----------------------------AaB03x
Content-Type: application/json
Content-Disposition: form-data; name="part1"
{"jsonKey1": "JsonValue1" }
-----------------------------AaB03x
Content-Type: application/json
Content-Disposition: form-data; name="part2"
{
"jsonKey2": "JsonValue2"
}
-----------------------------AaB03x
Content-Type: application/octet-stream
Content-Disposition: form-data; name="part3"
File Content here!!!!
-----------------------------AaB03x`
When I run this, I see that the request doesnt send the body correctly, instead it just sends some random data as,
POST data:
--vKOghkU7riRQbaANmmGpMs7j9TxCTUp3S2T0vE--
And gives an error response of,
`{"errorMsg":"Unable read headers from MultipartStream.","messageCode":"UnableReadHeadersFromMultipartStream","httpStat us":"BAD_REQUEST","requestName":"RequestName"}`
My second question is:
the part3 of the request sends a file to upload. Can I pass the file path somehow?

Given you set your own boundary and build your request manually I believe you need to uncheck Use multipart/form-data for POST in the HTTP Request Sampler
If your file encoding isn't very "exotic" you can try using __FileToString() function just instead of File Content here!!!!.
Looking into RFC 7578, it seems you also need a trailing -- at the end of the last line

You should try sending your JSON data as parameters. Also put your file path in the section for that... And even some servers don't actually need MIME type explicitly declared, you can check yours with some online tool like this one.
Your HTTP Request could look smethnig like:

Related

POST a JSON and a CSV in a multipart/form-data request through a NiFi 1.15 InvokeHTTP processor

I'm working on a NiFi 1.15 flow where I have to send a request to a service that requires 2 pieces of form-data sent in a POST request as a multipart/form-data. The first part is a simple JSON object with a few parameters, while the second part is a CSV file. Here is an example of what I am trying to achieve.
Content-Type: multipart/form-data; boundary=1cf28ed799fe4325b8cd0637a67dc612
--1cf28ed799fe4325b8cd0637a67dc612
Content-Disposition: form-data; name="json"; filename="json"
{"Param1": "Value1","Param2": "Value2","Param3": true}
--1cf28ed799fe4325b8cd0637a67dc612
Content-Disposition: form-data; name="file"; filename="body.csv"
Field1,Field2,Field3,Field4,Field5
VALUE_FIELD_1,VALUE_FIELD_2,VALUE_FIELD_3,"Some value for field 4",VALUE_FIELD_5
--1cf28ed799fe4325b8cd0637a67dc612--
Another acceptable output would have the Content-Disposition lines empty.
Due to a few restrictions in the environment I am working on, I am not allowed to use scripting processors, such as ExecuteGroovyScript as suggested in another SO question.
Instead, I started creating a GenerateFlowFile -> InvokeHTTP flow. The GenerateFlowFile would output to a flow file a text similar to the one mentioned above. Here is the screenshot of the GenerateFlowFile.
The connected InvokeHTTP processor is configured to use the POST Http Method and to send headers (the Authorization header in my case) and Send Message Body is set to true. It also extracts the Content-Type from the flow file previsously generated attribute through a ${mime.type} function. You can see the details in the following screenshots.
Sadly, this does not work. The server responds with an "Unexpected end of MIME multipart stream. MIME multipart message is not complete." error.
After searching for a while in SO, I found another question describing what looks like a similar problem, but there they are getting a different error and is also posting parameters through a different method.
I am also aware about the blog post from Otto Fowler where he shows how InvokeHTTP supports POSTs with multipart/form-data. I did try this approach too, but did not manage to get it working. The service throws an error stating that NiFi does not send one of my post:form:parts.
Right now I am stuck and am not able to send that data. I did manage to write a simple Python script to test if the server is working properly and it is. For reference, here is the script:
import requests
server = 'https://targetserver.com'
#Authentication
result = requests.post(server + '/authentication',
{'grant_type': 'password',
'username': 'username',
'password': 'password'})
token = result.json()['access_token']
#Build the request
headers = {'Authorization': 'bearer ' + token}
json_data = '{"Param1": "Value1","Param2": "Value2","Param3": true}'
# First the JSON then the csv file.
files = {'json': json_data,
'file': open('body.csv', 'rb')}
result = requests.post(server + '/endpoint', headers = headers, files = files)
print(result.text)
Does anyone have a suggestion on how to get around this situation?

Nifi/Minifi: How to read multipart/form-data request

I'm using HandleHttpRequest processor to receive a request with Content-Type: multipart/form-data. The request contains a text param and a file (Content-Type: image/jpeg). How can I read this parameters, and put them into attributes?

Jmeter parameterization for content of the file uploaded

I'm trying to parameterize content of the file uploaded through CSV Data Set Config
But file not picking the variables values ( can see the data of csv file in request but the uploaded file not updated with the number) Showing the request like this
**
POST data:
--3TJ-KduX0_gdJ3BvxwP97-p3PBN0Jki-2P7Iyvd
Content-Disposition: form-data; name="SO"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
403331689
--3TJ-KduX0_gdJ3BvxwP97-p3PBN0Jki-2P7Iyvd
Content-Disposition: form-data; name="sourceFile"; filename="SO_perf_test_porfornmance.xml"
Content-Type: text/xml
Content-Transfer-Encoding: binary
**
If you're sending the file via "Files Upload" tab of the HTTP Request sampler like this:
JMeter doesn't evaluate any Functions or Variables which are inside the file, it sends the file "as it is".
One of the solutions would be using a temporary file like SO_perf_test_porfornmance_modified.xml in the HTTP Request sampler and the content of this file can be modified "on-the-fly" using JSR223 PreProcessor like:
Add JSR223 PreProcessor as a child of the HTTP Request sampler which uploads tile
Put the following expression into "Parameters" section:
${__eval(${__FileToString(SO_perf_test_porfornmance.xml,,)})}
where:
__FileToString() function reads the content of the SO_perf_test_porfornmance.xml into memory
__eval() function resolves all the functions and variables in it
Check out Here’s What to Do to Combine Multiple JMeter Variables article if you need more detailed explanation.
Put the following code into "Script" area:
new File('SO_perf_test_porfornmance_modified.xml').text = Parameters
Configure your HTTP Request sampler to send SO_perf_test_porfornmance_modified.xml file instead of the SO_perf_test_porfornmance.xml
That's it, JMeter will now be sending the new file which contains all the nested functions and/or variables resolved to their respective values

Can Content-Disposition filename be used for text fields in multipart forms with Spring Webclient?

Working with the Service-Now API (for example) requires the request to provide the following:
POST /api/now/attachment/upload HTTP/1.1
Host: somehost.testenv.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MadHyZrFTrZu0gW
cache-control: no-cache
Content-Disposition: form-data; name="table_name"
some_table
Content-Disposition: form-data; name="table_sys_id"
82c9aca7kljasdfkljhasdfec8dfdb61d961920
Content-Disposition: form-data; name="uploadFile"; filename="undefined"
Content-Type: file
------WebKitFormBoundary7MA4YWxkTrZu0gW—
The above is generated from using Postman and providing form-data key value pairs.
However, based off the abstract of the RFC that defines Content-Disposition: https://www.rfc-editor.org/rfc/rfc2183.
Two values for this
header field are described in this memo; one for the ordinary linear
presentation of the body part, and another to facilitate the use of
mail to transfer files.
The Content-Disposition class used in Spring Webflux (https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/ContentDisposition.html) contains only an internal field for "filename" that is a string.
Is the ContentDisposition class in org.springframework.http missing a component as per RFC-2183 regarding a standard value (ordinary linear presentation of the body part)?
The HTTP request that is generated by the spring code automagically is as follows:
POST /api/now/attachment/upload HTTP/1.1
user-agent: ReactorNetty/0.7.9.RELEASE
transfer-encoding: chunked
host: somehost.testenv.com
accept: */*
accept-encoding: gzip
Content-Type: multipart/form-data;boundary=o-0JsSvUdGo98NDHJSWTwjvgzlRSXsmJ98-pWQ;charset=UTF-8
This is the source code that generates the above HTTP request:
MultipartBodyBuilder mbuilder = new MultipartBodyBuilder();
mbuilder.part("table_name", snConfig.getChangeRecordTableName());
mbuilder.part("table_sys_id", result.get(0).getSysId());
mbuilder.part("uploadFile", someFile);
return client.post()
.uri(snConfig.getEndpointAttachmentUpload())
.contentType(MediaType.MULTIPART_FORM_DATA)
.syncBody(mbuilder.build())
.retrieve()
.bodyToMono(AttachmentUploadResult.class);
It looks like the code is storing all of the MultipartBodyBuilder components into a single multipart/form-data, which is not the same format as the working HTTP Request.
However, even by manually providing the Content-Disposition headers, one can only create a name/value pair where the value is the "filename".
Is Content-Disposition missing functionality? Is this possible with WebClient?
Looks like this isn't supported within WebClient after digging on this for a long while.

Getting Jmeter to generate the boundary dashes in the Content-Type header (eg boundary=--V0a4bfux...)

This what my HTTP request is generating
Content-Type: multipart/form-data; boundary=V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp; charset=UTF-8
However, when compared to the POST data, it is lacking the 2 dashes in the front, which causes the server to reject the request:
--V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp
Content-Disposition: form-data; data="dataToBeSent"
--V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp--
How do I get Jmeter to generate the dashes in the header?
(besides from manually creating the multipart form)
Note:
I am using the 'Use multipart/formdata for POST' option.
If I intercept the request and manually add the dashes in the header, the
server accepts the request.
You don't need to generate these values, the solution is to tick Use multipart/form-data for POST box in the HTTP Request sampler (or in the HTTP Request Defaults)
If you have any definition of Content-Type header in the HTTP Header Manager - you need to remove it and let JMeter generate appropriate Content-Type header on its own.
The header doesn't need the dashes. This is simply how multipart/form-data works. The body is built as follows:
--<boundary>
<headers>
<content>
--<boundary>
<headers>
<content>
--<boundary>--
The -- part indicates a new part starts. The body ends with ---- to indicate no new parts will follow.

Resources