in src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PostWriter.java [175:324]
public void setHeaders(URLConnection connection, HTTPSamplerBase sampler) throws IOException {
// Get the encoding to use for the request
String contentEncoding = sampler.getContentEncoding();
long contentLength = 0L;
HTTPFileArg[] files = sampler.getHTTPFiles();
// Check if we should do a multipart/form-data or an
// application/x-www-form-urlencoded post request
if(sampler.getUseMultipart()) {
// Set the content type
connection.setRequestProperty(
HTTPConstants.HEADER_CONTENT_TYPE,
HTTPConstants.MULTIPART_FORM_DATA + "; boundary=" + getBoundary()); // $NON-NLS-1$
// Write the form section
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(bos, contentEncoding);
// Add any parameters
for (JMeterProperty jMeterProperty : sampler.getArguments()) {
HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
String parameterName = arg.getName();
if (arg.isSkippable(parameterName)) {
continue;
}
// Write multipart for parameter
writeFormMultipart(osw, contentEncoding, parameterName, arg.getValue(), sampler.getDoBrowserCompatibleMultipart());
}
osw.flush();
// Keep the content, will be sent later
formDataPostBody = bos.toByteArray();
contentLength = formDataPostBody.length;
// Now we just construct any multipart for the files
// We only construct the file multipart start, we do not write
// the actual file content
for (int i = 0; i < files.length; i++) {
bos.reset();
contentLength += multipartDividerBytes.length + CRLF.length;
HTTPFileArg file = files[i];
// Write multipart for file
writeStartFileMultipart(osw, contentEncoding, file.getPath(), file.getParamName(), file.getMimeType());
osw.flush();
// Technically speaking, we should refrain from decoding the header to string
// since we will have to encode it again when sending the request
// However, HTTPFileArg#setHeaer(byte[]) does not exist yet
String header = bos.toString(contentEncoding);
// If this is not the first file we can't write its header now
// for simplicity we always save it, even if there is only one file
file.setHeader(header);
contentLength += bos.size();
// Add also the length of the file content
File uploadFile = new File(file.getPath());
contentLength += uploadFile.length();
contentLength += CRLF.length;
}
// Add the end of multipart
contentLength += multipartDividerBytes.length + DASH_DASH_BYTES.length + CRLF.length;
// Set the content length
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_LENGTH, Long.toString(contentLength));
// Make the connection ready for sending post data
connection.setDoOutput(true);
connection.setDoInput(true);
}
else {
// Check if the header manager had a content type header
// This allows the user to specify their own content-type for a POST request
String contentTypeHeader = connection.getRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE);
boolean hasContentTypeHeader = contentTypeHeader != null && contentTypeHeader.length() > 0;
// If there are no arguments, we can send a file as the body of the request
if(sampler.getArguments() != null && sampler.getArguments().getArgumentCount() == 0 && sampler.getSendFileAsPostBody()) {
// we're sure that there is one file because of
// getSendFileAsPostBody method's return value.
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) {
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
}
else {
if(HTTPAbstractImpl.ADD_CONTENT_TYPE_TO_POST_IF_MISSING) {
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
}
}
// Create the content length we are going to write
File inputFile = new File(file.getPath());
contentLength = inputFile.length();
}
else {
// We create the post body content now, so we know the size
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// If none of the arguments have a name specified, we
// just send all the values as the post body
String postBody = null;
if(!sampler.getSendParameterValuesAsPostBody()) {
// Set the content type
if(!hasContentTypeHeader && HTTPAbstractImpl.ADD_CONTENT_TYPE_TO_POST_IF_MISSING) {
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
// It is a normal post request, with parameter names and values
postBody = sampler.getQueryString(contentEncoding);
}
else {
// 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) {
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
}
else {
if(HTTPAbstractImpl.ADD_CONTENT_TYPE_TO_POST_IF_MISSING) {
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
}
}
// Just append all the parameter values, and use that as the post body
StringBuilder postBodyBuffer = new StringBuilder();
for (JMeterProperty jMeterProperty : sampler.getArguments()) {
HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
postBodyBuffer.append(arg.getEncodedValue(contentEncoding));
}
postBody = postBodyBuffer.toString();
}
bos.write(postBody.getBytes(contentEncoding));
bos.flush();
bos.close();
// Keep the content, will be sent later
formDataUrlEncoded = bos.toByteArray();
contentLength = bos.toByteArray().length;
}
// Set the content length
connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_LENGTH, Long.toString(contentLength));
// Make the connection ready for sending post data
connection.setDoOutput(true);
}
}