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.toString());
158 Log.debug(e);
159 throw new IllegalArgumentException(resourceBase);
160 }
161 }
162
163
164
165
166
167 public String getCacheControl()
168 {
169 return _cacheControl.toString();
170 }
171
172
173
174
175
176 public void setCacheControl(String cacheControl)
177 {
178 _cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl);
179 }
180
181
182
183
184 public Resource getResource(String path) throws MalformedURLException
185 {
186 if (path==null || !path.startsWith("/"))
187 throw new MalformedURLException(path);
188
189 Resource base = _baseResource;
190 if (base==null)
191 {
192 if (_context==null)
193 return null;
194 base=_context.getBaseResource();
195 if (base==null)
196 return null;
197 }
198
199 try
200 {
201 path=URIUtil.canonicalPath(path);
202 Resource resource=base.addPath(path);
203 return resource;
204 }
205 catch(Exception e)
206 {
207 Log.ignore(e);
208 }
209
210 return null;
211 }
212
213
214 protected Resource getResource(HttpServletRequest request) throws MalformedURLException
215 {
216 String path_info=request.getPathInfo();
217 if (path_info==null)
218 return null;
219 return getResource(path_info);
220 }
221
222
223
224 public String[] getWelcomeFiles()
225 {
226 return _welcomeFiles;
227 }
228
229
230 public void setWelcomeFiles(String[] welcomeFiles)
231 {
232 _welcomeFiles=welcomeFiles;
233 }
234
235
236 protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException
237 {
238 for (int i=0;i<_welcomeFiles.length;i++)
239 {
240 Resource welcome=directory.addPath(_welcomeFiles[i]);
241 if (welcome.exists() && !welcome.isDirectory())
242 return welcome;
243 }
244
245 return null;
246 }
247
248
249
250
251
252 public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException
253 {
254 Request base_request = request instanceof Request?(Request)request:HttpConnection.getCurrentConnection().getRequest();
255 if (base_request.isHandled())
256 return;
257
258 boolean skipContentBody = false;
259 if(!HttpMethods.GET.equals(request.getMethod()))
260 {
261 if(!HttpMethods.HEAD.equals(request.getMethod()))
262 return;
263 skipContentBody = true;
264 }
265
266 Resource resource=getResource(request);
267
268 if (resource==null || !resource.exists())
269 return;
270 if (!_aliases && resource.getAlias()!=null)
271 {
272 Log.info(resource+" aliased to "+resource.getAlias());
273 return;
274 }
275
276
277 base_request.setHandled(true);
278
279 if (resource.isDirectory())
280 {
281 if (!request.getPathInfo().endsWith(URIUtil.SLASH))
282 {
283 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH)));
284 return;
285 }
286 resource=getWelcome(resource);
287
288 if (resource==null || !resource.exists() || resource.isDirectory())
289 {
290 response.sendError(HttpServletResponse.SC_FORBIDDEN);
291 return;
292 }
293 }
294
295
296 long last_modified=resource.lastModified();
297 if (last_modified>0)
298 {
299 long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
300 if (if_modified>0 && last_modified/1000<=if_modified/1000)
301 {
302 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
303 return;
304 }
305 }
306
307 Buffer mime=_mimeTypes.getMimeByExtension(resource.toString());
308 if (mime==null)
309 mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
310
311
312 doResponseHeaders(response,resource,mime!=null?mime.toString():null);
313 response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified);
314 if(skipContentBody)
315 return;
316
317 OutputStream out =null;
318 try {out = response.getOutputStream();}
319 catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
320
321
322 if (out instanceof HttpConnection.Output)
323 {
324
325 ((HttpConnection.Output)out).sendContent(resource.getInputStream());
326 }
327 else
328 {
329
330 resource.writeTo(out,0,resource.length());
331 }
332 }
333
334
335
336
337
338
339
340
341
342 protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType)
343 {
344 if (mimeType!=null)
345 response.setContentType(mimeType);
346
347 long length=resource.length();
348
349 if (response instanceof Response)
350 {
351 HttpFields fields = ((Response)response).getHttpFields();
352
353 if (length>0)
354 fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length);
355
356 if (_cacheControl!=null)
357 fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
358 }
359 else
360 {
361 if (length>0)
362 response.setHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(length));
363
364 if (_cacheControl!=null)
365 response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
366 }
367
368 }
369 }