001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027package org.apache.http.benchmark; 028 029import java.io.File; 030import java.net.MalformedURLException; 031import java.net.URL; 032 033import org.apache.commons.cli.CommandLine; 034import org.apache.commons.cli.HelpFormatter; 035import org.apache.commons.cli.Option; 036import org.apache.commons.cli.Options; 037 038public class CommandLineUtils { 039 040 public static Options getOptions() { 041 final Option iopt = new Option("i", false, "Do HEAD requests instead of GET (deprecated)"); 042 iopt.setRequired(false); 043 044 final Option oopt = new Option("o", false, "Use HTTP/S 1.0 instead of 1.1 (default)"); 045 oopt.setRequired(false); 046 047 final Option kopt = new Option("k", false, "Enable the HTTP KeepAlive feature, " + 048 "i.e., perform multiple requests within one HTTP session. " + 049 "Default is no KeepAlive"); 050 kopt.setRequired(false); 051 052 final Option uopt = new Option("u", false, "Chunk entity. Default is false"); 053 uopt.setRequired(false); 054 055 final Option xopt = new Option("x", false, "Use Expect-Continue. Default is false"); 056 xopt.setRequired(false); 057 058 final Option gopt = new Option("g", false, "Accept GZip. Default is false"); 059 gopt.setRequired(false); 060 061 final Option nopt = new Option("n", true, "Number of requests to perform for the " + 062 "benchmarking session. The default is to just perform a single " + 063 "request which usually leads to non-representative benchmarking " + 064 "results"); 065 nopt.setRequired(false); 066 nopt.setArgName("requests"); 067 068 final Option copt = new Option("c", true, "Concurrency while performing the " + 069 "benchmarking session. The default is to just use a single thread/client"); 070 copt.setRequired(false); 071 copt.setArgName("concurrency"); 072 073 final Option popt = new Option("p", true, "File containing data to POST or PUT"); 074 popt.setRequired(false); 075 popt.setArgName("Payload file"); 076 077 final Option mopt = new Option("m", true, "HTTP Method. Default is POST. " + 078 "Possible options are GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE"); 079 mopt.setRequired(false); 080 mopt.setArgName("HTTP method"); 081 082 final Option Topt = new Option("T", true, "Content-type header to use for POST/PUT data"); 083 Topt.setRequired(false); 084 Topt.setArgName("content-type"); 085 086 final Option topt = new Option("t", true, "Client side socket timeout (in ms) - default 60 Secs"); 087 topt.setRequired(false); 088 topt.setArgName("socket-Timeout"); 089 090 final Option Hopt = new Option("H", true, "Add arbitrary header line, " + 091 "eg. 'Accept-Encoding: gzip' inserted after all normal " + 092 "header lines. (repeatable as -H \"h1: v1\",\"h2: v2\" etc)"); 093 Hopt.setRequired(false); 094 Hopt.setArgName("header"); 095 096 final Option vopt = new Option("v", true, "Set verbosity level - 4 and above " + 097 "prints response content, 3 and above prints " + 098 "information on headers, 2 and above prints response codes (404, 200, " + 099 "etc.), 1 and above prints warnings and info"); 100 vopt.setRequired(false); 101 vopt.setArgName("verbosity"); 102 103 final Option hopt = new Option("h", false, "Display usage information"); 104 nopt.setRequired(false); 105 106 final Options options = new Options(); 107 options.addOption(iopt); 108 options.addOption(mopt); 109 options.addOption(uopt); 110 options.addOption(xopt); 111 options.addOption(gopt); 112 options.addOption(kopt); 113 options.addOption(nopt); 114 options.addOption(copt); 115 options.addOption(popt); 116 options.addOption(Topt); 117 options.addOption(vopt); 118 options.addOption(Hopt); 119 options.addOption(hopt); 120 options.addOption(topt); 121 options.addOption(oopt); 122 return options; 123 } 124 125 public static void parseCommandLine(final CommandLine cmd, final Config config) { 126 if (cmd.hasOption('v')) { 127 final String s = cmd.getOptionValue('v'); 128 try { 129 config.setVerbosity(Integer.parseInt(s)); 130 } catch (final NumberFormatException ex) { 131 printError("Invalid verbosity level: " + s); 132 } 133 } 134 135 if (cmd.hasOption('k')) { 136 config.setKeepAlive(true); 137 } 138 139 if (cmd.hasOption('c')) { 140 final String s = cmd.getOptionValue('c'); 141 try { 142 config.setThreads(Integer.parseInt(s)); 143 } catch (final NumberFormatException ex) { 144 printError("Invalid number for concurrency: " + s); 145 } 146 } 147 148 if (cmd.hasOption('n')) { 149 final String s = cmd.getOptionValue('n'); 150 try { 151 config.setRequests(Integer.parseInt(s)); 152 } catch (final NumberFormatException ex) { 153 printError("Invalid number of requests: " + s); 154 } 155 } 156 157 if (cmd.hasOption('p')) { 158 final File file = new File(cmd.getOptionValue('p')); 159 if (!file.exists()) { 160 printError("File not found: " + file); 161 } 162 config.setPayloadFile(file); 163 } 164 165 if (cmd.hasOption('T')) { 166 config.setContentType(cmd.getOptionValue('T')); 167 } 168 169 if (cmd.hasOption('i')) { 170 config.setHeadInsteadOfGet(true); 171 } 172 173 if (cmd.hasOption('H')) { 174 final String headerStr = cmd.getOptionValue('H'); 175 config.setHeaders(headerStr.split(",")); 176 } 177 178 if (cmd.hasOption('t')) { 179 final String t = cmd.getOptionValue('t'); 180 try { 181 config.setSocketTimeout(Integer.parseInt(t)); 182 } catch (final NumberFormatException ex) { 183 printError("Invalid socket timeout: " + t); 184 } 185 } 186 187 if (cmd.hasOption('o')) { 188 config.setUseHttp1_0(true); 189 } 190 191 if (cmd.hasOption('m')) { 192 config.setMethod(cmd.getOptionValue('m')); 193 } else if (cmd.hasOption('p')) { 194 config.setMethod("POST"); 195 } 196 197 if (cmd.hasOption('u')) { 198 config.setUseChunking(true); 199 } 200 201 if (cmd.hasOption('x')) { 202 config.setUseExpectContinue(true); 203 } 204 205 if (cmd.hasOption('g')) { 206 config.setUseAcceptGZip(true); 207 } 208 209 final String[] cmdargs = cmd.getArgs(); 210 if (cmdargs.length > 0) { 211 try { 212 config.setUrl(new URL(cmdargs[0])); 213 } catch (final MalformedURLException e) { 214 printError("Invalid request URL : " + cmdargs[0]); 215 } 216 } 217 } 218 219 static void showUsage(final Options options) { 220 final HelpFormatter formatter = new HelpFormatter(); 221 formatter.printHelp("HttpBenchmark [options] [http://]hostname[:port]/path?query", options); 222 } 223 224 static void printError(final String msg) { 225 System.err.println(msg); 226 showUsage(getOptions()); 227 System.exit(-1); 228 } 229}