Source code for /engineering/autohit-2003/src/autohit/server/service/HttpCommandHelper.javaOriginal file HttpCommandHelper.java
   1 /**
   2  * AUTOHIT 2003
   3  * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
   4  * 
   5  * This program is free software; you can redistribute it and/or modify 
   6  * it under the terms of the GNU General Public License as published by 
   7  * the Free Software Foundation; either version 2 of the License, or (at
   8  * your option) any later version.
   9  * This program is distributed in the hope that it will be useful, but
  10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12  * more details.
  13  * 
  14  * You should have received a copy of the GNU General Public License along
  15  * with this program; if not, write to the Free Software Foundation, Inc.,
  16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17  *
  18  * Additional license information can be found in the documentation.
  19  * @author Erich P Gatejen
  20  */
  21 package autohit.server.service;
  22 
  23 // import java.io.BufferedInputStream;
  24 // import java.io.BufferedOutputStream;
  25 import java.io.DataInputStream;
  26 import java.io.DataOutputStream;
  27 import java.io.StringReader;
  28 import java.net.Socket;
  29 
  30 import autohit.common.AutohitErrorCodes;
  31 import autohit.common.AutohitException;
  32 import autohit.common.AutohitLogInjectorWrapper;
  33 import autohit.common.channels.ChannelException;
  34 import autohit.common.channels.Injector;
  35 import autohit.server.ServerException;
  36 import autohit.server.command.CommandAtom;
  37 import autohit.server.invoker.SimTextCommand;
  38 
  39 /**
  40  * Http Command Helper.<br>
  41  * GET /command?param1¶m2¶mN<br>
  42  * The ? and & are interchangable.
  43  * <p>
  44  * @author Erich P. Gatejen
  45  * @version 1.0 <i>Version History </i> 
  46  * <code>EPG - Initial - 05Apr05</code>
  47  */
  48 public class HttpCommandHelper extends Thread {
  49 
  50 	final private static int BUFFER_SIZE = 512;
  51 
  52 	/**
  53 	 * Socket connection
  54 	 */
  55 	public Socket connection;
  56 	
  57 	private DataInputStream is;
  58 	private DataOutputStream os;
  59 	private Injector commandInjector;
  60 	private SimTextCommand commander;
  61 	private HttpCommandService callingService;
  62 
  63 	/**
  64 	 * Logging mechinism
  65 	 */
  66 	public AutohitLogInjectorWrapper myLog;
  67 
  68 	/**
  69 	 * Default constructor
  70 	 */
  71 	public HttpCommandHelper() {
  72 		super();
  73 	}
  74 
  75 	/**
  76 	 * Complete construction. This will be called when the VM is initialized.
  77 	 */
  78 	public void init(Socket ins, AutohitLogInjectorWrapper logger, Injector cin, SimTextCommand c, HttpCommandService caller) {
  79 		connection = ins;
  80 		myLog = logger;
  81 		callingService =  caller;
  82 		try {
  83 			is = new DataInputStream(ins.getInputStream());
  84 			os = new DataOutputStream(ins.getOutputStream());
  85 			commandInjector = cin;
  86 			commander = c;
  87 
  88 		} catch (Exception eee) {
  89 			myLog.error(
  90 					"HttpCommandHelper init() failed.  Something bad will happen.  message="
  91 							+ eee.getMessage(),
  92 					AutohitErrorCodes.CODE_SERVICE_GENERAL_FAULT);
  93 		}
  94 	}
  95 
  96 	/**
  97 	 * Run the context
  98 	 */
  99 	public void run() {
 100 
 101 		String input;
 102 		String path;
 103 		String result = "SOFTWARE BUG!  You should never see this in HttpCommandHelper.run()";
 104 		try {
 105 
 106 			// pull request line
 107 			input = is.readLine();
 108 			input = input.trim();
 109 			int spot = input.indexOf(' ');
 110 			
 111 			// Validate
 112 			if (spot < 0) {
 113 		         throw new Exception("Invalid HTTP Request Line");
 114 		    }	
 115 			
 116 			// Second
 117 			input = input.substring(spot).trim();
 118 			spot = input.indexOf(' ');
 119 		      
 120 			// Split
 121 			if (spot < 0) {
 122 		       // No protocol.  Must be old protocol
 123 		       path = input;
 124 			} else {
 125 				path = input.substring(1, spot);
 126 			}
 127 			
 128 			// Decode and build command
 129 			String command = decodePath(path);
 130 			CommandAtom a = commander.create(command);
 131 
 132 			// loop if no command
 133 			if (a == null) throw new Exception("Bad command.  Caused a null.");
 134 
 135 			// dispatch it
 136 			commandInjector.post(a);
 137 			
 138 			// Report OK
 139 			result = "PASS: Command accepted";
 140 			myLog.info(result,AutohitException.CODE_INFORMATIONAL_OK);
 141 
 142 		// } catch (InterruptedException ie) {
 143 
 144 		} catch (ServerException se) {
 145 			if (se.numeric==AutohitErrorCodes.CODE_SERVER_DONE) {
 146 				// Signal exiting
 147 				callingService.die();
 148 			} else {
 149 				result = "FAIL: HttpCommandService Server HALTED because of serious issue.  message=" + se.getMessage();
 150 				myLog.info(result,AutohitException.CODE_SERVICE_PANIC);
 151 			}
 152 			// We got the exit command
 153 			
 154 		} catch (ChannelException e) {
 155 			result = "FAIL: HttpCommandService Server HALTED because there is no command service running or command channel available.  This may be intentional during a shutdown.";
 156 			myLog.info(result,AutohitException.CODE_SERVICE_PANIC);
 157 			
 158 		} catch (Throwable e) {
 159 			result = "FAIL: Error processing HTTP Request: " + e;
 160 			myLog.info(result,AutohitException.CODE_SERVER_IO_ERROR);
 161 			
 162 		} finally {
 163 			try {
 164 				respond(result);
 165 				os.close();
 166 				connection.close();
 167 			} catch (Throwable e) {
 168 				// Bad place here
 169 			}
 170 		}
 171 	}
 172 
 173 	public void respond(String  content) throws Throwable {
 174 
 175 		println("HTTP 200 OK");
 176         println("Server: HttpCommandService");
 177         println("Content-Type: text/html");
 178         println("Content-Length: " + content.length());
 179         println("Accept-ranges: bytes");
 180         println("");
 181         print(content);
 182         try { 
 183         	Thread.sleep(100); 
 184         } catch (Exception e) {
 185         	// dont care
 186         }
 187 	}
 188 	
 189 	private void println(String text) throws Exception {
 190 		print(text);
 191 		os.write('\n');
 192 	}
 193    
 194 	private void print(String text) throws Exception {
 195    		byte bytes[] = text.getBytes();
 196 		os.write(bytes);
 197 	}
 198 
 199 	/*
 200 	 * Return as Command->param1->paramN
 201 	 */
 202 	private static String decodePath(String s) throws Throwable {
 203 		
 204 		int value;
 205 		String candidate;
 206 		
 207 		StringReader rin = new StringReader(s);
 208 		StringBuffer accumulator = new StringBuffer();
 209 		
 210 		int current = rin.read();
 211 		while (current >= 0) {
 212 			
 213 			// escape it
 214 			if (current=='%') {
 215 				current = rin.read();
 216 				if (current < 0) throw new Exception("Uncompleted escaped character in URL");
 217 				value = Character.digit((char)current,16);
 218 				value = value << 4;
 219 				current = rin.read();
 220 				if (current < 0) throw new Exception("Uncompleted escaped character in URL");
 221 				current = value + Character.digit((char)current,16);
 222 			}
 223 			
 224 			// process it
 225 			if ((current=='?')||(current=='&')) {
 226 				accumulator.append(' ');
 227 			} else {
 228 				accumulator.append((char)current);
 229 			}
 230 			
 231 			//DO NOT EDIT BELOW
 232 			current = rin.read();
 233 		}
 234 		
 235 		return (accumulator.toString());   
 236 	}   
 237 
 238 }