Jmeter post multipart form data with string - spring-boot

I am trying to upload file with string in JMeter. It doesn't work
POST http://localhost:8080/upload
POST data:
--v2IM1VsVLV5EbtspRzGOSrHaDQb-mlef6r
Content-Disposition: form-data; name="input"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
{ "name": "John", "country": "US" }
--v2IM1VsVLV5EbtspRzGOSrHaDQb-mlef6r
Content-Disposition: form-data; name="file"; filename="sample.txt"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
<actual file content, not shown here>
--v2IM1VsVLV5EbtspRzGOSrHaDQb-mlef6r--
[no cookies]
I got the following error using JMeter
{"code":"ERROR","message":"Required request parameter 'input' for method parameter type String is not present"}
I am able to hit the request using curl or Postman without any issues. Here is my curl request.
curl -i -X POST \
-H "Content-Type:multipart/form-data" \
-F "file=#\"./sample.txt\";type=text/plain;filename=\"sample.txt\"" \
-F "input={ \"name\": \"John\", \"country\": "US" }" \
'http://localhost:8080/upload'

If you're able to execute the request successfully using Postman you should be able to record the request using JMeter's HTTP(S) Test Script Recorder
Start the HTTP(S) Test Script Recorder
Configure Postman to use JMeter as the proxy
Copy the sample.txt file to "bin" folder of your JMeter installation
Run your request in Postman
JMeter will capture the request and generated proper HTTP Request sampler
More information: How to Convert Your Postman API Tests to JMeter for Scaling

Related

Adapt multipart/form-data request to curl with image and json in the same request

I need to rewrite this curl request extracted from the browser to execute it from bash, it is a multipart/form-data that combines the upload of an image together with a json in the same request, I have carried out several tests substituting the raw data for two -F but the server responds with error.
What would be the correct way?
I also fail to understand the key that is next to WebKitFormBoundary is a value that seems random, is it just a separator? can i use anything?
I have removed the headers that I considered irrelevant
curl 'https://localhost' \
-H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXXXXXXXXXXXXXXXX'
-H 'Accept: */*' \
--data-raw $'------WebKitFormBoundaryXXXXXXXXXXXXXXXX\r\nContent-Disposition: form-data; name="image"; filename="image.jpg"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundaryXXXXXXXXXXXXXXXX\r\nContent-Disposition: form-data; name="item"; filename="blob"\r\nContent-Type: application/json\r\n\r\n{"item1":"xxxx","item2":"yyyy"}\r\n------WebKitFormBoundaryXXXXXXXXXXXXXXXX--\r\n' \
Thanks
I also fail to understand the key that is next to WebKitFormBoundary is a value that seems random, is it just a separator? can i use anything?
yes and yes and practically speaking yes. it's supposed to be a random-guaranteed-unique string used as separator to signal start and end of forms.. if you know beforehand that none of your uploads contains the string stackoverflow, you could use Content-Type: multipart/form-data; boundary=stackoverflow for example (but this may break if you upload a file actually containing the string stackoverflow !), but you should let curl generate that string automatically, rather than specifying it yourself, curl will auto-generate a string that is practically guaranteed to be unique.
I have removed the headers that I considered irrelevant
... if you guessed wrong, the server may give you an error for missing a required header. assuimg that you didn't make any mistakes in removing irrelevant headers though, i think it's
curl 'https://localhost'\
--form "image=#image.jpg;type=image/jpeg"\
--form "item=#blob;type=application/json"
the request generated by that command is roghly:
POST / HTTP/1.1
Host: localhost
User-Agent: curl/7.81.0
Accept: */*
Content-Length: 359
Content-Type: multipart/form-data; boundary=------------------------7d0262831ce8f248
--------------------------7d0262831ce8f248
Content-Disposition: form-data; name="image"; filename="image.jpg"
Content-Type: image/jpeg
image.jpg content
--------------------------7d0262831ce8f248
Content-Disposition: form-data; name="item"; filename="blob"
Content-Type: application/json
["json lol"]
--------------------------7d0262831ce8f248--
as you can see above, Accept: */* is curl's default accept-header anyway, so there's no need to specify it, and curl auto-generated the boundary ------------------------7d0262831ce8f248 so there's no need to manually specify a boundary either.

How can I send multipart/form-data in JMeter

