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