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