Mercurial Hosting > luan
comparison src/org/eclipse/jetty/http/AbstractGenerator.java @ 983:23ec25435b8c
simplify AbstractGenerator
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 16 Oct 2016 22:58:41 -0600 |
parents | dbecd7faa1f5 |
children | 8c13b9224cff |
comparison
equal
deleted
inserted
replaced
982:dbecd7faa1f5 | 983:23ec25435b8c |
---|---|
36 * Currently this class uses a system parameter "jetty.direct.writers" to control | 36 * Currently this class uses a system parameter "jetty.direct.writers" to control |
37 * two optional writer to byte conversions. buffer.writers=true will probably be | 37 * two optional writer to byte conversions. buffer.writers=true will probably be |
38 * faster, but will consume more memory. This option is just for testing and tuning. | 38 * faster, but will consume more memory. This option is just for testing and tuning. |
39 * | 39 * |
40 */ | 40 */ |
41 public abstract class AbstractGenerator | 41 abstract class AbstractGenerator |
42 { | 42 { |
43 private static final Logger LOG = LoggerFactory.getLogger(AbstractGenerator.class); | 43 private static final Logger LOG = LoggerFactory.getLogger(AbstractGenerator.class); |
44 | 44 |
45 public static final boolean LAST=true; | 45 public static final boolean LAST=true; |
46 public static final boolean MORE=false; | 46 public static final boolean MORE=false; |
47 | 47 |
48 // states | 48 // states |
49 public final static int STATE_HEADER = 0; | 49 final static int STATE_HEADER = 0; |
50 public final static int STATE_CONTENT = 2; | 50 final static int STATE_CONTENT = 2; |
51 public final static int STATE_FLUSHING = 3; | 51 final static int STATE_FLUSHING = 3; |
52 public final static int STATE_END = 4; | 52 final static int STATE_END = 4; |
53 | |
54 public static final byte[] NO_BYTES = {}; | |
55 | 53 |
56 // data | 54 // data |
57 | 55 |
58 protected final Buffers _buffers; // source of buffers | 56 final Buffers _buffers; // source of buffers |
59 protected final EndPoint _endp; | 57 final EndPoint _endp; |
60 | 58 |
61 protected int _state = STATE_HEADER; | 59 int _state = STATE_HEADER; |
62 | 60 |
63 protected int _status = 0; | 61 int _status = 0; |
64 protected int _version = HttpVersions.HTTP_1_1_ORDINAL; | 62 int _version = HttpVersions.HTTP_1_1_ORDINAL; |
65 protected Buffer _reason; | 63 Buffer _reason; |
66 protected Buffer _method; | 64 Buffer _method; |
67 protected String _uri; | 65 String _uri; |
68 | 66 |
69 protected long _contentWritten = 0; | 67 long _contentWritten = 0; |
70 protected long _contentLength = HttpTokens.UNKNOWN_CONTENT; | 68 long _contentLength = HttpTokens.UNKNOWN_CONTENT; |
71 protected boolean _last = false; | 69 boolean _last = false; |
72 protected boolean _head = false; | 70 boolean _head = false; |
73 protected boolean _noContent = false; | 71 boolean _noContent = false; |
74 protected Boolean _persistent = null; | 72 Boolean _persistent = null; |
75 | 73 |
76 protected Buffer _header; // Buffer for HTTP header (and maybe small _content) | 74 Buffer _header; // Buffer for HTTP header (and maybe small _content) |
77 protected Buffer _buffer; // Buffer for copy of passed _content | 75 Buffer _buffer; // Buffer for copy of passed _content |
78 protected Buffer _content; // Buffer passed to addContent | 76 Buffer _content; // Buffer passed to addContent |
79 | |
80 protected Buffer _date; | |
81 | 77 |
82 | 78 |
83 /* ------------------------------------------------------------------------------- */ | 79 /* ------------------------------------------------------------------------------- */ |
84 /** | 80 /** |
85 * Constructor. | 81 * Constructor. |
86 * | 82 * |
87 * @param buffers buffer pool | 83 * @param buffers buffer pool |
88 * @param io the end point | 84 * @param io the end point |
89 */ | 85 */ |
90 public AbstractGenerator(Buffers buffers, EndPoint io) | 86 AbstractGenerator(Buffers buffers, EndPoint io) |
91 { | 87 { |
92 this._buffers = buffers; | 88 this._buffers = buffers; |
93 this._endp = io; | 89 this._endp = io; |
94 } | 90 } |
95 | 91 |
104 * or if the buffers are full and cannot be flushed. | 100 * or if the buffers are full and cannot be flushed. |
105 * @throws IOException if there is a problem flushing the buffers. | 101 * @throws IOException if there is a problem flushing the buffers. |
106 */ | 102 */ |
107 public abstract void addContent(Buffer content, boolean last) throws IOException; | 103 public abstract void addContent(Buffer content, boolean last) throws IOException; |
108 | 104 |
109 /* ------------------------------------------------------------------------------- */ | 105 abstract boolean isRequest(); |
110 public abstract boolean isRequest(); | 106 |
111 | 107 public final boolean isOpen() |
112 /* ------------------------------------------------------------------------------- */ | |
113 public abstract boolean isResponse(); | |
114 | |
115 /* ------------------------------------------------------------------------------- */ | |
116 public boolean isOpen() | |
117 { | 108 { |
118 return _endp.isOpen(); | 109 return _endp.isOpen(); |
119 } | 110 } |
120 | 111 |
121 /* ------------------------------------------------------------------------------- */ | |
122 public void reset() | 112 public void reset() |
123 { | 113 { |
124 _state = STATE_HEADER; | 114 _state = STATE_HEADER; |
125 _status = 0; | 115 _status = 0; |
126 _version = HttpVersions.HTTP_1_1_ORDINAL; | 116 _version = HttpVersions.HTTP_1_1_ORDINAL; |
129 _head = false; | 119 _head = false; |
130 _noContent=false; | 120 _noContent=false; |
131 _persistent = null; | 121 _persistent = null; |
132 _contentWritten = 0; | 122 _contentWritten = 0; |
133 _contentLength = HttpTokens.UNKNOWN_CONTENT; | 123 _contentLength = HttpTokens.UNKNOWN_CONTENT; |
134 _date = null; | |
135 | 124 |
136 _content = null; | 125 _content = null; |
137 _method=null; | 126 _method = null; |
138 } | 127 } |
139 | 128 |
140 /* ------------------------------------------------------------------------------- */ | 129 public final void returnBuffers() |
141 public void returnBuffers() | |
142 { | 130 { |
143 if (_buffer!=null && _buffer.length()==0) | 131 if (_buffer!=null && _buffer.length()==0) |
144 { | 132 { |
145 _buffers.returnBuffer(_buffer); | 133 _buffers.returnBuffer(_buffer); |
146 _buffer=null; | 134 _buffer=null; |
151 _buffers.returnBuffer(_header); | 139 _buffers.returnBuffer(_header); |
152 _header=null; | 140 _header=null; |
153 } | 141 } |
154 } | 142 } |
155 | 143 |
156 /* ------------------------------------------------------------------------------- */ | 144 public final void resetBuffer() |
157 public void resetBuffer() | |
158 { | 145 { |
159 if(_state>=STATE_FLUSHING) | 146 if(_state>=STATE_FLUSHING) |
160 throw new IllegalStateException("Flushed"); | 147 throw new IllegalStateException("Flushed"); |
161 | 148 |
162 _last = false; | 149 _last = false; |
170 | 157 |
171 /* ------------------------------------------------------------ */ | 158 /* ------------------------------------------------------------ */ |
172 /** | 159 /** |
173 * @return Returns the contentBufferSize. | 160 * @return Returns the contentBufferSize. |
174 */ | 161 */ |
175 public int getContentBufferSize() | 162 public final int getContentBufferSize() |
176 { | 163 { |
177 if (_buffer==null) | 164 if (_buffer==null) |
178 _buffer=_buffers.getBuffer(); | 165 _buffer=_buffers.getBuffer(); |
179 return _buffer.capacity(); | 166 return _buffer.capacity(); |
180 } | 167 } |
181 | 168 |
182 /* ------------------------------------------------------------ */ | 169 public final Buffer getUncheckedBuffer() |
183 /** | |
184 * @param contentBufferSize The contentBufferSize to set. | |
185 */ | |
186 public void increaseContentBufferSize(int contentBufferSize) | |
187 { | |
188 if (_buffer==null) | |
189 _buffer=_buffers.getBuffer(); | |
190 if (contentBufferSize > _buffer.capacity()) | |
191 { | |
192 Buffer nb = _buffers.getBuffer(contentBufferSize); | |
193 nb.put(_buffer); | |
194 _buffers.returnBuffer(_buffer); | |
195 _buffer = nb; | |
196 } | |
197 } | |
198 | |
199 /* ------------------------------------------------------------ */ | |
200 public Buffer getUncheckedBuffer() | |
201 { | 170 { |
202 return _buffer; | 171 return _buffer; |
203 } | 172 } |
204 | 173 |
205 /* ------------------------------------------------------------ */ | 174 public final boolean isComplete() |
206 public int getState() | |
207 { | |
208 return _state; | |
209 } | |
210 | |
211 /* ------------------------------------------------------------ */ | |
212 public boolean isState(int state) | |
213 { | |
214 return _state == state; | |
215 } | |
216 | |
217 /* ------------------------------------------------------------ */ | |
218 public boolean isComplete() | |
219 { | 175 { |
220 return _state == STATE_END; | 176 return _state == STATE_END; |
221 } | 177 } |
222 | 178 |
223 /* ------------------------------------------------------------ */ | 179 public final boolean isIdle() |
224 public boolean isIdle() | |
225 { | 180 { |
226 return _state == STATE_HEADER && _method==null && _status==0; | 181 return _state == STATE_HEADER && _method==null && _status==0; |
227 } | 182 } |
228 | 183 |
229 /* ------------------------------------------------------------ */ | 184 public final boolean isCommitted() |
230 public boolean isCommitted() | |
231 { | 185 { |
232 return _state != STATE_HEADER; | 186 return _state != STATE_HEADER; |
233 } | 187 } |
234 | 188 |
235 /* ------------------------------------------------------------ */ | 189 public final void setContentLength(long value) |
236 /** | |
237 * @return Returns the head. | |
238 */ | |
239 public boolean isHead() | |
240 { | |
241 return _head; | |
242 } | |
243 | |
244 /* ------------------------------------------------------------ */ | |
245 public void setContentLength(long value) | |
246 { | 190 { |
247 if (value<0) | 191 if (value<0) |
248 _contentLength=HttpTokens.UNKNOWN_CONTENT; | 192 _contentLength=HttpTokens.UNKNOWN_CONTENT; |
249 else | 193 else |
250 _contentLength=value; | 194 _contentLength=value; |
251 } | 195 } |
252 | 196 |
253 /* ------------------------------------------------------------ */ | 197 public final void setHead(boolean head) |
254 /** | |
255 * @param head The head to set. | |
256 */ | |
257 public void setHead(boolean head) | |
258 { | 198 { |
259 _head = head; | 199 _head = head; |
260 } | 200 } |
261 | 201 |
262 /* ------------------------------------------------------------ */ | 202 /* ------------------------------------------------------------ */ |
263 /** | 203 /** |
264 * @return <code>false</code> if the connection should be closed after a request has been read, | 204 * @return <code>false</code> if the connection should be closed after a request has been read, |
265 * <code>true</code> if it should be used for additional requests. | 205 * <code>true</code> if it should be used for additional requests. |
266 */ | 206 */ |
267 public boolean isPersistent() | 207 public final boolean isPersistent() |
268 { | 208 { |
269 return _persistent!=null | 209 return _persistent!=null |
270 ?_persistent.booleanValue() | 210 ?_persistent.booleanValue() |
271 :(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL); | 211 :(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL); |
272 } | 212 } |
273 | 213 |
274 /* ------------------------------------------------------------ */ | 214 public final void setPersistent(boolean persistent) |
275 public void setPersistent(boolean persistent) | 215 { |
276 { | 216 _persistent = persistent; |
277 _persistent=persistent; | |
278 } | 217 } |
279 | 218 |
280 /* ------------------------------------------------------------ */ | 219 /* ------------------------------------------------------------ */ |
281 /** | 220 /** |
282 * @param version The version of the client the response is being sent to (NB. Not the version | 221 * @param version The version of the client the response is being sent to (NB. Not the version |
283 * in the response, which is the version of the server). | 222 * in the response, which is the version of the server). |
284 */ | 223 */ |
285 public void setVersion(int version) | 224 public final void setVersion(int version) |
286 { | 225 { |
287 if (_state != STATE_HEADER) | 226 if (_state != STATE_HEADER) |
288 throw new IllegalStateException("STATE!=START "+_state); | 227 throw new IllegalStateException("STATE!=START "+_state); |
289 _version = version; | 228 _version = version; |
290 if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null) | 229 if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null) |
291 _noContent=true; | 230 _noContent=true; |
292 } | 231 } |
293 | 232 |
294 public int getVersion() | |
295 { | |
296 return _version; | |
297 } | |
298 | |
299 public void setDate(Buffer timeStampBuffer) | |
300 { | |
301 _date=timeStampBuffer; | |
302 } | |
303 | |
304 /* ------------------------------------------------------------ */ | |
305 /** | |
306 */ | |
307 public void setRequest(String method, String uri) | |
308 { | |
309 if (method==null || HttpMethods.GET.equals(method) ) | |
310 _method=HttpMethods.GET_BUFFER; | |
311 else | |
312 _method=HttpMethods.CACHE.lookup(method); | |
313 _uri=uri; | |
314 if (_version==HttpVersions.HTTP_0_9_ORDINAL) | |
315 _noContent=true; | |
316 } | |
317 | |
318 /* ------------------------------------------------------------ */ | 233 /* ------------------------------------------------------------ */ |
319 /** | 234 /** |
320 * @param status The status code to send. | 235 * @param status The status code to send. |
321 * @param reason the status message to send. | 236 * @param reason the status message to send. |
322 */ | 237 */ |
323 public void setResponse(int status, String reason) | 238 public final void setResponse(int status, String reason) |
324 { | 239 { |
325 if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START"); | 240 if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START"); |
326 _method=null; | 241 _method=null; |
327 _status = status; | 242 _status = status; |
328 if (reason!=null) | 243 if (reason!=null) |
342 _reason.put((byte)' '); | 257 _reason.put((byte)' '); |
343 } | 258 } |
344 } | 259 } |
345 } | 260 } |
346 | 261 |
347 /* ------------------------------------------------------------ */ | 262 public final void completeUncheckedAddContent() |
348 /** Prepare buffer for unchecked writes. | |
349 * Prepare the generator buffer to receive unchecked writes | |
350 * @return the available space in the buffer. | |
351 * @throws IOException | |
352 */ | |
353 public abstract int prepareUncheckedAddContent() throws IOException; | |
354 | |
355 /* ------------------------------------------------------------ */ | |
356 void uncheckedAddContent(int b) | |
357 { | |
358 _buffer.put((byte)b); | |
359 } | |
360 | |
361 /* ------------------------------------------------------------ */ | |
362 public void completeUncheckedAddContent() | |
363 { | 263 { |
364 if (_noContent) | 264 if (_noContent) |
365 { | 265 { |
366 if(_buffer!=null) | 266 if(_buffer!=null) |
367 _buffer.clear(); | 267 _buffer.clear(); |
372 if (_head) | 272 if (_head) |
373 _buffer.clear(); | 273 _buffer.clear(); |
374 } | 274 } |
375 } | 275 } |
376 | 276 |
377 /* ------------------------------------------------------------ */ | |
378 public boolean isBufferFull() | 277 public boolean isBufferFull() |
379 { | 278 { |
380 if (_buffer != null && _buffer.space()==0) | 279 if (_buffer != null && _buffer.space()==0) |
381 { | 280 { |
382 if (_buffer.length()==0 && !_buffer.isImmutable()) | 281 if (_buffer.length()==0 && !_buffer.isImmutable()) |
385 } | 284 } |
386 | 285 |
387 return _content!=null && _content.length()>0; | 286 return _content!=null && _content.length()>0; |
388 } | 287 } |
389 | 288 |
390 /* ------------------------------------------------------------ */ | 289 public final boolean isWritten() |
391 public boolean isWritten() | |
392 { | 290 { |
393 return _contentWritten>0; | 291 return _contentWritten>0; |
394 } | 292 } |
395 | 293 |
396 /* ------------------------------------------------------------ */ | 294 public final boolean isAllContentWritten() |
397 public boolean isAllContentWritten() | |
398 { | 295 { |
399 return _contentLength>=0 && _contentWritten>=_contentLength; | 296 return _contentLength>=0 && _contentWritten>=_contentLength; |
400 } | 297 } |
401 | 298 |
402 /* ------------------------------------------------------------ */ | |
403 public abstract void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException; | 299 public abstract void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException; |
404 | 300 |
405 /* ------------------------------------------------------------ */ | 301 /* ------------------------------------------------------------ */ |
406 /** | 302 /** |
407 * Complete the message. | 303 * Complete the message. |
421 LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength); | 317 LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength); |
422 _persistent = false; | 318 _persistent = false; |
423 } | 319 } |
424 } | 320 } |
425 | 321 |
426 /* ------------------------------------------------------------ */ | |
427 public abstract int flushBuffer() throws IOException; | 322 public abstract int flushBuffer() throws IOException; |
428 | 323 |
429 | 324 |
430 /* ------------------------------------------------------------ */ | 325 public final void flush(long maxIdleTime) throws IOException |
431 public void flush(long maxIdleTime) throws IOException | |
432 { | 326 { |
433 // block until everything is flushed | 327 // block until everything is flushed |
434 long now=System.currentTimeMillis(); | 328 long now=System.currentTimeMillis(); |
435 long end=now+maxIdleTime; | 329 long end=now+maxIdleTime; |
436 Buffer content = _content; | 330 Buffer content = _content; |
456 * @param reason The error reason | 350 * @param reason The error reason |
457 * @param content Contents of the error page | 351 * @param content Contents of the error page |
458 * @param close True if the connection should be closed | 352 * @param close True if the connection should be closed |
459 * @throws IOException if there is a problem flushing the response | 353 * @throws IOException if there is a problem flushing the response |
460 */ | 354 */ |
461 public void sendError(int code, String reason, String content, boolean close) throws IOException | 355 public final void sendError(int code, String reason, String content, boolean close) throws IOException |
462 { | 356 { |
463 if (close) | 357 if (close) |
464 _persistent=false; | 358 _persistent=false; |
465 if (isCommitted()) | 359 if (isCommitted()) |
466 { | 360 { |
486 } | 380 } |
487 complete(); | 381 complete(); |
488 } | 382 } |
489 } | 383 } |
490 | 384 |
491 /* ------------------------------------------------------------ */ | 385 public final long getContentWritten() |
492 /** | |
493 * @return Returns the contentWritten. | |
494 */ | |
495 public long getContentWritten() | |
496 { | 386 { |
497 return _contentWritten; | 387 return _contentWritten; |
498 } | 388 } |
499 | 389 |
500 | 390 |
501 | 391 public final void blockForOutput(long maxIdleTime) throws IOException |
502 /* ------------------------------------------------------------ */ | |
503 public void blockForOutput(long maxIdleTime) throws IOException | |
504 { | 392 { |
505 if (_endp.isBlocking()) | 393 if (_endp.isBlocking()) |
506 { | 394 { |
507 try | 395 try |
508 { | 396 { |