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