I want to send request payload as following in JMeter:
------WebKitFormBoundaryeBikRH0JCrgmtTvt
Content-Disposition: form-data; name="name"
test
------WebKitFormBoundaryeBikRH0JCrgmtTvt
Content-Disposition: form-data; name="description"
testing
------WebKitFormBoundaryeBikRH0JCrgmtTvt
Content-Disposition: form-data; name="configFile"; filename="test.json"
Content-Type: application/json
------WebKitFormBoundaryeBikRH0JCrgmtTvt--
So I tried to add the name and description part in Parameters tab with form-data as Content-type and added file in Files Upload tab in HTTP Request Sampler.
This is what I am getting in Request Body after execution:
POST data:
--t9u984dDyYVtn6R0e8-OiZQyWRv9gk1
Content-Disposition: form-data; name="name"
Content-Type: form-data; charset=US-ASCII
Content-Transfer-Encoding: 8bit
test
--t9u984dDyYVtn6R0e8-OiZQyWRv9gk1
Content-Disposition: form-data; name="description"
Content-Type: form-data; charset=US-ASCII
Content-Transfer-Encoding: 8bit
testing
--t9u984dDyYVtn6R0e8-OiZQyWRv9gk1
Content-Disposition: form-data; name="configFile"; filename="test.json"
Content-Type: application/json
Content-Transfer-Encoding: binary
<actual file content, not shown here>
--t9u984dDyYVtn6R0e8-OiZQyWRv9gk1--
I want to remove this part from the request for name and description part
Content-Type: form-data; charset=US-ASCII
Content-Transfer-Encoding: 8bit
This is resulting into failure with status code : 415
Need help on this please
If standard multipart HTTP Request generated by JMeter's HTTP Request sampler when you tick Use multipart/form-data box doesn't work for you be aware that you can manually build the HTTP Request by using:
HTTP Header Manager to set Content-Type header containing the boundary
__FileToString() function to load the contents of your .json file into the request body
Check Testing REST API File Uploads in JMeter for more comprehensive explanation and detailed example

Can't send a Jmeter request with graphql, 400 response using valid URL

From what I've read on https://graphql.org/learn/serving-over-http/ and Performance test for graphQL API, I can send a graphQL request over jmeter.
In the stack overflow example, a graphQL server was built with Apollo and then queried via Jmeter. I am just trying to do load testing and not build schemas or data sets, so I don't have Apollo on my local machine, and I'm also not sure that I would be testing the QA environment if I did try to do this all locally.
I can access our graphQL at https://proprietary-website/graphql/gql and if I run the following query, it returns the expected results:
query currentUserProfile {
currentUserProfile {
id
}
}
Now, I try to apply that to jmeter
I create a HTTP Request in my thread group with protocol: https, server name: proprietary-website, method: GET, path: /graphql/gql
I create an HTTP Header Manager and include the required Bearer Token and Content-Type headers
I create a listener to View Results Tree
Then I run a jmeter load test with 500 threads
I see the valid URL passed in the request body:
GET https://proprietary-website/graphql/gql
GET data:
{"query":{"currentUserProfile {id}"}}
[no cookies]
but I get back:
HTTP/1.0 400 Bad Request
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Content-Length: 1555
Date: Thu, 12 Dec 2019 16:40:26 GMT
I am new to graphql, am I not allowed to send Jmeter requests to the URL my dev gave me and do I have to use the apollo server? If so, can someone point me to some examples?
I am on Windows 10
I also tried:
k6, but this requires docker and i have no admin rights on my computer
easygraphql-lt but when I ran a test script with #easygraphql-lt, I got dependency errors that I don't quite understand how to fix
I looked at easygraphql-load-tester, but this would require me to have access to the project but all i have is the website. I don't have a graphQL.js or an index.js to reference
UPDATE: I just saw that I can copy the query as a curl request so I pasted that request in command line and it gave me extra headers that I put in my jmeter HTTP Header manager:
$ curl 'https://proprietary-website/graphql/gql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: https://proprietary-website' -H 'Authorization: Bearer redacted' --data-binary '{"query":" query currentUserProfile { currentUserProfile { id }}"}'
But I still get a 400 back, so I think I need to send the query differently as it is showing appended as a --data-binary (not sure what that means). I tried some other SO suggestions, no luck so far
I also tried against an app out of the O'Reilly graphql book, snowtooth.herokuapp.com. This was simpler, so the curl request was simpler, and the information I pasted into jmeter was less, but I still got the error: GET query missing using Protocol: HTTP, server name: snowtooth.herokuapp.com, method: GET and Body Data: {"query":"query { allLifts { name}}"}, plus all the requisite headers in the Header Manager
Not sure what your proprietary website implementation is, however this http://snowtooth.herokuapp.com/ can be tested like:
HTTP GET request:
HTTP POST request:
Also be aware that since JMeter 5.1 it's possible to create a JMeter test plan from CURL command, this http://snowtooth.herokuapp.com/ gives me the following CURL command:
curl 'http://snowtooth.herokuapp.com/' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: http://snowtooth.herokuapp.com' --data-binary '{"query":"{allLifts{name}}"}' --compressed
And when I import it to JMeter I can execute the requests successfully:

