Package org.apache.jmeter.protocol.http.proxy

Source Code of org.apache.jmeter.protocol.http.proxy.DefaultSamplerCreator

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.jmeter.protocol.http.proxy;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.jmeter.protocol.http.config.MultipartUrlConfig;
import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
import org.apache.jmeter.protocol.http.sampler.PostWriter;
import org.apache.jmeter.protocol.http.util.ConversionUtils;
import org.apache.jmeter.protocol.http.util.HTTPConstants;
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

/**
* Default implementation that handles classical HTTP textual + Multipart requests
*/
public class DefaultSamplerCreator extends AbstractSamplerCreator {
    private static final Logger log = LoggingManager.getLoggerForClass();
    /**
     *
     */
    public DefaultSamplerCreator() {
    }

    /**
     * @see org.apache.jmeter.protocol.http.proxy.SamplerCreator#getManagedContentTypes()
     */
    public String[] getManagedContentTypes() {
        return new String[0];
    }

    /**
     *
     * @see org.apache.jmeter.protocol.http.proxy.SamplerCreator#createSampler(org.apache.jmeter.protocol.http.proxy.HttpRequestHdr, java.util.Map, java.util.Map)
     */
    public HTTPSamplerBase createSampler(HttpRequestHdr request,
            Map<String, String> pageEncodings, Map<String, String> formEncodings) {
        // Instantiate the sampler
        HTTPSamplerBase sampler = HTTPSamplerFactory.newInstance(request.getHttpSamplerName());

        sampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());

        // Defaults
        sampler.setFollowRedirects(false);
        sampler.setUseKeepAlive(true);

