⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy.java

📁 测试工具
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.URL;
import java.util.Map;

import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.parser.HTMLParseException;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
import org.apache.jmeter.protocol.http.util.HTTPConstants;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Logger;

/**
 * Thread to handle one client request. Gets the request from the client and
 * passes it on to the server, then sends the response back to the client.
 * Information about the request and response is stored so it can be used in a
 * JMeter test plan.
 * 
 */
public class Proxy extends Thread {
	private static final Logger log = LoggingManager.getLoggerForClass();

    private static final String NEW_LINE = "\n"; // $NON-NLS-1$

    private static final String[] headersToRemove;

    // Allow list of headers to be overridden
	private static final String PROXY_HEADERS_REMOVE = "proxy.headers.remove"; // $NON-NLS-1$

	private static final String PROXY_HEADERS_REMOVE_DEFAULT = "If-Modified-Since,If-None-Match"; // $NON-NLS-1$

    private static final String PROXY_HEADERS_REMOVE_SEPARATOR = ","; // $NON-NLS-1$

    static {
    	String removeList = JMeterUtils.getPropDefault(PROXY_HEADERS_REMOVE,PROXY_HEADERS_REMOVE_DEFAULT);
    	headersToRemove = JOrphanUtils.split(removeList,PROXY_HEADERS_REMOVE_SEPARATOR);
    	log.info("Proxy will remove the headers: "+removeList);
    }

	/** Socket to client. */
	private Socket clientSocket = null;

	/** Target to receive the generated sampler. */
	private ProxyControl target;

	/** Whether or not to capture the HTTP headers. */
	private boolean captureHttpHeaders;

	/** Whether to try to spoof as https **/
	private boolean httpsSpoof;

	private String httpsSpoofMatch; // if non-empty, then URLs must match in order to be spoofed

    /** Reference to Deamon's Map of url string to page character encoding of that page */
    private Map pageEncodings;
    /** Reference to Deamon's Map of url string to character encoding for the form */
    private Map formEncodings;

	/**
	 * Default constructor - used by newInstance call in Daemon
	 */
	public Proxy() {
	}

	/**
	 * Create and configure a new Proxy object.
	 * 
	 * @param clientSocket
	 *            the socket connection to the client
	 * @param target
	 *            the ProxyControl which will receive the generated sampler
	 */
	Proxy(Socket clientSocket, ProxyControl target) {
		configure(clientSocket, target);
	}

	/**
	 * Configure the Proxy.
	 * 
	 * @param clientSocket
	 *            the socket connection to the client
	 * @param target
	 *            the ProxyControl which will receive the generated sampler
	 */
	void configure(Socket _clientSocket, ProxyControl _target) {
        configure(_clientSocket, _target, null, null);
    }
    
    /**
     * Configure the Proxy.
     * 
     * @param _clientSocket
     *            the socket connection to the client
     * @param _target
     *            the ProxyControl which will receive the generated sampler
     * @param _pageEncodings
     *            reference to the Map of Deamon, with mappings from page urls to encoding used
     * @param formEncodingsEncodings
     *            reference to the Map of Deamon, with mappings from form action urls to encoding used
     */
    void configure(Socket _clientSocket, ProxyControl _target, Map _pageEncodings, Map _formEncodings) {
        this.target = _target;
        this.clientSocket = _clientSocket;
        this.captureHttpHeaders = _target.getCaptureHttpHeaders();
        this.httpsSpoof = _target.getHttpsSpoof();
        this.httpsSpoofMatch = _target.getHttpsSpoofMatch();
        this.pageEncodings = _pageEncodings;
        this.formEncodings = _formEncodings;
    }

	/**
	 * Main processing method for the Proxy object
	 */
	public void run() {
		// Check which HTTPSampler class we should use
		String httpSamplerName = HTTPSamplerFactory.DEFAULT_CLASSNAME;
		if(target.getSamplerTypeName() == ProxyControl.SAMPLER_TYPE_HTTP_SAMPLER) {
			httpSamplerName = HTTPSamplerFactory.HTTP_SAMPLER_JAVA;
		}
		else if(target.getSamplerTypeName() == ProxyControl.SAMPLER_TYPE_HTTP_SAMPLER2) {
			httpSamplerName = HTTPSamplerFactory.HTTP_SAMPLER_APACHE;
		}
		// Instantiate the sampler
		HTTPSamplerBase sampler = HTTPSamplerFactory.newInstance(httpSamplerName);
		
		HttpRequestHdr request = new HttpRequestHdr(sampler);
		SampleResult result = null;
		HeaderManager headers = null;

		try {
			request.parse(new BufferedInputStream(clientSocket.getInputStream()));

			// Populate the sampler. It is the same sampler as we sent into
			// the constructor of the HttpRequestHdr instance above 
            request.getSampler(pageEncodings, formEncodings);

			/*
			 * Create a Header Manager to ensure that the browsers headers are
			 * captured and sent to the server
			 */
			headers = request.getHeaderManager();
			sampler.setHeaderManager(headers);
			
			/* 
			 * If we are trying to spoof https, change the protocol
			 */
			boolean forcedHTTP = false; // so we know when to revert
			if (httpsSpoof) {
				if (httpsSpoofMatch.length() > 0){
					String url = request.getUrl();
					if (url.matches(httpsSpoofMatch)){
						sampler.setProtocol(HTTPConstants.PROTOCOL_HTTPS);
						forcedHTTP = true;
					}
				} else {
				    sampler.setProtocol(HTTPConstants.PROTOCOL_HTTPS);
					forcedHTTP = true;
				}
			}
			sampler.threadStarted(); // Needed for HTTPSampler2
			result = sampler.sample();
			
			/*
			 * If we're dealing with text data, and if we're spoofing https, 
			 * replace all occurences of "https://" with "http://" for the client.
			 * TODO - also check the match string to restrict the changes further?
			 */
			if (forcedHTTP && SampleResult.TEXT.equals(result.getDataType()))
			{
				final String enc = result.getDataEncodingWithDefault();
				String noHttpsResult = new String(result.getResponseData(),enc);
				final String HTTPS_HOST = // match https://host[:port]/ and drop default port if present
					"https://([^:/]+)(:"+HTTPConstants.DEFAULT_HTTPS_PORT_STRING+")?"; // $NON-NLS-1$ $NON-NLS-2$
				noHttpsResult = noHttpsResult.replaceAll(HTTPS_HOST, "http://$1"); // $NON-NLS-1$
				result.setResponseData(noHttpsResult.getBytes(enc));
			}

            // Find the page encoding and possibly encodings for forms in the page
            // in the response from the web server
            String pageEncoding = addPageEncoding(result);
            addFormEncodings(result, pageEncoding);

			writeToClient(result, new BufferedOutputStream(clientSocket.getOutputStream()));
		} catch (UnknownHostException uhe) {
			log.warn("Server Not Found.", uhe);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -