Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java (revision 528364) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java (working copy) @@ -233,17 +233,26 @@ return ""; // $NON-NLS-1$ } - private MultipartUrlConfig isMultipart(String contentType) { - if (contentType != null && contentType.startsWith(MultipartUrlConfig.MULTIPART_FORM)) { - return new MultipartUrlConfig(contentType.substring(contentType.indexOf("oundary=") + 8)); - } else { - return null; - } - } + private boolean isMultipart(String contentType) { + if (contentType != null && contentType.startsWith(HTTPSamplerBase.MULTIPART_FORM_DATA)) { + return true; + } else { + return false; + } + } + private MultipartUrlConfig getMultipartConfig(String contentType) { + if(isMultipart(contentType)) { + // Get the boundary string for the multiparts from the content type + String boundaryString = contentType.substring(contentType.toLowerCase().indexOf("boundary=") + "boundary=".length()); + return new MultipartUrlConfig(boundaryString); + } + else { + return null; + } + } + private void populateSampler() { - MultipartUrlConfig urlConfig = null; - sampler.setDomain(serverName()); if (log.isDebugEnabled()) log.debug("Proxy: setting server: " + sampler.getDomain()); @@ -275,27 +284,41 @@ log.debug("Proxy setting default protocol to: http"); sampler.setProtocol(HTTP); } - if ((urlConfig = isMultipart(getContentType())) != null) { - urlConfig.parseArguments(postData); - // If no file is uploaded, then it was really a multipart/form-data - // post request. But currently, that is not supported, so we must - // change the "Content-Type" header from multipart/form-data to - // application/x-www-form-urlencoded, which is the one the HTTP Request - // sampler will send - if(urlConfig.getFilename() == null) { - System.out.println("jada"); - getHeaderManager().removeHeaderNamed("Content-Type"); - getHeaderManager().add(new Header("Content-Type", "application/x-www-form-urlencoded")); - } - sampler.setArguments(urlConfig.getArguments()); + + // Check if it was a multipart http post request + String contentType = getContentType(); + MultipartUrlConfig urlConfig = getMultipartConfig(contentType); + 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 + getHeaderManager().removeHeaderNamed(CONTENT_TYPE); + getHeaderManager().removeHeaderNamed(CONTENT_LENGTH); + + // Set the form data + sampler.setArguments(urlConfig.getArguments()); + // Set the file uploads sampler.setFileField(urlConfig.getFileFieldName()); sampler.setFilename(urlConfig.getFilename()); sampler.setMimetype(urlConfig.getMimeType()); } else if (postData != null && postData.trim().startsWith(" 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()) { + if(!hasContentTypeHeader) { + // Allow the mimetype of the file to control the content type + if(sampler.getMimetype() != null && sampler.getMimetype().length() > 0) { + connection.setRequestProperty(HTTPSamplerBase.HEADER_CONTENT_TYPE, sampler.getMimetype()); + } + else { + connection.setRequestProperty(HTTPSamplerBase.HEADER_CONTENT_TYPE, HTTPSamplerBase.APPLICATION_X_WWW_FORM_URLENCODED); + } + } + // Create the content length we are going to write File inputFile = new File(sampler.getFilename()); contentLength = inputFile.length(); } else { + // Set the content type + if(!hasContentTypeHeader) { + connection.setRequestProperty(HTTPSamplerBase.HEADER_CONTENT_TYPE, HTTPSamplerBase.APPLICATION_X_WWW_FORM_URLENCODED); + } + // We create the post body content now, so we know the size ByteArrayOutputStream bos = new ByteArrayOutputStream(); - String postBody = getQueryStringForPostBody(sampler, contentEncoding); + // 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()) { + // It is a normal post request, with parameter names and values + postBody = getQueryStringForPostBody(sampler, contentEncoding); + } + else { + // Just append all the parameter values, and use that as the post body + StringBuffer postBodyBuffer = new StringBuffer(); + PropertyIterator args = sampler.getArguments().iterator(); + while (args.hasNext()) { + HTTPArgument arg = (HTTPArgument) args.next().getObjectValue(); + postBodyBuffer.append(arg.getValue()); + } + postBody = postBodyBuffer.toString(); + } + // Query string should be encoded in UTF-8 bos.write(postBody.getBytes("UTF-8")); // $NON-NLS-1$ bos.flush(); Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java (revision 528364) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java (working copy) @@ -54,6 +54,7 @@ import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; +import org.apache.commons.httpclient.methods.StringRequestEntity; import org.apache.commons.httpclient.methods.TraceMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; @@ -313,11 +314,23 @@ } } else { - // Set the content type - post.setRequestHeader(HEADER_CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED); + // 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.getRequestHeader(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 if(getArguments().getArgumentCount() == 0 && getSendFileAsPostBody()) { + if(!hasContentTypeHeader) { + // Allow the mimetype of the file to control the content type + if(getMimetype() != null && getMimetype().length() > 0) { + post.setRequestHeader(HEADER_CONTENT_TYPE, getMimetype()); + } + else { + post.setRequestHeader(HEADER_CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED); + } + } + FileRequestEntity fileRequestEntity = new FileRequestEntity(new File(getFilename()),null); post.setRequestEntity(fileRequestEntity); @@ -327,21 +340,41 @@ else { // In an application/x-www-form-urlencoded request, we only support // parameters, no file upload is allowed - + if(!hasContentTypeHeader) { + // Set the content type + post.setRequestHeader(HEADER_CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED); + } + // If a content encoding is specified, we set it as http parameter, so that // the post body will be encoded in the specified content encoding final String contentEncoding = getContentEncoding(); if(contentEncoding != null && contentEncoding.trim().length() > 0) { post.getParams().setContentCharset(contentEncoding); } - - PropertyIterator args = getArguments().iterator(); - while (args.hasNext()) { - HTTPArgument arg = (HTTPArgument) args.next().getObjectValue(); - post.addParameter(arg.getName(), arg.getValue()); + + // If none of the arguments have a name specified, we + // just send all the values as the post body + if(!getSendParameterValuesAsPostBody()) { + // It is a normal post request, with parameter names and values + PropertyIterator args = getArguments().iterator(); + while (args.hasNext()) { + HTTPArgument arg = (HTTPArgument) args.next().getObjectValue(); + post.addParameter(arg.getName(), arg.getValue()); + } } + else { + // Just append all the parameter values, and use that as the post body + StringBuffer postBody = new StringBuffer(); + PropertyIterator args = getArguments().iterator(); + while (args.hasNext()) { + HTTPArgument arg = (HTTPArgument) args.next().getObjectValue(); + postBody.append(arg.getValue()); + } + StringRequestEntity requestEntity = new StringRequestEntity(postBody.toString(), post.getRequestHeader(HEADER_CONTENT_TYPE).getValue(), post.getRequestCharSet()); + post.setRequestEntity(requestEntity); + } - // If the Multipart is repeatable, we can send it first to + // If the request entity is repeatable, we can send it first to // our own stream, so we can return it if(post.getRequestEntity().isRepeatable()) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (revision 528364) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (working copy) @@ -207,9 +209,9 @@ protected static final String HEADER_LOCATION = "Location"; // $NON-NLS-1$ - protected static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; // $NON-NLS-1$ + public static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; // $NON-NLS-1$ - protected static final String MULTIPART_FORM_DATA = "multipart/form-data"; // $NON-NLS-1$ + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; // $NON-NLS-1$ // Derive the mapping of content types to parsers private static Map parsersForType = new HashMap(); @@ -288,11 +290,32 @@ * i.e. without any additional wrapping * * @return true if specified file is to be sent as the body, - * i.e. both FileField and MimeType are blank + * i.e. both FileField is blank */ - public boolean getSendFileAsPostBody(){ - return getFileField().length()== 0 && getMimetype().length() == 0; + public boolean getSendFileAsPostBody() { + // If no file field is specified, the file is sent as post body + return getFileField().length()== 0 && getFilename().length() > 0; } + + /** + * Determine if none of the parameters have a name, and if that + * is the case, it means that the parameter values should be sent + * as the post body + * + * @return true if none of the parameters have a name specified + */ + public boolean getSendParameterValuesAsPostBody() { + boolean noArgumentsHasName = true; + PropertyIterator args = getArguments().iterator(); + while (args.hasNext()) { + HTTPArgument arg = (HTTPArgument) args.next().getObjectValue(); + if(arg.getName() != null && arg.getName().length() > 0) { + noArgumentsHasName = false; + break; + } + } + return noArgumentsHasName; + } /** * Determine if we should use multipart/form-data or Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/config/MultipartUrlConfig.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/config/MultipartUrlConfig.java (revision 528364) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/protocol/http/org/apache/jmeter/protocol/http/config/MultipartUrlConfig.java (working copy) @@ -29,7 +29,7 @@ * @version $Revision$ */ public class MultipartUrlConfig implements Serializable { - + /** @deprecated use HTTPSamplerBase.MULTIPART_FORM_DATA instead */ public static final String MULTIPART_FORM = "multipart/form-data"; private String boundary, filename, fileField, mimetype;