1 5 package org.h2.server.web; 6 7 import java.io.BufferedOutputStream ; 8 import java.io.DataOutputStream ; 9 import java.io.IOException ; 10 import java.io.InputStream ; 11 import java.net.Socket ; 12 import java.util.Locale ; 13 import java.util.Properties ; 14 import java.util.StringTokenizer ; 15 16 import org.h2.message.TraceSystem; 17 import org.h2.util.StringUtils; 18 19 abstract class WebServerThread extends Thread { 20 protected WebServer server; 21 protected WebServerSession session; 22 protected Properties attributes; 23 protected Socket socket; 24 25 private InputStream input; 26 private String ifModifiedSince; 27 28 WebServerThread(Socket socket, WebServer server) { 29 this.server = server; 30 this.socket = socket; 31 } 32 33 abstract String process(String file); 34 35 protected String getCombobox(String [] elements, String selected) { 36 StringBuffer buff = new StringBuffer (); 37 for(int i=0; i<elements.length; i++) { 38 String value = elements[i]; 39 buff.append("<option value=\""); 40 buff.append(PageParser.escapeHtml(value)); 41 buff.append("\""); 42 if(value.equals(selected)) { 43 buff.append(" selected"); 44 } 45 buff.append(">"); 46 buff.append(PageParser.escapeHtml(value)); 47 buff.append("</option>"); 48 } 49 return buff.toString(); 50 } 51 52 protected String getCombobox(String [][] elements, String selected) { 53 StringBuffer buff = new StringBuffer (); 54 for(int i=0; i<elements.length; i++) { 55 String [] n = elements[i]; 56 buff.append("<option value=\""); 57 buff.append(PageParser.escapeHtml(n[0])); 58 buff.append("\""); 59 if(n[0].equals(selected)) { 60 buff.append(" selected"); 61 } 62 buff.append(">"); 63 buff.append(PageParser.escapeHtml(n[1])); 64 buff.append("</option>"); 65 } 66 return buff.toString(); 67 } 68 69 public void run() { 70 try { 71 input = socket.getInputStream(); 72 String head = readHeaderLine(); 73 if(head.startsWith("GET ") || head.startsWith("POST ")) { 74 int begin = head.indexOf('/'), end = head.lastIndexOf(' '); 75 String file = head.substring(begin+1, end).trim(); 76 if(file.length() == 0) { 77 file = "index.do"; 78 } 79 if(!allow()) { 80 file = "notAllowed.jsp"; 81 } 82 server.trace(head + " :" + file); 83 attributes = new Properties (); 84 int paramIndex = file.indexOf("?"); 85 session = null; 86 if(paramIndex >= 0) { 87 String attrib = file.substring(paramIndex+1); 88 parseAttributes(attrib); 89 String sessionId = attributes.getProperty("jsessionid"); 90 file = file.substring(0, paramIndex); 91 session = server.getSession(sessionId); 92 } 93 String mimeType; 95 boolean cache; 96 if(file.endsWith(".ico")) { 97 mimeType = "image/x-icon"; 98 cache=true; 99 } else if(file.endsWith(".gif")) { 100 mimeType = "image/gif"; 101 cache=true; 102 } else if(file.endsWith(".css")) { 103 cache=true; 104 mimeType = "text/css"; 105 } else if(file.endsWith(".html") || file.endsWith(".do") || file.endsWith(".jsp")) { 106 cache=false; 107 mimeType = "text/html"; 108 if (session == null) { 109 session = server.createNewSession(socket); 110 if (!file.equals("notAllowed.jsp")) { 111 file = "index.do"; 112 } 113 } 114 } else if(file.endsWith(".js")) { 115 cache=true; 116 mimeType = "text/javascript"; 117 } else { 118 cache = false; 119 mimeType = "text/html"; 120 file = "error.jsp"; 121 server.trace("unknown mime type, file "+file); 122 } 123 server.trace("mimeType="+mimeType); 124 parseHeader(); 125 server.trace(file); 126 if(file.endsWith(".do")) { 127 file = process(file); 128 } 129 String message; 130 byte[] bytes; 131 if(cache && ifModifiedSince!=null && ifModifiedSince.equals(server.getStartDateTime())) { 132 bytes = null; 133 message = "HTTP/1.1 304 Not Modified\n"; 134 } else { 135 bytes = server.getFile(file); 136 if(bytes == null) { 137 message = "HTTP/1.0 404 Not Found\n"; 138 bytes = StringUtils.utf8Encode("File not found: "+file); 139 } else { 140 if(session != null && file.endsWith(".jsp")) { 141 bytes = StringUtils.utf8Encode(fill(StringUtils.utf8Decode(bytes))); 142 } 143 message = "HTTP/1.1 200 OK\n"; 144 message += "Content-Type: "+mimeType+"\n"; 145 if(!cache) { 146 message += "Cache-Control: no-cache\n"; 147 } else { 148 message += "Cache-Control: max-age=10\n"; 149 message += "Last-Modified: "+server.getStartDateTime()+"\n"; 150 } 151 } 152 } 153 message += "\n"; 154 server.trace(message); 155 DataOutputStream output; 156 output = new DataOutputStream ( 157 new BufferedOutputStream (socket.getOutputStream())); 158 output.write(message.getBytes()); 159 if(bytes!=null) { 160 output.write(bytes); 161 } 162 output.flush(); 163 output.close(); 164 output.close(); 165 socket.close(); 166 return; 167 } 168 } catch (Exception e) { 169 TraceSystem.traceThrowable(e); 170 } 171 } 172 173 abstract boolean allow(); 174 175 private String readHeaderLine() throws IOException { 176 StringBuffer buff=new StringBuffer (); 177 while (true) { 178 int i = input.read(); 179 if (i == -1) { 180 throw new IOException ("Unexpected EOF"); 181 } else if (i == '\r' && input.read()=='\n') { 182 return buff.length() > 0 ? buff.toString() : null; 183 } else { 184 buff.append((char)i); 185 } 186 } 187 } 188 189 private void parseAttributes(String s) throws Exception { 190 server.trace("data="+s); 191 while(s != null) { 192 int idx = s.indexOf('='); 193 if(idx>=0) { 194 String property = s.substring(0, idx); 195 s = s.substring(idx+1); 196 idx = s.indexOf('&'); 197 String value; 198 if(idx >= 0) { 199 value = s.substring(0, idx); 200 s = s.substring(idx+1); 201 } else { 202 value = s; 203 } 204 String attr = StringUtils.urlDecode(value); 208 attributes.put(property, attr); 209 } else { 210 break; 211 } 212 } 213 server.trace(attributes.toString()); 214 } 215 216 private void parseHeader() throws Exception { 217 server.trace("parseHeader"); 218 int len = 0; 219 ifModifiedSince = null; 220 while(true) { 221 String line = readHeaderLine(); 222 if(line == null) { 223 break; 224 } 225 server.trace(" "+line); 226 String lower = StringUtils.toLowerEnglish(line); 227 if(lower.startsWith("if-modified-since")) { 228 ifModifiedSince = line.substring(line.indexOf(':')+1).trim(); 229 } else if(lower.startsWith("content-length")) { 230 len = Integer.parseInt(line.substring(line.indexOf(':')+1).trim()); 231 server.trace("len="+len); 232 } else if(lower.startsWith("accept-language")) { 233 if(session != null) { 234 Locale locale = session.locale; 235 if(locale == null) { 236 String languages = line.substring(line.indexOf(':')+1).trim(); 237 StringTokenizer tokenizer = new StringTokenizer (languages, ",;"); 238 while(tokenizer.hasMoreTokens()) { 239 String token = tokenizer.nextToken(); 240 if(!token.startsWith("q=")) { 241 if(server.supportsLanguage(token)) { 242 int dash = token.indexOf('-'); 243 if(dash >= 0) { 244 String language = token.substring(0, dash); 245 String country = token.substring(dash+1); 246 locale = new Locale (language, country); 247 } else { 248 locale = new Locale (token, ""); 249 } 250 session.locale = locale; 251 String language = locale.getLanguage(); 252 session.put("language", language); 253 server.readTranslations(session, language); 254 break; 255 } 256 } 257 } 258 } 259 } 260 } else if(line.trim().length()==0) { 261 break; 262 } 263 } 264 if(session != null && len > 0) { 265 byte[] bytes = new byte[len]; 266 for (int pos = 0; pos < len;) { 267 pos += input.read(bytes, pos, len - pos); 268 } 269 String s = new String (bytes); 270 parseAttributes(s); 271 } 272 } 273 274 private String fill(String page) { 275 return PageParser.parse(server, page, session.map); 276 } 277 278 } 279 | Popular Tags |