package org.httpkit;
import static org.httpkit.HttpUtils.SP;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
interface ReqGenerators {
public byte[] generate(HttpMethod method, String url);
}
class RandomGenerator implements ReqGenerators {
private static final Random r = new Random();
public byte[] generate(HttpMethod method, String url) {
byte[] bytes = new byte[r.nextInt(16 * 1024) + 1024];
r.nextBytes(bytes);
return bytes;
}
}
class GoodGenerator implements ReqGenerators {
private static final Random r = new Random();
public byte[] generate(HttpMethod method, String url) {
HeaderMap headers = new HeaderMap();
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
headers.put("Accept-Charset", "UTF-8,*;q=0.5");
headers.put(
"Cookie",
"BAIDUID=30CC53A6109D411534188A2FA0AF9DB5:FG=1; BDREFER=%7Burl%3A%22http%3A//internet.baidu.com/%22%2Cword%3A%22%22%7D; BDSVRTM=16; H_PS_PSSID=1423_2133_1944_2202_1788_2249_2288");
int length = 0;
if (method == HttpMethod.POST) {
length = r.nextInt(4096) + 1024;
headers.put("Content-Length", Integer.toString(length));
}
DynamicBytes bytes = new DynamicBytes(196);
bytes.append(method.toString()).append(SP).append(url);
bytes.append(" HTTP/1.1\r\n");
headers.encodeHeaders(bytes);
if (length > 0) {
byte[] body = new byte[length];
r.nextBytes(body);
bytes.append(body, body.length);
}
return Arrays.copyOf(bytes.get(), bytes.length());
}
}
class MonkeyGenerator implements ReqGenerators {
private static final Random r = new Random();
public byte[] generate(HttpMethod method, String url) {
byte[] buffer = new GoodGenerator().generate(method, url);
int b = r.nextInt(8) + 2;
int start = r.nextInt(buffer.length - b - 1);
for (int i = 0; i < b; i++) {
buffer[start + 1] = (byte) r.nextInt();
}
return buffer;
}
}
class Monkey2Generator implements ReqGenerators {
private static final Random r = new Random();
public byte[] generate(HttpMethod method, String url) {
byte[] buffer = new GoodGenerator().generate(method, url);
int b = r.nextInt(8) + 2;
for (int i = 0; i < b; i++) {
buffer[r.nextInt(32)] = (byte) r.nextInt();
}
return buffer;
}
}
class Monkey3Generator implements ReqGenerators {
private static final Random r = new Random();
public byte[] generate(HttpMethod method, String url) {
byte[] buffer = new GoodGenerator().generate(method, url);
return Arrays.copyOf(buffer, r.nextInt(buffer.length));
}
}
class Runner implements Runnable {
private final Random r = new Random();
private int total;
private int remaining;
private int success = 0;
private final InetSocketAddress addr;
private static final ReqGenerators[] generators = new ReqGenerators[] {
new RandomGenerator(), new MonkeyGenerator(), new Monkey2Generator(),
new GoodGenerator(), new Monkey3Generator() };
private static final HttpMethod[] methods = new HttpMethod[] { HttpMethod.GET,
HttpMethod.DELETE, HttpMethod.POST, HttpMethod.HEAD, HttpMethod.OPTIONS,
HttpMethod.PATCH, HttpMethod.PUT, HttpMethod.TRACE };
private static final String[] urls = new String[] { "/", "//////////////////",
"/-------------------------", "/ssss/sdfsdf" };
public Runner(int port, int count) {
this.total = count;
this.remaining = total;
this.addr = new InetSocketAddress("192.168.1.101", port);
}
private static Logger logger = LoggerFactory.getLogger(MaliciousClients.class);
public void run() {
while (remaining-- > 0) {
Socket s = new Socket();
try {
s.setReuseAddress(true);
s.setSoTimeout(100);
s.connect(addr);
ReqGenerators gen = generators[r.nextInt(generators.length)];
OutputStream os = s.getOutputStream();
os.write(gen.generate(methods[r.nextInt(methods.length)],
urls[r.nextInt(urls.length)]));
InputStream is = s.getInputStream();
byte[] buffer = new byte[8096];
int read = is.read(buffer);
// System.out.println(new String(buffer, 0, read));
is.close();
os.close();
if (read > 0)
success += 1;
} catch (NoRouteToHostException e) {
// Cannot assign requested address
try {
Thread.sleep(800);
} catch (InterruptedException e1) {
}
// e.printStackTrace();
} catch (Exception e) {
} finally {
try {
s.close();
} catch (IOException e) {
}
}
if (remaining % (total / 10) == 0) {
logger.info("total: {}, remaining: {} success: {}", total, remaining, success);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
logger.info("finished. total: {}, success: {}", total, success);
}
}
public class MaliciousClients {
private static final Logger LOGGER = LoggerFactory.getLogger(MaliciousClients.class);
public static void main(String[] args) throws InterruptedException {
int port = 9090;
int count = 100000;
int THREADS = 32;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
}
if (args.length > 1) {
count = Integer.parseInt(args[1]);
}
if (args.length > 2) {
THREADS = Integer.parseInt(args[2]);
}
LOGGER.info("port: {}, per thread count: {}, threads: {}", new Object[] { port, count,
THREADS });
ExecutorService executors = Executors.newFixedThreadPool(THREADS);
for (int i = 0; i < THREADS; i++) {
executors.submit(new Runner(port, count));
}
executors.shutdown();
executors.awaitTermination(120, TimeUnit.MINUTES);
}
}