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 {