Author: alf
Date: Sun Oct 14 05:46:26 2007
New Revision: 584535
URL: http://svn.apache.org/viewvc?rev=584535&view=rev
Log:
Make the HTTP PUT behave like HTTP POST, i.e. HTTP PUT will get a request body
similar to HTTP POST, but not multipart is supported for PUT.
Make the HTTP DELETE behave like HTTP GET, i.e. it supports parameters.
Some code restucturing to allow SoapSampler to soon use the code of
HttpSampler2 to construct the request.
The bugs for improving better support for the various HTTP methods will not be
set to fixed yet, I want to add some unit tests first. At that moment, I will
also add description of these changes to the changes.xml
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java?rev=584535&r1=584534&r2=584535&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java
(original)
+++
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java
Sun Oct 14 05:46:26 2007
@@ -105,9 +105,10 @@
sb.append(' ');
sb.append(u.toString());
sb.append("\n");
- if (HTTPSamplerBase.POST.equals(method)) {
+ // Include request body if it is a post or put
+ if (HTTPSamplerBase.POST.equals(method) ||
HTTPSamplerBase.PUT.equals(method)) {
sb.append("\nPOST data:\n");
- sb.append(queryString);
+ sb.append(queryString);
sb.append("\n");
}
if (cookies.length()>0){
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java?rev=584535&r1=584534&r2=584535&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
(original)
+++
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
Sun Oct 14 05:46:26 2007
@@ -95,18 +95,32 @@
}
private void setPutHeaders(URLConnection conn)
- {
- String filename = getFilename();
- if ((filename != null) && (filename.trim().length() > 0))
- {
- conn.setRequestProperty(HEADER_CONTENT_TYPE, getMimetype());
- conn.setDoOutput(true);
- conn.setDoInput(true);
+ {
+ boolean hasPutBody = false;
+ // Check if any files should be uploaded
+ if (hasUploadableFiles())
+ {
+ // Set content-type if we have a value for it
+ if(getMimetype() != null && getMimetype().trim().length() > 0) {
+ conn.setRequestProperty(HEADER_CONTENT_TYPE, getMimetype());
+ }
+ hasPutBody = true;
+ }
+ // Check if any parameters should be sent as body
+ if(getSendParameterValuesAsPostBody()) {
+ hasPutBody = true;
+ }
+ // If there is any files to upload, or other body content to be sent,
+ // we set the connection to accept output
+ if(hasPutBody) {
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
}
}
/**
* Send POST data from <code>Entry</code> to the open connection.
+ * This also handles sending data for PUT requests
*
* @param connection
* <code>URLConnection</code> where POST data should be sent
@@ -118,23 +132,10 @@
return postWriter.sendPostData(connection, this);
}
- private void sendPutData(URLConnection conn) throws IOException {
- String filename = getFilename();
- if ((filename != null) && (filename.trim().length() > 0)) {
- OutputStream out = conn.getOutputStream();
- byte[] buf = new byte[1024];
- int read;
- InputStream in = new BufferedInputStream(new
FileInputStream(filename));
- while ((read = in.read(buf)) > 0) {
- out.write(buf, 0, read);
- }
- in.close();
- out.flush();
- out.close();
- }
+ private String sendPutData(URLConnection connection) throws IOException {
+ return postWriter.sendPostData(connection, this);
}
-
/**
* Returns an <code>HttpURLConnection</code> fully ready to attempt
* connection. This means it sets the request method (GET or POST),
headers,
@@ -478,8 +479,10 @@
if (method.equals(POST)) {
String postBody = sendPostData(conn);
res.setQueryString(postBody);
- } else if (method.equals(PUT)) {
- sendPutData(conn);
+ }
+ else if (method.equals(PUT)) {
+ String putBody = sendPutData(conn);
+ res.setQueryString(putBody);
}
// Request sent. Now get the response:
byte[] responseData = readResponse(conn, res);
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java?rev=584535&r1=584534&r2=584535&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java
(original)
+++
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler2.java
Sun Oct 14 05:46:26 2007
@@ -282,9 +282,9 @@
HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
String parameterName = arg.getName();
if (parameterName.length()==0){
- continue; // Skip parameters with a blank name (allows use
of optional variables in parameter lists)
+ continue; // Skip parameters with a blank name (allows use
of optional variables in parameter lists)
}
- parts[partNo++] = new StringPart(arg.getName(),
arg.getValue(), contentEncoding);
+ parts[partNo++] = new StringPart(arg.getName(), arg.getValue(),
contentEncoding);
}
// Add any files
@@ -341,7 +341,7 @@
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(!hasArguments() && getSendFileAsPostBody()) {
if(!hasContentTypeHeader) {
// Allow the mimetype of the file to control the content
type
if(getMimetype() != null && getMimetype().length() > 0) {
@@ -358,7 +358,7 @@
// We just add placeholder text for file content
postedBody.append("<actual file content, not shown here>");
}
- else {
+ else {
// In an application/x-www-form-urlencoded request, we only
support
// parameters, no file upload is allowed
if(!hasContentTypeHeader) {
@@ -402,7 +402,7 @@
// it before adding it to the post request
String parameterName = arg.getName();
if (parameterName.length()==0){
- continue; // Skip parameters with a blank name
(allows use of optional variables in parameter lists)
+ continue; // Skip parameters with a blank name
(allows use of optional variables in parameter lists)
}
String parameterValue = arg.getValue();
if(!arg.isAlwaysEncoded()) {
@@ -448,7 +448,7 @@
bos.close();
}
else {
- postedBody.append("<Multipart was not repeatable, cannot
view what was sent>"); // $NON-NLS-1$
+ postedBody.append("<RequestEntity was not repeatable,
cannot view what was sent>");
}
}
}
@@ -565,6 +565,15 @@
return httpClient;
}
+ /**
+ * Set any default request headers to include
+ *
+ * @param httpMethod the HttpMethod used for the request
+ */
+ protected void setDefaultRequestHeaders(HttpMethod httpMethod) {
+ // Method left empty here, but allows subclasses to override
+ }
+
/**
* Gets the ResponseHeaders
*
@@ -750,8 +759,8 @@
String urlStr = url.toString();
- log.debug("Start : sample" + urlStr);
- log.debug("method" + method);
+ log.debug("Start : sample " + urlStr);
+ log.debug("method " + method);
HttpMethodBase httpMethod = null;
@@ -784,13 +793,17 @@
httpMethod = new GetMethod(urlStr);
}
+ // Set any default request headers
+ setDefaultRequestHeaders(httpMethod);
+ // Setup connection
client = setupConnection(url, httpMethod, res);
-
+ // Handle the various methods
if (method.equals(POST)) {
String postBody =
sendPostData((PostMethod)httpMethod);
res.setQueryString(postBody);
} else if (method.equals(PUT)) {
- setPutHeaders((PutMethod) httpMethod);
+ String putBody = sendPutData((PutMethod)httpMethod);
+ res.setQueryString(putBody);
}
res.setRequestHeaders(getConnectionHeaders(httpMethod));
@@ -893,17 +906,92 @@
}
/**
- * Set up the PUT data (if present)
+ * Set up the PUT data
*/
- private void setPutHeaders(PutMethod put)
- {
- String filename = getFilename();
- if ((filename != null) && (filename.trim().length() > 0))
- {
- RequestEntity requestEntity =
- new FileRequestEntity(new File(filename),getMimetype());
- put.setRequestEntity(requestEntity);
- }
+ private String sendPutData(PutMethod put) throws IOException {
+ // Buffer to hold the put body, except file content
+ StringBuffer putBody = new StringBuffer(1000);
+ boolean hasPutBody = false;
+
+ // 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 = put.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(!hasArguments() && getSendFileAsPostBody()) {
+ hasPutBody = true;
+
+ FileRequestEntity fileRequestEntity = new FileRequestEntity(new
File(getFilename()),null);
+ put.setRequestEntity(fileRequestEntity);
+
+ // We just add placeholder text for file content
+ putBody.append("<actual file content, not shown here>");
+ }
+ // If none of the arguments have a name specified, we
+ // just send all the values as the post body
+ else if(getSendParameterValuesAsPostBody()) {
+ hasPutBody = true;
+
+ // 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();
+ boolean haveContentEncoding = false;
+ if(contentEncoding != null && contentEncoding.trim().length() > 0)
{
+ put.getParams().setContentCharset(contentEncoding);
+ haveContentEncoding = true;
+ }
+
+ // Just append all the parameter values, and use that as the post
body
+ StringBuffer putBodyContent = new StringBuffer();
+ PropertyIterator args = getArguments().iterator();
+ while (args.hasNext()) {
+ HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
+ String value = null;
+ if (haveContentEncoding){
+ value = arg.getEncodedValue(contentEncoding);
+ } else {
+ value = arg.getEncodedValue();
+ }
+ putBody.append(value);
+ }
+ String contentTypeValue = null;
+ if(hasContentTypeHeader) {
+ contentTypeValue =
put.getRequestHeader(HEADER_CONTENT_TYPE).getValue();
+ }
+ StringRequestEntity requestEntity = new
StringRequestEntity(putBodyContent.toString(), contentTypeValue,
put.getRequestCharSet());
+ put.setRequestEntity(requestEntity);
+ }
+ // Check if we have any content to send for body
+ if(hasPutBody) {
+ // If the request entity is repeatable, we can send it first to
+ // our own stream, so we can return it
+ if(put.getRequestEntity().isRepeatable()) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ put.getRequestEntity().writeRequest(bos);
+ bos.flush();
+ // We get the posted bytes as UTF-8, since java is using UTF-8
+ putBody.append(new String(bos.toByteArray() , "UTF-8")); //
$NON-NLS-1$
+ bos.close();
+ }
+ else {
+ putBody.append("<RequestEntity was not repeatable, cannot view
what was sent>");
+ }
+ if(!hasContentTypeHeader) {
+ // 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
+ if(getMimetype() != null && getMimetype().length() > 0) {
+ put.setRequestHeader(HEADER_CONTENT_TYPE, getMimetype());
+ }
+ }
+ // Set the content length
+ put.setRequestHeader(HEADER_CONTENT_LENGTH,
Long.toString(put.getRequestEntity().getContentLength()));
+ return putBody.toString();
+ }
+ else {
+ return null;
+ }
}
// Implement locally, as current httpclient InputStreamRI
implementation does not close file...
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=584535&r1=584534&r2=584535&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
(original)
+++
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
Sun Oct 14 05:46:26 2007
@@ -375,7 +375,7 @@
* The encoding used for the querystring parameter values
*/
public void setPath(String path, String contentEncoding) {
- if (GET.equals(getMethod())) {
+ if (GET.equals(getMethod()) || DELETE.equals(getMethod())) {
int index = path.indexOf(QRY_PFX);
if (index > -1) {
setProperty(PATH, path.substring(0, index));
@@ -529,6 +529,10 @@
public void addArgument(String name, String value, String metadata) {
this.getArguments().addArgument(new HTTPArgument(name, value,
metadata));
}
+
+ public boolean hasArguments() {
+ return getArguments().getArgumentCount() > 0;
+ }
public void addTestElement(TestElement el) {
if (el instanceof CookieManager) {
@@ -708,8 +712,8 @@
}
pathAndQuery.append(path);
- // Add the query string if it is a HTTP GET request
- if(GET.equals(getMethod())) {
+ // Add the query string if it is a HTTP GET or DELETE request
+ if(GET.equals(getMethod()) || DELETE.equals(getMethod())) {
// Get the query string encoded in specified encoding
// If no encoding is specified by user, we will get it
// encoded in UTF-8, which is what the HTTP spec says
@@ -861,11 +865,18 @@
}
public String toString() {
- try {
- return this.getUrl().toString() +
((POST.equals(getMethod())) ? "\nQuery Data: " + getQueryString() : "");
- } catch (MalformedURLException e) {
- return "";
- }
+ try {
+ StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append(this.getUrl().toString());
+ // Append body if it is a post or put
+ if(POST.equals(getMethod()) || PUT.equals(getMethod())) {
+ stringBuffer.append("\nQuery Data: ");
+ stringBuffer.append(getQueryString());
+ }
+ return stringBuffer.toString();
+ } catch (MalformedURLException e) {
+ return "";
+ }
}
/**
@@ -1293,7 +1304,7 @@
* Method to tell if the request has any files to be uploaded
*/
protected boolean hasUploadableFiles() {
- return getFilename() != null && getFilename().length() > 0;
+ return getFilename() != null && getFilename().trim().length() > 0;
}
public static String[] getValidMethodsAsArray(){
Modified:
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java?rev=584535&r1=584534&r2=584535&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java
(original)
+++
jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java
Sun Oct 14 05:46:26 2007
@@ -125,7 +125,7 @@
}
else {
// 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(sampler.getArguments() != null && !sampler.hasArguments() &&
sampler.getSendFileAsPostBody()) {
OutputStream out = connection.getOutputStream();
writeFileToStream(sampler.getFilename(), out);
out.flush();
@@ -174,10 +174,14 @@
PropertyIterator args = sampler.getArguments().iterator();
while (args.hasNext()) {
HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
+ String parameterName = arg.getName();
+ if (parameterName.length()==0){
+ continue; // Skip parameters with a blank name (allows use
of optional variables in parameter lists)
+ }
// End the previous multipart
bos.write(CRLF);
// Write multipart for parameter
- writeFormMultipart(bos, arg.getName(), arg.getValue(),
contentEncoding);
+ writeFormMultipart(bos, parameterName, arg.getValue(),
contentEncoding);
}
// If there are any files, we need to end the previous multipart
if(sampler.hasUploadableFiles()) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]