user2626431
user2626431

Reputation: 457

jMeter multipart request with file upload

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.

Upvotes: 8

Views: 35171

Answers (4)

Jace Dan
Jace Dan

Reputation: 1

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);      
    }

Upvotes: 0

Abhishek Puri
Abhishek Puri

Reputation: 373

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.

Upvotes: 1

Duc Trung Mai
Duc Trung Mai

Reputation: 2588

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

Upvotes: 6

Dmitri T
Dmitri T

Reputation: 168082

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.

Upvotes: 12

Related Questions