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