001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http/HttpResponseImpl.java,v 1.13 2002/03/18 07:15:40 remm Exp $
003: * $Revision: 1.13 $
004: * $Date: 2002/03/18 07:15:40 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.catalina.connector.http;
065:
066: import java.io.IOException;
067: import java.io.PrintWriter;
068: import java.io.OutputStream;
069: import java.util.ArrayList;
070: import javax.servlet.ServletOutputStream;
071: import javax.servlet.http.HttpServletResponse;
072: import org.apache.catalina.connector.HttpResponseBase;
073:
074: /**
075: * Implementation of <b>HttpResponse</b> specific to the HTTP connector.
076: *
077: * @author Craig R. McClanahan
078: * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
079: * @version $Revision: 1.13 $ $Date: 2002/03/18 07:15:40 $
080: * @deprecated
081: */
082:
083: final class HttpResponseImpl extends HttpResponseBase {
084:
085: // ----------------------------------------------------- Instance Variables
086:
087: /**
088: * Descriptive information about this Response implementation.
089: */
090: protected static final String info = "org.apache.catalina.connector.http.HttpResponseImpl/1.0";
091:
092: /**
093: * True if chunking is allowed.
094: */
095: protected boolean allowChunking;
096:
097: /**
098: * Associated HTTP response stream.
099: */
100: protected HttpResponseStream responseStream;
101:
102: // ------------------------------------------------------------- Properties
103:
104: /**
105: * Return descriptive information about this Response implementation and
106: * the corresponding version number, in the format
107: * <code><description>/<version></code>.
108: */
109: public String getInfo() {
110:
111: return (info);
112:
113: }
114:
115: /**
116: * Set the chunking flag.
117: */
118: void setAllowChunking(boolean allowChunking) {
119: this .allowChunking = allowChunking;
120: }
121:
122: /**
123: * True if chunking is allowed.
124: */
125: public boolean isChunkingAllowed() {
126: return allowChunking;
127: }
128:
129: // ------------------------------------------------------ Protected Methods
130:
131: /**
132: * Return the HTTP protocol version implemented by this response
133: * object.
134: *
135: * @return The "HTTP/1.1" string.
136: */
137: protected String getProtocol() {
138: return ("HTTP/1.1");
139: }
140:
141: // --------------------------------------------------------- Public Methods
142:
143: /**
144: * Release all object references, and initialize instance variables, in
145: * preparation for reuse of this object.
146: */
147: public void recycle() {
148:
149: super .recycle();
150: responseStream = null;
151: allowChunking = false;
152:
153: }
154:
155: /**
156: * Send an error response with the specified status and message.
157: *
158: * @param status HTTP status code to send
159: * @param message Corresponding message to send
160: *
161: * @exception IllegalStateException if this response has
162: * already been committed
163: * @exception IOException if an input/output error occurs
164: */
165: public void sendError(int status, String message)
166: throws IOException {
167:
168: addHeader("Connection", "close");
169: super .sendError(status, message);
170:
171: }
172:
173: /**
174: * Clear any content written to the buffer. In addition, all cookies
175: * and headers are cleared, and the status is reset.
176: *
177: * @exception IllegalStateException if this response has already
178: * been committed
179: */
180: public void reset() {
181:
182: // Saving important HTTP/1.1 specific headers
183: String connectionValue = (String) getHeader("Connection");
184: String transferEncodingValue = (String) getHeader("Transfer-Encoding");
185: super .reset();
186: if (connectionValue != null)
187: addHeader("Connection", connectionValue);
188: if (transferEncodingValue != null)
189: addHeader("Transfer-Encoding", transferEncodingValue);
190:
191: }
192:
193: /**
194: * Create and return a ServletOutputStream to write the content
195: * associated with this Response.
196: *
197: * @exception IOException if an input/output error occurs
198: */
199: public ServletOutputStream createOutputStream() throws IOException {
200:
201: responseStream = new HttpResponseStream(this );
202: return (responseStream);
203:
204: }
205:
206: /**
207: * Tests is the connection will be closed after the processing of the
208: * request.
209: */
210: public boolean isCloseConnection() {
211: String connectionValue = (String) getHeader("Connection");
212: return (connectionValue != null && connectionValue
213: .equals("close"));
214: }
215:
216: /**
217: * Removes the specified header.
218: *
219: * @param name Name of the header to remove
220: * @param value Value to remove
221: */
222: public void removeHeader(String name, String value) {
223:
224: if (isCommitted())
225: return;
226:
227: if (included)
228: return; // Ignore any call from an included servlet
229:
230: synchronized (headers) {
231: ArrayList values = (ArrayList) headers.get(name);
232: if ((values != null) && (!values.isEmpty())) {
233: values.remove(value);
234: if (values.isEmpty())
235: headers.remove(name);
236: }
237: }
238:
239: }
240:
241: /**
242: * Has stream been created ?
243: */
244: public boolean isStreamInitialized() {
245: return (responseStream != null);
246: }
247:
248: /**
249: * Perform whatever actions are required to flush and close the output
250: * stream or writer, in a single operation.
251: *
252: * @exception IOException if an input/output error occurs
253: */
254: public void finishResponse() throws IOException {
255:
256: if (getStatus() < HttpServletResponse.SC_BAD_REQUEST) {
257: if ((!isStreamInitialized()) && (getContentLength() == -1)
258: && (getStatus() >= 200)
259: && (getStatus() != SC_NOT_MODIFIED)
260: && (getStatus() != SC_NO_CONTENT))
261: setContentLength(0);
262: } else {
263: setHeader("Connection", "close");
264: }
265: super .finishResponse();
266:
267: }
268:
269: // -------------------------------------------- HttpServletResponse Methods
270:
271: /**
272: * Set the HTTP status to be returned with this response.
273: *
274: * @param status The new HTTP status
275: */
276: public void setStatus(int status) {
277:
278: super .setStatus(status);
279:
280: if (responseStream != null)
281: responseStream.checkChunking(this );
282:
283: }
284:
285: /**
286: * Set the content length (in bytes) for this Response.
287: *
288: * @param length The new content length
289: */
290: public void setContentLength(int length) {
291:
292: if (isCommitted())
293: return;
294:
295: if (included)
296: return; // Ignore any call from an included servlet
297:
298: super.setContentLength(length);
299:
300: if (responseStream != null)
301: responseStream.checkChunking(this);
302:
303: }
304:
305: }
|