Multipart - How to test api of uploading a file and json data in jmeter

2.2k Views Asked by At

I have a difficulty of upload file(e.g. Upload.txt) and JSON data in Jmeter.

HTTP Header Manager

Request in View Result Tree

POST http://localhost:8080/xxxx/custom/uploaddocument

POST data:
--jmeter_is_great
Content-Type: application/json; charset=UTF-8
{
 "Document": {
  "documentName": "TEST.txt",
  "fullPath": "Test",
  "priority": "M",
  "referenceNo": "Ref12345",
  "descrption": "Testfile",
  "userDef1": "",
  "userDef2": "",
  "userDef3": "",
  "userDef4": "",
  "userDef5": "",
  "userDef6": "",
  "userDef7": "",
  "userDef8": "",
  "userDef9": "",
  "userDef10": "",
  "profile": {
   "id": -2,
   "index": [{
    "id": -7,
    "value": "Signature",
    "type": "D"
   }]
  },
  "ACL": {
   "isInherit": false,
   "permission": [{
    "permissionType": "U",
    "userID": 10001,
    "groupID": "",
    "roleID": "",
    "permissionString": "ROPKFIAENTCMDHZVWGLUSB",
    "mustFlag": false
   }]
  }
 }
}

--jmeter_is_great
Content-Type: text-plain

THIS IS TESTING FILE CONTENT

--jmeter_is_great--


[no cookies]

Request Headers:
Connection: keep-alive
Content-Length: 876
Content-Type: multipart/related; boundary=jmeter_is_great

Response Data

HTTP Status 415 - Unsupported Media Type

Actually, There is a part JSON inside the Document as below:

    "content": {
   "binary": [80, 97, 114, 97, 68, 77, 32, 84, 69, 83, 84, 32, 102, 105, 108, 101]
}

I have tried request header as follow and then send the whole JSON with "Content" to api:

[HTTP header] Authorization: YXBpYWRtaW46cGFzc3dvcmQ= Content-Type: application/json

However, HTTP 415 response error also be thrown.

Some article with simular issue I have read: Testing REST API File Uploads in JMeter

Look forward for any insight!

2

There are 2 best solutions below

1
On
  1. Your Authorization header seems to be malformed, to wit:

    • It should start with the capital A
    • My expectation is that it's should look like Basic YXBpYWRtaW46cGFzc3dvcmQ=

    Be aware that the better way of bypassing basic HTTP authentication in JMeter is using HTTP Authorization Manager configured like:

    • Base URL: http://localhost:8080/xxxx/
    • Username: apiadmin
    • Password: password
  2. Your Content-Type header is also not correct, you're using wrong boundary, i.e. in the HTTP Header Manager you have andytest and in request body there is jmeter_is_great and they must match.

  3. Assuming above 2 points I think I should warn you that when you're building a request manually any violation of the protocol standard (even extra or missing empty line or a character in lower case) will ruin your request

  4. The referred article assumes using Google Drive API for demo purposes, your application might work differently so you may have to reconsider the whole approach. Try recording your file upload (make sure to copy TEST.txt file to JMeter's "bin" folder) using HTTP(S) Test Script Recorder to see how does generated request look like as you might be going in a wrong direction.

  5. Don't run JMeter and the system under test on the same physical (or virtual) machine as they will be struggling for resources like CPU and RAM therefore you will not get accurate and reliable results.
0
On

I finally found the solution and hope the answer could help anyone facing the similar issue.

First, "HTTP Status 415 - Unsupported Media Type", if this error is thrown, which is highly possibility about incorrect Content-Type.

So, my approach is to try every possible Content-Type of HTTP Request Header, and I found that the error Code changes from 415 to 500 when Content-Type set to multipart/form-data.

Then, I have a insight from an useful link about file upload in https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2#file-upload

I changed my request body as below:

--boundary
Content-Disposition: form-data; name="documentJsonStr"
Content-Type: text/plain; charset=UTF-8

${myvar2}

--boundary
Content-Disposition: form-data; name="data"; filename="100MB.txt"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64

${__FileToString(100MB.txt,,)}

--boundary--

${myvar2} is set by BeanShell PreProcessor, which contains the Json request in string format. However, it might not be exactly same configuration depending on which parameter type the api accepts.

Hope this is useful.