jMeter multipart request with file upload
Asked Answered
H

4

7

I have a multipart request that I construct. Each part of the request is a jsonString body and it has a set of headers for the whole request and some for individual multiaprts.

I can use jMeter's 'Send parameters with request' to add Name-value for the jsonStrings, but I cannot specify headers within each of these parts. I can specify a header manager for the entire request, but can it be specified for each of the multiparts as well?

Also, while specifying the content to upload, I have a file whose contents are compressed and encoded into bytes by a JSR223 Sampler and I would want this to be sent along with the request.

Hide answered 17/8, 2016 at 22:10 Comment(0)
M
12

You can build the request manually, just take the following steps:

  1. Uncheck Use multipart/form-data for HTTP POST box in the HTTP Request Sampler
  2. Add HTTP Header Manager as a child of the HTTP Request Sampler and configure it to send Content-Type header with the value of multipart/form-data; boundary=your_custom_boundary
  3. Switch to "Body Data" tab of the HTTP Request Sampler and construct your request body there separating each parameter set with

    --your_custom_boundary
    

See Testing REST API File Uploads in JMeter guide for a little bit more detailed explanation and demo.

Mullens answered 18/8, 2016 at 14:10 Comment(3)
@Dimitri My data part of the request is a byte array of the file after it was compressed and stuff. I want to stream this byte array directly to the MultipartStream instead of adding it as part of the request body. IS that possible?Hide
Also, in your link you mentioned I could use Raw HTTP Request, but does it support https requests?Hide
Testing REST API File Uploads in JMeter link is down. Could you provide an example?Look
M
6

For anyone who's struggling with create multipart form data with JMeter. Here's an working example for me (Try copy paste my code):

  • Uncheck Use multipart-form-data
  • Paste this to Body data:
--AaB03x
content-disposition: form-data; name="name"

My name is James
--AaB03x
content-disposition: form-data; name="age"

24
--AaB03x
content-disposition: form-data; name="image"; filename="avatar.png"
Content-Type: image/png
Content-Transfer-Encoding: binary

$binarydata
--AaB03x--
  • Then in HTTP Header Manger, create a row with name is Content-type and value is multipart/form-data; boundary=AaB03x
  • Click Run to test

Note: as you can see above I fix the boundary with value AaB03x, in real case you should use an unique value

Maritzamariupol answered 21/8, 2020 at 2:36 Comment(3)
Hi Duc, how would the binary data be referenced from a file for the last part (.png file part)?Odle
Hi @Gopi, you can use StringFromFileMaritzamariupol
where to put this function?Tanker
C
1

As far as I can understand this issue. You need to send a request with separate headers for multipart data.

In this case, I would suggest you send the request via the client which you use to do so and then intercept the request using Fiddler or JMeter itself.

I never came across this scenario in the past. The above solutions won't work as the intended use is different.

Contortive answered 21/8, 2020 at 12:46 Comment(0)
S
0
import org.apache.http.HttpHeaders
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.ContentType
import org.apache.http.entity.mime.HttpMultipartMode
import org.apache.http.entity.mime.MultipartEntityBuilder
import org.apache.http.impl.client.HttpClients
import org.apache.http.message.BasicHeader
import org.apache.http.entity.mime.content.FileBody
import org.apache.http.entity.mime.content.StringBody
import org.apache.http.entity.mime.FormBodyPart
import org.apache.http.entity.mime.FormBodyPartBuilder
import org.apache.commons.codec.digest.DigestUtils
import org.apache.commons.io.FileUtils
import org.apache.http.util.EntityUtils


//String archiveFileName1='C:\\Users\\Yakov.Danilchuk\\Downloads\\export.zip';
String archiveFileName= vars.get("import_folder_svodki") + vars.get("import_subfolder_svodki") + "export.zip";

String urlRequest='http://' + '${host_svodki}' + ':8080' + '/web-api/synchronization/import-from-lower-level';

def postRequest = new HttpPost(urlRequest);
def file = new File(archiveFileName);
def builder = MultipartEntityBuilder.create();
def hashCode = DigestUtils.sha256Hex(FileUtils.readFileToByteArray(file))

FormBodyPart jsonPart = FormBodyPartBuilder.create().addField("Content-Disposition", "form-data;name=packageInfo").setBody(new StringBody(vars.get("jsonPart"), ContentType.APPLICATION_JSON)).setName("packageInfo").build();

FormBodyPart bodyFilePart = FormBodyPartBuilder.create().addField("Content-Disposition", "form-data;filename=export.zip").setBody(new FileBody(file, ContentType.TEXT_PLAIN)).setName("export.zip").build(); 

FormBodyPart hashPart = FormBodyPartBuilder.create().addField("Content-Disposition", "form-data;name=packageHash").setBody(new StringBody(hashCode, ContentType.APPLICATION_JSON)).setName("packageHash").build();

//builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//builder.addBinaryBody("filename", file, ContentType.DEFAULT_BINARY, archiveFileName);
def entity = builder.setBoundary(vars.get("boundary")).addPart(jsonPart).setBoundary(vars.get("boundary")).addPart(bodyFilePart).setBoundary(vars.get("boundary")).addPart(hashPart).setBoundary(vars.get("boundary")).build();
postRequest.setEntity(entity);
String rqHeaderContentType = "multipart/form-data; boundary=" + "\"" + vars.get("boundary") + "\"";
def header = new BasicHeader(HttpHeaders.CONTENT_TYPE, rqHeaderContentType);
def header_auth = new BasicHeader("Authorization", "Bearer ${access_token}");
def headers = Arrays.asList(header, header_auth);
def client = HttpClients.custom().setDefaultHeaders(headers).build();

def response = client.execute(postRequest);
String responseBody = EntityUtils.toString(response.getEntity());
int respCode = response.getStatusLine().getStatusCode();
SampleResult.setResponseCode(respCode as String);
SampleResult.setResponseMessage(responseBody);
if(respCode==200){
    SampleResult.setSuccessful(true);
    }
    else    {
    SampleResult.setSuccessful(false);      
    }
Socialize answered 3/3, 2023 at 16:11 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Heddie

© 2022 - 2024 — McMap. All rights reserved.