in src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java [1537:1677]
protected String setupHttpEntityEnclosingRequestData(HttpEntityEnclosingRequestBase entityEnclosingRequest) throws IOException {
// Buffer to hold the post body, except file content
StringBuilder postedBody = new StringBuilder(1000);
HTTPFileArg[] files = getHTTPFiles();
final String contentEncoding = getContentEncoding();
Charset charset = Charset.forName(contentEncoding);
final boolean haveContentEncoding = true;
// Check if we should do a multipart/form-data or an
// application/x-www-form-urlencoded post request
if(getUseMultipart()) {
if (entityEnclosingRequest.getHeaders(HTTPConstants.HEADER_CONTENT_TYPE).length > 0) {
log.info(
"Content-Header is set already on the request! Will be replaced by a Multipart-Header. Old headers: {}",
Arrays.asList(entityEnclosingRequest.getHeaders(HTTPConstants.HEADER_CONTENT_TYPE)));
entityEnclosingRequest.removeHeaders(HTTPConstants.HEADER_CONTENT_TYPE);
}
// doBrowserCompatibleMultipart means "use charset for encoding MIME headers",
// while RFC6532 means "use UTF-8 for encoding MIME headers"
boolean doBrowserCompatibleMultipart = getDoBrowserCompatibleMultipart();
if(log.isDebugEnabled()) {
log.debug("Building multipart with:getDoBrowserCompatibleMultipart(): {}, with charset:{}, haveContentEncoding:{}",
doBrowserCompatibleMultipart, charset, haveContentEncoding);
}
// Write the request to our own stream
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setCharset(charset);
if (doBrowserCompatibleMultipart) {
multipartEntityBuilder.setLaxMode();
} else {
// Use UTF-8 for encoding header names and values
multipartEntityBuilder.setMode(HttpMultipartMode.RFC6532);
}
// Create the parts
// Add any parameters
for (JMeterProperty jMeterProperty : getArguments()) {
HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
String parameterName = arg.getName();
if (arg.isSkippable(parameterName)) {
continue;
}
ContentType contentType;
if (arg.getContentType().indexOf(';') >= 0) {
// assume, that the content type contains charset info
// don't add another charset and use parse to cope with the semicolon
contentType = ContentType.parse(arg.getContentType());
} else {
contentType = ContentType.create(arg.getContentType(), charset);
}
StringBody stringBody = new StringBody(arg.getValue(), contentType);
FormBodyPart formPart = FormBodyPartBuilder.create(
parameterName, stringBody).build();
multipartEntityBuilder.addPart(formPart);
}
// Add any files
// Cannot retrieve parts once added to the MultiPartEntity, so have to save them here.
ViewableFileBody[] fileBodies = new ViewableFileBody[files.length];
for (int i=0; i < files.length; i++) {
HTTPFileArg file = files[i];
File reservedFile = FileServer.getFileServer().getResolvedFile(file.getPath());
Charset filenameCharset = doBrowserCompatibleMultipart ? charset : StandardCharsets.UTF_8;
fileBodies[i] = new ViewableFileBody(reservedFile, ContentType.parse(file.getMimeType()), filenameCharset);
multipartEntityBuilder.addPart(file.getParamName(), fileBodies[i] );
}
HttpEntity entity = multipartEntityBuilder.build();
entityEnclosingRequest.setEntity(entity);
writeEntityToSB(postedBody, entity, fileBodies, contentEncoding);
} else { // not multipart
// Check if the header manager had a content type header
// This allows the user to specify their own content-type for a POST request
Header contentTypeHeader = entityEnclosingRequest.getFirstHeader(HTTPConstants.HEADER_CONTENT_TYPE);
boolean hasContentTypeHeader = contentTypeHeader != null && contentTypeHeader.getValue() != null && contentTypeHeader.getValue().length() > 0;
// If there are no arguments, we can send a file as the body of the request
// TODO: needs a multiple file upload scenario
if(!hasArguments() && getSendFileAsPostBody()) {
// If getSendFileAsPostBody returned true, it's sure that file is not null
HTTPFileArg file = files[0];
if(!hasContentTypeHeader) {
// Allow the mimetype of the file to control the content type
if(file.getMimeType() != null && file.getMimeType().length() > 0) {
entityEnclosingRequest.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
}
else if(ADD_CONTENT_TYPE_TO_POST_IF_MISSING) {
entityEnclosingRequest.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
}
FileEntity fileRequestEntity = new FileEntity(FileServer.getFileServer().getResolvedFile(file.getPath()), (ContentType) null);
entityEnclosingRequest.setEntity(fileRequestEntity);
// We just add placeholder text for file content
postedBody.append("<actual file content, not shown here>");
} else {
// In a post request which is not multipart, we only support
// parameters, no file upload is allowed
// If none of the arguments have a name specified, we
// just send all the values as the post body
if(getSendParameterValuesAsPostBody()) {
// Allow the mimetype of the file to control the content type
// This is not obvious in GUI if you are not uploading any files,
// but just sending the content of nameless parameters
// TODO: needs a multiple file upload scenario
if(!hasContentTypeHeader) {
HTTPFileArg file = files.length > 0? files[0] : null;
if(file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
entityEnclosingRequest.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
}
else if(ADD_CONTENT_TYPE_TO_POST_IF_MISSING) {
entityEnclosingRequest.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
}
// Just append all the parameter values, and use that as the post body
StringBuilder postBody = new StringBuilder();
for (JMeterProperty jMeterProperty : getArguments()) {
HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
postBody.append(arg.getEncodedValue(contentEncoding));
}
// Let StringEntity perform the encoding
StringEntity requestEntity = new StringEntity(postBody.toString(), contentEncoding);
entityEnclosingRequest.setEntity(requestEntity);
postedBody.append(postBody.toString());
} else {
// It is a normal post request, with parameter names and values
// Set the content type
if(!hasContentTypeHeader && ADD_CONTENT_TYPE_TO_POST_IF_MISSING) {
entityEnclosingRequest.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
UrlEncodedFormEntity entity = createUrlEncodedFormEntity(contentEncoding);
entityEnclosingRequest.setEntity(entity);
writeEntityToSB(postedBody, entity, EMPTY_FILE_BODIES, contentEncoding);
}
}
}
return postedBody.toString();
}