Mercurial Hosting > luan
comparison src/org/eclipse/jetty/http/AbstractGenerator.java @ 877:fef4392f4905
remove sendServerVersion
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 04 Oct 2016 14:36:51 -0600 |
parents | 8e9db0bbf4f9 |
children | dbecd7faa1f5 |
comparison
equal
deleted
inserted
replaced
876:2efdb98f3543 | 877:fef4392f4905 |
---|---|
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 implements Generator | 41 public abstract class AbstractGenerator implements Generator |
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 // states | 45 // states |
46 public final static int STATE_HEADER = 0; | 46 public final static int STATE_HEADER = 0; |
47 public final static int STATE_CONTENT = 2; | 47 public final static int STATE_CONTENT = 2; |
48 public final static int STATE_FLUSHING = 3; | 48 public final static int STATE_FLUSHING = 3; |
49 public final static int STATE_END = 4; | 49 public final static int STATE_END = 4; |
50 | 50 |
51 public static final byte[] NO_BYTES = {}; | 51 public static final byte[] NO_BYTES = {}; |
52 | 52 |
53 // data | 53 // data |
54 | 54 |
55 protected final Buffers _buffers; // source of buffers | 55 protected final Buffers _buffers; // source of buffers |
56 protected final EndPoint _endp; | 56 protected final EndPoint _endp; |
57 | 57 |
58 protected int _state = STATE_HEADER; | 58 protected int _state = STATE_HEADER; |
59 | 59 |
60 protected int _status = 0; | 60 protected int _status = 0; |
61 protected int _version = HttpVersions.HTTP_1_1_ORDINAL; | 61 protected int _version = HttpVersions.HTTP_1_1_ORDINAL; |
62 protected Buffer _reason; | 62 protected Buffer _reason; |
63 protected Buffer _method; | 63 protected Buffer _method; |
64 protected String _uri; | 64 protected String _uri; |
65 | 65 |
66 protected long _contentWritten = 0; | 66 protected long _contentWritten = 0; |
67 protected long _contentLength = HttpTokens.UNKNOWN_CONTENT; | 67 protected long _contentLength = HttpTokens.UNKNOWN_CONTENT; |
68 protected boolean _last = false; | 68 protected boolean _last = false; |
69 protected boolean _head = false; | 69 protected boolean _head = false; |
70 protected boolean _noContent = false; | 70 protected boolean _noContent = false; |
71 protected Boolean _persistent = null; | 71 protected Boolean _persistent = null; |
72 | 72 |
73 protected Buffer _header; // Buffer for HTTP header (and maybe small _content) | 73 protected Buffer _header; // Buffer for HTTP header (and maybe small _content) |
74 protected Buffer _buffer; // Buffer for copy of passed _content | 74 protected Buffer _buffer; // Buffer for copy of passed _content |
75 protected Buffer _content; // Buffer passed to addContent | 75 protected Buffer _content; // Buffer passed to addContent |
76 | 76 |
77 protected Buffer _date; | 77 protected Buffer _date; |
78 | 78 |
79 private boolean _sendServerVersion; | 79 |
80 | 80 /* ------------------------------------------------------------------------------- */ |
81 | 81 /** |
82 /* ------------------------------------------------------------------------------- */ | 82 * Constructor. |
83 /** | 83 * |
84 * Constructor. | 84 * @param buffers buffer pool |
85 * | 85 * @param io the end point |
86 * @param buffers buffer pool | 86 */ |
87 * @param io the end point | 87 public AbstractGenerator(Buffers buffers, EndPoint io) |
88 */ | 88 { |
89 public AbstractGenerator(Buffers buffers, EndPoint io) | 89 this._buffers = buffers; |
90 { | 90 this._endp = io; |
91 this._buffers = buffers; | 91 } |
92 this._endp = io; | 92 |
93 } | 93 /* ------------------------------------------------------------------------------- */ |
94 | 94 public abstract boolean isRequest(); |
95 /* ------------------------------------------------------------------------------- */ | 95 |
96 public abstract boolean isRequest(); | 96 /* ------------------------------------------------------------------------------- */ |
97 | 97 public abstract boolean isResponse(); |
98 /* ------------------------------------------------------------------------------- */ | 98 |
99 public abstract boolean isResponse(); | 99 /* ------------------------------------------------------------------------------- */ |
100 | 100 public boolean isOpen() |
101 /* ------------------------------------------------------------------------------- */ | 101 { |
102 public boolean isOpen() | 102 return _endp.isOpen(); |
103 { | 103 } |
104 return _endp.isOpen(); | 104 |
105 } | 105 /* ------------------------------------------------------------------------------- */ |
106 | 106 public void reset() |
107 /* ------------------------------------------------------------------------------- */ | 107 { |
108 public void reset() | 108 _state = STATE_HEADER; |
109 { | 109 _status = 0; |
110 _state = STATE_HEADER; | 110 _version = HttpVersions.HTTP_1_1_ORDINAL; |
111 _status = 0; | 111 _reason = null; |
112 _version = HttpVersions.HTTP_1_1_ORDINAL; | 112 _last = false; |
113 _reason = null; | 113 _head = false; |
114 _last = false; | 114 _noContent=false; |
115 _head = false; | 115 _persistent = null; |
116 _noContent=false; | 116 _contentWritten = 0; |
117 _persistent = null; | 117 _contentLength = HttpTokens.UNKNOWN_CONTENT; |
118 _contentWritten = 0; | 118 _date = null; |
119 _contentLength = HttpTokens.UNKNOWN_CONTENT; | 119 |
120 _date = null; | 120 _content = null; |
121 | 121 _method=null; |
122 _content = null; | 122 } |
123 _method=null; | 123 |
124 } | 124 /* ------------------------------------------------------------------------------- */ |
125 | 125 public void returnBuffers() |
126 /* ------------------------------------------------------------------------------- */ | 126 { |
127 public void returnBuffers() | 127 if (_buffer!=null && _buffer.length()==0) |
128 { | 128 { |
129 if (_buffer!=null && _buffer.length()==0) | 129 _buffers.returnBuffer(_buffer); |
130 { | 130 _buffer=null; |
131 _buffers.returnBuffer(_buffer); | 131 } |
132 _buffer=null; | 132 |
133 } | 133 if (_header!=null && _header.length()==0) |
134 | 134 { |
135 if (_header!=null && _header.length()==0) | 135 _buffers.returnBuffer(_header); |
136 { | 136 _header=null; |
137 _buffers.returnBuffer(_header); | 137 } |
138 _header=null; | 138 } |
139 } | 139 |
140 } | 140 /* ------------------------------------------------------------------------------- */ |
141 | 141 public void resetBuffer() |
142 /* ------------------------------------------------------------------------------- */ | 142 { |
143 public void resetBuffer() | 143 if(_state>=STATE_FLUSHING) |
144 { | 144 throw new IllegalStateException("Flushed"); |
145 if(_state>=STATE_FLUSHING) | 145 |
146 throw new IllegalStateException("Flushed"); | 146 _last = false; |
147 | 147 _persistent=null; |
148 _last = false; | 148 _contentWritten = 0; |
149 _persistent=null; | 149 _contentLength = HttpTokens.UNKNOWN_CONTENT; |
150 _contentWritten = 0; | 150 _content=null; |
151 _contentLength = HttpTokens.UNKNOWN_CONTENT; | 151 if (_buffer!=null) |
152 _content=null; | 152 _buffer.clear(); |
153 if (_buffer!=null) | 153 } |
154 _buffer.clear(); | 154 |
155 } | 155 /* ------------------------------------------------------------ */ |
156 | 156 /** |
157 /* ------------------------------------------------------------ */ | 157 * @return Returns the contentBufferSize. |
158 /** | 158 */ |
159 * @return Returns the contentBufferSize. | 159 public int getContentBufferSize() |
160 */ | 160 { |
161 public int getContentBufferSize() | 161 if (_buffer==null) |
162 { | 162 _buffer=_buffers.getBuffer(); |
163 if (_buffer==null) | 163 return _buffer.capacity(); |
164 _buffer=_buffers.getBuffer(); | 164 } |
165 return _buffer.capacity(); | 165 |
166 } | 166 /* ------------------------------------------------------------ */ |
167 | 167 /** |
168 /* ------------------------------------------------------------ */ | 168 * @param contentBufferSize The contentBufferSize to set. |
169 /** | 169 */ |
170 * @param contentBufferSize The contentBufferSize to set. | 170 public void increaseContentBufferSize(int contentBufferSize) |
171 */ | 171 { |
172 public void increaseContentBufferSize(int contentBufferSize) | 172 if (_buffer==null) |
173 { | 173 _buffer=_buffers.getBuffer(); |
174 if (_buffer==null) | 174 if (contentBufferSize > _buffer.capacity()) |
175 _buffer=_buffers.getBuffer(); | 175 { |
176 if (contentBufferSize > _buffer.capacity()) | 176 Buffer nb = _buffers.getBuffer(contentBufferSize); |
177 { | 177 nb.put(_buffer); |
178 Buffer nb = _buffers.getBuffer(contentBufferSize); | 178 _buffers.returnBuffer(_buffer); |
179 nb.put(_buffer); | 179 _buffer = nb; |
180 _buffers.returnBuffer(_buffer); | 180 } |
181 _buffer = nb; | 181 } |
182 } | 182 |
183 } | 183 /* ------------------------------------------------------------ */ |
184 | 184 public Buffer getUncheckedBuffer() |
185 /* ------------------------------------------------------------ */ | 185 { |
186 public Buffer getUncheckedBuffer() | 186 return _buffer; |
187 { | 187 } |
188 return _buffer; | 188 |
189 } | 189 /* ------------------------------------------------------------ */ |
190 | 190 public int getState() |
191 /* ------------------------------------------------------------ */ | 191 { |
192 public boolean getSendServerVersion () | 192 return _state; |
193 { | 193 } |
194 return _sendServerVersion; | 194 |
195 } | 195 /* ------------------------------------------------------------ */ |
196 | 196 public boolean isState(int state) |
197 /* ------------------------------------------------------------ */ | 197 { |
198 public void setSendServerVersion (boolean sendServerVersion) | 198 return _state == state; |
199 { | 199 } |
200 _sendServerVersion = sendServerVersion; | 200 |
201 } | 201 /* ------------------------------------------------------------ */ |
202 | 202 public boolean isComplete() |
203 /* ------------------------------------------------------------ */ | 203 { |
204 public int getState() | 204 return _state == STATE_END; |
205 { | 205 } |
206 return _state; | 206 |
207 } | 207 /* ------------------------------------------------------------ */ |
208 | 208 public boolean isIdle() |
209 /* ------------------------------------------------------------ */ | 209 { |
210 public boolean isState(int state) | 210 return _state == STATE_HEADER && _method==null && _status==0; |
211 { | 211 } |
212 return _state == state; | 212 |
213 } | 213 /* ------------------------------------------------------------ */ |
214 | 214 public boolean isCommitted() |
215 /* ------------------------------------------------------------ */ | 215 { |
216 public boolean isComplete() | 216 return _state != STATE_HEADER; |
217 { | 217 } |
218 return _state == STATE_END; | 218 |
219 } | 219 /* ------------------------------------------------------------ */ |
220 | 220 /** |
221 /* ------------------------------------------------------------ */ | 221 * @return Returns the head. |
222 public boolean isIdle() | 222 */ |
223 { | 223 public boolean isHead() |
224 return _state == STATE_HEADER && _method==null && _status==0; | 224 { |
225 } | 225 return _head; |
226 | 226 } |
227 /* ------------------------------------------------------------ */ | 227 |
228 public boolean isCommitted() | 228 /* ------------------------------------------------------------ */ |
229 { | 229 public void setContentLength(long value) |
230 return _state != STATE_HEADER; | 230 { |
231 } | 231 if (value<0) |
232 | 232 _contentLength=HttpTokens.UNKNOWN_CONTENT; |
233 /* ------------------------------------------------------------ */ | 233 else |
234 /** | 234 _contentLength=value; |
235 * @return Returns the head. | 235 } |
236 */ | 236 |
237 public boolean isHead() | 237 /* ------------------------------------------------------------ */ |
238 { | 238 /** |
239 return _head; | 239 * @param head The head to set. |
240 } | 240 */ |
241 | 241 public void setHead(boolean head) |
242 /* ------------------------------------------------------------ */ | 242 { |
243 public void setContentLength(long value) | 243 _head = head; |
244 { | 244 } |
245 if (value<0) | 245 |
246 _contentLength=HttpTokens.UNKNOWN_CONTENT; | 246 /* ------------------------------------------------------------ */ |
247 else | 247 /** |
248 _contentLength=value; | 248 * @return <code>false</code> if the connection should be closed after a request has been read, |
249 } | 249 * <code>true</code> if it should be used for additional requests. |
250 | 250 */ |
251 /* ------------------------------------------------------------ */ | 251 public boolean isPersistent() |
252 /** | 252 { |
253 * @param head The head to set. | 253 return _persistent!=null |
254 */ | 254 ?_persistent.booleanValue() |
255 public void setHead(boolean head) | 255 :(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL); |
256 { | 256 } |
257 _head = head; | 257 |
258 } | 258 /* ------------------------------------------------------------ */ |
259 | 259 public void setPersistent(boolean persistent) |
260 /* ------------------------------------------------------------ */ | 260 { |
261 /** | 261 _persistent=persistent; |
262 * @return <code>false</code> if the connection should be closed after a request has been read, | 262 } |
263 * <code>true</code> if it should be used for additional requests. | 263 |
264 */ | 264 /* ------------------------------------------------------------ */ |
265 public boolean isPersistent() | 265 /** |
266 { | 266 * @param version The version of the client the response is being sent to (NB. Not the version |
267 return _persistent!=null | 267 * in the response, which is the version of the server). |
268 ?_persistent.booleanValue() | 268 */ |
269 :(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL); | 269 public void setVersion(int version) |
270 } | 270 { |
271 | 271 if (_state != STATE_HEADER) |
272 /* ------------------------------------------------------------ */ | 272 throw new IllegalStateException("STATE!=START "+_state); |
273 public void setPersistent(boolean persistent) | 273 _version = version; |
274 { | 274 if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null) |
275 _persistent=persistent; | 275 _noContent=true; |
276 } | 276 } |
277 | 277 |
278 /* ------------------------------------------------------------ */ | 278 /* ------------------------------------------------------------ */ |
279 /** | 279 public int getVersion() |
280 * @param version The version of the client the response is being sent to (NB. Not the version | 280 { |
281 * in the response, which is the version of the server). | 281 return _version; |
282 */ | 282 } |
283 public void setVersion(int version) | 283 |
284 { | 284 /* ------------------------------------------------------------ */ |
285 if (_state != STATE_HEADER) | 285 /** |
286 throw new IllegalStateException("STATE!=START "+_state); | 286 * @see org.eclipse.jetty.http.Generator#setDate(org.eclipse.jetty.io.Buffer) |
287 _version = version; | 287 */ |
288 if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null) | 288 public void setDate(Buffer timeStampBuffer) |
289 _noContent=true; | 289 { |
290 } | 290 _date=timeStampBuffer; |
291 | 291 } |
292 /* ------------------------------------------------------------ */ | 292 |
293 public int getVersion() | 293 /* ------------------------------------------------------------ */ |
294 { | 294 /** |
295 return _version; | 295 */ |
296 } | 296 public void setRequest(String method, String uri) |
297 | 297 { |
298 /* ------------------------------------------------------------ */ | 298 if (method==null || HttpMethods.GET.equals(method) ) |
299 /** | 299 _method=HttpMethods.GET_BUFFER; |
300 * @see org.eclipse.jetty.http.Generator#setDate(org.eclipse.jetty.io.Buffer) | 300 else |
301 */ | 301 _method=HttpMethods.CACHE.lookup(method); |
302 public void setDate(Buffer timeStampBuffer) | 302 _uri=uri; |
303 { | 303 if (_version==HttpVersions.HTTP_0_9_ORDINAL) |
304 _date=timeStampBuffer; | 304 _noContent=true; |
305 } | 305 } |
306 | 306 |
307 /* ------------------------------------------------------------ */ | 307 /* ------------------------------------------------------------ */ |
308 /** | 308 /** |
309 */ | 309 * @param status The status code to send. |
310 public void setRequest(String method, String uri) | 310 * @param reason the status message to send. |
311 { | 311 */ |
312 if (method==null || HttpMethods.GET.equals(method) ) | 312 public void setResponse(int status, String reason) |
313 _method=HttpMethods.GET_BUFFER; | 313 { |
314 else | 314 if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START"); |
315 _method=HttpMethods.CACHE.lookup(method); | 315 _method=null; |
316 _uri=uri; | 316 _status = status; |
317 if (_version==HttpVersions.HTTP_0_9_ORDINAL) | 317 if (reason!=null) |
318 _noContent=true; | 318 { |
319 } | 319 int len=reason.length(); |
320 | 320 |
321 /* ------------------------------------------------------------ */ | 321 // TODO don't hard code |
322 /** | 322 if (len>1024) |
323 * @param status The status code to send. | 323 len=1024; |
324 * @param reason the status message to send. | 324 _reason=new ByteArrayBuffer(len); |
325 */ | 325 for (int i=0;i<len;i++) |
326 public void setResponse(int status, String reason) | 326 { |
327 { | 327 char ch = reason.charAt(i); |
328 if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START"); | 328 if (ch!='\r'&&ch!='\n') |
329 _method=null; | 329 _reason.put((byte)ch); |
330 _status = status; | 330 else |
331 if (reason!=null) | 331 _reason.put((byte)' '); |
332 { | 332 } |
333 int len=reason.length(); | 333 } |
334 | 334 } |
335 // TODO don't hard code | 335 |
336 if (len>1024) | 336 /* ------------------------------------------------------------ */ |
337 len=1024; | 337 /** Prepare buffer for unchecked writes. |
338 _reason=new ByteArrayBuffer(len); | 338 * Prepare the generator buffer to receive unchecked writes |
339 for (int i=0;i<len;i++) | 339 * @return the available space in the buffer. |
340 { | 340 * @throws IOException |
341 char ch = reason.charAt(i); | 341 */ |
342 if (ch!='\r'&&ch!='\n') | 342 public abstract int prepareUncheckedAddContent() throws IOException; |
343 _reason.put((byte)ch); | 343 |
344 else | 344 /* ------------------------------------------------------------ */ |
345 _reason.put((byte)' '); | 345 void uncheckedAddContent(int b) |
346 } | 346 { |
347 } | 347 _buffer.put((byte)b); |
348 } | 348 } |
349 | 349 |
350 /* ------------------------------------------------------------ */ | 350 /* ------------------------------------------------------------ */ |
351 /** Prepare buffer for unchecked writes. | 351 public void completeUncheckedAddContent() |
352 * Prepare the generator buffer to receive unchecked writes | 352 { |
353 * @return the available space in the buffer. | 353 if (_noContent) |
354 * @throws IOException | 354 { |
355 */ | 355 if(_buffer!=null) |
356 public abstract int prepareUncheckedAddContent() throws IOException; | 356 _buffer.clear(); |
357 | 357 } |
358 /* ------------------------------------------------------------ */ | 358 else |
359 void uncheckedAddContent(int b) | 359 { |
360 { | 360 _contentWritten+=_buffer.length(); |
361 _buffer.put((byte)b); | 361 if (_head) |
362 } | 362 _buffer.clear(); |
363 | 363 } |
364 /* ------------------------------------------------------------ */ | 364 } |
365 public void completeUncheckedAddContent() | 365 |
366 { | 366 /* ------------------------------------------------------------ */ |
367 if (_noContent) | 367 public boolean isBufferFull() |
368 { | 368 { |
369 if(_buffer!=null) | 369 if (_buffer != null && _buffer.space()==0) |
370 _buffer.clear(); | 370 { |
371 } | 371 if (_buffer.length()==0 && !_buffer.isImmutable()) |
372 else | 372 _buffer.compact(); |
373 { | 373 return _buffer.space()==0; |
374 _contentWritten+=_buffer.length(); | 374 } |
375 if (_head) | 375 |
376 _buffer.clear(); | 376 return _content!=null && _content.length()>0; |
377 } | 377 } |
378 } | 378 |
379 | 379 /* ------------------------------------------------------------ */ |
380 /* ------------------------------------------------------------ */ | 380 public boolean isWritten() |
381 public boolean isBufferFull() | 381 { |
382 { | 382 return _contentWritten>0; |
383 if (_buffer != null && _buffer.space()==0) | 383 } |
384 { | 384 |
385 if (_buffer.length()==0 && !_buffer.isImmutable()) | 385 /* ------------------------------------------------------------ */ |
386 _buffer.compact(); | 386 public boolean isAllContentWritten() |
387 return _buffer.space()==0; | 387 { |
388 } | 388 return _contentLength>=0 && _contentWritten>=_contentLength; |
389 | 389 } |
390 return _content!=null && _content.length()>0; | 390 |
391 } | 391 /* ------------------------------------------------------------ */ |
392 | 392 public abstract void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException; |
393 /* ------------------------------------------------------------ */ | 393 |
394 public boolean isWritten() | 394 /* ------------------------------------------------------------ */ |
395 { | 395 /** |
396 return _contentWritten>0; | 396 * Complete the message. |
397 } | 397 * |
398 | 398 * @throws IOException |
399 /* ------------------------------------------------------------ */ | 399 */ |
400 public boolean isAllContentWritten() | 400 public void complete() throws IOException |
401 { | 401 { |
402 return _contentLength>=0 && _contentWritten>=_contentLength; | 402 if (_state == STATE_HEADER) |
403 } | 403 { |
404 | 404 throw new IllegalStateException("State==HEADER"); |
405 /* ------------------------------------------------------------ */ | 405 } |
406 public abstract void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException; | 406 |
407 | 407 if (_contentLength >= 0 && _contentLength != _contentWritten && !_head) |
408 /* ------------------------------------------------------------ */ | 408 { |
409 /** | 409 if (LOG.isDebugEnabled()) |
410 * Complete the message. | 410 LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength); |
411 * | 411 _persistent = false; |
412 * @throws IOException | 412 } |
413 */ | 413 } |
414 public void complete() throws IOException | 414 |
415 { | 415 /* ------------------------------------------------------------ */ |
416 if (_state == STATE_HEADER) | 416 public abstract int flushBuffer() throws IOException; |
417 { | 417 |
418 throw new IllegalStateException("State==HEADER"); | 418 |
419 } | 419 /* ------------------------------------------------------------ */ |
420 | 420 public void flush(long maxIdleTime) throws IOException |
421 if (_contentLength >= 0 && _contentLength != _contentWritten && !_head) | 421 { |
422 { | 422 // block until everything is flushed |
423 if (LOG.isDebugEnabled()) | 423 long now=System.currentTimeMillis(); |
424 LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength); | 424 long end=now+maxIdleTime; |
425 _persistent = false; | 425 Buffer content = _content; |
426 } | 426 Buffer buffer = _buffer; |
427 } | 427 if (content!=null && content.length()>0 || buffer!=null && buffer.length()>0 || isBufferFull()) |
428 | 428 { |
429 /* ------------------------------------------------------------ */ | 429 flushBuffer(); |
430 public abstract int flushBuffer() throws IOException; | 430 |
431 | 431 while (now<end && (content!=null && content.length()>0 ||buffer!=null && buffer.length()>0) && _endp.isOpen()&& !_endp.isOutputShutdown()) |
432 | 432 { |
433 /* ------------------------------------------------------------ */ | 433 blockForOutput(end-now); |
434 public void flush(long maxIdleTime) throws IOException | 434 now=System.currentTimeMillis(); |
435 { | 435 } |
436 // block until everything is flushed | 436 } |
437 long now=System.currentTimeMillis(); | 437 } |
438 long end=now+maxIdleTime; | 438 |
439 Buffer content = _content; | 439 /* ------------------------------------------------------------ */ |
440 Buffer buffer = _buffer; | 440 /** |
441 if (content!=null && content.length()>0 || buffer!=null && buffer.length()>0 || isBufferFull()) | 441 * Utility method to send an error response. If the builder is not committed, this call is |
442 { | 442 * equivalent to a setResponse, addContent and complete call. |
443 flushBuffer(); | 443 * |
444 | 444 * @param code The error code |
445 while (now<end && (content!=null && content.length()>0 ||buffer!=null && buffer.length()>0) && _endp.isOpen()&& !_endp.isOutputShutdown()) | 445 * @param reason The error reason |
446 { | 446 * @param content Contents of the error page |
447 blockForOutput(end-now); | 447 * @param close True if the connection should be closed |
448 now=System.currentTimeMillis(); | 448 * @throws IOException if there is a problem flushing the response |
449 } | 449 */ |
450 } | 450 public void sendError(int code, String reason, String content, boolean close) throws IOException |
451 } | 451 { |
452 | 452 if (close) |
453 /* ------------------------------------------------------------ */ | 453 _persistent=false; |
454 /** | 454 if (isCommitted()) |
455 * Utility method to send an error response. If the builder is not committed, this call is | 455 { |
456 * equivalent to a setResponse, addContent and complete call. | 456 LOG.debug("sendError on committed: {} {}",code,reason); |
457 * | 457 } |
458 * @param code The error code | 458 else |
459 * @param reason The error reason | 459 { |
460 * @param content Contents of the error page | 460 LOG.debug("sendError: {} {}",code,reason); |
461 * @param close True if the connection should be closed | 461 setResponse(code, reason); |
462 * @throws IOException if there is a problem flushing the response | 462 if (content != null) |
463 */ | 463 { |
464 public void sendError(int code, String reason, String content, boolean close) throws IOException | 464 completeHeader(null, false); |
465 { | 465 addContent(new View(new ByteArrayBuffer(content)), Generator.LAST); |
466 if (close) | 466 } |
467 _persistent=false; | 467 else if (code>=400) |
468 if (isCommitted()) | 468 { |
469 { | 469 completeHeader(null, false); |
470 LOG.debug("sendError on committed: {} {}",code,reason); | 470 addContent(new View(new ByteArrayBuffer("Error: "+(reason==null?(""+code):reason))), Generator.LAST); |
471 } | 471 } |
472 else | 472 else |
473 { | 473 { |
474 LOG.debug("sendError: {} {}",code,reason); | 474 completeHeader(null, true); |
475 setResponse(code, reason); | 475 } |
476 if (content != null) | 476 complete(); |
477 { | 477 } |
478 completeHeader(null, false); | 478 } |
479 addContent(new View(new ByteArrayBuffer(content)), Generator.LAST); | 479 |
480 } | 480 /* ------------------------------------------------------------ */ |
481 else if (code>=400) | 481 /** |
482 { | 482 * @return Returns the contentWritten. |
483 completeHeader(null, false); | 483 */ |
484 addContent(new View(new ByteArrayBuffer("Error: "+(reason==null?(""+code):reason))), Generator.LAST); | 484 public long getContentWritten() |
485 } | 485 { |
486 else | 486 return _contentWritten; |
487 { | 487 } |
488 completeHeader(null, true); | 488 |
489 } | 489 |
490 complete(); | 490 |
491 } | 491 /* ------------------------------------------------------------ */ |
492 } | 492 public void blockForOutput(long maxIdleTime) throws IOException |
493 | 493 { |
494 /* ------------------------------------------------------------ */ | 494 if (_endp.isBlocking()) |
495 /** | 495 { |
496 * @return Returns the contentWritten. | 496 try |
497 */ | 497 { |
498 public long getContentWritten() | 498 flushBuffer(); |
499 { | 499 } |
500 return _contentWritten; | 500 catch(IOException e) |
501 } | 501 { |
502 | 502 _endp.close(); |
503 | 503 throw e; |
504 | 504 } |
505 /* ------------------------------------------------------------ */ | 505 } |
506 public void blockForOutput(long maxIdleTime) throws IOException | 506 else |
507 { | 507 { |
508 if (_endp.isBlocking()) | 508 if (!_endp.blockWritable(maxIdleTime)) |
509 { | 509 { |
510 try | 510 _endp.close(); |
511 { | 511 throw new EofException("timeout"); |
512 flushBuffer(); | 512 } |
513 } | 513 |
514 catch(IOException e) | 514 flushBuffer(); |
515 { | 515 } |
516 _endp.close(); | 516 } |
517 throw e; | |
518 } | |
519 } | |
520 else | |
521 { | |
522 if (!_endp.blockWritable(maxIdleTime)) | |
523 { | |
524 _endp.close(); | |
525 throw new EofException("timeout"); | |
526 } | |
527 | |
528 flushBuffer(); | |
529 } | |
530 } | |
531 | 517 |
532 } | 518 } |