Source Code Cross Referenced for StaticResourceServlet.java in  » Web-Server » Winstone » winstone » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Winstone » winstone 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         */
007:        package winstone;
008:
009:        import java.io.File;
010:        import java.io.FileInputStream;
011:        import java.io.IOException;
012:        import java.io.InputStream;
013:        import java.io.OutputStream;
014:        import java.io.StringWriter;
015:        import java.io.Writer;
016:        import java.text.DateFormat;
017:        import java.text.SimpleDateFormat;
018:        import java.util.ArrayList;
019:        import java.util.Arrays;
020:        import java.util.Date;
021:        import java.util.Iterator;
022:        import java.util.List;
023:        import java.util.StringTokenizer;
024:
025:        import javax.servlet.ServletConfig;
026:        import javax.servlet.ServletException;
027:        import javax.servlet.http.HttpServlet;
028:        import javax.servlet.http.HttpServletRequest;
029:        import javax.servlet.http.HttpServletResponse;
030:
031:        /**
032:         * Servlet to handle static resources. Simply finds and sends them, or
033:         * dispatches to the error servlet.
034:         * 
035:         * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
036:         * @version $Id: StaticResourceServlet.java,v 1.17 2004/12/31 07:21:00
037:         *          rickknowles Exp $
038:         */
039:        public class StaticResourceServlet extends HttpServlet {
040:            // final String JSP_FILE = "org.apache.catalina.jsp_file";
041:            final static String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
042:            final static String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
043:            final static String CACHED_RESOURCE_DATE_HEADER = "If-Modified-Since";
044:            final static String LAST_MODIFIED_DATE_HEADER = "Last-Modified";
045:            final static String RANGE_HEADER = "Range";
046:            final static String ACCEPT_RANGES_HEADER = "Accept-Ranges";
047:            final static String CONTENT_RANGE_HEADER = "Content-Range";
048:            final static String RESOURCE_FILE = "winstone.LocalStrings";
049:            private DateFormat sdfFileDate = new SimpleDateFormat(
050:                    "dd-MM-yyyy HH:mm");
051:            private File webRoot;
052:            private String prefix;
053:            private boolean directoryList;
054:
055:            public void init(ServletConfig config) throws ServletException {
056:                super .init(config);
057:                this .webRoot = new File(config.getInitParameter("webRoot"));
058:                this .prefix = config.getInitParameter("prefix");
059:                String dirList = config.getInitParameter("directoryList");
060:                this .directoryList = (dirList == null)
061:                        || dirList.equalsIgnoreCase("true")
062:                        || dirList.equalsIgnoreCase("yes");
063:            }
064:
065:            public void doPost(HttpServletRequest request,
066:                    HttpServletResponse response) throws ServletException,
067:                    IOException {
068:                doGet(request, response);
069:            }
070:
071:            public void doGet(HttpServletRequest request,
072:                    HttpServletResponse response) throws ServletException,
073:                    IOException {
074:                boolean isInclude = (request.getAttribute(INCLUDE_SERVLET_PATH) != null);
075:                boolean isForward = (request.getAttribute(FORWARD_SERVLET_PATH) != null);
076:                String path = null;
077:
078:                if (isInclude)
079:                    path = (String) request.getAttribute(INCLUDE_SERVLET_PATH);
080:                else {
081:                    path = request.getServletPath();
082:                }
083:
084:                // URL decode path
085:                path = WinstoneRequest.decodeURLToken(path);
086:
087:                long cachedResDate = request
088:                        .getDateHeader(CACHED_RESOURCE_DATE_HEADER);
089:                Logger.log(Logger.DEBUG, Launcher.RESOURCES,
090:                        "StaticResourceServlet.PathRequested", new String[] {
091:                                getServletConfig().getServletName(), path });
092:
093:                // Check for the resource
094:                File res = path.equals("") ? this .webRoot : new File(
095:                        this .webRoot, path);
096:
097:                // Send a 404 if not found
098:                if (!res.exists())
099:                    response
100:                            .sendError(
101:                                    HttpServletResponse.SC_NOT_FOUND,
102:                                    Launcher.RESOURCES
103:                                            .getString(
104:                                                    "StaticResourceServlet.PathNotFound",
105:                                                    path));
106:
107:                // Check we are below the webroot
108:                else if (!isDescendant(this .webRoot, res, this .webRoot)) {
109:                    Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
110:                            "StaticResourceServlet.OutsideWebroot",
111:                            new String[] { res.getCanonicalPath(),
112:                                    this .webRoot.toString() });
113:                    response.sendError(HttpServletResponse.SC_FORBIDDEN,
114:                            Launcher.RESOURCES.getString(
115:                                    "StaticResourceServlet.PathInvalid", path));
116:                }
117:
118:                // Check we are not below the web-inf
119:                else if (!isInclude
120:                        && !isForward
121:                        && isDescendant(new File(this .webRoot, "WEB-INF"), res,
122:                                this .webRoot))
123:                    response.sendError(HttpServletResponse.SC_NOT_FOUND,
124:                            Launcher.RESOURCES.getString(
125:                                    "StaticResourceServlet.PathInvalid", path));
126:
127:                // Check we are not below the meta-inf
128:                else if (!isInclude
129:                        && !isForward
130:                        && isDescendant(new File(this .webRoot, "META-INF"),
131:                                res, this .webRoot))
132:                    response.sendError(HttpServletResponse.SC_NOT_FOUND,
133:                            Launcher.RESOURCES.getString(
134:                                    "StaticResourceServlet.PathInvalid", path));
135:
136:                // check for the directory case
137:                else if (res.isDirectory()) {
138:                    if (path.endsWith("/")) {
139:                        // Try to match each of the welcome files
140:                        // String matchedWelcome = matchWelcomeFiles(path, res);
141:                        // if (matchedWelcome != null)
142:                        // response.sendRedirect(this.prefix + path + matchedWelcome);
143:                        // else
144:                        if (this .directoryList)
145:                            generateDirectoryList(request, response, path);
146:                        else
147:                            response
148:                                    .sendError(
149:                                            HttpServletResponse.SC_FORBIDDEN,
150:                                            Launcher.RESOURCES
151:                                                    .getString("StaticResourceServlet.AccessDenied"));
152:                    } else
153:                        response.sendRedirect(this .prefix + path + "/");
154:                }
155:
156:                // Send a 304 if not modified
157:                else if (!isInclude
158:                        && (cachedResDate != -1)
159:                        && (cachedResDate < (System.currentTimeMillis() / 1000L * 1000L))
160:                        && (cachedResDate >= (res.lastModified() / 1000L * 1000L))) {
161:                    String mimeType = getServletContext().getMimeType(
162:                            res.getName().toLowerCase());
163:                    if (mimeType != null)
164:                        response.setContentType(mimeType);
165:                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
166:                    response.setContentLength(0);
167:                    response.flushBuffer();
168:                }
169:
170:                // Write out the resource if not range or is included
171:                else if ((request.getHeader(RANGE_HEADER) == null) || isInclude) {
172:                    String mimeType = getServletContext().getMimeType(
173:                            res.getName().toLowerCase());
174:                    if (mimeType != null)
175:                        response.setContentType(mimeType);
176:                    InputStream resStream = new FileInputStream(res);
177:
178:                    response.setStatus(HttpServletResponse.SC_OK);
179:                    response.setContentLength((int) res.length());
180:                    //            response.addHeader(ACCEPT_RANGES_HEADER, "bytes");
181:                    response.addDateHeader(LAST_MODIFIED_DATE_HEADER, res
182:                            .lastModified());
183:                    OutputStream out = null;
184:                    Writer outWriter = null;
185:                    try {
186:                        out = response.getOutputStream();
187:                    } catch (IllegalStateException err) {
188:                        outWriter = response.getWriter();
189:                    } catch (IllegalArgumentException err) {
190:                        outWriter = response.getWriter();
191:                    }
192:                    byte buffer[] = new byte[4096];
193:                    int read = resStream.read(buffer);
194:                    while (read > 0) {
195:                        if (out != null) {
196:                            out.write(buffer, 0, read);
197:                        } else {
198:                            outWriter.write(new String(buffer, 0, read,
199:                                    response.getCharacterEncoding()));
200:                        }
201:                        read = resStream.read(buffer);
202:                    }
203:                    resStream.close();
204:                } else if (request.getHeader(RANGE_HEADER).startsWith("bytes=")) {
205:                    String mimeType = getServletContext().getMimeType(
206:                            res.getName().toLowerCase());
207:                    if (mimeType != null)
208:                        response.setContentType(mimeType);
209:                    InputStream resStream = new FileInputStream(res);
210:
211:                    List ranges = new ArrayList();
212:                    StringTokenizer st = new StringTokenizer(request.getHeader(
213:                            RANGE_HEADER).substring(6).trim(), ",", false);
214:                    int totalSent = 0;
215:                    String rangeText = "";
216:                    while (st.hasMoreTokens()) {
217:                        String rangeBlock = st.nextToken();
218:                        int start = 0;
219:                        int end = (int) res.length();
220:                        int delim = rangeBlock.indexOf('-');
221:                        if (delim != 0)
222:                            start = Integer.parseInt(rangeBlock.substring(0,
223:                                    delim).trim());
224:                        if (delim != rangeBlock.length() - 1)
225:                            end = Integer.parseInt(rangeBlock.substring(
226:                                    delim + 1).trim());
227:                        totalSent += (end - start);
228:                        rangeText += "," + start + "-" + end;
229:                        ranges.add(start + "-" + end);
230:                    }
231:                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
232:                    response.addHeader(CONTENT_RANGE_HEADER, "bytes "
233:                            + rangeText.substring(1) + "/" + res.length());
234:                    response.setContentLength(totalSent);
235:
236:                    response.addHeader(ACCEPT_RANGES_HEADER, "bytes");
237:                    response.addDateHeader(LAST_MODIFIED_DATE_HEADER, res
238:                            .lastModified());
239:                    OutputStream out = response.getOutputStream();
240:                    int bytesRead = 0;
241:                    for (Iterator i = ranges.iterator(); i.hasNext();) {
242:                        String rangeBlock = (String) i.next();
243:                        int delim = rangeBlock.indexOf('-');
244:                        int start = Integer.parseInt(rangeBlock.substring(0,
245:                                delim));
246:                        int end = Integer.parseInt(rangeBlock
247:                                .substring(delim + 1));
248:                        int read = 0;
249:                        while ((read != -1) && (bytesRead <= res.length())) {
250:                            read = resStream.read();
251:                            if ((bytesRead >= start) && (bytesRead < end))
252:                                out.write(read);
253:                            bytesRead++;
254:                        }
255:                    }
256:                    resStream.close();
257:                } else
258:                    response
259:                            .sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
260:            }
261:
262:            /**
263:             * Generate a list of the files in this directory
264:             */
265:            private void generateDirectoryList(HttpServletRequest request,
266:                    HttpServletResponse response, String path)
267:                    throws ServletException, IOException {
268:                // Get the file list
269:                File dir = path.equals("") ? this .webRoot : new File(
270:                        this .webRoot, path);
271:                File children[] = dir.listFiles();
272:                Arrays.sort(children);
273:
274:                // Build row content
275:                StringWriter rowString = new StringWriter();
276:                String oddColour = Launcher.RESOURCES
277:                        .getString("StaticResourceServlet.DirectoryList.OddColour");
278:                String evenColour = Launcher.RESOURCES
279:                        .getString("StaticResourceServlet.DirectoryList.EvenColour");
280:                String rowTextColour = Launcher.RESOURCES
281:                        .getString("StaticResourceServlet.DirectoryList.RowTextColour");
282:
283:                String directoryLabel = Launcher.RESOURCES
284:                        .getString("StaticResourceServlet.DirectoryList.DirectoryLabel");
285:                String parentDirLabel = Launcher.RESOURCES
286:                        .getString("StaticResourceServlet.DirectoryList.ParentDirectoryLabel");
287:                String noDateLabel = Launcher.RESOURCES
288:                        .getString("StaticResourceServlet.DirectoryList.NoDateLabel");
289:
290:                int rowCount = 0;
291:
292:                // Write the parent dir row
293:                if (!path.equals("") && !path.equals("/")) {
294:                    rowString.write(Launcher.RESOURCES.getString(
295:                            "StaticResourceServlet.DirectoryList.Row",
296:                            new String[] { rowTextColour, evenColour,
297:                                    parentDirLabel, "..", noDateLabel,
298:                                    directoryLabel }));
299:                    rowCount++;
300:                }
301:
302:                // Write the rows for each file
303:                for (int n = 0; n < children.length; n++) {
304:                    if (!children[n].getName().equalsIgnoreCase("web-inf")
305:                            && !children[n].getName().equalsIgnoreCase(
306:                                    "meta-inf")) {
307:                        File file = children[n];
308:                        String date = noDateLabel;
309:                        String size = directoryLabel;
310:                        if (!file.isDirectory()) {
311:                            size = "" + file.length();
312:                            synchronized (sdfFileDate) {
313:                                date = sdfFileDate.format(new Date(file
314:                                        .lastModified()));
315:                            }
316:                        }
317:                        rowString.write(Launcher.RESOURCES.getString(
318:                                "StaticResourceServlet.DirectoryList.Row",
319:                                new String[] {
320:                                        rowTextColour,
321:                                        rowCount % 2 == 0 ? evenColour
322:                                                : oddColour,
323:                                        file.getName()
324:                                                + (file.isDirectory() ? "/"
325:                                                        : ""),
326:                                        "./"
327:                                                + file.getName()
328:                                                + (file.isDirectory() ? "/"
329:                                                        : ""), date, size }));
330:                        rowCount++;
331:                    }
332:                }
333:
334:                // Build wrapper body
335:                String out = Launcher.RESOURCES
336:                        .getString(
337:                                "StaticResourceServlet.DirectoryList.Body",
338:                                new String[] {
339:                                        Launcher.RESOURCES
340:                                                .getString("StaticResourceServlet.DirectoryList.HeaderColour"),
341:                                        Launcher.RESOURCES
342:                                                .getString("StaticResourceServlet.DirectoryList.HeaderTextColour"),
343:                                        Launcher.RESOURCES
344:                                                .getString("StaticResourceServlet.DirectoryList.LabelColour"),
345:                                        Launcher.RESOURCES
346:                                                .getString("StaticResourceServlet.DirectoryList.LabelTextColour"),
347:                                        new Date() + "",
348:                                        Launcher.RESOURCES
349:                                                .getString("ServerVersion"),
350:                                        path.equals("") ? "/" : path,
351:                                        rowString.toString() });
352:
353:                response.setContentLength(out.getBytes().length);
354:                response.setContentType("text/html");
355:                Writer w = response.getWriter();
356:                w.write(out);
357:                w.close();
358:            }
359:
360:            public static boolean isDescendant(File parent, File child,
361:                    File commonBase) throws IOException {
362:                if (child.equals(parent)) {
363:                    return true;
364:                } else {
365:                    // Start by checking canonicals
366:                    String canonicalParent = parent.getAbsoluteFile()
367:                            .getCanonicalPath();
368:                    String canonicalChild = child.getAbsoluteFile()
369:                            .getCanonicalPath();
370:                    if (canonicalChild.startsWith(canonicalParent)) {
371:                        return true;
372:                    }
373:
374:                    // If canonicals don't match, we're dealing with symlinked files, so if we can
375:                    // build a path from the parent to the child, 
376:                    String childOCValue = constructOurCanonicalVersion(child,
377:                            commonBase);
378:                    String parentOCValue = constructOurCanonicalVersion(parent,
379:                            commonBase);
380:                    return childOCValue.startsWith(parentOCValue);
381:                }
382:            }
383:
384:            public static String constructOurCanonicalVersion(File current,
385:                    File stopPoint) {
386:                int backOnes = 0;
387:                StringBuffer ourCanonicalVersion = new StringBuffer();
388:                while ((current != null) && !current.equals(stopPoint)) {
389:                    if (current.getName().equals("..")) {
390:                        backOnes++;
391:                    } else if (current.getName().equals(".")) {
392:                        // skip - do nothing
393:                    } else if (backOnes > 0) {
394:                        backOnes--;
395:                    } else {
396:                        ourCanonicalVersion.insert(0, "/" + current.getName());
397:                    }
398:                    current = current.getParentFile();
399:                }
400:                return ourCanonicalVersion.toString();
401:            }
402:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.