• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18 
19 package org.eclipse.jetty.server;
20 
21 import java.io.IOException;
22 import java.io.Writer;
23 
24 import javax.servlet.ServletOutputStream;
25 
26 import org.eclipse.jetty.http.AbstractGenerator;
27 import org.eclipse.jetty.http.Generator;
28 import org.eclipse.jetty.io.Buffer;
29 import org.eclipse.jetty.io.ByteArrayBuffer;
30 import org.eclipse.jetty.io.EofException;
31 import org.eclipse.jetty.util.ByteArrayOutputStream2;
32 
33 /** Output.
34  *
35  * <p>
36  * Implements  {@link javax.servlet.ServletOutputStream} from the <code>javax.servlet</code> package.
37  * </p>
38  * A {@link ServletOutputStream} implementation that writes content
39  * to a {@link AbstractGenerator}.   The class is designed to be reused
40  * and can be reopened after a close.
41  */
42 public class HttpOutput extends ServletOutputStream
43 {
44     protected final AbstractHttpConnection _connection;
45     protected final AbstractGenerator _generator;
46     private boolean _closed;
47     private ByteArrayBuffer _onebyte;
48 
49     // These are held here for reuse by Writer
50     String _characterEncoding;
51     Writer _converter;
52     char[] _chars;
53     ByteArrayOutputStream2 _bytes;
54 
55     /* ------------------------------------------------------------ */
HttpOutput(AbstractHttpConnection connection)56     public HttpOutput(AbstractHttpConnection connection)
57     {
58         _connection=connection;
59         _generator=(AbstractGenerator)connection.getGenerator();
60     }
61 
62     /* ------------------------------------------------------------ */
getMaxIdleTime()63     public int getMaxIdleTime()
64     {
65         return _connection.getMaxIdleTime();
66     }
67 
68     /* ------------------------------------------------------------ */
isWritten()69     public boolean isWritten()
70     {
71         return _generator.getContentWritten()>0;
72     }
73 
74     /* ------------------------------------------------------------ */
75     /*
76      * @see java.io.OutputStream#close()
77      */
78     @Override
close()79     public void close() throws IOException
80     {
81         _closed=true;
82     }
83 
84     /* ------------------------------------------------------------ */
isClosed()85     public boolean isClosed()
86     {
87         return _closed;
88     }
89 
90     /* ------------------------------------------------------------ */
reopen()91     public void reopen()
92     {
93         _closed=false;
94     }
95 
96     /* ------------------------------------------------------------ */
97     @Override
flush()98     public void flush() throws IOException
99     {
100         _generator.flush(getMaxIdleTime());
101     }
102 
103     /* ------------------------------------------------------------ */
104     @Override
write(byte[] b, int off, int len)105     public void write(byte[] b, int off, int len) throws IOException
106     {
107         write(new ByteArrayBuffer(b,off,len));
108     }
109 
110     /* ------------------------------------------------------------ */
111     /*
112      * @see java.io.OutputStream#write(byte[])
113      */
114     @Override
write(byte[] b)115     public void write(byte[] b) throws IOException
116     {
117         write(new ByteArrayBuffer(b));
118     }
119 
120 
121     /* ------------------------------------------------------------ */
122     /*
123      * @see java.io.OutputStream#write(int)
124      */
125     @Override
write(int b)126     public void write(int b) throws IOException
127     {
128         if (_onebyte==null)
129             _onebyte=new ByteArrayBuffer(1);
130         else
131             _onebyte.clear();
132         _onebyte.put((byte)b);
133         write(_onebyte);
134     }
135 
136     /* ------------------------------------------------------------ */
write(Buffer buffer)137     private void write(Buffer buffer) throws IOException
138     {
139         if (_closed)
140             throw new IOException("Closed");
141         if (!_generator.isOpen())
142             throw new EofException();
143 
144         // Block until we can add _content.
145         while (_generator.isBufferFull())
146         {
147             _generator.blockForOutput(getMaxIdleTime());
148             if (_closed)
149                 throw new IOException("Closed");
150             if (!_generator.isOpen())
151                 throw new EofException();
152         }
153 
154         // Add the _content
155         _generator.addContent(buffer, Generator.MORE);
156 
157         // Have to flush and complete headers?
158 
159         if (_generator.isAllContentWritten())
160         {
161             flush();
162             close();
163         }
164         else if (_generator.isBufferFull())
165             _connection.commitResponse(Generator.MORE);
166 
167         // Block until our buffer is free
168         while (buffer.length() > 0 && _generator.isOpen())
169         {
170             _generator.blockForOutput(getMaxIdleTime());
171         }
172     }
173 
174     /* ------------------------------------------------------------ */
175     /*
176      * @see javax.servlet.ServletOutputStream#print(java.lang.String)
177      */
178     @Override
print(String s)179     public void print(String s) throws IOException
180     {
181         write(s.getBytes());
182     }
183 }
184