KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > server > web > WebServerThread


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.server.web;
6
7 import java.io.BufferedOutputStream JavaDoc;
8 import java.io.DataOutputStream JavaDoc;
9 import java.io.IOException JavaDoc;
10 import java.io.InputStream JavaDoc;
11 import java.net.Socket JavaDoc;
12 import java.util.Locale JavaDoc;
13 import java.util.Properties JavaDoc;
14 import java.util.StringTokenizer JavaDoc;
15
16 import org.h2.message.TraceSystem;
17 import org.h2.util.StringUtils;
18
19 abstract class WebServerThread extends Thread JavaDoc {
20     protected WebServer server;
21     protected WebServerSession session;
22     protected Properties JavaDoc attributes;
23     protected Socket JavaDoc socket;
24     
25     private InputStream JavaDoc input;
26     private String JavaDoc ifModifiedSince;
27
28     WebServerThread(Socket JavaDoc socket, WebServer server) {
29         this.server = server;
30         this.socket = socket;
31     }
32     
33     abstract String JavaDoc process(String JavaDoc file);
34
35     protected String JavaDoc getCombobox(String JavaDoc[] elements, String JavaDoc selected) {
36         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
37         for(int i=0; i<elements.length; i++) {
38             String JavaDoc 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 JavaDoc getCombobox(String JavaDoc[][] elements, String JavaDoc selected) {
53         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
54         for(int i=0; i<elements.length; i++) {
55             String JavaDoc[] 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 JavaDoc head = readHeaderLine();
73             if(head.startsWith("GET ") || head.startsWith("POST ")) {
74                 int begin = head.indexOf('/'), end = head.lastIndexOf(' ');
75                 String JavaDoc 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 JavaDoc();
84                 int paramIndex = file.indexOf("?");
85                 session = null;
86                 if(paramIndex >= 0) {
87                     String JavaDoc attrib = file.substring(paramIndex+1);
88                     parseAttributes(attrib);
89                     String JavaDoc sessionId = attributes.getProperty("jsessionid");
90                     file = file.substring(0, paramIndex);
91                     session = server.getSession(sessionId);
92                 }
93                 // TODO web: support errors
94
String JavaDoc 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 JavaDoc 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 JavaDoc output;
156                 output = new DataOutputStream JavaDoc(
157                         new BufferedOutputStream JavaDoc(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 JavaDoc e) {
169             TraceSystem.traceThrowable(e);
170         }
171     }
172
173     abstract boolean allow();
174
175     private String JavaDoc readHeaderLine() throws IOException JavaDoc {
176         StringBuffer JavaDoc buff=new StringBuffer JavaDoc();
177         while (true) {
178             int i = input.read();
179             if (i == -1) {
180                 throw new IOException JavaDoc("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 JavaDoc s) throws Exception JavaDoc {
190         server.trace("data="+s);
191         while(s != null) {
192             int idx = s.indexOf('=');
193             if(idx>=0) {
194                 String JavaDoc property = s.substring(0, idx);
195                 s = s.substring(idx+1);
196                 idx = s.indexOf('&');
197                 String JavaDoc value;
198                 if(idx >= 0) {
199                     value = s.substring(0, idx);
200                     s = s.substring(idx+1);
201                 } else {
202                     value = s;
203                 }
204                 // TODO compatibility problem with JDK 1.3
205
//String attr = URLDecoder.decode(value, "UTF-8");
206
// String attr = URLDecoder.decode(value);
207
String JavaDoc 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 JavaDoc {
217         server.trace("parseHeader");
218         int len = 0;
219         ifModifiedSince = null;
220         while(true) {
221             String JavaDoc line = readHeaderLine();
222             if(line == null) {
223                 break;
224             }
225             server.trace(" "+line);
226             String JavaDoc 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 JavaDoc locale = session.locale;
235                     if(locale == null) {
236                         String JavaDoc languages = line.substring(line.indexOf(':')+1).trim();
237                         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(languages, ",;");
238                         while(tokenizer.hasMoreTokens()) {
239                             String JavaDoc token = tokenizer.nextToken();
240                             if(!token.startsWith("q=")) {
241                                 if(server.supportsLanguage(token)) {
242                                     int dash = token.indexOf('-');
243                                     if(dash >= 0) {
244                                         String JavaDoc language = token.substring(0, dash);
245                                         String JavaDoc country = token.substring(dash+1);
246                                         locale = new Locale JavaDoc(language, country);
247                                     } else {
248                                         locale = new Locale JavaDoc(token, "");
249                                     }
250                                     session.locale = locale;
251                                     String JavaDoc 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 JavaDoc s = new String JavaDoc(bytes);
270             parseAttributes(s);
271         }
272     }
273     
274     private String JavaDoc fill(String JavaDoc page) {
275         return PageParser.parse(server, page, session.map);
276     }
277
278 }
279
Popular Tags