home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / net / www / httpd / basichttpserver.java next >
Text File  |  1995-08-11  |  8KB  |  245 lines

  1. /*
  2.  * @(#)BasicHttpServer.java    1.2 95/01/31 James Gosling
  3.  * 
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for NON-COMMERCIAL purposes and without fee is hereby
  8.  * granted provided that this copyright notice appears in all copies. Please
  9.  * refer to the file "copyright.html" for further important copyright and
  10.  * licensing information.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  15.  * OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
  16.  * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  17.  * ITS DERIVATIVES.
  18.  */
  19. package net.www.httpd;
  20.  
  21. import net.NetworkServer;
  22. import net.InetAddress;
  23. import net.www.html.MessageHeader;
  24. import net.www.html.URL;
  25. import java.io.*;
  26.  
  27. /**
  28.  * This is the base class for http servers.  To define a new type
  29.  * of server define a new subclass of BasicHttpServer with a getRequest
  30.  * method that services one request.  Start the server by executing:
  31.  * <pre>
  32.  *    new MyServerClass().startServer(port);
  33.  * </pre>
  34.  */
  35. public class BasicHttpServer extends NetworkServer {
  36.  
  37.     /** The mime header from the request. */
  38.     MessageHeader mh;
  39.     static int totalConnections;
  40.  
  41.     static URL defaultContext = new URL("http", InetAddress.localHostName, "/");
  42.  
  43.     /** True iff the client expects a mime header (ie. HTTP/1.n) */
  44.     boolean expectsMime;
  45.  
  46.     /** Satisfy one get request.  It is invoked with the clientInput and
  47.     clientOutput streams initialized.  This method handles one client
  48.     connection. When it is done, it can simply exit. The default
  49.     server just echoes it's input. */
  50.     protected void getRequest(URL u, String param) {
  51.     if (u.file.equals("/statistics.html"))
  52.         generateStatistics();
  53.     else if (u.file.equals("/processes.html"))
  54.         generateProcessOutput("Running processes", "/usr/ucb/ps uaxwww");
  55.     else if (u.file.equals("/uptime.html"))
  56.         generateProcessOutput("System uptime", "/usr/ucb/uptime");
  57.     else if (u.file.equals("/sin.dat")) {
  58.         if (expectsMime) {
  59.             clientOutput.print("HTTP/1.0 200 Document follows\n" +
  60.                   "Server: Java/" + getClass().getName() + "\n" +
  61.                        "Content-type: application/chart\n\n");
  62.         }
  63.         for (int i = 0; i<10000; i++) {
  64.         clientOutput.print(Math.sin(i/20.0)+"\n");
  65.         clientOutput.flush();
  66.         Thread.sleep(200);
  67.         }
  68.     }
  69.     else if (u.file.equals("/stock.dat")) {
  70.         if (expectsMime) {
  71.             clientOutput.print("HTTP/1.0 200 Document follows\n" +
  72.                   "Server: Java/" + getClass().getName() + "\n" +
  73.                        "Content-type: application/chart\n\n");
  74.         }
  75.         double stock = 0;
  76.         for (int i = 0; i<10000; i++) {
  77.         clientOutput.print(stock+"\n");
  78.         clientOutput.flush();
  79.         stock+=Math.random()-0.5;
  80.         if (stock > 20) stock = stock-Math.random();
  81.         if (stock < -20) stock = stock+Math.random();
  82.         Thread.sleep(900);
  83.         }
  84.     }
  85.     else if (u.file.equals("/frac.dat")) {
  86.         if (expectsMime) {
  87.             clientOutput.print("HTTP/1.0 200 Document follows\n" +
  88.                   "Server: Java/" + getClass().getName() + "\n" +
  89.                        "Content-type: application/chart\n\n");
  90.         }
  91.         double stock = 0;
  92.         for (int i = 0; i<10000; i++) {
  93.         clientOutput.print(stock+"\n");
  94.         clientOutput.flush();
  95.         stock+=(Math.random()-0.5)*Math.sin(i*30.0);
  96.         if (stock > 20) stock = stock-Math.random();
  97.         if (stock < -20) stock = stock+Math.random();
  98.         Thread.sleep(200);
  99.         }
  100.     }
  101.     else if (u.file.equals("/echo.html")) {
  102.         startHtml("Echo reply");
  103.         clientOutput.print("<p>URL was " + u.toExternalForm() + "\n");
  104.         clientOutput.print("<p>Socket was " + clientSocket + "\n<p><pre>");
  105.         mh.print(clientOutput);
  106.     } else {
  107.         try {
  108.         String fn = u.file;
  109.         if (fn.endsWith("/"))
  110.             fn = fn + "index.html";
  111.         if (fn.startsWith("/~")) {
  112.             int sl2 = fn.indexOf('/', 2);
  113.             if (sl2 < 0) sl2 = fn.length();
  114.             fn = "/home/"+fn.substring(2,sl2)+"/public_html"+fn.substring(sl2);
  115.         } else
  116.             fn = "/net/tachyon/export/disk1/Mosaic/docs/" + fn;
  117.         InputStream is = new FileInputStream(fn);
  118.         if (expectsMime) {
  119.             String ct = "text/plain";
  120.             if (fn.endsWith(".html"))
  121.             ct = "text/html";
  122.             else if (fn.endsWith(".gif"))
  123.             ct = "image/gif";
  124.             clientOutput.print("HTTP/1.0 200 Document follows\n" +
  125.                   "Server: Java/" + getClass().getName() + "\n" +
  126.                        "Content-type: " + ct + "\n\n");
  127.         }
  128.         int nb;
  129.         byte buf[] = new byte[2048];
  130.         while ((nb = is.read(buf)) >= 0)
  131.             clientOutput.write(buf, 0, nb);
  132.         is.close();
  133.         } catch(Exception e) {
  134.         error("Can't read " + u.file);
  135. //        System.out.print("Failed on "+u.file+"\n");
  136. //        e.printStackTrace();
  137.         }
  138.     }
  139.     }
  140.  
  141.     /** Start generating an html reply to a get request.  This is a
  142.         convenience method to simplify getRequest */
  143.     protected void startHtml(String title) {
  144.     if (expectsMime)
  145.         clientOutput.print("HTTP/1.0 200 Document follows\n" +
  146.                    "Server: Java/" + getClass().getName() + "\n" +
  147.                    "Content-type: text/html\n\n");
  148.     clientOutput.print("<html><head><title>" + title +
  149.                "</title></head>\n<body><h1>" +
  150.                title + "</h1>\n");
  151.     }
  152.  
  153.     /** Generate an html reply to a get request that contains a
  154.     dump of the statistics for the current server.  getRequest
  155.     handlers can call it in response to special file names. */
  156.     protected void generateStatistics() {
  157.     startHtml("Server statistics");
  158.     clientOutput.print(totalConnections + " total connections.<p>\n");
  159.     }
  160.  
  161.     /** Generate an html reply to a get request that contains the
  162.     output after executing a system command.  getRequest
  163.     handlers can call it in response to special file names. */
  164.     protected void generateProcessOutput(String title, String command) {
  165.     startHtml(title);
  166.     try {
  167.         InputStream in = new BufferedInputStream(System.execin(command));
  168.         clientOutput.print("<pre>\n");
  169.         int c;
  170.         while ((c = in.read()) >= 0)
  171.         switch (c) {
  172.           case '<':
  173.             clientOutput.print("<");
  174.             break;
  175.           case '&':
  176.             clientOutput.print("&");
  177.             break;
  178.           default:
  179.             clientOutput.write(c);
  180.             break;
  181.         }
  182.         in.close();
  183.         clientOutput.print("</pre>\n");
  184.     } catch(Exception e) {
  185.         clientOutput.print("Failed to execute " + command + "\n");
  186.     }
  187.     }
  188.  
  189.     protected void error(String msg) {
  190.     if (expectsMime)
  191.         clientOutput.print("HTTP/1.0 403 Error - msg\n" +
  192.                    "Content-type: text/html\n\n");
  193.     clientOutput.print("<html><head>Error</head><body>" +
  194.                "<H1>Error when fetching document:</h1>\n" +
  195.                msg + "\n");
  196.     if (mh != null) {
  197.         clientOutput.print("<p><pre>");
  198.         mh.print(clientOutput);
  199.     }
  200.     }
  201.  
  202.     final public void serviceRequest() {
  203.     totalConnections++;
  204.     try {
  205.         mh = new MessageHeader(clientInput);
  206.         String cmd = mh.findValue(null);
  207.         if (cmd == null) {
  208.         error("Missing command " + mh);
  209.         return;
  210.         }
  211.         int fsp = cmd.indexOf(' ');
  212.         if (fsp < 0) {
  213.         error("Syntax error in command: " + cmd);
  214.         return;
  215.         }
  216.         String k = cmd.substring(0, fsp);
  217.         int nsp = cmd.indexOf(' ', fsp + 1);
  218.         String p1, p2;
  219.         if (nsp > 0) {
  220.         p1 = cmd.substring(fsp + 1, nsp);
  221.         p2 = cmd.substring(nsp + 1);
  222.         } else {
  223.         p1 = cmd.substring(fsp + 1);
  224.         p2 = null;
  225.         }
  226.         expectsMime = p2 != null;
  227.         if (k.equalsIgnoreCase("get"))
  228.         getRequest(new URL(defaultContext, p1), p2);
  229.         else {
  230.         error("Unknown command: " + k + " (" + cmd + ")");
  231.         return;
  232.         }
  233.     } catch(IOException e) {
  234.         // totally ignore IOException.  They're usually client crashes.
  235.     } catch(Exception e) {
  236.         error("Exception: " + e);
  237.         e.printStackTrace();
  238.     }
  239.     }
  240.  
  241.     public static void main(String argv[]) {
  242.     new BasicHttpServer ().startServer(8888);
  243.     }
  244. }
  245.