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