001    package org.shiftone.jrat.core.command;
002    
003    import org.shiftone.jrat.core.spi.Commandlet;
004    import org.shiftone.jrat.util.io.IOUtil;
005    import org.shiftone.jrat.util.log.Logger;
006    
007    import java.io.*;
008    import java.net.ServerSocket;
009    import java.net.Socket;
010    
011    /**
012     * @author jeff@shiftone.org (Jeff Drost)
013     */
014    public class TinyWebServer extends Thread {
015    
016        private static final Logger LOG = Logger.getLogger(TinyWebServer.class);
017    
018        private ServerSocket serverSocket = null;
019        private int flushNumber;
020        private final CommandletRegistry registry;
021        private final int port;
022    
023        public TinyWebServer(CommandletRegistry registry, int port) {
024            this.registry = registry;
025            this.port = port;
026            setDaemon(true);
027            setName("HTTP");
028        }
029    
030    
031        private Commandlet readRequest(Socket socket) throws IOException {
032    
033            boolean doRefresh = false;
034            InputStream inputStream = null;
035            LineNumberReader reader = null;
036    
037            inputStream = socket.getInputStream();
038            reader = new LineNumberReader(new InputStreamReader(inputStream));
039    
040            String line;
041    
042            line = reader.readLine();
043    
044            String commandletKey = null;
045            int a = line.indexOf(' ');
046            int b = line.lastIndexOf(' ');
047            String uri = line.substring(a + 1, b);
048            LOG.info("LINE = " + line + ">" + uri + "<");
049            int commandletIndex = uri.indexOf("commandlet=");
050    
051            if (commandletIndex != -1) {
052    
053                commandletKey = uri.substring(commandletIndex + 11);
054                LOG.info("commandletKey = " + commandletKey);
055    
056            }
057    
058            while ((line != null) && (line.length() > 0)) {
059                line = reader.readLine();
060            }
061    
062            // the following code is kinda crapy
063    
064            Commandlet commandlet = null;
065    
066            if (commandletKey != null) {
067                commandlet = (Commandlet) registry.getCommandlets().get(commandletKey);
068            }
069    
070            if (commandlet == null) {
071                LOG.warn("line(" + line + ") using default key");
072                commandlet = registry.getDefaultCommandlet();
073            }
074    
075            return commandlet;
076        }
077    
078    
079        public void run() {
080    
081            Socket socket = null;
082            OutputStream outputStream = null;
083            Writer writer = null;
084            long start;
085    
086            try {
087    
088                LOG.info("starting on port " + port + "...");
089    
090                serverSocket = new ServerSocket(port);
091    
092                while (true) {
093                    socket = serverSocket.accept();
094    
095                    LOG.info("accept");
096    
097                    try {
098    
099                        outputStream = socket.getOutputStream();
100                        writer = new OutputStreamWriter(outputStream);
101                        start = System.currentTimeMillis();
102    
103                        flushNumber++;
104    
105                        Commandlet commandlet = readRequest(socket);
106    
107                        writer.write("HTTP/1.1 200 OK\n");
108                        writer.write("Content-Type: " + commandlet.getContentType() + "\n");
109                        writer.write("Cache-Control: no-store, no-cache, must-revalidate\n");    // normal
110                        writer.write("Cache-Control: post-check=0, pre-check=0");                // IE
111                        writer.write("Pragma: no-cache\n");                                      // good luck
112                        writer.write("Expires: Sat, 6 May 1995 12:00:00 GMT\n");                 // more lock
113                        writer.write("\n");
114                        writer.flush();
115    
116                        commandlet.execute(outputStream);
117    
118                        outputStream.flush();
119    
120                    } catch (Exception e) {
121    
122                        LOG.error("Flush error", e);
123    
124                    } finally {
125    
126                        IOUtil.close(writer);
127                        IOUtil.close(outputStream);
128                        IOUtil.close(socket);
129    
130                    }
131                }
132            }
133            catch (Exception e) {
134    
135                LOG.error("unable to listen on port : " + port, e);
136    
137            }
138        }
139    
140    }