View Javadoc

1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Attic/RequestOutputStream.java,v 1.21.2.1 2004/02/22 18:21:13 olegk Exp $
3    * $Revision: 1.21.2.1 $
4    * $Date: 2004/02/22 18:21:13 $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   * [Additional notices, if required by prior licensing conditions]
29   *
30   */
31  
32  package org.apache.commons.httpclient;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  import java.io.IOException;
38  import java.io.OutputStream;
39  
40  
41  /***
42   * <p>
43   * {@link OutputStream} wrapper supporting the chunked transfer encoding.
44   * </p>
45   * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
46   * @author Sean C. Sullivan
47   * @author <a href="mailto:dion@apache.org">dIon Gillard</a>
48   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
49   * @version $Revision: 1.21.2.1 $ $Date: 2004/02/22 18:21:13 $
50   *
51   * @deprecated Use new ChunkedOutputStream(HttpConnecion#getRequestOutputStream());
52   *
53   */
54  public class RequestOutputStream
55      extends OutputStream {
56  
57      // ----------------------------------------------------------- Constructors
58  
59      /***
60       * Construct an output stream wrapping the given stream.
61       * The stream will not use chunking.
62       *
63       * @param stream wrapped output stream. Must be non-null.
64       * 
65       * @deprecated Use ChunkedOutputStream;
66       */
67      public RequestOutputStream(OutputStream stream) {
68          this(stream, false);
69      }
70  
71      /***
72       * Construct an output stream wrapping the given stream.
73       *
74       * @param stream wrapped output stream. Must be non-null.
75       * @param useChunking when <code>true</code>, the chunked transfer encoding
76       *                    will be used
77       * 
78       * @deprecated Use ChunkedOutputStream;
79       */
80      public RequestOutputStream(OutputStream stream, boolean useChunking) {
81          if (stream == null) {
82              throw new NullPointerException("stream parameter is null");
83          }
84          this.stream = stream;
85          this.useChunking = useChunking;
86      }
87  
88      // ------------------------------------------------------- Static Variables
89  
90      /*** Log object for this class. */
91      private static final Log LOG = LogFactory.getLog(RequestOutputStream.class);
92  
93      // ----------------------------------------------------- Instance Variables
94  
95      /*** Has this stream been closed? */
96      private boolean closed = false;
97  
98      /*** The underlying output stream to which we will write data */
99      private OutputStream stream = null;
100 
101     /*** True if chunking is allowed */
102     private boolean useChunking = false;
103 
104     /*** <tt>"\r\n"</tt>, as bytes. */
105     private static final byte CRLF[] = new byte[] {(byte) 13, (byte) 10};
106 
107     /*** End chunk */
108     private static final byte ENDCHUNK[] = CRLF;
109 
110     /*** 0 */
111     private static final byte ZERO[] = new byte[] {(byte) '0'};
112 
113     /*** 1 */
114     private static final byte ONE[] = new byte[] {(byte) '1'};
115 
116     // ------------------------------------------------------------- Properties
117 
118 
119     /***
120      * Use chunking flag setter.
121      *
122      * @param useChunking true if chunking is to be used, false otherwise
123      * 
124      * @deprecated Use ChunkedOutputStream;
125      */
126     public void setUseChunking(boolean useChunking) {
127         this.useChunking = useChunking;
128     }
129 
130 
131     /***
132      * Use chunking flag getter.
133      *
134      * @return true if chunking is to be used, false otherwise
135      * 
136      * @deprecated Use ChunkedOutputStream;
137      */
138     public boolean isUseChunking() {
139         return useChunking;
140     }
141 
142     // --------------------------------------------------------- Public Methods
143 
144     /***
145      * Writes a <code>String</code> to the client, without a carriage return
146      * line feed (CRLF) character at the end.
147      *
148      * @param s the <code>String</code> to send to the client. Must be non-null.
149      * @throws IOException if an input or output exception occurred
150      * 
151      * @deprecated Use ChunkedOutputStream;
152      */
153     public void print(String s) throws IOException {
154         LOG.trace("enter RequestOutputStream.print(String)");
155 
156         if (s == null) {
157             s = "null";
158         }
159         int len = s.length();
160         for (int i = 0; i < len; i++) {
161             write(s.charAt(i));
162         }
163     }
164 
165     /***
166      * Writes a carriage return-line feed (CRLF) to the client.
167      *
168      * @throws IOException   if an input or output exception occurred
169      * 
170      * @deprecated Use ChunkedOutputStream;
171      */
172     public void println() throws IOException {
173         print("\r\n");
174     }
175 
176     /***
177      * Writes a <code>String</code> to the client,
178      * followed by a carriage return-line feed (CRLF).
179      *
180      * @param s         the </code>String</code> to write to the client
181      * @exception IOException   if an input or output exception occurred
182      * 
183      * @deprecated Use ChunkedOutputStream;
184      */
185     public void println(String s) throws IOException {
186         print(s);
187         println();
188     }
189 
190     // -------------------------------------------- ServletOutputStream Methods
191 
192     /***
193      * Write the specified byte to our output stream.
194      *
195      * @param b The byte to be written
196      * @throws IOException if an input/output error occurs
197      * 
198      * @deprecated Use ChunkedOutputStream;
199      */
200     public void write(int b) throws IOException {
201 
202         //FIXME: If using chunking, the chunks are ONE byte long!
203         if (useChunking) {
204             stream.write(ONE, 0, ONE.length);
205             stream.write(CRLF, 0, CRLF.length);
206             stream.write(b);
207             stream.write(ENDCHUNK, 0, ENDCHUNK.length);
208         } else {
209             stream.write(b);
210         }
211     }
212 
213     /***
214      * Write the specified byte array.
215      *
216      * @param b the byte array to write out
217      * @param off the offset within <code>b</code> to start writing from
218      * @param len the length of data within <code>b</code> to write
219      * @throws IOException when errors occur writing output
220      * 
221      * @deprecated Use ChunkedOutputStream;
222      */
223     public void write(byte[] b, int off, int len) throws IOException {
224         LOG.trace("enter RequestOutputStream.write(byte[], int, int)");
225 
226         if (useChunking) {
227             byte chunkHeader[] = HttpConstants.getBytes(Integer.toHexString(len) + "\r\n");
228             stream.write(chunkHeader, 0, chunkHeader.length);
229             stream.write(b, off, len);
230             stream.write(ENDCHUNK, 0, ENDCHUNK.length);
231         } else {
232             stream.write(b, off, len);
233         }
234     }
235 
236     /***
237      * Close this output stream, causing any buffered data to be flushed and
238      * any further output data to throw an IOException.
239      *
240      * @throws IOException if an error occurs closing the stream
241      * 
242      * @deprecated Use ChunkedOutputStream;
243      */
244     public void close() throws IOException {
245         LOG.trace("enter RequestOutputStream.close()");
246 
247         if (!closed) {
248             try {
249                 if (useChunking) {
250                     // Write the final chunk.
251                     stream.write(ZERO, 0, ZERO.length);
252                     stream.write(CRLF, 0, CRLF.length);
253                     stream.write(ENDCHUNK, 0, ENDCHUNK.length);
254                 }
255             } catch (IOException ioe) {
256                 LOG.debug("Unexpected exception caught when closing output "
257                     + " stream", ioe);
258                 throw ioe;
259             } finally {
260                 // regardless of what happens, mark the stream as closed.
261                 // if there are errors closing it, there's not much we can do
262                 // about it
263                 closed = true;
264                 super.close();
265             }
266         }
267 
268     }
269 
270 }