package org.httpkit; import org.httpkit.server.WSDecoder; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.*; import java.nio.ByteBuffer; import java.util.Arrays; public class SpecialHttpClient { public static void main(String[] args) throws Exception { // System.out.println(http10("http://127.0.0.1:9090/")); slowWebSocketClient("ws://localhost:9090/ws2/echo"); } // request + request sent to server, wait for 2 server responses public static String get2(String url) throws URISyntaxException, IOException { URI uri = new URI(url); InetSocketAddress addr = HttpUtils.getServerAddr(uri); Socket s = new Socket(); s.connect(addr); OutputStream os = s.getOutputStream(); String request = "GET " + HttpUtils.getPath(uri) + " HTTP/1.1\r\nHost: localhost\r\n\r\n"; os.write((request + request).getBytes()); os.flush(); InputStream is = s.getInputStream(); byte[] buffer = new byte[8096]; int read = is.read(buffer); s.close(); return new String(buffer, 0, read); } public static String http10(String url) throws Exception { URI uri = new URI(url); InetSocketAddress addr = HttpUtils.getServerAddr(uri); Socket s = new Socket(); s.connect(addr); OutputStream os = s.getOutputStream(); String request = "GET " + HttpUtils.getPath(uri) + " HTTP/1.0\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n"; os.write((request + request).getBytes()); os.flush(); InputStream is = s.getInputStream(); byte[] buffer = new byte[8096]; int read = is.read(buffer); s.close(); return new String(buffer, 0, read); } // sent request one byte at a time public static String slowGet(String url) throws URISyntaxException, IOException, InterruptedException { URI uri = new URI(url); InetSocketAddress addr = HttpUtils.getServerAddr(uri); Socket s = new Socket(); s.setTcpNoDelay(false); s.connect(addr); String request = "GET " + HttpUtils.getPath(uri) + " HTTP/1.1\r\n"; request += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; request += "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17\r\n"; request += "Connection: close\n"; request += "\r\n"; byte[] bytes = request.getBytes(); InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); for (byte b : bytes) { os.write(b); if (Math.random() > 0.6) { Thread.sleep(1); } os.flush(); } byte[] buffer = new byte[8096]; int read = is.read(buffer); s.close(); return new String(buffer, 0, read); } public static byte[] encodeWsRequest(String mesg) { byte[] payload = mesg.getBytes(); ByteBuffer buffer = ByteBuffer.allocate(payload.length + 1024); byte b0 = 0; b0 |= 1 << 7; // is final b0 |= WSDecoder.OPCODE_TEXT; buffer.put(b0); byte b1 = 0; b1 |= 1 << 7; // masked if (payload.length <= 125) { b1 |= payload.length; buffer.put(b1); } else if (payload.length <= 0xffff) { b1 |= 126; buffer.put(b1); buffer.putShort((short) payload.length); } else { b1 |= 127; buffer.put(b1); buffer.putLong(payload.length); } // masking key int random = (int) (Math.random() * Integer.MAX_VALUE); buffer.putInt(random); byte[] mask = ByteBuffer.allocate(4).putInt(random).array(); int counter = 0; for (int i = 0; i < payload.length; i++) { // mast the data buffer.put((byte) (payload[i] ^ mask[counter++ % 4])); } return Arrays.copyOf(buffer.array(), buffer.position()); } // a special websocket client to test the robustness of the Decoder // sent a byte at a time public static boolean slowWebSocketClient(String url) { try { URI uri = new URI(url); InetSocketAddress addr = HttpUtils.getServerAddr(uri); Socket s = new Socket(); s.connect(addr); OutputStream os = s.getOutputStream(); InputStream is = s.getInputStream(); byte[] buffer = new byte[8096]; String request = "GET " + HttpUtils.getPath(uri) + " HTTP/1.1\r\nHost: localhost\r\nUpgrade: websocket\r\nSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\r\n"; os.write(request.getBytes()); int read = is.read(buffer); if (!new String(buffer, 0, read).contains("websocket")) { return false; } String msg = "this is a test; this is a test; this is a test"; for (int i = 0; i < 2; i++) { wsRequest(os, is, msg); msg += (msg + msg + msg + msg); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } private static void wsRequest(OutputStream os, InputStream is, String msg) throws Exception { byte[] request = encodeWsRequest(msg); // sent one byte at a time for (byte b : request) { os.write(b); if (Math.random() > 0.6) { Thread.sleep(1); } os.flush(); } // os.write(request); byte[] buffer = new byte[16 * 1024]; int read; read = is.read(buffer); ByteBuffer wrap = ByteBuffer.wrap(buffer, 0, read); wrap.get(); // opcode is ignored byte b2 = wrap.get(); int idx = 2; int resultLength = b2 & 0x7f; if (resultLength == 126) { idx += 2; resultLength = wrap.getShort(); } else if (resultLength == 127) { idx += 8; resultLength = (int) wrap.getLong(); } String response = new String(buffer, idx, resultLength); if (!response.equals(msg)) { throw new Exception("should equal"); } } public static String getPartial(String url) { try { URI uri = new URI(url); InetSocketAddress addr = HttpUtils.getServerAddr(uri); Socket s = new Socket(); s.connect(addr); s.setSoTimeout(100); OutputStream os = s.getOutputStream(); String request = "GET " + HttpUtils.getPath(uri) + " HTTP/1.1\r\nHost: localhost\r\n\r\n"; os.write(request.getBytes()); os.flush(); InputStream is = s.getInputStream(); byte[] buffer = new byte[8096]; int read = is.read(buffer); s.close(); return new String(buffer, 0, read); } catch (Exception e) { return null; } } }