All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blazemeter.jmeter.http2.sampler.HTTP2SampleResult Maven / Gradle / Ivy

There is a newer version: 1.4
Show newest version
/*
 * 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 com.blazemeter.jmeter.http2.sampler;

import org.apache.jmeter.protocol.http.util.HTTPConstants;
import org.apache.jmeter.samplers.SampleResult;
import org.eclipse.jetty.http.HttpFields;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * This is a specialisation of the SampleResult class for the HTTP protocol.
 *
 */
public class HTTP2SampleResult extends SampleResult {

	private static final long serialVersionUID = 241L;

	/** Set of all HTTP methods, that have no body */
	private static final Set METHODS_WITHOUT_BODY = new HashSet<>(
			Arrays.asList(HTTPConstants.HEAD, HTTPConstants.OPTIONS, HTTPConstants.TRACE));

	private String cookies = ""; // never null

	private static int idCount = 0;

	private int id;

	private int embebedResultsDepth;
	private String method;
	private transient HttpFields httpFieldsResponse;
	private boolean embebedResults;
	private transient Queue  pendingResults = new ConcurrentLinkedQueue<>();
	
	private boolean secondaryRequest;

	private String embeddedUrlRE;

	private boolean isPushed;

	/**
	 * The raw value of the Location: header; may be null. This is supposed to
	 * be an absolute URL: RFC2616
	 * sec14.30 but is often relative.
	 */
	private String redirectLocation;

	private String queryString = ""; // never null

	protected static final String NON_HTTP_RESPONSE_CODE = "Non HTTP response code";
	protected static final String NON_HTTP_RESPONSE_MESSAGE = "Non HTTP response message";
	protected static final String HTTP2_PENDING_RESPONSE = "Pending";
	protected static final String HTTP2_RESPONSE_RECEIVED = "Received";
	protected static final String HTTP2_RESPONSE_CODE_4 = "Not Found";

	private boolean pendingResponse;

	private String requestId;


	public HTTP2SampleResult() {
		super();
	}

	public HTTP2SampleResult(URL url, String method) {
		super();

		this.setSampleLabel(url.toString()); // May be replaced later
		this.setHTTPMethod(method);
		this.setURL(url);
		this.setPendingResponse(true);
		this.setId(HTTP2SampleResult.getNextId());
		this.setPushed(false);
		this.setEmbebedResultsDepth(1);
		this.setEmbebedResults(false);
		this.setResponseCode(HTTP2_PENDING_RESPONSE);
		this.setResponseMessage(HTTP2_PENDING_RESPONSE);
	}

	/**
	 * Construct a 'parent' result for an already-existing result, essentially
	 * cloning it
	 *
	 * @param res
	 *            existing sample result
	 */
	public HTTP2SampleResult(HTTP2SampleResult res) {
		super(res);
		method = res.method;
		cookies = res.cookies;
		queryString = res.queryString;
		redirectLocation = res.redirectLocation;
	}

	/**
	 * Populates the provided HTTPSampleResult with details from the Exception.
	 * Does not create a new instance, so should not be used directly to add a
	 * subsample.
	 *
	 * @param e
	 *            Exception representing the error.
	 * @param res
	 *            SampleResult to be modified
	 * @return the modified sampling result containing details of the Exception.
	 */
	protected static HTTP2SampleResult errorResult(Throwable e, HTTP2SampleResult res) {
		res.setSampleLabel(res.getSampleLabel());
		res.setDataType(SampleResult.TEXT);
		ByteArrayOutputStream text = new ByteArrayOutputStream(200);
		e.printStackTrace(new PrintStream(text));
		res.setResponseData(text.toByteArray());
		res.setResponseCode(NON_HTTP_RESPONSE_CODE + ": " + e.getClass().getName());
		res.setResponseMessage(NON_HTTP_RESPONSE_MESSAGE + ": " + e.getMessage());
		res.setSuccessful(false);
		res.setPendingResponse(false);
		// res.setMonitor(this.isMonitor()); // TODO see if applies to http2
		return res;
	}

	public void setHTTPMethod(String method) {
		this.method = method;
	}

	public String getHTTPMethod() {
		return method;
	}

	public static synchronized int getNextId() {
		int ret = idCount;
		idCount += 1;
		return ret;
	}

	public boolean isEmbebedResults() {
		return embebedResults;
	}

	public String getEmbeddedUrlRE() {
		return embeddedUrlRE;
	}

	public void setEmbeddedUrlRE(String embeddedUrlRE) {
		this.embeddedUrlRE = embeddedUrlRE;
	}

	public void setEmbebedResults(boolean embebedResults) {
		this.embebedResults = embebedResults;
	}

	public int getEmbebedResultsDepth() {
		return embebedResultsDepth;
	}

