| /* |
| * ==================================================================== |
| * 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. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| * |
| */ |
| package org.apache.http.benchmark; |
| |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.net.URL; |
| |
| import org.apache.commons.cli.CommandLine; |
| import org.apache.commons.cli.CommandLineParser; |
| import org.apache.commons.cli.Options; |
| import org.apache.commons.cli.PosixParser; |
| import org.apache.http.Header; |
| import org.apache.http.HttpHost; |
| import org.apache.http.HttpRequest; |
| import org.apache.http.HttpVersion; |
| import org.apache.http.entity.ContentType; |
| import org.apache.http.entity.FileEntity; |
| import org.apache.http.message.BasicHttpEntityEnclosingRequest; |
| import org.apache.http.message.BasicHttpRequest; |
| import org.apache.http.params.BasicHttpParams; |
| import org.apache.http.params.HttpConnectionParams; |
| import org.apache.http.params.HttpParams; |
| import org.apache.http.params.HttpProtocolParams; |
| import org.apache.http.protocol.HTTP; |
| |
| import java.security.KeyStore; |
| import java.util.concurrent.LinkedBlockingQueue; |
| import java.util.concurrent.ThreadFactory; |
| import java.util.concurrent.ThreadPoolExecutor; |
| import java.util.concurrent.TimeUnit; |
| |
| import javax.net.SocketFactory; |
| import javax.net.ssl.KeyManager; |
| import javax.net.ssl.KeyManagerFactory; |
| import javax.net.ssl.SSLContext; |
| import javax.net.ssl.TrustManager; |
| import javax.net.ssl.TrustManagerFactory; |
| import javax.net.ssl.X509TrustManager; |
| |
| import org.apache.http.HttpEntity; |
| import org.apache.http.entity.StringEntity; |
| |
| /** |
| * Main program of the HTTP benchmark. |
| * |
| * |
| * @since 4.0 |
| */ |
| public class HttpBenchmark { |
| |
| private final Config config; |
| |
| public static void main(String[] args) throws Exception { |
| |
| Options options = CommandLineUtils.getOptions(); |
| CommandLineParser parser = new PosixParser(); |
| CommandLine cmd = parser.parse(options, args); |
| |
| if (args.length == 0 || cmd.hasOption('h') || cmd.getArgs().length != 1) { |
| CommandLineUtils.showUsage(options); |
| System.exit(1); |
| } |
| |
| Config config = new Config(); |
| CommandLineUtils.parseCommandLine(cmd, config); |
| |
| if (config.getUrl() == null) { |
| CommandLineUtils.showUsage(options); |
| System.exit(1); |
| } |
| |
| HttpBenchmark httpBenchmark = new HttpBenchmark(config); |
| httpBenchmark.execute(); |
| } |
| |
| public HttpBenchmark(final Config config) { |
| super(); |
| this.config = config != null ? config : new Config(); |
| } |
| |
| private HttpRequest createRequest() { |
| HttpParams params = new BasicHttpParams(); |
| params.setParameter(HttpProtocolParams.PROTOCOL_VERSION, |
| config.isUseHttp1_0() ? HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1) |
| .setParameter(HttpProtocolParams.USER_AGENT, "HttpCore-AB/1.1") |
| .setBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, config.isUseExpectContinue()) |
| .setBooleanParameter(HttpConnectionParams.STALE_CONNECTION_CHECK, false) |
| .setIntParameter(HttpConnectionParams.SO_TIMEOUT, config.getSocketTimeout()); |
| |
| URL url = config.getUrl(); |
| HttpEntity entity = null; |
| |
| // Prepare requests for each thread |
| if (config.getPayloadFile() != null) { |
| FileEntity fe = new FileEntity(config.getPayloadFile()); |
| fe.setContentType(config.getContentType()); |
| fe.setChunked(config.isUseChunking()); |
| entity = fe; |
| } else if (config.getPayloadText() != null) { |
| StringEntity se = new StringEntity(config.getPayloadText(), |
| ContentType.parse(config.getContentType())); |
| se.setChunked(config.isUseChunking()); |
| entity = se; |
| } |
| HttpRequest request; |
| if ("POST".equals(config.getMethod())) { |
| BasicHttpEntityEnclosingRequest httppost = |
| new BasicHttpEntityEnclosingRequest("POST", url.getPath()); |
| httppost.setEntity(entity); |
| request = httppost; |
| } else if ("PUT".equals(config.getMethod())) { |
| BasicHttpEntityEnclosingRequest httpput = |
| new BasicHttpEntityEnclosingRequest("PUT", url.getPath()); |
| httpput.setEntity(entity); |
| request = httpput; |
| } else { |
| String path = url.getPath(); |
| if (url.getQuery() != null && url.getQuery().length() > 0) { |
| path += "?" + url.getQuery(); |
| } else if (path.trim().length() == 0) { |
| path = "/"; |
| } |
| request = new BasicHttpRequest(config.getMethod(), path); |
| } |
| |
| if (!config.isKeepAlive()) { |
| request.addHeader(new DefaultHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE)); |
| } |
| |
| String[] headers = config.getHeaders(); |
| if (headers != null) { |
| for (int i = 0; i < headers.length; i++) { |
| String s = headers[i]; |
| int pos = s.indexOf(':'); |
| if (pos != -1) { |
| Header header = new DefaultHeader(s.substring(0, pos).trim(), s.substring(pos + 1)); |
| request.addHeader(header); |
| } |
| } |
| } |
| |
| if (config.isUseAcceptGZip()) { |
| request.addHeader(new DefaultHeader("Accept-Encoding", "gzip")); |
| } |
| |
| if (config.getSoapAction() != null && config.getSoapAction().length() > 0) { |
| request.addHeader(new DefaultHeader("SOAPAction", config.getSoapAction())); |
| } |
| return request; |
| } |
| |
| public String execute() throws Exception { |
| |
| URL url = config.getUrl(); |
| HttpHost host = new HttpHost(url.getHost(), url.getPort(), url.getProtocol()); |
| |
| ThreadPoolExecutor workerPool = new ThreadPoolExecutor( |
| config.getThreads(), config.getThreads(), 5, TimeUnit.SECONDS, |
| new LinkedBlockingQueue<Runnable>(), |
| new ThreadFactory() { |
| |
| public Thread newThread(Runnable r) { |
| return new Thread(r, "ClientPool"); |
| } |
| |
| }); |
| workerPool.prestartAllCoreThreads(); |
| |
| SocketFactory socketFactory = null; |
| if ("https".equals(host.getSchemeName())) { |
| TrustManager[] trustManagers = null; |
| if (config.isDisableSSLVerification()) { |
| // Create a trust manager that does not validate certificate chains |
| trustManagers = new TrustManager[] { |
| new X509TrustManager() { |
| |
| public java.security.cert.X509Certificate[] getAcceptedIssuers() { |
| return null; |
| } |
| |
| public void checkClientTrusted( |
| java.security.cert.X509Certificate[] certs, String authType) { |
| } |
| |
| public void checkServerTrusted( |
| java.security.cert.X509Certificate[] certs, String authType) { |
| } |
| } |
| }; |
| } else if (config.getTrustStorePath() != null) { |
| KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| FileInputStream instream = new FileInputStream(config.getTrustStorePath()); |
| try { |
| trustStore.load(instream, config.getTrustStorePath() != null ? |
| config.getTrustStorePath().toCharArray() : null); |
| } finally { |
| try { instream.close(); } catch (IOException ignore) {} |
| } |
| TrustManagerFactory tmfactory = TrustManagerFactory.getInstance( |
| TrustManagerFactory.getDefaultAlgorithm()); |
| tmfactory.init(trustStore); |
| trustManagers = tmfactory.getTrustManagers(); |
| } |
| KeyManager[] keyManagers = null; |
| if (config.getIdentityStorePath() != null) { |
| KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| FileInputStream instream = new FileInputStream(config.getIdentityStorePath()); |
| try { |
| identityStore.load(instream, config.getIdentityStorePassword() != null ? |
| config.getIdentityStorePassword().toCharArray() : null); |
| } finally { |
| try { instream.close(); } catch (IOException ignore) {} |
| } |
| KeyManagerFactory kmf = KeyManagerFactory.getInstance( |
| KeyManagerFactory.getDefaultAlgorithm()); |
| kmf.init(identityStore, config.getIdentityStorePassword() != null ? |
| config.getIdentityStorePassword().toCharArray() : null); |
| keyManagers = kmf.getKeyManagers(); |
| } |
| SSLContext sc = SSLContext.getInstance("SSL"); |
| sc.init(keyManagers, trustManagers, null); |
| socketFactory = sc.getSocketFactory(); |
| } |
| |
| BenchmarkWorker[] workers = new BenchmarkWorker[config.getThreads()]; |
| for (int i = 0; i < workers.length; i++) { |
| workers[i] = new BenchmarkWorker( |
| createRequest(), |
| host, |
| config.getRequests(), |
| config.isKeepAlive(), |
| config.getVerbosity(), |
| socketFactory); |
| workerPool.execute(workers[i]); |
| } |
| |
| while (workerPool.getCompletedTaskCount() < config.getThreads()) { |
| Thread.yield(); |
| try { |
| Thread.sleep(1000); |
| } catch (InterruptedException ignore) { |
| } |
| } |
| |
| workerPool.shutdown(); |
| return ResultProcessor.printResults(workers, host, config.getUrl().toString()); |
| } |
| |
| } |