use of org.apache.jmeter.protocol.http.util.HTTPFileArg in project jmeter by apache.
the class MultipartUrlConfigTest method testParseArgumentsCRLF.
@Test
public void testParseArgumentsCRLF() {
String queryString = "Content-Disposition: form-data; name=\"aa\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "bb\r\n" + "--7d159c1302d0y0\r\n" + "Content-Disposition: form-data; name=\"xx\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "yy\r\n" + "--7d159c1302d0y0\r\n" + "Content-Disposition: form-data; name=\"abc\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "xyz \r\n" + "xyz \r\n" + "--7d159c1302d0y0\r\n" + "Content-Disposition: form-data; name=\"param1\"; filename=\"file1\"\r\n" + "Content-Type: text/plain\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "file content\r\n" + "\r\n";
MultipartUrlConfig muc = new MultipartUrlConfig("7d159c1302d0y0");
muc.parseArguments(queryString);
HTTPFileArgs files = muc.getHTTPFileArgs();
assertEquals(1, files.getHTTPFileArgCount());
HTTPFileArg file = (HTTPFileArg) files.iterator().next().getObjectValue();
assertEquals("file1", file.getPath());
assertEquals("param1", file.getParamName());
assertEquals("text/plain", file.getMimeType());
Arguments args = muc.getArguments();
assertEquals(3, args.getArgumentCount());
Argument arg = args.getArgument(0);
assertEquals("aa", arg.getName());
assertEquals("bb", arg.getValue());
arg = args.getArgument(1);
assertEquals("xx", arg.getName());
assertEquals("yy", arg.getValue());
arg = args.getArgument(2);
assertEquals("abc", arg.getName());
assertEquals("xyz \r\nxyz ", arg.getValue());
}
use of org.apache.jmeter.protocol.http.util.HTTPFileArg in project jmeter by apache.
the class MultipartUrlConfigTest method testParseArgumentsLF.
// TODO - should LF-only EOL be allowed?
@Test
public void testParseArgumentsLF() {
String queryString = "Content-Disposition: form-data; name=\"aa\"\n" + "Content-Type: text/plain; charset=ISO-8859-1\n" + "Content-Transfer-Encoding: 8bit\n" + "\n" + "bb\n" + "--7d159c1302d0y0\n" + "Content-Disposition: form-data; name=\"xx\"\n" + "Content-Type: text/plain; charset=ISO-8859-1\n" + "Content-Transfer-Encoding: 8bit\n" + "\n" + "yy\n" + "--7d159c1302d0y0\n" + "Content-Disposition: form-data; name=\"abc\"\n" + "Content-Type: text/plain; charset=ISO-8859-1\n" + "Content-Transfer-Encoding: 8bit\n" + "\n" + "xyz \n" + "xyz \n" + "--7d159c1302d0y0\n" + "Content-Disposition: form-data; name=\"param1\"; filename=\"file1\"\n" + "Content-Type: text/plain\n" + "Content-Transfer-Encoding: binary\n" + "\n" + "file content\n" + "\n";
MultipartUrlConfig muc = new MultipartUrlConfig("7d159c1302d0y0");
muc.parseArguments(queryString);
HTTPFileArgs files = muc.getHTTPFileArgs();
assertEquals(1, files.getHTTPFileArgCount());
HTTPFileArg file = (HTTPFileArg) files.iterator().next().getObjectValue();
assertEquals("file1", file.getPath());
assertEquals("param1", file.getParamName());
assertEquals("text/plain", file.getMimeType());
Arguments args = muc.getArguments();
assertEquals(3, args.getArgumentCount());
Argument arg = args.getArgument(0);
assertEquals("aa", arg.getName());
assertEquals("bb", arg.getValue());
arg = args.getArgument(1);
assertEquals("xx", arg.getName());
assertEquals("yy", arg.getValue());
arg = args.getArgument(2);
assertEquals("abc", arg.getName());
assertEquals("xyz \nxyz ", arg.getValue());
}
use of org.apache.jmeter.protocol.http.util.HTTPFileArg in project jmeter by apache.
the class HTTPHC4Impl method sendEntityData.
// TODO merge put and post methods as far as possible.
// e.g. post checks for multipart form/files, and if not, invokes sendData(HttpEntityEnclosingRequestBase)
/**
* Creates the entity data to be sent.
* <p>
* If there is a file entry with a non-empty MIME type we use that to
* set the request Content-Type header, otherwise we default to whatever
* header is present from a Header Manager.
* <p>
* If the content charset {@link #getContentEncoding()} is null or empty
* we use the HC4 default provided by {@link HTTP#DEF_CONTENT_CHARSET} which is
* ISO-8859-1.
*
* @param entity to be processed, e.g. PUT or PATCH
* @return the entity content, may be empty
* @throws UnsupportedEncodingException for invalid charset name
* @throws IOException cannot really occur for ByteArrayOutputStream methods
*/
protected String sendEntityData(HttpEntityEnclosingRequestBase entity) throws IOException {
boolean hasEntityBody = false;
final HTTPFileArg[] files = getHTTPFiles();
// 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
final HTTPFileArg file = files.length > 0 ? files[0] : null;
String contentTypeValue = null;
if (file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
contentTypeValue = file.getMimeType();
// we provide the MIME type here
entity.setHeader(HEADER_CONTENT_TYPE, contentTypeValue);
}
// Check for local contentEncoding (charset) override; fall back to default for content body
// we do this here rather so we can use the same charset to retrieve the data
final String charset = getContentEncoding(HTTP.DEF_CONTENT_CHARSET.name());
if (!hasArguments() && getSendFileAsPostBody()) {
hasEntityBody = true;
// If getSendFileAsPostBody returned true, it's sure that file is not null
File reservedFile = FileServer.getFileServer().getResolvedFile(files[0].getPath());
// no need for content-type here
FileEntity fileRequestEntity = new FileEntity(reservedFile);
entity.setEntity(fileRequestEntity);
} else // just send all the values as the entity body
if (getSendParameterValuesAsPostBody()) {
hasEntityBody = true;
// Just append all the parameter values, and use that as the entity body
Arguments arguments = getArguments();
StringBuilder entityBodyContent = new StringBuilder(arguments.getArgumentCount() * 15);
for (JMeterProperty jMeterProperty : arguments) {
HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
// Note: if "Encoded?" is not selected, arg.getEncodedValue is equivalent to arg.getValue
if (charset != null) {
entityBodyContent.append(arg.getEncodedValue(charset));
} else {
entityBodyContent.append(arg.getEncodedValue());
}
}
StringEntity requestEntity = new StringEntity(entityBodyContent.toString(), charset);
entity.setEntity(requestEntity);
}
// Check if we have any content to send for body
if (hasEntityBody) {
// If the request entity is repeatable, we can send it first to
// our own stream, so we can return it
final HttpEntity entityEntry = entity.getEntity();
// Buffer to hold the entity body
StringBuilder entityBody = null;
if (entityEntry.isRepeatable()) {
entityBody = new StringBuilder(1000);
// FIXME Charset
try (InputStream in = entityEntry.getContent();
InputStream bounded = new BoundedInputStream(in, MAX_BODY_RETAIN_SIZE)) {
entityBody.append(IOUtils.toString(bounded));
}
if (entityEntry.getContentLength() > MAX_BODY_RETAIN_SIZE) {
entityBody.append("<actual file content shortened>");
}
} else {
entityBody = new StringBuilder(65);
// this probably cannot happen
entityBody.append("<RequestEntity was not repeatable, cannot view what was sent>");
}
return entityBody.toString();
}
// may be the empty string
return "";
}
use of org.apache.jmeter.protocol.http.util.HTTPFileArg in project jmeter by apache.
the class HTTPHC4Impl method sendPostData.
// TODO needs cleaning up
/**
*
* @param post {@link HttpPost}
* @return String posted body if computable
* @throws IOException if sending the data fails due to I/O
*/
protected String sendPostData(HttpPost post) throws IOException {
// Buffer to hold the post body, except file content
StringBuilder postedBody = new StringBuilder(1000);
HTTPFileArg[] files = getHTTPFiles();
final String contentEncoding = getContentEncodingOrNull();
final boolean haveContentEncoding = contentEncoding != null;
// application/x-www-form-urlencoded post request
if (getUseMultipartForPost()) {
// If a content encoding is specified, we use that as the
// encoding of any parameter values
Charset charset = null;
if (haveContentEncoding) {
charset = Charset.forName(contentEncoding);
} else {
charset = MIME.DEFAULT_CHARSET;
}
if (log.isDebugEnabled()) {
log.debug("Building multipart with:getDoBrowserCompatibleMultipart(): {}, with charset:{}, haveContentEncoding:{}", getDoBrowserCompatibleMultipart(), charset, haveContentEncoding);
}
// Write the request to our own stream
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setCharset(charset);
if (getDoBrowserCompatibleMultipart()) {
multipartEntityBuilder.setLaxMode();
} else {
multipartEntityBuilder.setStrictMode();
}
// Add any parameters
for (JMeterProperty jMeterProperty : getArguments()) {
HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
String parameterName = arg.getName();
if (arg.isSkippable(parameterName)) {
continue;
}
StringBody stringBody = new StringBody(arg.getValue(), ContentType.create("text/plain", charset));
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());
fileBodies[i] = new ViewableFileBody(reservedFile, file.getMimeType());
multipartEntityBuilder.addPart(file.getParamName(), fileBodies[i]);
}
HttpEntity entity = multipartEntityBuilder.build();
post.setEntity(entity);
if (entity.isRepeatable()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (ViewableFileBody fileBody : fileBodies) {
fileBody.hideFileData = true;
}
entity.writeTo(bos);
for (ViewableFileBody fileBody : fileBodies) {
fileBody.hideFileData = false;
}
bos.flush();
// We get the posted bytes using the encoding used to create it
postedBody.append(bos.toString(// $NON-NLS-1$ this is the default used by HttpClient
contentEncoding == null ? // $NON-NLS-1$ this is the default used by HttpClient
"US-ASCII" : contentEncoding));
bos.close();
} else {
// $NON-NLS-1$
postedBody.append("<Multipart was not repeatable, cannot view what was sent>");
}
// // Set the content type TODO - needed?
// String multiPartContentType = multiPart.getContentType().getValue();
// post.setHeader(HEADER_CONTENT_TYPE, multiPartContentType);
} else {
// not multipart
// Check if the header manager had a content type header
// This allows the user to specify his own content-type for a POST request
Header contentTypeHeader = post.getFirstHeader(HTTPConstants.HEADER_CONTENT_TYPE);
boolean hasContentTypeHeader = contentTypeHeader != null && contentTypeHeader.getValue() != null && contentTypeHeader.getValue().length() > 0;
// TODO: needs a multiple file upload scenerio
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) {
post.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
} else {
post.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
}
// TODO is null correct?
FileEntity fileRequestEntity = new FileEntity(new File(file.getPath()), (ContentType) null);
post.setEntity(fileRequestEntity);
// We just add placeholder text for file content
postedBody.append("<actual file content, not shown here>");
} else {
// the post body will be encoded in the specified content encoding
if (haveContentEncoding) {
post.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, contentEncoding);
}
// just send all the values as the post body
if (getSendParameterValuesAsPostBody()) {
// TODO: needs a multiple file upload scenerio
if (!hasContentTypeHeader) {
HTTPFileArg file = files.length > 0 ? files[0] : null;
if (file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
post.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
} else {
// TODO - is this the correct default?
post.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();
// Note: if "Encoded?" is not selected, arg.getEncodedValue is equivalent to arg.getValue
if (haveContentEncoding) {
postBody.append(arg.getEncodedValue(contentEncoding));
} else {
postBody.append(arg.getEncodedValue());
}
}
// Let StringEntity perform the encoding
StringEntity requestEntity = new StringEntity(postBody.toString(), contentEncoding);
post.setEntity(requestEntity);
postedBody.append(postBody.toString());
} else {
// Set the content type
if (!hasContentTypeHeader) {
post.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
}
// Add the parameters
PropertyIterator args = getArguments().iterator();
List<NameValuePair> nvps = new ArrayList<>();
String urlContentEncoding = contentEncoding;
if (urlContentEncoding == null || urlContentEncoding.length() == 0) {
// Use the default encoding for urls
urlContentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
}
while (args.hasNext()) {
HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
// The HTTPClient always urlencodes both name and value,
// so if the argument is already encoded, we have to decode
// it before adding it to the post request
String parameterName = arg.getName();
if (arg.isSkippable(parameterName)) {
continue;
}
String parameterValue = arg.getValue();
if (!arg.isAlwaysEncoded()) {
// The value is already encoded by the user
// Must decode the value now, so that when the
// httpclient encodes it, we end up with the same value
// as the user had entered.
parameterName = URLDecoder.decode(parameterName, urlContentEncoding);
parameterValue = URLDecoder.decode(parameterValue, urlContentEncoding);
}
// Add the parameter, httpclient will urlencode it
nvps.add(new BasicNameValuePair(parameterName, parameterValue));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvps, urlContentEncoding);
post.setEntity(entity);
if (entity.isRepeatable()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
post.getEntity().writeTo(bos);
bos.flush();
// We get the posted bytes using the encoding used to create it
postedBody.append(bos.toString(contentEncoding != null ? contentEncoding : SampleResult.DEFAULT_HTTP_ENCODING));
bos.close();
} else {
postedBody.append("<RequestEntity was not repeatable, cannot view what was sent>");
}
}
}
}
return postedBody.toString();
}
use of org.apache.jmeter.protocol.http.util.HTTPFileArg in project jmeter by apache.
the class DefaultSamplerCreator method computeFromPostBody.
/**
* Compute sampler informations from Request Header
* @param sampler {@link HTTPSamplerBase}
* @param request {@link HttpRequestHdr}
* @throws Exception when something fails
*/
protected void computeFromPostBody(HTTPSamplerBase sampler, HttpRequestHdr request) throws Exception {
// to do parse the rest of the request if it is not a GET request
if ((!HTTPConstants.CONNECT.equals(request.getMethod())) && (!HTTPConstants.GET.equals(request.getMethod()))) {
// Check if it was a multipart http post request
final String contentType = request.getContentType();
MultipartUrlConfig urlConfig = request.getMultipartConfig(contentType);
String contentEncoding = sampler.getContentEncoding();
// Get the post data using the content encoding of the request
String postData = null;
if (log.isDebugEnabled()) {
if (!StringUtils.isEmpty(contentEncoding)) {
log.debug("Using encoding " + contentEncoding + " for request body");
} else {
log.debug("No encoding found, using JRE default encoding for request body");
}
}
if (!StringUtils.isEmpty(contentEncoding)) {
postData = new String(request.getRawPostData(), contentEncoding);
} else {
// Use default encoding
postData = new String(request.getRawPostData(), PostWriter.ENCODING);
}
if (urlConfig != null) {
urlConfig.parseArguments(postData);
// Tell the sampler to do a multipart post
sampler.setDoMultipartPost(true);
// Remove the header for content-type and content-length, since
// those values will most likely be incorrect when the sampler
// performs the multipart request, because the boundary string
// will change
request.getHeaderManager().removeHeaderNamed(HttpRequestHdr.CONTENT_TYPE);
request.getHeaderManager().removeHeaderNamed(HttpRequestHdr.CONTENT_LENGTH);
// Set the form data
sampler.setArguments(urlConfig.getArguments());
// Set the file uploads
sampler.setHTTPFiles(urlConfig.getHTTPFileArgs().asArray());
// we are parsing browser input here
sampler.setDoBrowserCompatibleMultipart(true);
// used when postData is pure xml (eg. an xml-rpc call) or for PUT
} else if (postData.trim().startsWith("<?") || HTTPConstants.PUT.equals(sampler.getMethod()) || isPotentialXml(postData)) {
sampler.addNonEncodedArgument("", postData, "");
} else if (contentType == null || (contentType.startsWith(HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED) && !isBinaryContent(contentType))) {
// It is the most common post request, with parameter name and values
// We also assume this if no content type is present, to be most backwards compatible,
// but maybe we should only parse arguments if the content type is as expected
//standard name=value postData
sampler.parseArguments(postData.trim(), contentEncoding);
} else if (postData.length() > 0) {
if (isBinaryContent(contentType)) {
try {
File tempDir = new File(getBinaryDirectory());
File out = File.createTempFile(request.getMethod(), getBinaryFileSuffix(), tempDir);
FileUtils.writeByteArrayToFile(out, request.getRawPostData());
HTTPFileArg[] files = { new HTTPFileArg(out.getPath(), "", contentType) };
sampler.setHTTPFiles(files);
} catch (IOException e) {
log.warn("Could not create binary file: " + e);
}
} else {
// Just put the whole postbody as the value of a parameter
//used when postData is pure xml (ex. an xml-rpc call)
sampler.addNonEncodedArgument("", postData, "");
}
}
}
}
Aggregations