/* * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/** * A cut-down Http/1 Server for testing various error situations * * use interrupt() to halt
*/ publicclass MockServer extendsThreadimplements Closeable {
final ServerSocket ss; privatefinal List<Connection> sockets; privatefinal List<Connection> removals; privatefinal List<Connection> additions;
AtomicInteger counter = new AtomicInteger(0); // if specified (not null), only requests which // contain this value in their status line // will be taken into account and returned by activity(). // Other requests will get summarily closed. // When specified, this can prevent answering to rogue // (external) clients that might be lurking // on the test machine instead of answering // to the test client. final String root;
// waits up to 2000 seconds for something to happen // dont use this unless certain activity coming. public Connection activity() { for (int i = 0; i < 80 * 100; i++) {
doRemovalsAndAdditions(); for (Connection c : sockets) { if (c.poll()) { if (root != null) { // if a root was specified in MockServer // constructor, rejects (by closing) all // requests whose statusLine does not contain // root. if (!c.statusLine.contains(root)) {
System.out.println("Bad statusLine: "
+ c.statusLine
+ " closing connection");
c.close(); continue;
}
} return c;
}
} try { Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
} returnnull;
}
privatevoid doRemovalsAndAdditions() { synchronized (removals) {
Iterator<Connection> i = removals.iterator(); while (i.hasNext()) {
Connection c = i.next();
System.out.println("socket removed: " + c);
sockets.remove(c);
}
removals.clear();
}
synchronized (additions) {
Iterator<Connection> i = additions.iterator(); while (i.hasNext()) {
Connection c = i.next();
System.out.println("socket added: " + c);
sockets.add(c);
}
additions.clear();
}
}
// clears all current connections on Server. publicvoid reset() { for (Connection c : sockets) {
c.close();
}
}
/** * Reads data into an ArrayBlockingQueue<String> where each String * is a line of input, that was terminated by CRLF (not included)
*/ class Connection extendsThread {
Connection(Socket s) throws IOException { this.socket = s;
id = counter.incrementAndGet();
is = s.getInputStream();
os = s.getOutputStream();
incoming = new ArrayBlockingQueue<>(100);
setName("Server-Connection");
setDaemon(true);
} final Socket socket; finalint id; final InputStream is; final OutputStream os; final ArrayBlockingQueue<String> incoming; volatile String statusLine;
privatevoid cleanup() { if (released) return; synchronized(this) { if (released) return;
released = true;
} try {
socket.close();
} catch (Throwable e) {} synchronized (removals) {
removals.add(this);
}
}
}
MockServer(int port, ServerSocketFactory factory, String root) throws IOException {
ss = factory.createServerSocket();
ss.setReuseAddress(false);
ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); this.root = root; // if specified, any request which don't have this value // in their statusLine will be rejected.
sockets = Collections.synchronizedList(new LinkedList<>());
removals = new LinkedList<>();
additions = new LinkedList<>();
setName("Test-Server");
setDaemon(true);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.