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

📄 httprequesthdr.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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.commons.lang.CharUtils;
import org.apache.jmeter.protocol.http.config.MultipartUrlConfig;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui;
import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui2;
import org.apache.jmeter.protocol.http.gui.HeaderPanel;
import org.apache.jmeter.protocol.http.sampler.HTTPSampler2;
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.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;

//For unit tests, @see TestHttpRequestHdr

/**
 * The headers of the client HTTP request.
 * 
 */
public class HttpRequestHdr {
    private static final Logger log = LoggingManager.getLoggerForClass();

    private static final String HTTP = "http"; // $NON-NLS-1$
    private static final String HTTPS = "https"; // $NON-NLS-1$
    private static final String PROXY_CONNECTION = "proxy-connection"; // $NON-NLS-1$
    private static final String CONTENT_TYPE = "content-type"; // $NON-NLS-1$
    private static final String CONTENT_LENGTH = "content-length"; // $NON-NLS-1$

	/**
	 * Http Request method. Such as get or post.
	 */
	private String method = ""; // $NON-NLS-1$

	/**
	 * The requested url. The universal resource locator that hopefully uniquely
	 * describes the object or service the client is requesting.
	 */
	private String url = ""; // $NON-NLS-1$

	/**
	 * Version of http being used. Such as HTTP/1.0.
	 */
	private String version = ""; // NOTREAD // $NON-NLS-1$

    private byte[] rawPostData;

	private Map headers = new HashMap();

	private HTTPSamplerBase sampler;

	private HeaderManager headerManager;
	
	/*
	 * Optionally number the requests
	 */
	private static final boolean numberRequests = 
        JMeterUtils.getPropDefault("proxy.number.requests", false); // $NON-NLS-1$

	private static int requestNumber = 0;// running number

	public HttpRequestHdr() {
		this.sampler = HTTPSamplerFactory.newInstance();
	}
	
	/**
	 * @param sampler the http sampler
	 */
	public HttpRequestHdr(HTTPSamplerBase sampler) {
		this.sampler = sampler;
	}
	
	/**
	 * Parses a http header from a stream.
	 * 
	 * @param in
	 *            the stream to parse.
	 * @return array of bytes from client.
	 */
	public byte[] parse(InputStream in) throws IOException {
		boolean inHeaders = true;
		int readLength = 0;
		int dataLength = 0;
		boolean first = true;
		ByteArrayOutputStream clientRequest = new ByteArrayOutputStream();
		ByteArrayOutputStream line = new ByteArrayOutputStream();
		int x;
		while ((inHeaders || readLength < dataLength) && ((x = in.read()) != -1)) {
			line.write(x);
			clientRequest.write(x);
			if (first && !CharUtils.isAscii((char) x)){
				throw new IllegalArgumentException("Only ASCII supported in headers (perhaps SSL was used?)");
			}
			if (inHeaders && (byte) x == (byte) '\n') { // $NON-NLS-1$
				if (line.size() < 3) {
					inHeaders = false;
					first = false; // cannot be first line either
				}
				if (first) {
					parseFirstLine(line.toString());
					first = false;
				} else {
					dataLength = Math.max(parseLine(line.toString()), dataLength);
				}
                if (log.isDebugEnabled()){
    				log.debug("Client Request Line: " + line.toString());
                }
				line.reset();
			} else if (!inHeaders) {
				readLength++;
			}
		}
        // Keep the raw post data
        rawPostData = line.toByteArray();

        if (log.isDebugEnabled()){
            log.debug("rawPostData in default JRE encoding: " + new String(rawPostData));
    		log.debug("Request: " + clientRequest.toString());
        }
		return clientRequest.toByteArray();
	}

