httpserver.java

来自「cqME :java framework for TCK test.」· Java 代码 · 共 790 行 · 第 1/2 页

JAVA
790
字号
/* * $Id$ * * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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 program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package com.sun.cldc.communication.http;import java.io.*;import java.net.*;import java.util.*;import com.sun.cldc.communication.Server;import com.sun.cldc.communication.TestProvider;import com.sun.cldc.communication.http.util.ByteBuffer;public class HttpServer implements Server {    private int handlerCount = 5;    private TestProvider testProvider;    private String mainClass;    private String jarSourceDir;    private int port;    private String testRoot;    private int retry;    private String host;    private String extraURI;    private ServerSocket socket;    private boolean done;    private boolean finish;    private RequestHandler[] runners;    private boolean verbose;    private boolean useIPAddress;    private final String TCK_ROOT = "test.root=";    private final String HTTP_PORT = "http.port=";    private final String HTTP_URL = "http.url=";    private final String RETRY_AFTER = "retry.after=";    private final String VERBOSE = "verbose=";    private final String USEIPADDRESS = "useIPAddress=";    private final String EXTRA_URI = "extra.uri=";    private final String NO_PROVIDER = "Http server error: test provider not set";    private final String NO_SOCKET = "Http server error: couldn't create server socket";    private final String UNKNOWN_ARG = "Http server error: unrecognized argument";    private final String ILLEGAL_PORT = "Http server error: illegal port number";    private final String ILLEGAL_URL = "Http server error: illegal URL";    private final String ILLEGAL_RETRY = "Http server error: illegal retry value";    private final String BAD_STATE = "Http server error: illegal state";    private final String verboseId = "HTTP SERVER:   ";    public HttpServer() {        port = 80;        testRoot = "/test";        extraURI = "getNextApp";        retry = 0;        done = true;        finish = true;        try {            host = InetAddress.getLocalHost().getHostName();        } catch (UnknownHostException uhe) {            host = "localhost";        }    }    /**     * Initialize the server with necessary parameters.     * "test.root=bar"     * "http.port=42"     */    public void init(String[] arg) {        for (int i=0; arg!=null && i<arg.length; i++) {            if (arg[i].startsWith(TCK_ROOT) && arg[i].length() > TCK_ROOT.length()) {                testRoot = arg[i].substring(TCK_ROOT.length());                continue;            }            if (arg[i].startsWith(RETRY_AFTER) && arg[i].length() > RETRY_AFTER.length()) {                try {                    retry = Integer.parseInt(arg[i].substring(RETRY_AFTER.length()));                } catch (NumberFormatException nfe) {                    throw new IllegalArgumentException(ILLEGAL_RETRY + " = "                                       + arg[i].substring(RETRY_AFTER.length()));                }                continue;            }            if (arg[i].startsWith(HTTP_PORT) && arg[i].length() > HTTP_PORT.length()) {                try {                    port = Integer.parseInt(arg[i].substring(HTTP_PORT.length()));                } catch (NumberFormatException nfe) {                    throw new IllegalArgumentException(ILLEGAL_PORT + " = "                                       + arg[i].substring(HTTP_PORT.length()));                }                continue;            }            if (arg[i].startsWith(HTTP_URL) && arg[i].length() > HTTP_URL.length()) {                try {                    URL url = new URL(arg[i].substring(HTTP_URL.length()));                    host = url.getHost();                    verifyHost(host);                    port = url.getPort();                    verifyPort(port);                    testRoot = url.getFile();                } catch (MalformedURLException e) {                    throw new IllegalArgumentException(ILLEGAL_URL + " = "                                       + arg[i].substring(HTTP_URL.length()));                }                continue;            }            if (arg[i].startsWith(VERBOSE) && arg[i].length() > VERBOSE.length()) {                verbose = new Boolean(arg[i].substring(VERBOSE.length())).booleanValue();                continue;            }            if (arg[i].startsWith(USEIPADDRESS) && arg[i].length() > USEIPADDRESS.length()) {                useIPAddress = new Boolean(arg[i].substring(USEIPADDRESS.length())).booleanValue();                continue;            }            if (arg[i].startsWith(EXTRA_URI) && arg[i].length() > EXTRA_URI.length()) {                extraURI = arg[i].substring(EXTRA_URI.length());                continue;            }            throw new IllegalArgumentException(UNKNOWN_ARG + ": " + arg[i]);        }        if (!testRoot.endsWith("/")) {            testRoot = testRoot + "/";        }        runners = new RequestHandler[handlerCount];        for (int i = 0; i < handlerCount; i++) {            runners[i] = new RequestHandler();            runners[i].setName("RequestHandler"+i);        }    }    /**     * Set test provider. There is only one test provider      * per server. Next call to setTestProvider removes the previous      * one. Null argument causes removal of current test provider.     */    public void setTestProvider(TestProvider tp) {        testProvider = tp;        mainClass = tp.getAppMainClass();        if (mainClass == null) {            throw new NullPointerException(                    "Provider main class not defined");        }        jarSourceDir = tp.getJarSourceDirectory();        if (jarSourceDir == null) {            throw new NullPointerException(                    "Provider jar source directory not defined");        }    }    /**     * Returns current test provider.     */    public TestProvider getTestProvider() {        return testProvider;    }    public synchronized void start() {        if (!finish) throw new IllegalThreadStateException(BAD_STATE +                     " - start without stopping previous run.");        if (testProvider == null) {            throw new NullPointerException(NO_PROVIDER);        }        try {            socket = new ServerSocket(port, 50);            socket.setSoTimeout(5000);        } catch (IOException ioe) {            throw new RuntimeException(NO_SOCKET + " at " + port);        }         done = false;        finish = false;        for (int i = 0; i < handlerCount; i++) {            runners[i].start();        }    }    public synchronized void stop() {        if (done) return;        done = true;        synchronized ( testProvider ) {            testProvider.notifyAll();        }        // wait for 5 sec to let the handlers process         // client's requests        long timeout = 5000;        long endtime = System.currentTimeMillis() + timeout;        do {            try {                Thread.currentThread().sleep(timeout);	    } catch (InterruptedException e) {}            timeout = endtime - System.currentTimeMillis();        } while (timeout > 0);        // exit handlers        finish = true;        // wait for 1 sec to let the handlers exit gracefully        try {            Thread.currentThread().sleep(1000);	} catch (InterruptedException e) {}        // it didn't do it - try to force it        for (int i = 0; i < handlerCount; i++) {            if (runners[i].isAlive()) {                runners[i].interrupt();            }        }        try {socket.close();} catch (IOException x) {}    }    private void verifyHost(String host) {        if (host == null || host.equals("")) {            throw new IllegalArgumentException("Host null or empty");        }        try {            InetAddress[] entered = InetAddress.getAllByName(host);            for (int i = 0; i < entered.length; i++) {                if (NetworkInterface.getByInetAddress(entered[i]) != null) {                    return;                }            }            throw new IllegalArgumentException(                    host + " does not correspond to any network interface");        } catch (UnknownHostException e) {            throw new IllegalArgumentException(                    "Unknown host: " + host);        } catch (SocketException e) {            throw new IllegalArgumentException(                    "Socket exception while attempting to "                    + "determine network interfaces: " + e);        }    }    private void verifyPort(int port) {       if (port <= 0) {           throw new IllegalArgumentException("Port should be positive");       }    }    // -----------------------------------------class RequestHandler extends Thread implements HttpConstants {    private int version;    private Vector responseHeaders;    private Hashtable requestHeaders;    private OutputStream raw;    private PrintWriter out;    private boolean readChunks;    private int chunksize = -1;    private ByteArrayOutputStream bos;    private ByteBuffer buffer;    private String IPAddr;    private final String GET = "GET";    private final String POST = "POST";    public RequestHandler() {        requestHeaders = new Hashtable();        responseHeaders = new Vector();        bos = new ByteArrayOutputStream();        buffer = new ByteBuffer(32768);    }    private String phrase(int code) {        switch (code) {            case 200: return "Ok";            case 400: return "Bad Request";            case 404: return "Not Found";            case 405: return "Bad Method";            case 500: return "Server Error";            default: return null;        }    }    private String getHeaderField(String field) {        if (requestHeaders == null) return null;        Enumeration enumeration = requestHeaders.keys();        while (enumeration.hasMoreElements()) {            String key = (String)enumeration.nextElement();            if (key.equalsIgnoreCase(field)) return (String)requestHeaders.get(key);        }        return null;    }    private void readHeaders(DataInputStream in) throws IOException {        requestHeaders.clear();        int index;        String line;        for (;;) {            line = in.readLine();            // funny enough, but this deprecated method does exactly what we need!            // zero-extension from byte to character corresponds to ISO8859_1!            if (line == null || line.length() == 0) break;            index = line.indexOf(':');            if (index <= 0 || index + 1 == line.length()) continue;            requestHeaders.put(line.substring(0, index), line.substring(index + 1).trim());        }    }    private void handleGet(URL request, PrintWriter out,                           OutputStream raw, DataInputStream in) throws IOException {        String path = request.getFile();        String JAMId = "";        String bundleId = "";        String baseGetNextAppURI = testRoot + extraURI;        // cmd "get next app"        if (path.startsWith(baseGetNextAppURI)) {            verboseln(getName() + " " + extraURI);                        if (done) {                sendDiagnostics(HTTP_NOT_FOUND, out);                return;            }            if (path.length() > baseGetNextAppURI.length()) {                char separator = path.charAt(baseGetNextAppURI.length());                boolean properSeparatorBeforeJamName = separator == '/';                boolean nonEmptyJamName                        = path.length() > baseGetNextAppURI.length() + 1;                if (properSeparatorBeforeJamName && nonEmptyJamName) {                    JAMId = path.substring(baseGetNextAppURI.length() + 1);                } else {                    System.out.println("ERROR: "                            + "Invalid request for the test bundle. "                            + "JAMName is not properly specified.");                    System.out.println("Invalid request: " + path);                    // Most logical response code would be                    // HTTP_BAD_REQUEST, but WTK and some RIs would just                    // continue to send new requests over and over again.                    // Responding with HTTP_NOT_FOUND stops that.                    sendDiagnostics(HTTP_NOT_FOUND, out);                    return;                }            }            if (useIPAddress)                JAMId = JAMId + IPAddr;            String next_app = testProvider.getNextApp(JAMId);            if (done) {                sendDiagnostics(HTTP_NOT_FOUND, out);                return;            }            if (next_app == null) {                sendDiagnostics(HTTP_NOT_FOUND, out);                return;            }            if ("".equals(next_app)) {                sendDiagnostics(HTTP_UNAVAILABLE, out);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?