Load testing server with http multipart/related request which contains audio content

We built a server which handles speech recorded by user using an app. The audio data is sent through http post in real time. The body looks like this:
--BOUNDARY
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset="UTF-8"
<JSON FORMATTED METADATA HERE>
--BOUNDARY
Content-Disposition: form-data; name="audio"
Content-Type: application/octet-stream
<AUDIO BYTES HERE>
--BOUNDARY--
Now, I need to do load testing for the server. I am thinking of using ApacheBench and just do consistent uploading requests but I wish to use the same format as above for each request. How could that be setup in AB?
I was able to solve the problem by using the following command:
ab -p test -T "multipart/form-data; boundary=BOUNDARY" -c 1000 -n 1000 -l http://someipaddress.com/
where test is a file containing the post content.

Is it possible to send RingCentral SMS / MMS using multipart/form-data?

The OpenAPI spec for the Create SMS Message endpoint includes the following request content types:
consumes:
- application/json
- multipart/mixed
- multipart/form-data
https://netstorage.ringcentral.com/dpw/api-reference/specs/rc-platform.yml?v=2019082420190816-0828
I found the SMS / MMS instructions to include a multipart/mixed example in the API Reference, but don't see any information on using multipart/form-data. I'm specifically interested in sending files.
https://developers.ringcentral.com/api-reference/SMS/createSMSMessage
The same API Reference shows support for both multipart/form-data and multipart/mixed for sending faxes.
https://developers.ringcentral.com/api-reference/Fax/createFaxMessage
Since both APIs send files and metadata so I'm wondering if the SMS API also supports multipart/form-data and, if so, how to send it?
No, it does not appear so.
The example you'd linked for the SMS message uses multipart/mixed to separate the API call itself (which is in turn sent as application/json) from the payload being sent as an MMS (image/png).
The use of multipart/form-data in the fax API is specific to the way that particular metadata is included, but there isn't an equivalent system for SMS/MMS as they both need that particular meta information encoded either as a single JSON document or as the JSON element of a multipart/mixed message.
To send a file, though, multipart/mixed is fine. Your request would then be something like:
POST /restapi/v1.0/account/403391985008/extension/403391985008/sms
Content-Type: multipart/mixed; boundary=Boundary_1_14413901_1361871080888
--Boundary_1_14413901_1361871080888
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{"to" :[{"phoneNumber": "+18772004569"},{"phoneNumber": "+18772094569"}],
"text" :"hello",
"from" :{"phoneNumber": "+18882004237"}}
--Boundary_1_14413901_1361871080888
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="filename.zip"
[Some encoded binary stream here ...]
--Boundary_1_14413901_1361871080888--
It'd be up to you to set the file's mime type properly and ensure things are encoded. The key points here are that the message information is encoded in the first JSON component in your multipart message, while the file attached to the MMS is encoded in the second.
multipart/form-data can be sent as shown in the following example:
POST / HTTP/1.1
HOST: platform.ringcentral.com/restapi/v1.0/account/~/extension/~/sms
Authorization: Bearer <MyToken>
Content-Type: multipart/form-data; boundary=12345
--12345
Content-Disposition: form-data; name="to"
+16505550101
--12345
Content-Disposition: form-data; name="to"
+16505550102
--12345
Content-Disposition: form-data; name="from"
+16505550100
--12345
Content-Disposition: form-data; name="text"
Hello World
--12345
Content-Disposition: form-data; name="attachment" filename="picture.jpg"
content of picture.jpg ...
--12345--
This can be done using curl as follows:
curl -XPOST https://platform.ringcentral.com/restapi/v1.0/account/~/extension/~/sms \
-H 'Authorization: Bearer <MyToken>' \
-F 'to=+16505550101' \
-F 'to=+16505550102' \
-F 'from=+16505550100' \
-F 'text=Hello World' \
-F 'attachment=#picture.jpg'

Resources