        if (log.isDebugEnabled()) {
            log.debug("getSampler: sampler path = " + sampler.getPath());
        }
        return sampler;
    }

    /**
     * @see org.apache.jmeter.protocol.http.proxy.SamplerCreator#populateSampler(org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase, org.apache.jmeter.protocol.http.proxy.HttpRequestHdr, java.util.Map, java.util.Map)
     */
    public final void populateSampler(HTTPSamplerBase sampler,
            HttpRequestHdr request, Map<String, String> pageEncodings,
            Map<String, String> formEncodings) throws Exception{
        computeFromHeader(sampler, request, pageEncodings, formEncodings);

        computeFromPostBody(sampler, request);
        if (log.isDebugEnabled()) {
            log.debug("sampler path = " + sampler.getPath());
        }
    }

    /**
     * Compute sampler informations from Request Header
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     * @param pageEncodings Map<String, String>
     * @param formEncodings Map<String, String>
     * @throws Exception
     */
    protected void computeFromHeader(HTTPSamplerBase sampler,
            HttpRequestHdr request, Map<String, String> pageEncodings,
            Map<String, String> formEncodings) throws Exception {
        computeDomain(sampler, request);
       
        computeMethod(sampler, request);
       
        computePort(sampler, request);
       
        computeProtocol(sampler, request);

        computeContentEncoding(sampler, request,
                pageEncodings, formEncodings);

        computePath(sampler, request);
       
        computeSamplerName(sampler, request);
    }

    /**
     * Compute sampler informations from Request Header
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     * @throws Exception
     */
    protected void computeFromPostBody(HTTPSamplerBase sampler,
            HttpRequestHdr request) throws Exception {
        // If it was a HTTP GET request, then all parameters in the URL
        // has been handled by the sampler.setPath above, so we just need
        // to do parse the rest of the request if it is not a GET request
        if((!HTTPConstants.CONNECT.equals(request.getMethod())) && (!HTTPConstants.GET.equals(request.getMethod()))) {
            // Check if it was a multipart http post request
            final String contentType = request.getContentType();
            MultipartUrlConfig urlConfig = request.getMultipartConfig(contentType);
            String contentEncoding = sampler.getContentEncoding();
            // Get the post data using the content encoding of the request
            String postData = null;
            if (log.isDebugEnabled()) {
                if(!StringUtils.isEmpty(contentEncoding)) {
                    log.debug("Using encoding " + contentEncoding + " for request body");
                }
                else {
                    log.debug("No encoding found, using JRE default encoding for request body");
                }
            }
           
           
            if (!StringUtils.isEmpty(contentEncoding)) {
                postData = new String(request.getRawPostData(), contentEncoding);
            } else {
                // Use default encoding
                postData = new String(request.getRawPostData(), PostWriter.ENCODING);
            }
           
            if (urlConfig != null) {
                urlConfig.parseArguments(postData);
                // Tell the sampler to do a multipart post
                sampler.setDoMultipartPost(true);
                // Remove the header for content-type and content-length, since
                // those values will most likely be incorrect when the sampler
                // performs the multipart request, because the boundary string
                // will change
                request.getHeaderManager().removeHeaderNamed(HttpRequestHdr.CONTENT_TYPE);
                request.getHeaderManager().removeHeaderNamed(HttpRequestHdr.CONTENT_LENGTH);

                // Set the form data
                sampler.setArguments(urlConfig.getArguments());
                // Set the file uploads
                sampler.setHTTPFiles(urlConfig.getHTTPFileArgs().asArray());
            // used when postData is pure xml (eg. an xml-rpc call) or for PUT
            } else if (postData.trim().startsWith("<?") || "PUT".equals(sampler.getMethod())) {
                sampler.addNonEncodedArgument("", postData, "");
            } else if (contentType == null || contentType.startsWith(HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED) ){
                // It is the most common post request, with parameter name and values
                // We also assume this if no content type is present, to be most backwards compatible,
                // but maybe we should only parse arguments if the content type is as expected
                sampler.parseArguments(postData.trim(), contentEncoding); //standard name=value postData
            } else if (postData.length() > 0) {
                if (isBinaryContent(contentType)) {
                    try {
                        File tempDir = new File(getBinaryDirectory());
                        File out = File.createTempFile(request.getMethod(), getBinaryFileSuffix(), tempDir);
                        FileUtils.writeByteArrayToFile(out,request.getRawPostData());
                        HTTPFileArg [] files = {new HTTPFileArg(out.getPath(),"",contentType)};
                        sampler.setHTTPFiles(files);
                    } catch (IOException e) {
                        log.warn("Could not create binary file: "+e);
                    }
                } else {
                    // Just put the whole postbody as the value of a parameter
                    sampler.addNonEncodedArgument("", postData, ""); //used when postData is pure xml (ex. an xml-rpc call)
                }
            }
        }
    }

    /**
     * Compute sampler name
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     */
    protected void computeSamplerName(HTTPSamplerBase sampler,
            HttpRequestHdr request) {
        if (!HTTPConstants.CONNECT.equals(request.getMethod()) && isNumberRequests()) {
            incrementRequestNumber();
            sampler.setName(getRequestNumber() + " " + sampler.getPath());
        } else {
            sampler.setName(sampler.getPath());
        }
    }

    /**
     * Set path on sampler
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     */
    protected void computePath(HTTPSamplerBase sampler, HttpRequestHdr request) {
        if(sampler.getContentEncoding() != null) {
            sampler.setPath(request.getPath(), sampler.getContentEncoding());
        }
        else {
            // Although the spec says UTF-8 should be used for encoding URL parameters,
            // most browser use ISO-8859-1 for default if encoding is not known.
            // We use null for contentEncoding, then the url parameters will be added
            // with the value in the URL, and the "encode?" flag set to false
            sampler.setPath(request.getPath(), null);
        }
        if (log.isDebugEnabled()) {
            log.debug("Proxy: setting path: " + sampler.getPath());
        }
    }

    /**
     * Compute content encoding
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     * @param pageEncodings Map<String, String>
     * @param formEncodings Map<String, String>
     * @throws MalformedURLException
     */
    protected void computeContentEncoding(HTTPSamplerBase sampler,
            HttpRequestHdr request, Map<String, String> pageEncodings,
            Map<String, String> formEncodings) throws MalformedURLException {
        URL pageUrl = null;
        if(sampler.isProtocolDefaultPort()) {
            pageUrl = new URL(sampler.getProtocol(), sampler.getDomain(), request.getPath());
        }
        else {
            pageUrl = new URL(sampler.getProtocol(), sampler.getDomain(),
                    sampler.getPort(), request.getPath());
        }
        String urlWithoutQuery = request.getUrlWithoutQuery(pageUrl);


        String contentEncoding = computeContentEncoding(request, pageEncodings,
                formEncodings, urlWithoutQuery);
       
        // Set the content encoding
        if(!StringUtils.isEmpty(contentEncoding)) {
            sampler.setContentEncoding(contentEncoding);
        }
    }
   
    /**
     * Computes content encoding from request and if not found uses pageEncoding
     * and formEncoding to see if URL was previously computed with a content type
     * @param request {@link HttpRequestHdr}
     * @param pageEncodings Map<String, String>
     * @param formEncodings Map<String, String>
     * @return String content encoding
     */
    protected String computeContentEncoding(HttpRequestHdr request,
            Map<String, String> pageEncodings,
            Map<String, String> formEncodings, String urlWithoutQuery) {
        // Check if the request itself tells us what the encoding is
        String contentEncoding = null;
        String requestContentEncoding = ConversionUtils.getEncodingFromContentType(
                request.getContentType());
        if(requestContentEncoding != null) {
            contentEncoding = requestContentEncoding;
        }
        else {
            // Check if we know the encoding of the page
            if (pageEncodings != null) {
                synchronized (pageEncodings) {
                    contentEncoding = pageEncodings.get(urlWithoutQuery);
                }
            }
            // Check if we know the encoding of the form
            if (formEncodings != null) {
                synchronized (formEncodings) {
                    String formEncoding = formEncodings.get(urlWithoutQuery);
                    // Form encoding has priority over page encoding
                    if (formEncoding != null) {
                        contentEncoding = formEncoding;
                    }
                }
            }
        }
        return contentEncoding;
    }

    /**
     * Set protocol on sampler
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     */
    protected void computeProtocol(HTTPSamplerBase sampler,
            HttpRequestHdr request) {
        sampler.setProtocol(request.getProtocol(sampler));
    }

    /**
     * Set Port on sampler
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     */
    protected void computePort(HTTPSamplerBase sampler, HttpRequestHdr request) {
        sampler.setPort(request.serverPort());
        if (log.isDebugEnabled()) {
            log.debug("Proxy: setting port: " + sampler.getPort());
        }
    }

    /**
     * Set method on sampler
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     */
    protected void computeMethod(HTTPSamplerBase sampler, HttpRequestHdr request) {
        sampler.setMethod(request.getMethod());
        log.debug("Proxy: setting method: " + sampler.getMethod());
    }

    /**
     * Set domain on sampler
     * @param sampler {@link HTTPSamplerBase}
     * @param request {@link HttpRequestHdr}
     */
    protected void computeDomain(HTTPSamplerBase sampler, HttpRequestHdr request) {
        sampler.setDomain(request.serverName());
        if (log.isDebugEnabled()) {
            log.debug("Proxy: setting server: " + sampler.getDomain());
        }
    }
}
TOP

Related Classes of org.apache.jmeter.protocol.http.proxy.DefaultSamplerCreator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.