	public void setEmbebedResultsDepth(int embebedResultsDepth) {
		this.embebedResultsDepth = embebedResultsDepth;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public boolean isPushed() {
		return isPushed;
	}

	public void setPushed(boolean pushed) {
		isPushed = pushed;
	}

	public HttpFields getHttpFieldsResponse() {
		return httpFieldsResponse;
	}

	public void setHttpFieldsResponse(HttpFields httpFieldsResponse) {
		this.httpFieldsResponse = httpFieldsResponse;
	}

	public void setRedirectLocation(String redirectLocation) {
		this.redirectLocation = redirectLocation;
	}

	public String getRedirectLocation() {
		return redirectLocation;
	}

	/**
	 * Determine whether this result is a redirect. Returns true for:
	 * 301,302,303 and 307(GET or HEAD)
	 * 
	 * @return true iff res is an HTTP redirect response
	 */
	public boolean isRedirect() {
		/*
		 * Don't redirect the following: 300 = Multiple choice 304 = Not
		 * Modified 305 = Use Proxy 306 = (Unused)
		 */
		final String[] REDIRECT_CODES = { HTTPConstants.SC_MOVED_PERMANENTLY, HTTPConstants.SC_MOVED_TEMPORARILY,
				HTTPConstants.SC_SEE_OTHER };
		String code = getResponseCode();
		for (String redirectCode : REDIRECT_CODES) {
			if (redirectCode.equals(code)) {
				return true;
			}
		}
		// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
		// If the 307 status code is received in response to a request other
		// than GET or HEAD,
		// the user agent MUST NOT automatically redirect the request unless it
		// can be confirmed by the user,
		// since this might change the conditions under which the request was
		// issued.
		// See Bug 54119
		if (HTTPConstants.SC_TEMPORARY_REDIRECT.equals(code)
				&& (HTTPConstants.GET.equals(getHTTPMethod()) || HTTPConstants.HEAD.equals(getHTTPMethod()))) {
			return true;
		}
		return false;
	}

	/**
	 * Overrides version in Sampler data to provide more details
	 * 

* {@inheritDoc} */ @Override public String getSamplerData() { StringBuilder sb = new StringBuilder(); sb.append(method); URL u = super.getURL(); if (u != null) { sb.append(' '); sb.append(u.toString()); sb.append('\n'); // Include request body if it can have one if (!METHODS_WITHOUT_BODY.contains(method)) { sb.append("\n").append(method).append(" data:\n"); sb.append(queryString); sb.append('\n'); } if (cookies.length() > 0) { sb.append("\nCookie Data:\n"); sb.append(cookies); } else { sb.append("\n[no cookies]"); } sb.append('\n'); } final String sampData = super.getSamplerData(); if (sampData != null) { sb.append(sampData); } return sb.toString(); } /** * @return cookies as a string */ public String getCookies() { return cookies; } /** * @param string * representing the cookies */ public void setCookies(String string) { if (string == null) { cookies = "";// $NON-NLS-1$ } else { cookies = string; } } /** * Fetch the query string * * @return the query string */ public String getQueryString() { return queryString; } /** * Save the query string * * @param string * the query string */ public void setQueryString(String string) { if (string == null) { queryString = "";// $NON-NLS-1$ } else { queryString = string; } } /** * Overrides the method from SampleResult - so the encoding can be extracted * from the Meta content-type if necessary. * * Updates the dataEncoding field if the content-type is found. * * @param defaultEncoding * Default encoding used if there is no data encoding * @return the dataEncoding value as a String */ @Override public String getDataEncodingWithDefault(String defaultEncoding) { String dataEncodingNoDefault = getDataEncodingNoDefault(); if (dataEncodingNoDefault != null && dataEncodingNoDefault.length() > 0) { return dataEncodingNoDefault; } return defaultEncoding; } /** * Overrides the method from SampleResult - so the encoding can be extracted * from the Meta content-type if necessary. * * Updates the dataEncoding field if the content-type is found. * * @return the dataEncoding value as a String */ @Override public String getDataEncodingNoDefault() { if (super.getDataEncodingNoDefault() == null && getContentType().startsWith("text/html")) { // $NON-NLS-1$ byte[] bytes = getResponseData(); // get the start of the file String prefix = new String(bytes, 0, Math.min(bytes.length, 2000), Charset.forName(DEFAULT_HTTP_ENCODING)); // Preserve original case String matchAgainst = prefix.toLowerCase(java.util.Locale.ENGLISH); // Extract the content-type if present final String METATAG = " getSearchableTokens() throws Exception { List list = new ArrayList<>(super.getSearchableTokens()); list.add(getQueryString()); list.add(getCookies()); return list; } public void setPendingResponse(boolean pendingResp) { pendingResponse = pendingResp; } public boolean isPendingResponse() { boolean ret = pendingResponse; SampleResult[] sons = this.getSubResults(); int i = 0; if (sons.length != 0) { while ((i < sons.length) && (!ret)) { HTTP2SampleResult h = (HTTP2SampleResult) sons[i]; i++; if (h.isSecondaryRequest()) ret = ret || (h.isPendingResponse()); } } return ret; } public void setRequestId(String id) { requestId = id; } public String getRequestId() { return requestId; } public boolean isSecondaryRequest() { return secondaryRequest; } public void setSecondaryRequest(boolean secondaryRequest) { this.secondaryRequest = secondaryRequest; } public void addPendingResult (HTTP2SampleResult pendingResult){ this.pendingResults.add(pendingResult); } public Queue getPendingResults(){ return pendingResults; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy