1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.handler;
16
17 import java.io.IOException;
18 import java.io.OutputStream;
19 import java.net.MalformedURLException;
20
21 import javax.servlet.ServletException;
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24
25 import org.mortbay.io.Buffer;
26 import org.mortbay.io.ByteArrayBuffer;
27 import org.mortbay.io.WriterOutputStream;
28 import org.mortbay.jetty.HttpConnection;
29 import org.mortbay.jetty.HttpFields;
30 import org.mortbay.jetty.HttpHeaders;
31 import org.mortbay.jetty.HttpMethods;
32 import org.mortbay.jetty.MimeTypes;
33 import org.mortbay.jetty.Request;
34 import org.mortbay.jetty.Response;
35 import org.mortbay.jetty.handler.ContextHandler.SContext;
36 import org.mortbay.log.Log;
37 import org.mortbay.resource.FileResource;
38 import org.mortbay.resource.Resource;
39 import org.mortbay.util.StringUtil;
40 import org.mortbay.util.TypeUtil;
41 import org.mortbay.util.URIUtil;
42
43
44
45
46
47
48
49
50
51
52
53
54 public class ResourceHandler extends AbstractHandler
55 {
56 ContextHandler _context;
57 Resource _baseResource;
58 String[] _welcomeFiles={"index.html"};
59 MimeTypes _mimeTypes = new MimeTypes();
60 ByteArrayBuffer _cacheControl;
61 boolean _aliases;
62
63
64 public ResourceHandler()
65 {
66 }
67
68
69 public MimeTypes getMimeTypes()
70 {
71 return _mimeTypes;
72 }
73
74
75 public void setMimeTypes(MimeTypes mimeTypes)
76 {
77 _mimeTypes = mimeTypes;
78 }
79
80
81
82
83
84 public boolean isAliases()
85 {
86 return _aliases;
87 }
88
89
90
91
92
93
94
95 public void setAliases(boolean aliases)
96 {
97 _aliases = aliases;
98 }
99
100
101 public void doStart()
102 throws Exception
103 {
104 SContext scontext = ContextHandler.getCurrentContext();
105 _context = (scontext==null?null:scontext.getContextHandler());
106
107 if (!_aliases && !FileResource.getCheckAliases())
108 throw new IllegalStateException("Alias checking disabled");
109
110 super.doStart();
111 }
112
113
114
115
116
117 public Resource getBaseResource()
118 {
119 if (_baseResource==null)
120 return null;
121 return _baseResource;
122 }
123
124
125
126
127
128 public String getResourceBase()
129 {
130 if (_baseResource==null)
131 return null;
132 return _baseResource.toString();
133 }
134
135
136
137
138
139
140 public void setBaseResource(Resource base)
141 {
142 _baseResource=base;
143 }
144
145
146
147
148
149 public void setResourceBase(String resourceBase)
150 {
151 try
152 {
153 setBaseResource(Resource.newResource(resourceBase));
154 }
155 catch (Exception e)
156 {
157 Log.warn(e);
158 throw new IllegalArgumentException(resourceBase);
159 }
160 }
161
162
163
164
165
166 public String getCacheControl()
167 {
168 return _cacheControl.toString();
169 }
170
171
172
173
174
175 public void setCacheControl(String cacheControl)
176 {
177 _cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl);
178 }
179
180
181
182
183 public Resource getResource(String path) throws MalformedURLException
184 {
185 if (path==null || !path.startsWith("/"))
186 throw new MalformedURLException(path);
187
188 Resource base = _baseResource;
189 if (base==null)
190 {
191 if (_context==null)
192 return null;
193 base=_context.getBaseResource();
194 if (base==null)
195 return null;
196 }
197
198 try
199 {
200 path=URIUtil.canonicalPath(path);
201 Resource resource=base.addPath(path);
202 return resource;
203 }
204 catch(Exception e)
205 {
206 Log.ignore(e);
207 }
208
209 return null;
210 }
211
212
213 protected Resource getResource(HttpServletRequest request) throws MalformedURLException
214 {
215 String path_info=request.getPathInfo();
216 if (path_info==null)
217 return null;
218 return getResource(path_info);
219 }
220
221
222
223 public String[] getWelcomeFiles()
224 {
225 return _welcomeFiles;
226 }
227
228
229 public void setWelcomeFiles(String[] welcomeFiles)
230 {
231 _welcomeFiles=welcomeFiles;
232 }
233
234
235 protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException
236 {
237 for (int i=0;i<_welcomeFiles.length;i++)
238 {
239 Resource welcome=directory.addPath(_welcomeFiles[i]);
240 if (welcome.exists() && !welcome.isDirectory())
241 return welcome;
242 }
243
244 return null;
245 }
246
247
248
249
250
251 public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException
252 {
253 Request base_request = request instanceof Request?(Request)request:HttpConnection.getCurrentConnection().getRequest();
254 if (base_request.isHandled())
255 return;
256
257 boolean skipContentBody = false;
258 if(!HttpMethods.GET.equals(request.getMethod()))
259 {
260 if(!HttpMethods.HEAD.equals(request.getMethod()))
261 return;
262 skipContentBody = true;
263 }
264
265 Resource resource=getResource(request);
266
267 if (resource==null || !resource.exists())
268 return;
269 if (!_aliases && resource.getAlias()!=null)
270 {
271 Log.info(resource+" aliased to "+resource.getAlias());
272 return;
273 }
274
275
276 base_request.setHandled(true);
277
278 if (resource.isDirectory())
279 {
280 if (!request.getPathInfo().endsWith(URIUtil.SLASH))
281 {
282 response.sendRedirect(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH));
283 return;
284 }
285 resource=getWelcome(resource);
286
287 if (resource==null || !resource.exists() || resource.isDirectory())
288 {
289 response.sendError(HttpServletResponse.SC_FORBIDDEN);
290 return;
291 }
292 }
293
294
295 long last_modified=resource.lastModified();
296 if (last_modified>0)
297 {
298 long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
299 if (if_modified>0 && last_modified/1000<=if_modified/1000)
300 {
301 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
302 return;
303 }
304 }
305
306 Buffer mime=_mimeTypes.getMimeByExtension(resource.toString());
307 if (mime==null)
308 mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
309
310
311 doResponseHeaders(response,resource,mime!=null?mime.toString():null);
312 response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified);
313 if(skipContentBody)
314 return;
315
316 OutputStream out =null;
317 try {out = response.getOutputStream();}
318 catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
319
320
321 if (out instanceof HttpConnection.Output)
322 {
323
324 ((HttpConnection.Output)out).sendContent(resource.getInputStream());
325 }
326 else
327 {
328
329 resource.writeTo(out,0,resource.length());
330 }
331 }
332
333
334
335
336
337
338
339
340
341 protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType)
342 {
343 if (mimeType!=null)
344 response.setContentType(mimeType);
345
346 long length=resource.length();
347
348 if (response instanceof Response)
349 {
350 HttpFields fields = ((Response)response).getHttpFields();
351
352 if (length>0)
353 fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length);
354
355 if (_cacheControl!=null)
356 fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
357 }
358 else
359 {
360 if (length>0)
361 response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(length));
362
363 if (_cacheControl!=null)
364 response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
365 }
366
367 }
368 }