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 }