1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.nested;
14
15 import java.io.IOException;
16
17 import javax.servlet.http.HttpServletResponse;
18
19 import org.eclipse.jetty.http.AbstractGenerator;
20 import org.eclipse.jetty.http.HttpFields;
21 import org.eclipse.jetty.http.HttpHeaders;
22 import org.eclipse.jetty.http.HttpVersions;
23 import org.eclipse.jetty.io.Buffer;
24 import org.eclipse.jetty.io.Buffers;
25 import org.eclipse.jetty.io.EndPoint;
26 import org.eclipse.jetty.server.Server;
27 import org.eclipse.jetty.util.log.Log;
28
29 public class NestedGenerator extends AbstractGenerator
30 {
31 final HttpServletResponse _response;
32 final String _nestedIn;
33
34 public NestedGenerator(Buffers buffers, EndPoint io, HttpServletResponse response, String nestedIn)
35 {
36 super(buffers,io);
37 _response=response;
38 _nestedIn=nestedIn;
39 }
40
41 public void addContent(Buffer content, boolean last) throws IOException
42 {
43
44 if (_noContent)
45 {
46 content.clear();
47 return;
48 }
49
50 if (content.isImmutable())
51 throw new IllegalArgumentException("immutable");
52
53 if (_last || _state == STATE_END)
54 {
55 Log.debug("Ignoring extra content {}", content);
56 content.clear();
57 return;
58 }
59 _last = last;
60
61 if(!_endp.isOpen())
62 {
63 _state = STATE_END;
64 return;
65 }
66
67
68 if (_content != null && _content.length() > 0)
69 {
70
71 flushBuffer();
72 if (_content != null && _content.length() > 0)
73 throw new IllegalStateException("FULL");
74 }
75
76 _content = content;
77
78 _contentWritten += content.length();
79
80
81 if (_head)
82 {
83 content.clear();
84 _content = null;
85 }
86 else
87 {
88
89 initContent();
90
91 int len = 0;
92 len = _buffer.put(_content);
93
94
95 if (len > 0 && _buffer.space() == 0)
96 {
97 len--;
98 _buffer.setPutIndex(_buffer.putIndex() - 1);
99 }
100
101 _content.skip(len);
102
103 if (_content.length() == 0)
104 _content = null;
105 }
106 }
107
108 public boolean addContent(byte b) throws IOException
109 {
110
111 if (_noContent)
112 return false;
113
114 if (_last || _state == STATE_END)
115 throw new IllegalStateException("Closed");
116
117
118 if(!_endp.isOpen())
119 {
120 _state = STATE_END;
121 return false;
122 }
123
124
125 if (_content != null && _content.length() > 0)
126 {
127 flushBuffer();
128 if (_content != null && _content.length() > 0)
129 throw new IllegalStateException("FULL");
130 }
131
132 _contentWritten++;
133
134
135 if (_head)
136 return false;
137
138
139 initContent();
140
141
142
143 _buffer.put(b);
144
145 return _buffer.space() <= 1;
146 }
147
148
149 private void initContent() throws IOException
150 {
151 if (_buffer == null)
152 {
153
154 _buffer = _buffers.getBuffer();
155 }
156 }
157
158
159 @Override
160 public boolean isRequest()
161 {
162 return false;
163 }
164
165
166 @Override
167 public boolean isResponse()
168 {
169 return true;
170 }
171
172
173 @Override
174 public int prepareUncheckedAddContent() throws IOException
175 {
176 initContent();
177 return _buffer.space();
178 }
179
180
181 @Override
182 public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
183 {
184 if (Log.isDebugEnabled())
185 Log.debug("completeHeader: {}",fields.toString().trim().replace("\r\n","|"));
186 if (_state != STATE_HEADER)
187 return;
188
189 if (_last && !allContentAdded)
190 throw new IllegalStateException("last?");
191 _last = _last | allContentAdded;
192
193 if (_persistent==null)
194 _persistent=(_version > HttpVersions.HTTP_1_0_ORDINAL);
195
196
197 if (_reason == null)
198 _response.setStatus(_status);
199 else
200 _response.setStatus(_status,_reason.toString());
201
202 if (_status == 100 || _status == 204 || _status == 304)
203 {
204 _noContent = true;
205 _content = null;
206 }
207
208
209 boolean has_server = false;
210 if (fields != null)
211 {
212
213 int s=fields.size();
214 for (int f=0;f<s;f++)
215 {
216 HttpFields.Field field = fields.getField(f);
217 if (field==null)
218 continue;
219 _response.setHeader(field.getName(),field.getValue());
220 }
221 }
222
223 if (!has_server && _status > 100 && getSendServerVersion())
224 _response.setHeader(HttpHeaders.SERVER,"Jetty("+Server.getVersion()+",nested in "+_nestedIn+")");
225
226 _state = STATE_CONTENT;
227 }
228
229
230 @Override
231 public long flushBuffer() throws IOException
232 {
233 if (_state == STATE_HEADER)
234 throw new IllegalStateException("State==HEADER");
235
236
237 if (_content != null && _content.length() < _buffer.space() && _state != STATE_FLUSHING)
238 {
239 initContent();
240 _buffer.put(_content);
241 _content.clear();
242 _content = null;
243 }
244
245 if (_buffer==null)
246 return 0;
247
248 int size=_buffer.length();
249 int len = _buffer==null?0:_endp.flush(_buffer);
250 Log.debug("flushBuffer {} of {}",len,size);
251 if (len>0)
252 _buffer.skip(len);
253
254 return len;
255 }
256
257 }