?? serve.java
字號:
sun.misc.BASE64Decoder base64Dec = new sun.misc.BASE64Decoder(); // for sessions int uniqer; HttpSessionContextImpl sessions; static int expiredIn; protected Hashtable arguments; /// Constructor. public Serve( Hashtable arguments, PrintStream logStream ) { this.arguments = arguments; this.logStream = logStream; registry = new PathTreeDictionary(); realms = new PathTreeDictionary(); attributes = new Hashtable(); sessions = new HttpSessionContextImpl(); setAccessLogged(); expiredIn = arguments.get(ARG_SESSION_TIMEOUT) != null? ((Integer)arguments.get(ARG_SESSION_TIMEOUT)).intValue():DEF_SESSION_TIMEOUT; port = arguments.get(ARG_PORT) != null? ((Integer)arguments.get(ARG_PORT)).intValue():DEF_PORT; } public Serve() { this( new Hashtable(), System.err ); } void setAccessLogged() { String logflags = (String)arguments.get(ARG_LOG_OPTIONS); if (logflags != null) { useAccLog = true; showUserAgent = logflags.indexOf('A') >= 0; showReferer = logflags.indexOf('R') >= 0; } } boolean isAccessLogged() { return useAccLog; } boolean isShowReferer() { return showReferer; } boolean isShowUserAgent() { return showUserAgent; } /// Register a Servlet by class name. Registration consists of a URL // pattern, which can contain wildcards, and the class name of the Servlet // to launch when a matching URL comes in. Patterns are checked for // matches in the order they were added, and only the first match is run. public void addServlet( String urlPat, String className ) { addServlet( urlPat, className, (Hashtable)null ); } public void addServlet( String urlPat, String className, Hashtable initParams) { // Check if we're allowed to make one of these. SecurityManager security = System.getSecurityManager(); if ( security != null ) { int i = className.lastIndexOf( '.' ); if ( i != -1 ) { security.checkPackageAccess( className.substring( 0, i ) ); security.checkPackageDefinition( className.substring( 0, i ) ); } } // Make a new one. try { addServlet( urlPat, (Servlet) Class.forName( className ).newInstance(), initParams ); return; } catch ( ClassNotFoundException e ) { log( "Class not found: " + className ); } catch ( ClassCastException e ) { log( "Class cast problem: " + e.getMessage() ); } catch ( InstantiationException e ) { log( "Instantiation problem: " + e.getMessage() ); } catch ( IllegalAccessException e ) { log( "Illegal class access: " + e.getMessage() ); } catch ( Exception e ) { log( "Unexpected problem creating servlet: " + e, e ); } } /// Register a Servlet. Registration consists of a URL pattern, // which can contain wildcards, and the Servlet to // launch when a matching URL comes in. Patterns are checked for // matches in the order they were added, and only the first match is run. public void addServlet( String urlPat, Servlet servlet ) { addServlet( urlPat, servlet, (Hashtable)null); } public void addServlet( String urlPat, Servlet servlet, Hashtable initParams ) { try { servlet.init( new ServeConfig( (ServletContext) this, initParams, urlPat ) ); registry.put( urlPat, servlet ); } catch ( ServletException e ) { log( "Problem initializing servlet: " + e ); } } /// Register a standard set of Servlets. These will return // files or directory listings, and run CGI programs, much like a // standard HTTP server. // <P> // Because of the pattern checking order, this should be called // <B>after</B> you've added any custom Servlets. // <P> // The current set of default servlet mappings: // <UL> // <LI> If enabled, *.cgi goes to CgiServlet, and gets run as a CGI program. // <LI> * goes to FileServlet, and gets served up as a file or directory. // </UL> // @param cgi whether to run CGI programs // TODO: provide user specified CGI directory public void addDefaultServlets( String cgi ) { if ( cgi != null ) addServlet( "/"+cgi, new Acme.Serve.CgiServlet() ); addServlet( "/", new Acme.Serve.FileServlet() ); } /// Register a standard set of Servlets, with throttles. // @param cgi whether to run CGI programs // @param throttles filename to read FileServlet throttle settings from public void addDefaultServlets( String cgi, String throttles ) throws IOException { if ( cgi != null ) addServlet( "/"+cgi, new Acme.Serve.CgiServlet() ); addServlet( "/", new Acme.Serve.FileServlet( throttles ) ); } // Run the server. Returns only on errors. boolean running = true; public void serve() { final ServerSocket serverSocket; try { serverSocket = createServerSocket(); } catch ( IOException e ) { log( "Server socket: " + e ); return; } hostName = serverSocket.getInetAddress().getHostName(); new Thread(new Runnable() { public void run() { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String line; while (true) { try { System.out.print("Press \"q\" <ENTER>, for gracefully stopping the server "); line = in.readLine(); if (line != null && line.length() > 0 && line.charAt(0) == 'q') { running = false; serverSocket.close(); break; } } catch(IOException e) { } } } }, "Stop Monitor").start(); if (expiredIn > 0) { Thread t = new Thread(new Runnable() { public void run() { while ( running ) { try { Thread.sleep(expiredIn*60*1000); } catch(InterruptedException ie) { } Enumeration e = sessions.keys(); while(e.hasMoreElements()) { Object sid = e.nextElement(); if (sid != null) { AcmeSession as = (AcmeSession)sessions.get(sid); if (as != null && (as.getMaxInactiveInterval()*1000 < System.currentTimeMillis() - as.getLastAccessedTime() || !as.isValid())) { //log("sesion is timeouted, last accessed " + new Date(as.getLastAccessedTime())); // hashtable is synchronized impl as = (AcmeSession)sessions.remove(sid); if (as != null && as.isValid()) try { as.invalidate(); } catch(IllegalStateException ise) { } } } } } } }, "Session cleaner"); t.setPriority(Thread.MIN_PRIORITY); t.start(); } else expiredIn = -expiredIn; System.out.println("WebServer :"+port+" is ready."); try { while ( running ) { Socket socket = serverSocket.accept(); new ServeConnection( socket, this ); } } catch ( IOException e ) { log( "Accept: " + e ); } finally { try { serverSocket.close(); } catch ( IOException e ) {} destroyAllServlets(); } } public static interface SocketFactory { public ServerSocket createSocket(Hashtable arguments) throws IOException, IllegalArgumentException; } protected ServerSocket createServerSocket() throws IOException { String socketFactoryClass = (String)arguments.get(ARG_SOCKET_FACTORY); if (socketFactoryClass != null) try { return ((SocketFactory)Class.forName(socketFactoryClass).newInstance() ).createSocket(arguments); } catch(Exception e) { System.err.println("Couldn't create custom socket factory "+socketFactoryClass +" or call creation method. Standard socket will be created. "+e); } return new ServerSocket( port, 1000 ); } // Methods from ServletContext. /// Gets a servlet by name. // @param name the servlet name // @return null if the servlet does not exist public Servlet getServlet( String name ) { try { return (Servlet) ((Object[])registry.get( name ))[0]; } catch(NullPointerException npe) { return null; } } /// Enumerates the servlets in this context (server). Only servlets that // are accesible will be returned. This enumeration always includes the // servlet itself. public Enumeration getServlets() { return registry.elements(); } /// Enumerates the names of the servlets in this context (server). Only // servlets that are accesible will be returned. This enumeration always // includes the servlet itself. public Enumeration getServletNames() { return registry.keys(); } /// Destroys all currently-loaded servlets. public void destroyAllServlets() { Enumeration en = registry.elements(); while ( en.hasMoreElements() ) { Servlet servlet = (Servlet) en.nextElement(); servlet.destroy(); } registry = new PathTreeDictionary(); // invalidate all sessions? } public void setMappingTable(PathTreeDictionary mappingtable) { this.mappingtable = mappingtable; } public void setRealms(PathTreeDictionary realms) { this.realms = realms; } Object getSession(String id) { return sessions.get(id); } HttpSession createSession() { HttpSession result = new AcmeSession(generateSessionId(), expiredIn*60, this, sessions); sessions.put(result.getId(), result); return result; } void removeSession(String id) { sessions.remove(id); } /// Write information to the servlet log. // @param message the message to log public void log( String message ) { Date date = new Date( System.currentTimeMillis() ); logStream.println( "[" + date.toString() + "] " + message ); } public void log(String message, Throwable throwable) { StringWriter sw=new StringWriter(); throwable.printStackTrace(new PrintWriter(sw)); log(message+'\n'+sw); } /// Write a stack trace to the servlet log. // @param exception where to get the stack trace // @param message the message to log public void log( Exception exception, String message ) { StringWriter sw=new StringWriter(); exception.printStackTrace(new PrintWriter(sw)); log( ""+sw+'\n'+message ); } /// Applies alias rules to the specified virtual path and returns the // corresponding real path. It returns null if the translation // cannot be performed. // @param path the path to be translated public String getRealPath( String path ) { //System.err.print("["+path+"]->["); try { // this code only for debug purpose // check if it absolute URL URL url = new URL(path); path = url.getFile(); new Exception("URL "+path+" specified in getRealPath").printStackTrace(); path = null; } catch (MalformedURLException mfue) { } if (mappingtable != null) { // try find first sub-path Object [] os = mappingtable.get(path); if (os[0] == null) return null; int slpos = ((Integer)os[1]).intValue(); if (path.length() > slpos && slpos > 0) { path = path.substring(slpos+1); } else if (path.length() > 0) { char s = path.charAt(0); if(s == '/' || s == '\\') path = path.substring(1); } //System.err.println("Base:"+((String)os[0])+"\npath="+path+"\n pos="+slpos+']'); return ((String)os[0])+File.separatorChar+path; } return path; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -