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 + -
显示快捷键?