📄 httpsampler.java
字号:
/*
* 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.sampler;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.BindException;
import java.net.HttpURLConnection;
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.CookieManager;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.control.HeaderManager;
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.
*
*/
public class HTTPSampler extends HTTPSamplerBase {
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$
}
private static final byte[] NULL_BA = new byte[0];// can share these
/** Handles writing of a post request */
private transient PostWriter postWriter;
/**
* 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 {
postWriter = new PostWriter();
postWriter.setHeaders(conn, this);
}
private void setPutHeaders(URLConnection conn) throws IOException {
postWriter = new PutWriter();
postWriter.setHeaders(conn, this);
}
/**
* 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 postWriter.sendPostData(connection, this);
}
private String sendPutData(URLConnection connection) throws IOException {
return postWriter.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);
}
}
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
// Update follow redirects setting just for this connection
conn.setInstanceFollowRedirects(getAutoRedirects());
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());
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.setURL(u);
res.setHTTPMethod(method);
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 {
byte[] readBuffer = getThreadContext().getReadBuffer();
BufferedInputStream in;
if ((conn.getContentLength() == 0)
&& JMeterUtils.getPropDefault("httpsampler.obey_contentlength", // $NON-NLS-1$
false)) {
log.info("Content-Length: 0, not reading http-body");
res.setResponseHeaders(getResponseHeaders(conn));
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));
return NULL_BA;
}
else {
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());
}
java.io.ByteArrayOutputStream w = new ByteArrayOutputStream();
int x = 0;
boolean first = true;
while ((x = in.read(readBuffer)) > -1) {
if (first) {
res.latencyEnd();
first = false;
}
w.write(readBuffer, 0, x);
}
in.close();
w.flush();
w.close();
return w.toByteArray();
}
/**
* 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) {
StringBuffer headerBuf = new StringBuffer();
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$
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -