📄 httpsamplerbase.java
字号:
res = fileSample(new URI(PROTOCOL_FILE,getPath(),null));
} else {
res = sample(getUrl(), getMethod(), false, 0);
}
res.setSampleLabel(getName());
return res;
} catch (MalformedURLException e) {
return errorResult(e, new HTTPSampleResult());
} catch (IOException e) {
return errorResult(e, new HTTPSampleResult());
} catch (URISyntaxException e) {
return errorResult(e, new HTTPSampleResult());
}
}
private HTTPSampleResult fileSample(URI uri) throws IOException {
String urlStr = uri.toString();
HTTPSampleResult res = new HTTPSampleResult();
res.setMonitor(isMonitor());
res.setHTTPMethod(GET); // Dummy
res.setURL(new URL(urlStr));
res.setSampleLabel(urlStr);
FileReader reader = null;
res.sampleStart();
try {
byte[] responseData;
StringBuffer ctb=new StringBuffer("text/html"); // $NON-NLS-1$
reader = new FileReader(getPath());
String contentEncoding = getContentEncoding();
if (contentEncoding.length() == 0) {
responseData = IOUtils.toByteArray(reader);
} else {
ctb.append("; charset="); // $NON-NLS-1$
ctb.append(contentEncoding);
responseData = IOUtils.toByteArray(reader,contentEncoding);
}
res.sampleEnd();
res.setResponseData(responseData);
res.setResponseCodeOK();
res.setResponseMessageOK();
res.setSuccessful(true);
String ct = ctb.toString();
res.setContentType(ct);
res.setEncodingAndType(ct);
} finally {
IOUtils.closeQuietly(reader);
}
//res.setResponseHeaders("");
return res;
}
/**
* Samples the URL passed in and stores the result in
* <code>HTTPSampleResult</code>, following redirects and downloading
* page resources as appropriate.
* <p>
* When getting a redirect target, redirects are not followed and resources
* are not downloaded. The caller will take care of this.
*
* @param u
* URL to sample
* @param method
* HTTP method: GET, POST,...
* @param areFollowingRedirect
* whether we're getting a redirect target
* @param depth
* Depth of this target in the frame structure. Used only to
* prevent infinite recursion.
* @return results of the sampling
*/
protected abstract HTTPSampleResult sample(URL u,
String method, boolean areFollowingRedirect, int depth);
/**
* Download the resources of an HTML page.
* <p>
* If createContainerResult is true, the returned result will contain one
* subsample for each request issued, including the original one that was
* passed in. It will otherwise look exactly like that original one.
* <p>
* If createContainerResult is false, one subsample will be added to the
* provided result for each requests issued.
*
* @param res
* result of the initial request - must contain an HTML response
* @param container
* for storing the results
* @param frameDepth
* Depth of this target in the frame structure. Used only to
* prevent infinite recursion.
* @return "Container" result with one subsample per request issued
*/
protected HTTPSampleResult downloadPageResources(HTTPSampleResult res, HTTPSampleResult container, int frameDepth) {
Iterator urls = null;
try {
final byte[] responseData = res.getResponseData();
if (responseData.length > 0){ // Bug 39205
String parserName = getParserClass(res);
if(parserName != null)
{
final HTMLParser parser =
parserName.length() > 0 ? // we have a name
HTMLParser.getParser(parserName)
:
HTMLParser.getParser(); // we don't; use the default parser
urls = parser.getEmbeddedResourceURLs(responseData, res.getURL());
}
}
} catch (HTMLParseException e) {
// Don't break the world just because this failed:
res.addSubResult(errorResult(e, res));
res.setSuccessful(false);
}
// Iterate through the URLs and download each image:
if (urls != null && urls.hasNext()) {
if (container == null) {
res = new HTTPSampleResult(res);
} else {
res = container;
}
// Get the URL matcher
String re=getEmbeddedUrlRE();
Perl5Matcher localMatcher = null;
Pattern pattern = null;
if (re.length()>0){
try {
pattern = JMeterUtils.getPattern(re);
localMatcher = JMeterUtils.getMatcher();// don't fetch unless pattern compiles
} catch (MalformedCachePatternException e) {
log.warn("Ignoring embedded URL match string: "+e.getMessage());
}
}
while (urls.hasNext()) {
Object binURL = urls.next();
try {
URL url = (URL) binURL;
if (url == null) {
log.warn("Null URL detected (should not happen)");
} else {
String urlstr = url.toString();
String urlStrEnc=encodeSpaces(urlstr);
if (!urlstr.equals(urlStrEnc)){// There were some spaces in the URL
try {
url = new URL(urlStrEnc);
} catch (MalformedURLException e) {
res.addSubResult(errorResult(new Exception(urlStrEnc + " is not a correct URI"), res));
res.setSuccessful(false);
continue;
}
}
// I don't think localMatcher can be null here, but check just in case
if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc, pattern)) {
continue; // we have a pattern and the URL does not match, so skip it
}
HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
res.addSubResult(binRes);
res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
}
} catch (ClassCastException e) {
res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
res.setSuccessful(false);
continue;
}
}
}
return res;
}
/*
* @param res HTTPSampleResult to check
* @return parser class name (may be "") or null if entry does not exist
*/
private String getParserClass(HTTPSampleResult res) {
final String ct = res.getMediaType();
return (String)parsersForType.get(ct);
}
// TODO: make static?
protected String encodeSpaces(String path) {
return JOrphanUtils.replaceAllChars(path, ' ', "%20"); // $NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see org.apache.jmeter.testelement.TestListener#testEnded()
*/
public void testEnded() {
dynamicPath = false;
}
/*
* (non-Javadoc)
*
* @see org.apache.jmeter.testelement.TestListener#testEnded(java.lang.String)
*/
public void testEnded(String host) {
testEnded();
}
/*
* (non-Javadoc)
*
* @see org.apache.jmeter.testelement.TestListener#testIterationStart(org.apache.jmeter.engine.event.LoopIterationEvent)
*/
public void testIterationStart(LoopIterationEvent event) {
}
/*
* (non-Javadoc)
*
* @see org.apache.jmeter.testelement.TestListener#testStarted()
*/
public void testStarted() {
JMeterProperty pathP = getProperty(PATH);
log.debug("path property is a " + pathP.getClass().getName());
log.debug("path beginning value = " + pathP.getStringValue());
if (pathP instanceof StringProperty && !"".equals(pathP.getStringValue())) {
log.debug("Encoding spaces in path");
pathP.setObjectValue(encodeSpaces(pathP.getStringValue()));
dynamicPath = false;
} else {
log.debug("setting dynamic path to true");
dynamicPath = true;
}
log.debug("path ending value = " + pathP.getStringValue());
}
/*
* (non-Javadoc)
*
* @see org.apache.jmeter.testelement.TestListener#testStarted(java.lang.String)
*/
public void testStarted(String host) {
testStarted();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#clone()
*/
public Object clone() {
HTTPSamplerBase base = (HTTPSamplerBase) super.clone();
base.dynamicPath = dynamicPath;
return base;
}
/**
* Iteratively download the redirect targets of a redirect response.
* <p>
* The returned result will contain one subsample for each request issued,
* including the original one that was passed in. It will be an
* HTTPSampleResult that should mostly look as if the final destination of
* the redirect chain had been obtained in a single shot.
*
* @param res
* result of the initial request - must be a redirect response
* @param frameDepth
* Depth of this target in the frame structure. Used only to
* prevent infinite recursion.
* @return "Container" result with one subsample per request issued
*/
protected HTTPSampleResult followRedirects(HTTPSampleResult res, int frameDepth) {
HTTPSampleResult totalRes = new HTTPSampleResult(res);
HTTPSampleResult lastRes = res;
int redirect;
for (redirect = 0; redirect < MAX_REDIRECTS; redirect++) {
boolean invalidRedirectUrl = false;
// Browsers seem to tolerate Location headers with spaces,
// replacing them automatically with %20. We want to emulate
// this behaviour.
String location = encodeSpaces(lastRes.getRedirectLocation());
try {
lastRes = sample(new URL(lastRes.getURL(), location), GET, true, frameDepth);
} catch (MalformedURLException e) {
lastRes = errorResult(e, lastRes);
// The redirect URL we got was not a valid URL
invalidRedirectUrl = true;
}
if (lastRes.getSubResults() != null && lastRes.getSubResults().length > 0) {
SampleResult[] subs = lastRes.getSubResults();
for (int i = 0; i < subs.length; i++) {
totalRes.addSubResult(subs[i]);
}
} else {
// Only add sample if it is a sample of valid url redirect, i.e. that
// we have actually sampled the URL
if(!invalidRedirectUrl) {
totalRes.addSubResult(lastRes);
}
}
if (!lastRes.isRedirect()) {
break;
}
}
if (redirect >= MAX_REDIRECTS) {
lastRes = errorResult(new IOException("Exceeeded maximum number of redirects: " + MAX_REDIRECTS), lastRes);
totalRes.addSubResult(lastRes);
}
// Now populate the any totalRes fields that need to
// come from lastRes:
totalRes.setSampleLabel(totalRes.getSampleLabel() + "->" + lastRes.getSampleLabel());
// The following three can be discussed: should they be from the
// first request or from the final one? I chose to do it this way
// because that's what browsers do: they show the final URL of the
// redirect chain in the location field.
totalRes.setURL(lastRes.getURL());
totalRes.setHTTPMethod(lastRes.getHTTPMethod());
totalRes.setQueryString(lastRes.getQueryString());
totalRes.setRequestHeaders(lastRes.getRequestHeaders());
totalRes.setResponseData(lastRes.getResponseData());
totalRes.setResponseCode(lastRes.getResponseCode());
totalRes.setSuccessful(lastRes.isSuccessful());
totalRes.setResponseMessage(lastRes.getResponseMessage());
totalRes.setDataType(lastRes.getDataType());
totalRes.setResponseHeaders(lastRes.getResponseHeaders());
totalRes.setContentType(lastRes.getContentType());
totalRes.setDataEncoding(lastRes.getDataEncoding());
return totalRes;
}
/**
* Follow redirects and download page resources if appropriate. this works,
* but the container stuff here is what's doing it. followRedirects() is
* actually doing the work to make sure we have only one container to make
* this work more naturally, I think this method - sample() - needs to take
* an HTTPSamplerResult container parameter instead of a
* boolean:areFollowingRedirect.
*
* @param areFollowingRedirect
* @param frameDepth
* @param res
* @return the sample result
*/
protected HTTPSampleResult resultProcessing(boolean areFollowingRedirect, int frameDepth, HTTPSampleResult res) {
boolean wasRedirected = false;
if (!areFollowingRedirect) {
if (res.isRedirect()) {
log.debug("Location set to - " + res.getRedirectLocation());
if (getFollowRedirects()) {
res = followRedirects(res, frameDepth);
areFollowingRedirect = true;
wasRedirected = true;
}
}
}
if (isImageParser() && (HTTPSampleResult.TEXT).equals(res.getDataType()) && res.isSuccessful()) {
if (frameDepth > MAX_FRAME_DEPTH) {
res.addSubResult(errorResult(new Exception("Maximum frame/iframe nesting depth exceeded."), res));
} else {
// If we followed redirects, we already have a container:
if(!areFollowingRedirect) {
HTTPSampleResult container = (HTTPSampleResult) (areFollowingRedirect ? res.getParent() : res);
// Only download page resources if we were not redirected.
// If we were redirected, the page resources have already been
// downloaded for the sample made for the redirected url
if(!wasRedirected) {
res = downloadPageResources(res, container, frameDepth);
}
}
}
}
return res;
}
/**
* Determine if the HTTP status code is successful or not
* i.e. in range 200 to 399 inclusive
*
* @return whether in range 200-399 or not
*/
protected boolean isSuccessCode(int code){
return (code >= 200 && code <= 399);
}
protected static String encodeBackSlashes(String value) {
StringBuffer newValue = new StringBuffer();
for (int i = 0; i < value.length(); i++) {
char charAt = value.charAt(i);
if (charAt == '\\') { // $NON-NLS-1$
newValue.append("\\\\"); // $NON-NLS-1$
} else {
newValue.append(charAt);
}
}
return newValue.toString();
}
/**
* Method to tell if the request has any files to be uploaded
*/
protected boolean hasUploadableFiles() {
return getFilename() != null && getFilename().trim().length() > 0;
}
public static String[] getValidMethodsAsArray(){
return (String[]) METHODLIST.toArray(new String[0]);
}
public static boolean isSecure(String protocol){
return PROTOCOL_HTTPS.equalsIgnoreCase(protocol);
}
public static boolean isSecure(URL url){
return isSecure(url.getProtocol());
}
// Implement these here, to avoid re-implementing for sub-classes
// (previously these were implemented in all TestElements)
public void threadStarted(){
}
public void threadFinished(){
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -