3261N/A * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * This class implements a simple HTTP server. It uses multiple threads to 0N/A * can be handled per thread. 0N/A * It must be instantiated with a {@link HttpCallback} object to which 0N/A * requests are given and must be handled. 0N/A * Simple synchronization between the client(s) and server can be done 0N/A * using the {@link #waitForCondition(String)}, {@link #setCondition(String)} and 0N/A * {@link #rendezvous(String,int)} methods. 0N/A * NOTE NOTE NOTE NOTE NOTE NOTE NOTE 0N/A * If changes are made here, please sure they are propagated to 0N/A * the HTTPS equivalent in the JSSE regression test suite. 0N/A * NOTE NOTE NOTE NOTE NOTE NOTE NOTE 0N/A * Create a <code>HttpServer<code> instance with the specified callback object 0N/A * for handling requests. One thread is created to handle requests, 0N/A * and up to ten TCP connections will be handled simultaneously. 0N/A * @param cb the callback object which is invoked to handle each 0N/A * Create a <code>HttpServer<code> instance with the specified number of 0N/A * threads and maximum number of connections per thread. This functions 0N/A * the same as the 4 arg constructor, where the port argument is set to zero. 0N/A * @param cb the callback object which is invoked to handle each 0N/A * @param threads the number of threads to create to handle requests 0N/A * @param cperthread the number of simultaneous TCP connections to 0N/A * Create a <code>HttpServer<code> instance with the specified number 0N/A * of threads and maximum number of connections per thread and running on 0N/A * the specified port. The specified number of threads are created to 0N/A * handle incoming requests, and each thread is allowed 0N/A * to handle a number of simultaneous TCP connections. 0N/A * @param cb the callback object which is invoked to handle 0N/A * each incoming request 0N/A * @param threads the number of threads to create to handle 0N/A * requests in parallel 0N/A * @param cperthread the number of simultaneous TCP connections 0N/A * to handle per thread 0N/A * @param port the port number to bind the server to. <code>Zero</code> 0N/A * means choose any free port. 0N/A /** Tell all threads in the server to exit within 5 seconds. 0N/A * This is an abortive termination. Just prior to the thread exiting 0N/A * all channels in that thread waiting to be closed are forceably closed. 0N/A * return the local port number to which the server is bound. 0N/A * @return the local port number 0N/A /* Stop the thread as soon as possible */ 0N/A /* false notification */ 0N/A /* read all the data off the channel without looking at it 0N/A * return true if connection closed 0N/A /* return true if the connection is closed, false otherwise */ 0N/A /* invalid request line */ 0N/A if (((
cr &
0xff) !=
0x0d) ||
0N/A "Expected <CR><LF>: got '" +
cr +
"/" +
lf +
"'");
0N/A if (c >=
'a' && c <=
'f') {
0N/A }
else if (c >=
'A' && c <=
'F') {
0N/A }
else if (c >=
'0' && c <=
'9') {
0N/A byte[] b =
new byte [
512];
0N/A /** close the channel associated with the current key by: 0N/A * 1. shutdownOutput (send a FIN) 0N/A * 2. mark the key so that incoming data is to be consumed and discarded 0N/A * 3. After a period, close the socket 0N/A * Implements blocking reading semantics on top of a non-blocking channel 0N/A }
else {
/* satisfy from channel */ 0N/A * block() only called when available==0 and buf is empty 0N/A //assert available == 0; 0N/A * Utilities for synchronization. A condition is 0N/A * identified by a string name, and is initialized 0N/A * upon first use (ie. setCondition() or waitForCondition()). Threads 0N/A * are blocked until some thread calls (or has called) setCondition() for the same 0N/A * A rendezvous built on a condition is also provided for synchronizing 0N/A * Modifiable boolean object 0N/A * Modifiable int object 0N/A * Set the condition to true. Any threads that are currently blocked 0N/A * waiting on the condition, will be unblocked and allowed to continue. 0N/A * Threads that subsequently call waitForCondition() will not block. 0N/A * If the named condition did not exist prior to the call, then it is created 0N/A * If the named condition does not exist, then it is created and initialized 0N/A * to false. If the condition exists or has just been created and its value 0N/A * is false, then the thread blocks until another thread sets the condition. 0N/A * If the condition exists and is already set to true, then this call returns 0N/A * immediately without blocking. 0N/A /* conditions must be locked when accessing this */ 0N/A * Force N threads to rendezvous (ie. wait for each other) before proceeding. 0N/A * The first thread(s) to call are blocked until the last 0N/A * thread makes the call. Then all threads continue. 0N/A * All threads that call with the same condition name, must use the same value 0N/A * for N (or the results may be not be as expected). 0N/A * Obviously, if fewer than N threads make the rendezvous then the result 0N/A /* get the condition */ 0N/A /* we are first caller */ 0N/A /* already initialised, just decrement the counter */ 0N/A * If the named condition exists and is set then remove it, so it can 0N/A * be re-initialized and used again. If the condition does not exist, or 0N/A * exists but is not set, then the call returns without doing anything. 0N/A * Note, some higher level synchronization 0N/A * may be needed between clear and the other operations.