	private void parseFirstLine(String firstLine) {
        if (log.isDebugEnabled()) {
    		log.debug("browser request: " + firstLine);
        }
        if (!CharUtils.isAsciiAlphanumeric(firstLine.charAt(0))) {
        	throw new IllegalArgumentException("Unrecognised header line (probably used HTTPS)");
        }
		StringTokenizer tz = new StringTokenizer(firstLine);
		method = getToken(tz).toUpperCase();
		url = getToken(tz);
		if (url.toLowerCase().startsWith(HTTPConstants.PROTOCOL_HTTPS)) {
			throw new IllegalArgumentException("Cannot handle https URLS: " + url);
		}
		version = getToken(tz);
        if (log.isDebugEnabled()) {
    		log.debug("parser input:  " + firstLine);
    		log.debug("parsed method: " + method);
    		log.debug("parsed url:    " + url);
    		log.debug("parsed version:" + version);
        }
        if ("CONNECT".equalsIgnoreCase(method)){
        	throw new IllegalArgumentException("Cannot handle CONNECT - probably used HTTPS");        	
        }
	}

    /*
     * Split line into name/value pairs and store in headers if relevant
     * If name = "content-length", then return value as int, else return 0
     */
	private int parseLine(String nextLine) {
		StringTokenizer tz;
		tz = new StringTokenizer(nextLine);
		String token = getToken(tz);
		// look for termination of HTTP command
		if (0 == token.length()) {
			return 0;
		} else {
			String trimmed = token.trim();
            String name = trimmed.substring(0, trimmed.length() - 1);// drop ':'
			String value = getRemainder(tz);
			headers.put(name.toLowerCase(), new Header(name, value));
			if (name.equalsIgnoreCase(CONTENT_LENGTH)) {
				return Integer.parseInt(value);
			}
		}
		return 0;
	}

	private HeaderManager createHeaderManager() {
		HeaderManager manager = new HeaderManager();
		Iterator keys = headers.keySet().iterator();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			if (!key.equals(PROXY_CONNECTION) && !key.equals(CONTENT_LENGTH)) {
				manager.add((Header) headers.get(key));
			}
		}
		manager.setName("Browser-derived headers");
		manager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
		manager.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
		return manager;
	}

	public HeaderManager getHeaderManager() {
		if(headerManager == null) {
			headerManager = createHeaderManager();
		}
		return headerManager;
	}

    public HTTPSamplerBase getSampler(Map pageEncodings, Map formEncodings)
            throws MalformedURLException, IOException, ProtocolException {
		// Damn! A whole new GUI just to instantiate a test element?
		// Isn't there a beter way?
		HttpTestSampleGui tempGui = null;
		// Create the corresponding gui for the sampler class
		if(sampler instanceof HTTPSampler2) {
			tempGui = new HttpTestSampleGui2();
		}
		else {
			tempGui = new HttpTestSampleGui();
		}
		sampler.setProperty(TestElement.GUI_CLASS, tempGui.getClass().getName());

        // Populate the sampler
        populateSampler(pageEncodings, formEncodings);
		
		tempGui.configure(sampler);
		tempGui.modifyTestElement(sampler);
		// Defaults
		sampler.setFollowRedirects(false);
		sampler.setUseKeepAlive(true);
		
        if (log.isDebugEnabled())
    		log.debug("getSampler: sampler path = " + sampler.getPath());
		return sampler;
	}
    
    /**
     * 
     * @return the sampler
     * @throws MalformedURLException
     * @throws IOException
     * @throws ProtocolException
     * @deprecated use the getSampler(HashMap pageEncodings, HashMap formEncodings) instead, since
     * that properly handles the encodings of the page
     */
    public HTTPSamplerBase getSampler() throws MalformedURLException, IOException, ProtocolException {
        return getSampler(null, null);
    }

	private String getContentType() {
		Header contentTypeHeader = (Header) headers.get(CONTENT_TYPE);
		if (contentTypeHeader != null) {
			return contentTypeHeader.getValue();
		}
        return null;
	}

    private String getContentEncoding() {
        String contentType = getContentType();
        if(contentType != null) {
            int charSetStartPos = contentType.toLowerCase().indexOf("charset="); 
            if(charSetStartPos >= 0) {
                String charSet = contentType.substring(charSetStartPos + "charset=".length());
                if(charSet != null && charSet.length() > 0) {
                    // Remove quotes if present 
                    charSet = JOrphanUtils.replaceAllChars(charSet, '"', "");
                    if(charSet.length() > 0) {
                        return charSet;
                    }
                }
            }
        }
        return null;
    }

⌨️ 快捷键说明

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