/******************************************************************************* * Copyright 2013-2014 alladin-IT GmbH * * Licensed 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. ******************************************************************************/ package at.alladin.rmbt.client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.Locale; import java.util.Scanner; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import at.alladin.rmbt.client.helper.Config; public abstract class AbstractRMBTTest { protected static final String EXPECT_GREETING = Config.RMBT_VERSION_STRING; protected final RMBTClient client; protected final RMBTTestParameter params; protected final int threadId; protected InputStreamCounter in; protected BufferedReader reader; protected OutputStreamCounter out; protected long totalDown; protected long totalUp; protected int chunksize; protected byte[] buf; /** * * @param client * @param params * @param threadId */ public AbstractRMBTTest(RMBTClient client, RMBTTestParameter params, int threadId) { this.threadId = threadId; this.client = client; this.params = params; } protected Socket getSocket(final String host, final int port, final boolean isSecure, final int timeOut) throws UnknownHostException, IOException { InetSocketAddress sockAddr = new InetSocketAddress(host, port); final Socket socket; if (client.getSslSocketFactory() != null && isSecure) { socket = client.getSslSocketFactory().createSocket(); } else { socket = new Socket(); } if (socket != null) { System.out.println("Connecting to " + sockAddr + " with timout: " + timeOut + "ms " + socket + " [SSL: " + isSecure + "]"); socket.connect(sockAddr, timeOut); } return socket; } protected Socket connect(final TestResult testResult, final InetAddress host, final int port, final String protocolVersion, final String response, final boolean isSecure, final int connTimeOut) throws IOException { log(String.format(Locale.US, "thread %d: connecting...", threadId)); final InetAddress inetAddress = host; final Socket s = getSocket(inetAddress.getHostAddress(), port, isSecure, connTimeOut); s.setSoTimeout(12000); if (testResult != null) { testResult.ip_local = s.getLocalAddress(); testResult.ip_server = s.getInetAddress(); testResult.port_remote = s.getPort(); } if (s instanceof SSLSocket) { final SSLSocket sslSocket = (SSLSocket) s; final SSLSession session = sslSocket.getSession(); if (testResult != null) { testResult.encryption = String.format(Locale.US, "%s (%s)", session.getProtocol(), session.getCipherSuite()); } } log(String.format(Locale.US, "thread %d: ReceiveBufferSize: '%s'.", threadId, s.getReceiveBufferSize())); log(String.format(Locale.US, "thread %d: SendBufferSize: '%s'.", threadId, s.getSendBufferSize())); if (in != null) totalDown += in.getCount(); if (out != null) totalUp += out.getCount(); in = new InputStreamCounter(s.getInputStream()); reader = new BufferedReader(new InputStreamReader(in, "US-ASCII"), 4096); out = new OutputStreamCounter(s.getOutputStream()); String line = reader.readLine(); if (!line.equals(protocolVersion)) { log(String.format(Locale.US, "thread %d: got '%s' expected '%s'", threadId, line, EXPECT_GREETING)); return null; } line = reader.readLine(); if (!line.startsWith("ACCEPT ")) { log(String.format(Locale.US, "thread %d: got '%s' expected 'ACCEPT'", threadId, line)); return null; } final String send = String.format(Locale.US, "TOKEN %s\n", params.getToken()); out.write(send.getBytes("US-ASCII")); line = reader.readLine(); if (line == null) { log(String.format(Locale.US, "thread %d: got no answer expected 'OK'", threadId, line)); return null; } else if (!line.equals("OK")) { log(String.format(Locale.US, "thread %d: got '%s' expected 'OK'", threadId, line)); return null; } line = reader.readLine(); final Scanner scanner = new Scanner(line); try { if (response.equals("CHUNKSIZE")) { if (!response.equals(scanner.next())) { log(String.format(Locale.US, "thread %d: got '%s' expected 'CHUNKSIZE'", threadId, line)); return null; } try { chunksize = scanner.nextInt(); log(String.format(Locale.US, "thread %d: CHUNKSIZE is %d", threadId, chunksize)); } catch (final Exception e) { log(String.format(Locale.US, "thread %d: invalid CHUNKSIZE: '%s'", threadId, line)); return null; } if (buf == null || buf != null && buf.length != chunksize) buf = new byte[chunksize]; s.setSoTimeout(0); return s; } else { log(String.format(Locale.US, "thread %d: got '%s'", threadId, line)); s.setSoTimeout(0); return s; } } finally { scanner.close(); } } protected Socket connect(final TestResult testResult) throws IOException { return connect(testResult, InetAddress.getByName(params.getHost()), params.getPort(), EXPECT_GREETING, "CHUNKSIZE", true, 20000); } /** * * @param message * @return * @throws IOException * @throws UnsupportedEncodingException */ protected void sendMessage(final String message) throws UnsupportedEncodingException, IOException { String send; send = String.format(Locale.US, message); System.out.println("sending command (thread " + Thread.currentThread().getId() + "): " + send); out.write(send.getBytes("US-ASCII")); out.flush(); } protected void log(final CharSequence text) { client.log(text); } }