You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@jakarta.apache.org by se...@apache.org on 2010/11/30 01:43:01 UTC

svn commit: r1040363 - in /jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler: HTTPSampler.java HTTPSampler2.java

Author: sebb
Date: Tue Nov 30 00:43:01 2010
New Revision: 1040363

URL: http://svn.apache.org/viewvc?rev=1040363&view=rev
Log:
Rewrite original samplers to use new implementations

Modified:
    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

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=1040363&r1=1040362&r2=1040363&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 Tue Nov 30 00:43:01 2010
@@ -16,631 +16,30 @@
  */
 package org.apache.jmeter.protocol.http.sampler;
 
-import java.io.BufferedInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-import java.net.BindException;
-import java.net.HttpURLConnection;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.URL;
-import java.net.URLConnection;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.jmeter.protocol.http.control.AuthManager;
-import org.apache.jmeter.protocol.http.control.Authorization;
-import org.apache.jmeter.protocol.http.control.CacheManager;
-import org.apache.jmeter.protocol.http.control.CookieManager;
-import org.apache.jmeter.protocol.http.control.Header;
-import org.apache.jmeter.protocol.http.control.HeaderManager;
-
 import org.apache.jmeter.samplers.Interruptible;
-import org.apache.jmeter.samplers.SampleResult;
-import org.apache.jmeter.testelement.property.CollectionProperty;
-import org.apache.jmeter.testelement.property.PropertyIterator;
-
-import org.apache.jmeter.util.JMeterUtils;
-import org.apache.jmeter.util.SSLManager;
-
-import org.apache.jorphan.logging.LoggingManager;
-
-import org.apache.log.Logger;
 
 /**
  * A sampler which understands all the parts necessary to read statistics about
  * HTTP requests, including cookies and authentication.
- *
+ * This sampler uses the default Java HTTP implementation
  */
 public class HTTPSampler extends HTTPSamplerBase implements Interruptible {
-    private static final boolean OBEY_CONTENT_LENGTH =
-        JMeterUtils.getPropDefault("httpsampler.obey_contentlength", false); // $NON-NLS-1$
-
-    private static final long serialVersionUID = 233L;
-
-    private static final Logger log = LoggingManager.getLoggerForClass();
-
-    private static final int MAX_CONN_RETRIES =
-        JMeterUtils.getPropDefault("http.java.sampler.retries" // $NON-NLS-1$
-                ,10); // Maximum connection retries
 
-    static {
-        log.info("Maximum connection retries = "+MAX_CONN_RETRIES); // $NON-NLS-1$
-        // Temporary copies, so can set the final ones
-    }
-
-    private static final byte[] NULL_BA = new byte[0];// can share these
-
-    /** Handles writing of a post or put request */
-    private transient PostWriter postOrPutWriter;
-
-    private volatile HttpURLConnection savedConn;
-
-    /**
-     * Constructor for the HTTPSampler object.
-     *
-     * Consider using HTTPSamplerFactory.newInstance() instead
-     */
-    public HTTPSampler() {
-    }
-
-    /**
-     * Set request headers in preparation to opening a connection.
-     *
-     * @param conn
-     *            <code>URLConnection</code> to set headers on
-     * @exception IOException
-     *                if an I/O exception occurs
-     */
-    protected void setPostHeaders(URLConnection conn) throws IOException {
-        postOrPutWriter = new PostWriter();
-        postOrPutWriter.setHeaders(conn, this);
-    }
-
-    private void setPutHeaders(URLConnection conn) throws IOException {
-        postOrPutWriter = new PutWriter();
-        postOrPutWriter.setHeaders(conn, this);
-    }
+    private static final long serialVersionUID = 241L;
 
-    /**
-     * 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
-     * @return a String show what was posted. Will not contain actual file upload content
-     * @exception IOException
-     *                if an I/O exception occurs
-     */
-    protected String sendPostData(URLConnection connection) throws IOException {
-        return postOrPutWriter.sendPostData(connection, this);
+    private final transient HTTPAbstractImpl hc;
+    
+    public HTTPSampler(){
+        hc = new HTTPJavaImpl(this);
     }
 
-    private String sendPutData(URLConnection connection) throws IOException {
-        return postOrPutWriter.sendPostData(connection, this);
-    }
-
-    /**
-     * Returns an <code>HttpURLConnection</code> fully ready to attempt
-     * connection. This means it sets the request method (GET or POST), headers,
-     * cookies, and authorization for the URL request.
-     * <p>
-     * The request infos are saved into the sample result if one is provided.
-     *
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param method
-     *            GET, POST etc
-     * @param res
-     *            sample result to save request infos to
-     * @return <code>HttpURLConnection</code> ready for .connect
-     * @exception IOException
-     *                if an I/O Exception occurs
-     */
-    protected HttpURLConnection setupConnection(URL u, String method, HTTPSampleResult res) throws IOException {
-        SSLManager sslmgr = null;
-        if (PROTOCOL_HTTPS.equalsIgnoreCase(u.getProtocol())) {
-            try {
-                sslmgr=SSLManager.getInstance(); // N.B. this needs to be done before opening the connection
-            } catch (Exception e) {
-                log.warn("Problem creating the SSLManager: ", e);
-            }
-        }
-
-        final HttpURLConnection conn;
-        final String proxyHost = getProxyHost();
-        final int proxyPort = getProxyPortInt();
-        if (proxyHost.length() > 0 && proxyPort > 0){
-            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
-            //TODO - how to define proxy authentication for a single connection?
-            // It's not clear if this is possible
-//            String user = getProxyUser();
-//            if (user.length() > 0){
-//                Authenticator auth = new ProxyAuthenticator(user, getProxyPass());
-//            }
-            conn = (HttpURLConnection) u.openConnection(proxy);
-        } else {
-            conn = (HttpURLConnection) u.openConnection();
-        }
-
-        // Update follow redirects setting just for this connection
-        conn.setInstanceFollowRedirects(getAutoRedirects());
-
-        int cto = getConnectTimeout();
-        if (cto > 0){
-            conn.setConnectTimeout(cto);
-        }
-
-        int rto = getResponseTimeout();
-        if (rto > 0){
-            conn.setReadTimeout(rto);
-        }
-
-        if (PROTOCOL_HTTPS.equalsIgnoreCase(u.getProtocol())) {
-            try {
-                if (null != sslmgr){
-                    sslmgr.setContext(conn); // N.B. must be done after opening connection
-                }
-            } catch (Exception e) {
-                log.warn("Problem setting the SSLManager for the connection: ", e);
-            }
-        }
-
-        // a well-bahaved browser is supposed to send 'Connection: close'
-        // with the last request to an HTTP server. Instead, most browsers
-        // leave it to the server to close the connection after their
-        // timeout period. Leave it to the JMeter user to decide.
-        if (getUseKeepAlive()) {
-            conn.setRequestProperty(HEADER_CONNECTION, KEEP_ALIVE);
-        } else {
-            conn.setRequestProperty(HEADER_CONNECTION, CONNECTION_CLOSE);
-        }
-
-        conn.setRequestMethod(method);
-        setConnectionHeaders(conn, u, getHeaderManager(), getCacheManager());
-        String cookies = setConnectionCookie(conn, u, getCookieManager());
-
-        setConnectionAuthorization(conn, u, getAuthManager());
-
-        if (method.equals(POST)) {
-            setPostHeaders(conn);
-        } else if (method.equals(PUT)) {
-            setPutHeaders(conn);
-        }
-
-        if (res != null) {
-            res.setRequestHeaders(getConnectionHeaders(conn));
-            res.setCookies(cookies);
-        }
-
-        return conn;
-    }
-
-    /**
-     * Reads the response from the URL connection.
-     *
-     * @param conn
-     *            URL from which to read response
-     * @return response content
-     * @exception IOException
-     *                if an I/O exception occurs
-     */
-    protected byte[] readResponse(HttpURLConnection conn, SampleResult res) throws IOException {
-        BufferedInputStream in;
-
-        final int contentLength = conn.getContentLength();
-        if ((contentLength == 0)
-            && OBEY_CONTENT_LENGTH) {
-            log.info("Content-Length: 0, not reading http-body");
-            res.setResponseHeaders(getResponseHeaders(conn));
-            res.latencyEnd();
-            return NULL_BA;
-        }
-
-        // works OK even if ContentEncoding is null
-        boolean gzipped = ENCODING_GZIP.equals(conn.getContentEncoding());
-
-        try {
-            if (gzipped) {
-                in = new BufferedInputStream(new GZIPInputStream(conn.getInputStream()));
-            } else {
-                in = new BufferedInputStream(conn.getInputStream());
-            }
-        } catch (IOException e) {
-            if (! (e.getCause() instanceof FileNotFoundException))
-            {
-                log.error("readResponse: "+e.toString());
-                Throwable cause = e.getCause();
-                if (cause != null){
-                    log.error("Cause: "+cause);
-                }
-            }
-            // Normal InputStream is not available
-            InputStream errorStream = conn.getErrorStream();
-            if (errorStream == null) {
-                log.info("Error Response Code: "+conn.getResponseCode()+", Server sent no Errorpage");
-                res.setResponseHeaders(getResponseHeaders(conn));
-                res.latencyEnd();
-                return NULL_BA;
-            }
-
-            log.info("Error Response Code: "+conn.getResponseCode());
-
-            if (gzipped) {
-                in = new BufferedInputStream(new GZIPInputStream(errorStream));
-            } else {
-                in = new BufferedInputStream(errorStream);
-            }
-        } catch (Exception e) {
-            log.error("readResponse: "+e.toString());
-            Throwable cause = e.getCause();
-            if (cause != null){
-                log.error("Cause: "+cause);
-            }
-            in = new BufferedInputStream(conn.getErrorStream());
-        }
-        return readResponse(res, in, contentLength);
-    }
-
-    /**
-     * Gets the ResponseHeaders from the URLConnection
-     *
-     * @param conn
-     *            connection from which the headers are read
-     * @return string containing the headers, one per line
-     */
-    protected String getResponseHeaders(HttpURLConnection conn) {
-        StringBuilder headerBuf = new StringBuilder();
-        headerBuf.append(conn.getHeaderField(0));// Leave header as is
-        // headerBuf.append(conn.getHeaderField(0).substring(0, 8));
-        // headerBuf.append(" ");
-        // headerBuf.append(conn.getResponseCode());
-        // headerBuf.append(" ");
-        // headerBuf.append(conn.getResponseMessage());
-        headerBuf.append("\n"); //$NON-NLS-1$
-
-        String hfk;
-        for (int i = 1; (hfk=conn.getHeaderFieldKey(i)) != null; i++) {
-            headerBuf.append(hfk);
-            headerBuf.append(": "); // $NON-NLS-1$
-            headerBuf.append(conn.getHeaderField(i));
-            headerBuf.append("\n"); // $NON-NLS-1$
-        }
-        return headerBuf.toString();
-    }
-
-    /**
-     * Extracts all the required cookies for that particular URL request and
-     * sets them in the <code>HttpURLConnection</code> passed in.
-     *
-     * @param conn
-     *            <code>HttpUrlConnection</code> which represents the URL
-     *            request
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param cookieManager
-     *            the <code>CookieManager</code> containing all the cookies
-     *            for this <code>UrlConfig</code>
-     */
-    private String setConnectionCookie(HttpURLConnection conn, URL u, CookieManager cookieManager) {
-        String cookieHeader = null;
-        if (cookieManager != null) {
-            cookieHeader = cookieManager.getCookieHeaderForURL(u);
-            if (cookieHeader != null) {
-                conn.setRequestProperty(HEADER_COOKIE, cookieHeader);
-            }
-        }
-        return cookieHeader;
-    }
-
-    /**
-     * Extracts all the required headers for that particular URL request and
-     * sets them in the <code>HttpURLConnection</code> passed in
-     *
-     * @param conn
-     *            <code>HttpUrlConnection</code> which represents the URL
-     *            request
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param headerManager
-     *            the <code>HeaderManager</code> containing all the cookies
-     *            for this <code>UrlConfig</code>
-     * @param cacheManager the CacheManager (may be null)
-     */
-    private void setConnectionHeaders(HttpURLConnection conn, URL u, HeaderManager headerManager, CacheManager cacheManager) {
-        // Add all the headers from the HeaderManager
-        if (headerManager != null) {
-            CollectionProperty headers = headerManager.getHeaders();
-            if (headers != null) {
-                PropertyIterator i = headers.iterator();
-                while (i.hasNext()) {
-                    Header header = (Header) i.next().getObjectValue();
-                    String n = header.getName();
-                    String v = header.getValue();
-                    conn.addRequestProperty(n, v);
-                }
-            }
-        }
-        if (cacheManager != null){
-            cacheManager.setHeaders(conn, u);
-        }
-    }
-
-    /**
-     * Get all the headers for the <code>HttpURLConnection</code> passed in
-     *
-     * @param conn
-     *            <code>HttpUrlConnection</code> which represents the URL
-     *            request
-     * @return the headers as a string
-     */
-    private String getConnectionHeaders(HttpURLConnection conn) {
-        // Get all the request properties, which are the headers set on the connection
-        StringBuilder hdrs = new StringBuilder(100);
-        Map<String, List<String>> requestHeaders = conn.getRequestProperties();
-        Set<Map.Entry<String, List<String>>> headerFields = requestHeaders.entrySet();
-        for(Iterator<Map.Entry<String, List<String>>> i = headerFields.iterator(); i.hasNext();) {
-            Map.Entry<String, List<String>> entry = i.next();
-            String headerKey=entry.getKey();
-            // Exclude the COOKIE header, since cookie is reported separately in the sample
-            if(!HEADER_COOKIE.equalsIgnoreCase(headerKey)) {
-                List<String> values = entry.getValue();// value is a List of Strings
-                for (int j=0;j<values.size();j++){
-                    hdrs.append(headerKey);
-                    hdrs.append(": "); // $NON-NLS-1$
-                    hdrs.append(values.get(j));
-                    hdrs.append("\n"); // $NON-NLS-1$
-                }
-            }
-        }
-        return hdrs.toString();
-    }
-
-    /**
-     * Extracts all the required authorization for that particular URL request
-     * and sets it in the <code>HttpURLConnection</code> passed in.
-     *
-     * @param conn
-     *            <code>HttpUrlConnection</code> which represents the URL
-     *            request
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param authManager
-     *            the <code>AuthManager</code> containing all the cookies for
-     *            this <code>UrlConfig</code>
-     */
-    private void setConnectionAuthorization(HttpURLConnection conn, URL u, AuthManager authManager) {
-        if (authManager != null) {
-            Authorization auth = authManager.getAuthForURL(u);
-            if (auth != null) {
-                conn.setRequestProperty(HEADER_AUTHORIZATION, auth.toBasicHeader());
-            }
-        }
+    public boolean interrupt() {
+        return hc.interrupt();
     }
 
-    /**
-     * Samples the URL passed in and stores the result in
-     * <code>HTTPSampleResult</code>, following redirects and downloading
-     * page resources as appropriate.
-     * <p>
-     * When getting a redirect target, redirects are not followed and resources
-     * are not downloaded. The caller will take care of this.
-     *
-     * @param url
-     *            URL to sample
-     * @param method
-     *            HTTP method: GET, POST,...
-     * @param areFollowingRedirect
-     *            whether we're getting a redirect target
-     * @param frameDepth
-     *            Depth of this target in the frame structure. Used only to
-     *            prevent infinite recursion.
-     * @return results of the sampling
-     */
     @Override
-    protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
-        HttpURLConnection conn = null;
-
-        String urlStr = url.toString();
-        log.debug("Start : sample " + urlStr);
-
-        HTTPSampleResult res = new HTTPSampleResult();
-        res.setMonitor(isMonitor());
-
-        res.setSampleLabel(urlStr);
-        res.setURL(url);
-        res.setHTTPMethod(method);
-
-        res.sampleStart(); // Count the retries as well in the time
-
-        // Check cache for an entry with an Expires header in the future
-        final CacheManager cacheManager = getCacheManager();
-        if (cacheManager != null && GET.equalsIgnoreCase(method)) {
-           if (cacheManager.inCache(url)) {
-               res.sampleEnd();
-               res.setResponseNoContent();
-               res.setSuccessful(true);
-               return res;
-           }
-        }
-
-        try {
-            // Sampling proper - establish the connection and read the response:
-            // Repeatedly try to connect:
-            int retry;
-            // Start with 0 so tries at least once, and retries at most MAX_CONN_RETRIES times
-            for (retry = 0; retry <= MAX_CONN_RETRIES; retry++) {
-                try {
-                    conn = setupConnection(url, method, res);
-                    // Attempt the connection:
-                    savedConn = conn;
-                    conn.connect();
-                    break;
-                } catch (BindException e) {
-                    if (retry >= MAX_CONN_RETRIES) {
-                        log.error("Can't connect after "+retry+" retries, "+e);
-                        throw e;
-                    }
-                    log.debug("Bind exception, try again");
-                    if (conn!=null) {
-                        savedConn = null; // we don't want interrupt to try disconnection again
-                        conn.disconnect();
-                    }
-                    this.setUseKeepAlive(false);
-                    continue; // try again
-                } catch (IOException e) {
-                    log.debug("Connection failed, giving up");
-                    throw e;
-                }
-            }
-            if (retry > MAX_CONN_RETRIES) {
-                // This should never happen, but...
-                throw new BindException();
-            }
-            // Nice, we've got a connection. Finish sending the request:
-            if (method.equals(POST)) {
-                String postBody = sendPostData(conn);
-                res.setQueryString(postBody);
-            }
-            else if (method.equals(PUT)) {
-                String putBody = sendPutData(conn);
-                res.setQueryString(putBody);
-            }
-            // Request sent. Now get the response:
-            byte[] responseData = readResponse(conn, res);
-
-            res.sampleEnd();
-            // Done with the sampling proper.
-
-            // Now collect the results into the HTTPSampleResult:
-
-            res.setResponseData(responseData);
-
-            int errorLevel = conn.getResponseCode();
-            String respMsg = conn.getResponseMessage();
-            String hdr=conn.getHeaderField(0);
-            if (hdr == null) {
-                hdr="(null)";  // $NON-NLS-1$
-            }
-            if (errorLevel == -1){// Bug 38902 - sometimes -1 seems to be returned unnecessarily
-                if (respMsg != null) {// Bug 41902 - NPE
-                    try {
-                        errorLevel = Integer.parseInt(respMsg.substring(0, 3));
-                        log.warn("ResponseCode==-1; parsed "+respMsg+ " as "+errorLevel);
-                      } catch (NumberFormatException e) {
-                        log.warn("ResponseCode==-1; could not parse "+respMsg+" hdr: "+hdr);
-                      }
-                } else {
-                    respMsg=hdr; // for result
-                    log.warn("ResponseCode==-1 & null ResponseMessage. Header(0)= "+hdr);
-                }
-            }
-            if (errorLevel == -1) {
-                res.setResponseCode("(null)"); // $NON-NLS-1$
-            } else {
-                res.setResponseCode(Integer.toString(errorLevel));
-            }
-            res.setSuccessful(isSuccessCode(errorLevel));
-
-            if (respMsg == null) {// has been seen in a redirect
-                respMsg=hdr; // use header (if possible) if no message found
-            }
-            res.setResponseMessage(respMsg);
-
-            String ct = conn.getContentType();
-            if (ct != null){
-                res.setContentType(ct);// e.g. text/html; charset=ISO-8859-1
-                res.setEncodingAndType(ct);
-            }
-
-            res.setResponseHeaders(getResponseHeaders(conn));
-            if (res.isRedirect()) {
-                res.setRedirectLocation(conn.getHeaderField(HEADER_LOCATION));
-            }
-
-            // If we redirected automatically, the URL may have changed
-            if (getAutoRedirects()){
-                res.setURL(conn.getURL());
-            }
-
-            // Store any cookies received in the cookie manager:
-            saveConnectionCookies(conn, url, getCookieManager());
-
-            // Save cache information
-            if (cacheManager != null){
-                cacheManager.saveDetails(conn, res);
-            }
-
-            res = resultProcessing(areFollowingRedirect, frameDepth, res);
-
-            log.debug("End : sample");
-            return res;
-        } catch (IOException e) {
-            res.sampleEnd();
-            // We don't want to continue using this connection, even if KeepAlive is set
-            if (conn != null) { // May not exist
-                savedConn = null; // we don't want interrupt to try disconnection again
-                conn.disconnect();
-            }
-            savedConn = null; // we don't want interrupt to try disconnection again
-            conn=null; // Don't process again
-            return errorResult(e, res);
-        } finally {
-            // calling disconnect doesn't close the connection immediately,
-            // but indicates we're through with it. The JVM should close
-            // it when necessary.
-            savedConn = null; // we don't want interrupt to try disconnection again
-            disconnect(conn); // Disconnect unless using KeepAlive
-        }
-    }
-
-    protected void disconnect(HttpURLConnection conn) {
-        if (conn != null) {
-            String connection = conn.getHeaderField(HEADER_CONNECTION);
-            String protocol = conn.getHeaderField(0);
-            if ((connection == null && (protocol == null || !protocol.startsWith(HTTP_1_1)))
-                    || (connection != null && connection.equalsIgnoreCase(CONNECTION_CLOSE))) {
-                conn.disconnect();
-            } // TODO ? perhaps note connection so it can be disconnected at end of test?
-        }
-    }
-
-    /**
-     * From the <code>HttpURLConnection</code>, store all the "set-cookie"
-     * key-pair values in the cookieManager of the <code>UrlConfig</code>.
-     *
-     * @param conn
-     *            <code>HttpUrlConnection</code> which represents the URL
-     *            request
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param cookieManager
-     *            the <code>CookieManager</code> containing all the cookies
-     *            for this <code>UrlConfig</code>
-     */
-    private void saveConnectionCookies(HttpURLConnection conn, URL u, CookieManager cookieManager) {
-        if (cookieManager != null) {
-            for (int i = 1; conn.getHeaderFieldKey(i) != null; i++) {
-                if (conn.getHeaderFieldKey(i).equalsIgnoreCase(HEADER_SET_COOKIE)) {
-                    cookieManager.addCookieFromHeader(conn.getHeaderField(i), u);
-                }
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    public boolean interrupt() {
-        HttpURLConnection conn = savedConn;
-        if (conn != null) {
-            savedConn = null;
-            conn.disconnect();
-        }
-        return conn != null;
+    protected HTTPSampleResult sample(java.net.URL u, String method,
+            boolean areFollowingRedirect, int depth) {
+        return hc.sample(u, method, areFollowingRedirect, depth);
     }
 }

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=1040363&r1=1040362&r2=1040363&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 Tue Nov 30 00:43:01 2010
@@ -16,1158 +16,32 @@
  */
 package org.apache.jmeter.protocol.http.sampler;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HostConfiguration;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpConnectionManager;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpMethodBase;
-import org.apache.commons.httpclient.HttpVersion;
-import org.apache.commons.httpclient.NTCredentials;
-import org.apache.commons.httpclient.ProtocolException;
-import org.apache.commons.httpclient.SimpleHttpConnectionManager;
-import org.apache.commons.httpclient.auth.AuthScope;
-import org.apache.commons.httpclient.cookie.CookiePolicy;
-import org.apache.commons.httpclient.methods.DeleteMethod;
-import org.apache.commons.httpclient.methods.FileRequestEntity;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.HeadMethod;
-import org.apache.commons.httpclient.methods.OptionsMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.PutMethod;
-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;
-import org.apache.commons.httpclient.methods.multipart.Part;
-import org.apache.commons.httpclient.methods.multipart.PartBase;
-import org.apache.commons.httpclient.methods.multipart.StringPart;
-import org.apache.commons.httpclient.params.DefaultHttpParams;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.apache.commons.httpclient.params.HttpParams;
-import org.apache.commons.httpclient.protocol.Protocol;
-import org.apache.jmeter.JMeter;
-import org.apache.jmeter.protocol.http.control.AuthManager;
-import org.apache.jmeter.protocol.http.control.Authorization;
-import org.apache.jmeter.protocol.http.control.CacheManager;
-import org.apache.jmeter.protocol.http.control.CookieManager;
-import org.apache.jmeter.protocol.http.control.HeaderManager;
-import org.apache.jmeter.protocol.http.util.EncoderCache;
-import org.apache.jmeter.protocol.http.util.HTTPArgument;
-import org.apache.jmeter.protocol.http.util.HTTPFileArg;
-import org.apache.jmeter.protocol.http.util.LoopbackHttpClientSocketFactory;
-import org.apache.jmeter.protocol.http.util.SlowHttpClientSocketFactory;
 import org.apache.jmeter.samplers.Interruptible;
-import org.apache.jmeter.testelement.property.CollectionProperty;
-import org.apache.jmeter.testelement.property.PropertyIterator;
-import org.apache.jmeter.util.JMeterUtils;
-import org.apache.jmeter.util.SSLManager;
-import org.apache.jorphan.logging.LoggingManager;
-import org.apache.jorphan.util.JOrphanUtils;
-import org.apache.log.Logger;
 
 /**
  * A sampler which understands all the parts necessary to read statistics about
  * HTTP requests, including cookies and authentication.
+ * This sampler uses HttpClient 3.1.
  *
  */
 public class HTTPSampler2 extends HTTPSamplerBase implements Interruptible {
 
-    private static final Logger log = LoggingManager.getLoggerForClass();
-
     private static final long serialVersionUID = 240L;
 
-    private static final String HTTP_AUTHENTICATION_PREEMPTIVE = "http.authentication.preemptive"; // $NON-NLS-1$
-
-    private static final boolean canSetPreEmptive; // OK to set pre-emptive auth?
-
-    private static final String PROXY_HOST =
-        System.getProperty("http.proxyHost",""); // $NON-NLS-1$
-
-    private static final String NONPROXY_HOSTS =
-        System.getProperty("http.nonProxyHosts",""); // $NON-NLS-1$
-
-    private static final int PROXY_PORT =
-        Integer.parseInt(System.getProperty("http.proxyPort","0")); // $NON-NLS-1$
-
-    // Have proxy details been provided?
-    private static final boolean PROXY_DEFINED = PROXY_HOST.length() > 0 && PROXY_PORT > 0;
-
-    private static final String PROXY_USER =
-        JMeterUtils.getPropDefault(JMeter.HTTP_PROXY_USER,""); // $NON-NLS-1$
-
-    private static final String PROXY_PASS =
-        JMeterUtils.getPropDefault(JMeter.HTTP_PROXY_PASS,""); // $NON-NLS-1$
-
-    private static final String PROXY_DOMAIN =
-        JMeterUtils.getPropDefault("http.proxyDomain",""); // $NON-NLS-1$ $NON-NLS-2$
-
-    static final InetAddress localAddress;
-
-    private static final String localHost;
-
-    /*
-     * Connection is re-used within the thread if possible
-     */
-    static final ThreadLocal<Map<HostConfiguration, HttpClient>> httpClients =
-        new ThreadLocal<Map<HostConfiguration, HttpClient>>();
-
-    private static final Set<String> nonProxyHostFull   = new HashSet<String>();// www.apache.org
-    private static final List<String> nonProxyHostSuffix = new ArrayList<String>();// .apache.org
-
-    private static final int nonProxyHostSuffixSize;
-
-    protected volatile HttpClient savedClient;
-
-    private static boolean isNonProxy(String host){
-        return nonProxyHostFull.contains(host) || isPartialMatch(host);
-    }
-
-    private static boolean isPartialMatch(String host) {
-        for (int i=0;i<nonProxyHostSuffixSize;i++){
-            if (host.endsWith(nonProxyHostSuffix.get(i))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static {
-        if (NONPROXY_HOSTS.length() > 0){
-            StringTokenizer s = new StringTokenizer(NONPROXY_HOSTS,"|");// $NON-NLS-1$
-            while (s.hasMoreTokens()){
-                String t = s.nextToken();
-                if (t.indexOf("*") ==0){// e.g. *.apache.org // $NON-NLS-1$
-                    nonProxyHostSuffix.add(t.substring(1));
-                } else {
-                    nonProxyHostFull.add(t);// e.g. www.apache.org
-                }
-            }
-        }
-        nonProxyHostSuffixSize=nonProxyHostSuffix.size();
-
-        int cps =
-            JMeterUtils.getPropDefault("httpclient.socket.http.cps", 0); // $NON-NLS-1$
-
-        if (cps > 0) {
-            log.info("Setting up HTTP SlowProtocol, cps="+cps);
-            Protocol.registerProtocol(PROTOCOL_HTTP,
-                    new Protocol(PROTOCOL_HTTP,new SlowHttpClientSocketFactory(cps),DEFAULT_HTTP_PORT));
-        }
-
-        // Now done in JsseSSLManager (which needs to register the protocol)
-//        cps =
-//            JMeterUtils.getPropDefault("httpclient.socket.https.cps", 0); // $NON-NLS-1$
-//
-//        if (cps > 0) {
-//            log.info("Setting up HTTPS SlowProtocol, cps="+cps);
-//            Protocol.registerProtocol(PROTOCOL_HTTPS,
-//                    new Protocol(PROTOCOL_HTTPS,new SlowHttpClientSocketFactory(cps),DEFAULT_HTTPS_PORT));
-//        }
-
-        InetAddress inet=null;
-        String localHostOrIP =
-            JMeterUtils.getPropDefault("httpclient.localaddress",""); // $NON-NLS-1$
-        if (localHostOrIP.length() > 0){
-            try {
-                inet = InetAddress.getByName(localHostOrIP);
-                log.info("Using localAddress "+inet.getHostAddress());
-            } catch (UnknownHostException e) {
-                log.warn(e.getLocalizedMessage());
-            }
-        } else {
-            try {
-                InetAddress addr = InetAddress.getLocalHost();
-                // Get hostname
-                localHostOrIP = addr.getHostName();
-            } catch (UnknownHostException e) {
-                log.warn("Cannot determine localhost name, and httpclient.localaddress was not specified");
-            }
-        }
-        localAddress = inet;
-        localHost = localHostOrIP;
-        log.info("Local host = "+localHost);
-
-        // Set default parameters as needed
-       HttpParams params = DefaultHttpParams.getDefaultParams();
-
-        // Process httpclient parameters file
-        String file=JMeterUtils.getProperty("httpclient.parameters.file"); // $NON-NLS-1$
-        if (file != null) {
-            HttpClientDefaultParameters.load(file,params);
-        }
-
-        // If the pre-emptive parameter is undefined, then we cans set it as needed
-        // otherwise we should do what the user requested.
-        canSetPreEmptive =  params.getParameter(HTTP_AUTHENTICATION_PREEMPTIVE) == null;
-
-        // Handle old-style JMeter properties
-        // Default to HTTP version 1.1
-        String ver=JMeterUtils.getPropDefault("httpclient.version","1.1"); // $NON-NLS-1$ $NON-NLS-2$
-        try {
-            params.setParameter(HttpMethodParams.PROTOCOL_VERSION, HttpVersion.parse("HTTP/"+ver));
-        } catch (ProtocolException e) {
-            log.warn("Problem setting protocol version "+e.getLocalizedMessage());
-        }
-        String to= JMeterUtils.getProperty("httpclient.timeout"); // $NON-NLS-1$
-        if (to != null){
-            params.setIntParameter(HttpMethodParams.SO_TIMEOUT, Integer.parseInt(to));
-        }
-
-        // This must be done last, as must not be overridden
-        params.setParameter(HttpMethodParams.COOKIE_POLICY,CookiePolicy.IGNORE_COOKIES);
-        // We do our own cookie handling
-
-        if (JMeterUtils.getPropDefault("httpclient.loopback",false)){// $NON-NLS-1$
-            LoopbackHttpClientSocketFactory.setup();
-        }
+    private final transient HTTPAbstractImpl hc;
+    
+    public HTTPSampler2(){
+        hc = new HTTPJavaImpl(this);
     }
 
-    /**
-     * Constructor for the HTTPSampler2 object.
-     *
-     * Consider using HTTPSamplerFactory.newInstance() instead
-     */
-    public HTTPSampler2() {
-    }
-
-    /*
-     * Send POST data from <code>Entry</code> to the open connection.
-     *
-     * @param connection
-     *            <code>URLConnection</code> where POST data should be sent
-     * @return a String show what was posted. Will not contain actual file upload content
-     * @exception IOException
-     *                if an I/O exception occurs
-     */
-    private String sendPostData(PostMethod post) throws IOException {
-        // Buffer to hold the post body, except file content
-        StringBuilder postedBody = new StringBuilder(1000);
-        HTTPFileArg files[] = getHTTPFiles();
-        // Check if we should do a multipart/form-data or an
-        // 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
-            String contentEncoding = getContentEncoding();
-            if(contentEncoding != null && contentEncoding.length() == 0) {
-                contentEncoding = null;
-            }
-
-            // We don't know how many entries will be skipped
-            ArrayList<PartBase> partlist = new ArrayList<PartBase>();
-            // Create the parts
-            // Add any parameters
-            PropertyIterator args = getArguments().iterator();
-            while (args.hasNext()) {
-               HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
-               String parameterName = arg.getName();
-               if (arg.isSkippable(parameterName)){
-                   continue;
-               }
-               partlist.add(new StringPart(arg.getName(), arg.getValue(), contentEncoding));
-            }
-
-            // Add any files
-            for (int i=0; i < files.length; i++) {
-                HTTPFileArg file = files[i];
-                File inputFile = new File(file.getPath());
-                // We do not know the char set of the file to be uploaded, so we set it to null
-                ViewableFilePart filePart = new ViewableFilePart(file.getParamName(), inputFile, file.getMimeType(), null);
-                filePart.setCharSet(null); // We do not know what the char set of the file is
-                partlist.add(filePart);
-            }
-
-            // Set the multipart for the post
-            int partNo = partlist.size();
-            Part[] parts = partlist.toArray(new Part[partNo]);
-            MultipartRequestEntity multiPart = new MultipartRequestEntity(parts, post.getParams());
-            post.setRequestEntity(multiPart);
-
-            // Set the content type
-            String multiPartContentType = multiPart.getContentType();
-            post.setRequestHeader(HEADER_CONTENT_TYPE, multiPartContentType);
-
-            // If the Multipart is repeatable, we can send it first to
-            // our own stream, without the actual file content, so we can return it
-            if(multiPart.isRepeatable()) {
-                // For all the file multiparts, we must tell it to not include
-                // the actual file content
-                for(int i = 0; i < partNo; i++) {
-                    if(parts[i] instanceof ViewableFilePart) {
-                        ((ViewableFilePart) parts[i]).setHideFileData(true); // .sendMultipartWithoutFileContent(bos);
-                    }
-                }
-                // Write the request to our own stream
-                ByteArrayOutputStream bos = new ByteArrayOutputStream();
-                multiPart.writeRequest(bos);
-                bos.flush();
-                // We get the posted bytes using the encoding used to create it
-                postedBody.append(new String(bos.toByteArray(),
-                        contentEncoding == null ? "US-ASCII" // $NON-NLS-1$ this is the default used by HttpClient
-                        : contentEncoding));
-                bos.close();
-
-                // For all the file multiparts, we must revert the hiding of
-                // the actual file content
-                for(int i = 0; i < partNo; i++) {
-                    if(parts[i] instanceof ViewableFilePart) {
-                        ((ViewableFilePart) parts[i]).setHideFileData(false);
-                    }
-                }
-            }
-            else {
-                postedBody.append("<Multipart was not repeatable, cannot view what was sent>"); // $NON-NLS-1$
-            }
-        }
-        else {
-            // 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
-            // 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.setRequestHeader(HEADER_CONTENT_TYPE, file.getMimeType());
-                    }
-                    else {
-                        post.setRequestHeader(HEADER_CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED);
-                    }
-                }
-
-                FileRequestEntity fileRequestEntity = new FileRequestEntity(new File(file.getPath()),null);
-                post.setRequestEntity(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 a content encoding is specified, we set it as http parameter, so that
-                // the post body will be encoded in the specified content encoding
-                String contentEncoding = getContentEncoding();
-                boolean haveContentEncoding = false;
-                if(contentEncoding != null && contentEncoding.trim().length() > 0) {
-                    post.getParams().setContentCharset(contentEncoding);
-                    haveContentEncoding = true;
-                } else if (contentEncoding != null && contentEncoding.trim().length() == 0){
-                    contentEncoding=null;
-                }
-
-                // 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 scenerio
-                    if(!hasContentTypeHeader) {
-                        HTTPFileArg file = files.length > 0? files[0] : null;
-                        if(file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
-                            post.setRequestHeader(HEADER_CONTENT_TYPE, file.getMimeType());
-                        }
-                        else {
-                             // TODO - is this the correct default?
-                            post.setRequestHeader(HEADER_CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED);
-                        }
-                    }
-
-                    // Just append all the parameter values, and use that as the post body
-                    StringBuilder postBody = new StringBuilder();
-                    PropertyIterator args = getArguments().iterator();
-                    while (args.hasNext()) {
-                        HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
-                        String value;
-                        if (haveContentEncoding){
-                            value = arg.getEncodedValue(contentEncoding);
-                        } else {
-                            value = arg.getEncodedValue();
-                        }
-                        postBody.append(value);
-                    }
-                    StringRequestEntity requestEntity = new StringRequestEntity(postBody.toString(), post.getRequestHeader(HEADER_CONTENT_TYPE).getValue(), contentEncoding);
-                    post.setRequestEntity(requestEntity);
-                }
-                else {
-                    // It is a normal post request, with parameter names and values
-
-                    // Set the content type
-                    if(!hasContentTypeHeader) {
-                        post.setRequestHeader(HEADER_CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED);
-                    }
-                    // Add the parameters
-                    PropertyIterator args = getArguments().iterator();
-                    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.
-                            String urlContentEncoding = contentEncoding;
-                            if(urlContentEncoding == null || urlContentEncoding.length() == 0) {
-                                // Use the default encoding for urls
-                                urlContentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
-                            }
-                            parameterName = URLDecoder.decode(parameterName, urlContentEncoding);
-                            parameterValue = URLDecoder.decode(parameterValue, urlContentEncoding);
-                        }
-                        // Add the parameter, httpclient will urlencode it
-                        post.addParameter(parameterName, parameterValue);
-                    }
-
-/*
-//                    // Alternative implementation, to make sure that HTTPSampler and HTTPSampler2
-//                    // sends the same post body.
-//
-//                    // Only include the content char set in the content-type header if it is not
-//                    // an APPLICATION_X_WWW_FORM_URLENCODED content type
-//                    String contentCharSet = null;
-//                    if(!post.getRequestHeader(HEADER_CONTENT_TYPE).getValue().equals(APPLICATION_X_WWW_FORM_URLENCODED)) {
-//                        contentCharSet = post.getRequestCharSet();
-//                    }
-//                    StringRequestEntity requestEntity = new StringRequestEntity(getQueryString(contentEncoding), post.getRequestHeader(HEADER_CONTENT_TYPE).getValue(), contentCharSet);
-//                    post.setRequestEntity(requestEntity);
-*/
-                }
-
-                // 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();
-                    post.getRequestEntity().writeRequest(bos);
-                    bos.flush();
-                    // We get the posted bytes using the encoding used to create it
-                    postedBody.append(new String(bos.toByteArray(),post.getRequestCharSet()));
-                    bos.close();
-                }
-                else {
-                    postedBody.append("<RequestEntity was not repeatable, cannot view what was sent>");
-                }
-            }
-        }
-        // Set the content length
-        post.setRequestHeader(HEADER_CONTENT_LENGTH, Long.toString(post.getRequestEntity().getContentLength()));
-
-        return postedBody.toString();
-    }
-
-    /**
-     * Returns an <code>HttpConnection</code> fully ready to attempt
-     * connection. This means it sets the request method (GET or POST), headers,
-     * cookies, and authorization for the URL request.
-     * <p>
-     * The request infos are saved into the sample result if one is provided.
-     *
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param httpMethod
-     *            GET/PUT/HEAD etc
-     * @param res
-     *            sample result to save request infos to
-     * @return <code>HttpConnection</code> ready for .connect
-     * @exception IOException
-     *                if an I/O Exception occurs
-     */
-    protected HttpClient setupConnection(URL u, HttpMethodBase httpMethod, HTTPSampleResult res) throws IOException {
-
-        String urlStr = u.toString();
-
-        org.apache.commons.httpclient.URI uri = new org.apache.commons.httpclient.URI(urlStr,false);
-
-        String schema = uri.getScheme();
-        if ((schema == null) || (schema.length()==0)) {
-            schema = PROTOCOL_HTTP;
-        }
-
-        if (PROTOCOL_HTTPS.equalsIgnoreCase(schema)){
-            SSLManager.getInstance(); // ensure the manager is initialised
-            // we don't currently need to do anything further, as this sets the default https protocol
-        }
-
-        Protocol protocol = Protocol.getProtocol(schema);
-
-        String host = uri.getHost();
-        int port = uri.getPort();
-
-        /*
-         *  We use the HostConfiguration as the key to retrieve the HttpClient,
-         *  so need to ensure that any items used in its equals/hashcode methods are
-         *  not changed after use, i.e.:
-         *  host, port, protocol, localAddress, proxy
-         *
-        */
-        HostConfiguration hc = new HostConfiguration();
-        hc.setHost(host, port, protocol); // All needed to ensure re-usablility
-
-        // Set up the local address if one exists
-        if (localAddress != null){
-            hc.setLocalAddress(localAddress);
-        } else {
-            final String ipSource = getIpSource();
-            if (ipSource.length() > 0) {// Use special field ip source address (for pseudo 'ip spoofing')
-                InetAddress inetAddr = InetAddress.getByName(ipSource);
-                hc.setLocalAddress(inetAddr);
-            }
-        }
-
-        boolean useStaticProxy = PROXY_DEFINED && !isNonProxy(host);
-        boolean useDynamicProxy = false;
-
-        final String proxyHost = getProxyHost();
-        final int proxyPort = getProxyPortInt();
-        if (proxyHost.length() > 0 && proxyPort > 0){
-            hc.setProxy(proxyHost, proxyPort);
-            useStaticProxy = false; // Dynamic proxy overrules static proxy
-            useDynamicProxy = true;
-        } else {
-            if (useStaticProxy) {
-                if (log.isDebugEnabled()){
-                    log.debug("Setting proxy: "+PROXY_HOST+":"+PROXY_PORT);
-                }
-                hc.setProxy(PROXY_HOST, PROXY_PORT);
-            }
-        }
-
-        Map<HostConfiguration, HttpClient> map = httpClients.get();
-        // N.B. HostConfiguration.equals() includes proxy settings in the compare.
-        HttpClient httpClient = map.get(hc);
-
-        if ( httpClient == null )
-        {
-            httpClient = new HttpClient(new SimpleHttpConnectionManager());
-            if (log.isDebugEnabled()) {
-                log.debug("Created new HttpClient: @"+System.identityHashCode(httpClient));
-            }
-            httpClient.setHostConfiguration(hc);
-            map.put(hc, httpClient);
-        } else {
-            if (log.isDebugEnabled()) {
-                log.debug("Reusing the HttpClient: @"+System.identityHashCode(httpClient));
-            }
-        }
-
-        // Set up any required Proxy credentials
-        if (useDynamicProxy){
-            String user = getProxyUser();
-            if (user.length() > 0){
-                httpClient.getState().setProxyCredentials(
-                        new AuthScope(proxyHost,proxyPort,null,AuthScope.ANY_SCHEME),
-                        new NTCredentials(user,getProxyPass(),localHost,PROXY_DOMAIN)
-                    );
-            } else {
-                httpClient.getState().clearProxyCredentials();
-            }
-        } else {
-            if (useStaticProxy) {
-                if (PROXY_USER.length() > 0){
-                    httpClient.getState().setProxyCredentials(
-                        new AuthScope(PROXY_HOST,PROXY_PORT,null,AuthScope.ANY_SCHEME),
-                        new NTCredentials(PROXY_USER,PROXY_PASS,localHost,PROXY_DOMAIN)
-                    );
-                }
-            } else {
-                httpClient.getState().clearProxyCredentials();
-            }
-        }
-
-        int rto = getResponseTimeout();
-        if (rto > 0){
-            httpMethod.getParams().setSoTimeout(rto);
-        }
-
-        int cto = getConnectTimeout();
-        if (cto > 0){
-            httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(cto);
-        }
-
-
-        // Allow HttpClient to handle the redirects:
-        httpMethod.setFollowRedirects(getAutoRedirects());
-
-        // a well-behaved browser is supposed to send 'Connection: close'
-        // with the last request to an HTTP server. Instead, most browsers
-        // leave it to the server to close the connection after their
-        // timeout period. Leave it to the JMeter user to decide.
-        if (getUseKeepAlive()) {
-            httpMethod.setRequestHeader(HEADER_CONNECTION, KEEP_ALIVE);
-        } else {
-            httpMethod.setRequestHeader(HEADER_CONNECTION, CONNECTION_CLOSE);
-        }
-
-        setConnectionHeaders(httpMethod, u, getHeaderManager(), getCacheManager());
-        String cookies = setConnectionCookie(httpMethod, u, getCookieManager());
-
-        setConnectionAuthorization(httpClient, u, getAuthManager());
-
-        if (res != null) {
-            res.setCookies(cookies);
-        }
-
-        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
-     *
-     * @param method
-     *            connection from which the headers are read
-     * @return string containing the headers, one per line
-     */
-    protected String getResponseHeaders(HttpMethod method) {
-        StringBuilder headerBuf = new StringBuilder();
-        org.apache.commons.httpclient.Header rh[] = method.getResponseHeaders();
-        headerBuf.append(method.getStatusLine());// header[0] is not the status line...
-        headerBuf.append("\n"); // $NON-NLS-1$
-
-        for (int i = 0; i < rh.length; i++) {
-            String key = rh[i].getName();
-            headerBuf.append(key);
-            headerBuf.append(": "); // $NON-NLS-1$
-            headerBuf.append(rh[i].getValue());
-            headerBuf.append("\n"); // $NON-NLS-1$
-        }
-        return headerBuf.toString();
-    }
-
-    /**
-     * Extracts all the required cookies for that particular URL request and
-     * sets them in the <code>HttpMethod</code> passed in.
-     *
-     * @param method <code>HttpMethod</code> for the request
-     * @param u <code>URL</code> of the request
-     * @param cookieManager the <code>CookieManager</code> containing all the cookies
-     * @return a String containing the cookie details (for the response)
-     * May be null
-     */
-    private String setConnectionCookie(HttpMethod method, URL u, CookieManager cookieManager) {
-        String cookieHeader = null;
-        if (cookieManager != null) {
-            cookieHeader = cookieManager.getCookieHeaderForURL(u);
-            if (cookieHeader != null) {
-                method.setRequestHeader(HEADER_COOKIE, cookieHeader);
-            }
-        }
-        return cookieHeader;
-    }
-
-    /**
-     * Extracts all the required non-cookie headers for that particular URL request and
-     * sets them in the <code>HttpMethod</code> passed in
-     *
-     * @param method
-     *            <code>HttpMethod</code> which represents the request
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param headerManager
-     *            the <code>HeaderManager</code> containing all the cookies
-     *            for this <code>UrlConfig</code>
-     * @param cacheManager the CacheManager (may be null)
-     */
-    private void setConnectionHeaders(HttpMethod method, URL u, HeaderManager headerManager, CacheManager cacheManager) {
-        // Set all the headers from the HeaderManager
-        if (headerManager != null) {
-            CollectionProperty headers = headerManager.getHeaders();
-            if (headers != null) {
-                PropertyIterator i = headers.iterator();
-                while (i.hasNext()) {
-                    org.apache.jmeter.protocol.http.control.Header header
-                    = (org.apache.jmeter.protocol.http.control.Header)
-                       i.next().getObjectValue();
-                    String n = header.getName();
-                    // Don't allow override of Content-Length
-                    // This helps with SoapSampler hack too
-                    // TODO - what other headers are not allowed?
-                    if (! HEADER_CONTENT_LENGTH.equalsIgnoreCase(n)){
-                        String v = header.getValue();
-                        method.addRequestHeader(n, v);
-                    }
-                }
-            }
-        }
-        if (cacheManager != null){
-            cacheManager.setHeaders(u, method);
-        }
-    }
-
-    /**
-     * Get all the request headers for the <code>HttpMethod</code>
-     *
-     * @param method
-     *            <code>HttpMethod</code> which represents the request
-     * @return the headers as a string
-     */
-    protected String getConnectionHeaders(HttpMethod method) {
-        // Get all the request headers
-        StringBuilder hdrs = new StringBuilder(100);
-        Header[] requestHeaders = method.getRequestHeaders();
-        for(int i = 0; i < requestHeaders.length; i++) {
-            // Exclude the COOKIE header, since cookie is reported separately in the sample
-            if(!HEADER_COOKIE.equalsIgnoreCase(requestHeaders[i].getName())) {
-                hdrs.append(requestHeaders[i].getName());
-                hdrs.append(": "); // $NON-NLS-1$
-                hdrs.append(requestHeaders[i].getValue());
-                hdrs.append("\n"); // $NON-NLS-1$
-            }
-        }
-
-        return hdrs.toString();
-    }
-
-
-    /**
-     * Extracts all the required authorization for that particular URL request
-     * and sets it in the <code>HttpMethod</code> passed in.
-     *
-     * @param client the HttpClient object
-     *
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param authManager
-     *            the <code>AuthManager</code> containing all the authorisations for
-     *            this <code>UrlConfig</code>
-     */
-    private void setConnectionAuthorization(HttpClient client, URL u, AuthManager authManager) {
-        HttpParams params = client.getParams();
-        if (authManager != null) {
-            Authorization auth = authManager.getAuthForURL(u);
-            if (auth != null) {
-                    String username = auth.getUser();
-                    String realm = auth.getRealm();
-                    String domain = auth.getDomain();
-                    if (log.isDebugEnabled()){
-                        log.debug(username + " >  D="+ username + " D="+domain+" R="+realm);
-                    }
-                    client.getState().setCredentials(
-                            new AuthScope(u.getHost(),u.getPort(),
-                                    realm.length()==0 ? null : realm //"" is not the same as no realm
-                                    ,AuthScope.ANY_SCHEME),
-                            // NT Includes other types of Credentials
-                            new NTCredentials(
-                                    username,
-                                    auth.getPass(),
-                                    localHost,
-                                    domain
-                            ));
-                    // We have credentials - should we set pre-emptive authentication?
-                    if (canSetPreEmptive){
-                        log.debug("Setting Pre-emptive authentication");
-                        params.setBooleanParameter(HTTP_AUTHENTICATION_PREEMPTIVE, true);
-                    }
-            }
-            else
-            {
-                client.getState().clearCredentials();
-                if (canSetPreEmptive){
-                    params.setBooleanParameter(HTTP_AUTHENTICATION_PREEMPTIVE, false);
-                }
-            }
-        }
-        else
-        {
-            client.getState().clearCredentials();
-        }
-    }
-
-    /**
-     * Samples the URL passed in and stores the result in
-     * <code>HTTPSampleResult</code>, following redirects and downloading
-     * page resources as appropriate.
-     * <p>
-     * When getting a redirect target, redirects are not followed and resources
-     * are not downloaded. The caller will take care of this.
-     *
-     * @param url
-     *            URL to sample
-     * @param method
-     *            HTTP method: GET, POST,...
-     * @param areFollowingRedirect
-     *            whether we're getting a redirect target
-     * @param frameDepth
-     *            Depth of this target in the frame structure. Used only to
-     *            prevent infinite recursion.
-     * @return results of the sampling
-     */
-    @Override
-    protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
-
-        String urlStr = url.toString();
-
-        log.debug("Start : sample " + urlStr);
-        log.debug("method " + method);
-
-        HttpMethodBase httpMethod = null;
-
-        HTTPSampleResult res = new HTTPSampleResult();
-        res.setMonitor(isMonitor());
-
-        res.setSampleLabel(urlStr); // May be replaced later
-        res.setHTTPMethod(method);
-        res.setURL(url);
-
-        res.sampleStart(); // Count the retries as well in the time
-        HttpClient client = null;
-        InputStream instream = null;
-        try {
-            // May generate IllegalArgumentException
-            if (method.equals(POST)) {
-                httpMethod = new PostMethod(urlStr);
-            } else if (method.equals(PUT)){
-                httpMethod = new PutMethod(urlStr);
-            } else if (method.equals(HEAD)){
-                httpMethod = new HeadMethod(urlStr);
-            } else if (method.equals(TRACE)){
-                httpMethod = new TraceMethod(urlStr);
-            } else if (method.equals(OPTIONS)){
-                httpMethod = new OptionsMethod(urlStr);
-            } else if (method.equals(DELETE)){
-                httpMethod = new DeleteMethod(urlStr);
-            } else if (method.equals(GET)){
-                httpMethod = new GetMethod(urlStr);
-                final CacheManager cacheManager = getCacheManager();
-                if (cacheManager != null && GET.equalsIgnoreCase(method)) {
-                   if (cacheManager.inCache(url)) {
-                       res.sampleEnd();
-                       res.setResponseNoContent();
-                       res.setSuccessful(true);
-                       return res;
-                   }
-                }
-            } else {
-                log.error("Unexpected method (converted to GET): "+method);
-                httpMethod = new GetMethod(urlStr);
-            }
-
-            // Set any default request headers
-            setDefaultRequestHeaders(httpMethod);
-            // Setup connection
-            client = setupConnection(url, httpMethod, res);
-            savedClient = client;
-
-            // Handle the various methods
-            if (method.equals(POST)) {
-                String postBody = sendPostData((PostMethod)httpMethod);
-                res.setQueryString(postBody);
-            } else if (method.equals(PUT)) {
-                String putBody = sendPutData((PutMethod)httpMethod);
-                res.setQueryString(putBody);
-            }
-
-            int statusCode = client.executeMethod(httpMethod);
-
-            // Needs to be done after execute to pick up all the headers
-            res.setRequestHeaders(getConnectionHeaders(httpMethod));
-
-            // Request sent. Now get the response:
-            instream = httpMethod.getResponseBodyAsStream();
-
-            if (instream != null) {// will be null for HEAD
-
-                Header responseHeader = httpMethod.getResponseHeader(HEADER_CONTENT_ENCODING);
-                if (responseHeader!= null && ENCODING_GZIP.equals(responseHeader.getValue())) {
-                    instream = new GZIPInputStream(instream);
-                }
-                res.setResponseData(readResponse(res, instream, (int) httpMethod.getResponseContentLength()));
-            }
-
-            res.sampleEnd();
-            // Done with the sampling proper.
-
-            // Now collect the results into the HTTPSampleResult:
-
-            res.setSampleLabel(httpMethod.getURI().toString());
-            // Pick up Actual path (after redirects)
-
-            res.setResponseCode(Integer.toString(statusCode));
-            res.setSuccessful(isSuccessCode(statusCode));
-
-            res.setResponseMessage(httpMethod.getStatusText());
-
-            String ct = null;
-            org.apache.commons.httpclient.Header h
-                = httpMethod.getResponseHeader(HEADER_CONTENT_TYPE);
-            if (h != null)// Can be missing, e.g. on redirect
-            {
-                ct = h.getValue();
-                res.setContentType(ct);// e.g. text/html; charset=ISO-8859-1
-                res.setEncodingAndType(ct);
-            }
-
-            res.setResponseHeaders(getResponseHeaders(httpMethod));
-            if (res.isRedirect()) {
-                final Header headerLocation = httpMethod.getResponseHeader(HEADER_LOCATION);
-                if (headerLocation == null) { // HTTP protocol violation, but avoids NPE
-                    throw new IllegalArgumentException("Missing location header");
-                }
-                res.setRedirectLocation(headerLocation.getValue());
-            }
-
-            // If we redirected automatically, the URL may have changed
-            if (getAutoRedirects()){
-                res.setURL(new URL(httpMethod.getURI().toString()));
-            }
-
-            // Store any cookies received in the cookie manager:
-            saveConnectionCookies(httpMethod, res.getURL(), getCookieManager());
-
-            // Save cache information
-            final CacheManager cacheManager = getCacheManager();
-            if (cacheManager != null){
-                cacheManager.saveDetails(httpMethod, res);
-            }
-
-            // Follow redirects and download page resources if appropriate:
-            res = resultProcessing(areFollowingRedirect, frameDepth, res);
-
-            log.debug("End : sample");
-            httpMethod.releaseConnection();
-            return res;
-        } catch (IllegalArgumentException e)// e.g. some kinds of invalid URL
-        {
-            res.sampleEnd();
-            HTTPSampleResult err = errorResult(e, res);
-            err.setSampleLabel("Error: " + url.toString());
-            return err;
-        } catch (IOException e) {
-            res.sampleEnd();
-            HTTPSampleResult err = errorResult(e, res);
-            err.setSampleLabel("Error: " + url.toString());
-            return err;
-        } finally {
-            savedClient = null;
-            JOrphanUtils.closeQuietly(instream);
-            if (httpMethod != null) {
-                httpMethod.releaseConnection();
-            }
-        }
-    }
-
-    /**
-     * Set up the PUT data
-     */
-    private String sendPutData(PutMethod put) throws IOException {
-        // Buffer to hold the put body, except file content
-        StringBuilder putBody = new StringBuilder(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;
-        HTTPFileArg files[] = getHTTPFiles();
-
-        // If there are no arguments, we can send a file as the body of the request
-
-        if(!hasArguments() && getSendFileAsPostBody()) {
-            hasPutBody = true;
-
-            // If getSendFileAsPostBody returned true, it's sure that file is not null
-            FileRequestEntity fileRequestEntity = new FileRequestEntity(new File(files[0].getPath()),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 put 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
-            StringBuilder putBodyContent = new StringBuilder();
-            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();
-                }
-                putBodyContent.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 using the charset that was used to create them
-                putBody.append(new String(bos.toByteArray(),put.getRequestCharSet()));
-                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
-                // TODO: needs a multiple file upload scenerio
-                HTTPFileArg file = files.length > 0? files[0] : null;
-                if(file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
-                    put.setRequestHeader(HEADER_CONTENT_TYPE, file.getMimeType());
-                }
-            }
-            // Set the content length
-            put.setRequestHeader(HEADER_CONTENT_LENGTH, Long.toString(put.getRequestEntity().getContentLength()));
-            return putBody.toString();
-        }
-        return null;
-    }
-
-    /**
-     * Class extending FilePart, so that we can send placeholder text
-     * instead of the actual file content
-     */
-    private static class ViewableFilePart extends FilePart {
-        private boolean hideFileData;
-
-        public ViewableFilePart(String name, File file, String contentType, String charset) throws FileNotFoundException {
-            super(name, file, contentType, charset);
-            this.hideFileData = false;
-        }
-
-        public void setHideFileData(boolean hideFileData) {
-            this.hideFileData = hideFileData;
-        }
-
-        @Override
-        protected void sendData(OutputStream out) throws IOException {
-            // Check if we should send only placeholder text for the
-            // file content, or the real file content
-            if(hideFileData) {
-                out.write("<actual file content, not shown here>".getBytes());// encoding does not really matter here
-            }
-            else {
-                super.sendData(out);
-            }
-        }
-    }
-
-    /**
-     * From the <code>HttpMethod</code>, store all the "set-cookie" key-pair
-     * values in the cookieManager of the <code>UrlConfig</code>.
-     *
-     * @param method
-     *            <code>HttpMethod</code> which represents the request
-     * @param u
-     *            <code>URL</code> of the URL request
-     * @param cookieManager
-     *            the <code>CookieManager</code> containing all the cookies
-     */
-    protected void saveConnectionCookies(HttpMethod method, URL u, CookieManager cookieManager) {
-        if (cookieManager != null) {
-            Header hdr[] = method.getResponseHeaders(HEADER_SET_COOKIE);
-            for (int i = 0; i < hdr.length; i++) {
-                cookieManager.addCookieFromHeader(hdr[i].getValue(),u);
-            }
-        }
-    }
-
-
-    @Override
-    public void threadStarted() {
-        log.debug("Thread Started");
-
-        // Does not need to be synchronised, as all access is from same thread
-        httpClients.set ( new HashMap<HostConfiguration, HttpClient>() );
+    public boolean interrupt() {
+        return hc.interrupt();
     }
 
     @Override
-    public void threadFinished() {
-        log.debug("Thread Finished");
-
-        // Does not need to be synchronised, as all access is from same thread
-        Map<HostConfiguration, HttpClient> map = httpClients.get();
-
-        if ( map != null ) {
-            for ( Iterator<Map.Entry<HostConfiguration, HttpClient> > it = map.entrySet().iterator(); it.hasNext(); )
-            {
-                Map.Entry<HostConfiguration, HttpClient> entry = it.next();
-                HttpClient cl = entry.getValue();
-                // Can cause NPE in HttpClient 3.1
-                //((SimpleHttpConnectionManager)cl.getHttpConnectionManager()).shutdown();// Closes the connection
-                // Revert to original method:
-                cl.getHttpConnectionManager().closeIdleConnections(-1000);// Closes the connection
-            }
-            map.clear();
-        }
+    protected HTTPSampleResult sample(java.net.URL u, String method,
+            boolean areFollowingRedirect, int depth) {
+        return hc.sample(u, method, areFollowingRedirect, depth);
     }
 
-    /** {@inheritDoc} */
-    public boolean interrupt() {
-        HttpClient client = savedClient;
-        if (client != null) {
-            savedClient = null;
-            // TODO - not sure this is the best method
-            final HttpConnectionManager httpConnectionManager = client.getHttpConnectionManager();
-            if (httpConnectionManager instanceof SimpleHttpConnectionManager) {// Should be true
-                ((SimpleHttpConnectionManager)httpConnectionManager).shutdown();
-            }
-        }
-        return client != null;
-    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
For additional commands, e-mail: notifications-help@jakarta.apache.org