001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.catalina.ssi;
018:
019: import java.io.BufferedReader;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.InputStreamReader;
023: import java.io.PrintWriter;
024: import java.io.StringWriter;
025: import java.net.URL;
026: import java.net.URLConnection;
027: import javax.servlet.ServletContext;
028: import javax.servlet.ServletException;
029: import javax.servlet.http.HttpServlet;
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpServletResponse;
032: import org.apache.catalina.Globals;
033:
034: /**
035: * Servlet to process SSI requests within a webpage. Mapped to a path from
036: * within web.xml.
037: *
038: * @author Bip Thelin
039: * @author Amy Roh
040: * @author Dan Sandberg
041: * @author David Becker
042: * @version $Revision: 531303 $, $Date: 2007-04-23 02:24:01 +0200 (lun., 23 avr. 2007) $
043: */
044: public class SSIServlet extends HttpServlet {
045: /** Debug level for this servlet. */
046: protected int debug = 0;
047: /** Should the output be buffered. */
048: protected boolean buffered = false;
049: /** Expiration time in seconds for the doc. */
050: protected Long expires = null;
051: /** virtual path can be webapp-relative */
052: protected boolean isVirtualWebappRelative = false;
053: /** Input encoding. If not specified, uses platform default */
054: protected String inputEncoding = null;
055: /** Output encoding. If not specified, uses platform default */
056: protected String outputEncoding = "UTF-8";
057:
058: //----------------- Public methods.
059: /**
060: * Initialize this servlet.
061: *
062: * @exception ServletException
063: * if an error occurs
064: */
065: public void init() throws ServletException {
066:
067: if (getServletConfig().getInitParameter("debug") != null)
068: debug = Integer.parseInt(getServletConfig()
069: .getInitParameter("debug"));
070:
071: isVirtualWebappRelative = Boolean
072: .parseBoolean(getServletConfig().getInitParameter(
073: "isVirtualWebappRelative"));
074:
075: if (getServletConfig().getInitParameter("expires") != null)
076: expires = Long.valueOf(getServletConfig().getInitParameter(
077: "expires"));
078:
079: buffered = Boolean.parseBoolean(getServletConfig()
080: .getInitParameter("buffered"));
081:
082: inputEncoding = getServletConfig().getInitParameter(
083: "inputEncoding");
084:
085: if (getServletConfig().getInitParameter("outputEncoding") != null)
086: outputEncoding = getServletConfig().getInitParameter(
087: "outputEncoding");
088:
089: if (debug > 0)
090: log("SSIServlet.init() SSI invoker started with 'debug'="
091: + debug);
092:
093: }
094:
095: /**
096: * Process and forward the GET request to our <code>requestHandler()</code>*
097: *
098: * @param req
099: * a value of type 'HttpServletRequest'
100: * @param res
101: * a value of type 'HttpServletResponse'
102: * @exception IOException
103: * if an error occurs
104: * @exception ServletException
105: * if an error occurs
106: */
107: public void doGet(HttpServletRequest req, HttpServletResponse res)
108: throws IOException, ServletException {
109: if (debug > 0)
110: log("SSIServlet.doGet()");
111: requestHandler(req, res);
112: }
113:
114: /**
115: * Process and forward the POST request to our
116: * <code>requestHandler()</code>.
117: *
118: * @param req
119: * a value of type 'HttpServletRequest'
120: * @param res
121: * a value of type 'HttpServletResponse'
122: * @exception IOException
123: * if an error occurs
124: * @exception ServletException
125: * if an error occurs
126: */
127: public void doPost(HttpServletRequest req, HttpServletResponse res)
128: throws IOException, ServletException {
129: if (debug > 0)
130: log("SSIServlet.doPost()");
131: requestHandler(req, res);
132: }
133:
134: /**
135: * Process our request and locate right SSI command.
136: *
137: * @param req
138: * a value of type 'HttpServletRequest'
139: * @param res
140: * a value of type 'HttpServletResponse'
141: */
142: protected void requestHandler(HttpServletRequest req,
143: HttpServletResponse res) throws IOException,
144: ServletException {
145: ServletContext servletContext = getServletContext();
146: String path = SSIServletRequestUtil.getRelativePath(req);
147: if (debug > 0)
148: log("SSIServlet.requestHandler()\n" + "Serving "
149: + (buffered ? "buffered " : "unbuffered ")
150: + "resource '" + path + "'");
151: // Exclude any resource in the /WEB-INF and /META-INF subdirectories
152: // (the "toUpperCase()" avoids problems on Windows systems)
153: if (path == null || path.toUpperCase().startsWith("/WEB-INF")
154: || path.toUpperCase().startsWith("/META-INF")) {
155: res.sendError(HttpServletResponse.SC_NOT_FOUND, path);
156: log("Can't serve file: " + path);
157: return;
158: }
159: URL resource = servletContext.getResource(path);
160: if (resource == null) {
161: res.sendError(HttpServletResponse.SC_NOT_FOUND, path);
162: log("Can't find file: " + path);
163: return;
164: }
165: String resourceMimeType = servletContext.getMimeType(path);
166: if (resourceMimeType == null) {
167: resourceMimeType = "text/html";
168: }
169: res.setContentType(resourceMimeType + ";charset="
170: + outputEncoding);
171: if (expires != null) {
172: res.setDateHeader("Expires", (new java.util.Date())
173: .getTime()
174: + expires.longValue() * 1000);
175: }
176: req.setAttribute(Globals.SSI_FLAG_ATTR, "true");
177: processSSI(req, res, resource);
178: }
179:
180: protected void processSSI(HttpServletRequest req,
181: HttpServletResponse res, URL resource) throws IOException {
182: SSIExternalResolver ssiExternalResolver = new SSIServletExternalResolver(
183: getServletContext(), req, res, isVirtualWebappRelative,
184: debug, inputEncoding);
185: SSIProcessor ssiProcessor = new SSIProcessor(
186: ssiExternalResolver, debug);
187: PrintWriter printWriter = null;
188: StringWriter stringWriter = null;
189: if (buffered) {
190: stringWriter = new StringWriter();
191: printWriter = new PrintWriter(stringWriter);
192: } else {
193: printWriter = res.getWriter();
194: }
195:
196: URLConnection resourceInfo = resource.openConnection();
197: InputStream resourceInputStream = resourceInfo.getInputStream();
198: String encoding = resourceInfo.getContentEncoding();
199: if (encoding == null) {
200: encoding = inputEncoding;
201: }
202: InputStreamReader isr;
203: if (encoding == null) {
204: isr = new InputStreamReader(resourceInputStream);
205: } else {
206: isr = new InputStreamReader(resourceInputStream, encoding);
207: }
208: BufferedReader bufferedReader = new BufferedReader(isr);
209:
210: long lastModified = ssiProcessor.process(bufferedReader,
211: resourceInfo.getLastModified(), printWriter);
212: if (lastModified > 0) {
213: res.setDateHeader("last-modified", lastModified);
214: }
215: if (buffered) {
216: printWriter.flush();
217: String text = stringWriter.toString();
218: res.getWriter().write(text);
219: }
220: }
221: }
|