comparison src/org/eclipse/jetty/server/AbstractHttpConnection.java @ 826:6ebf86e4d2ca

remove HttpContent
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 14 Sep 2016 18:51:34 -0600
parents 292f2e31ab41
children 86338c0029a9
comparison
equal deleted inserted replaced
825:7fb7c1915788 826:6ebf86e4d2ca
31 31
32 import org.eclipse.jetty.continuation.ContinuationThrowable; 32 import org.eclipse.jetty.continuation.ContinuationThrowable;
33 import org.eclipse.jetty.http.EncodedHttpURI; 33 import org.eclipse.jetty.http.EncodedHttpURI;
34 import org.eclipse.jetty.http.Generator; 34 import org.eclipse.jetty.http.Generator;
35 import org.eclipse.jetty.http.HttpBuffers; 35 import org.eclipse.jetty.http.HttpBuffers;
36 import org.eclipse.jetty.http.HttpContent;
37 import org.eclipse.jetty.http.HttpException; 36 import org.eclipse.jetty.http.HttpException;
38 import org.eclipse.jetty.http.HttpFields; 37 import org.eclipse.jetty.http.HttpFields;
39 import org.eclipse.jetty.http.HttpGenerator; 38 import org.eclipse.jetty.http.HttpGenerator;
40 import org.eclipse.jetty.http.HttpHeaderValues; 39 import org.eclipse.jetty.http.HttpHeaderValues;
41 import org.eclipse.jetty.http.HttpHeaders; 40 import org.eclipse.jetty.http.HttpHeaders;
97 * </p> 96 * </p>
98 * 97 *
99 */ 98 */
100 public abstract class AbstractHttpConnection extends AbstractConnection 99 public abstract class AbstractHttpConnection extends AbstractConnection
101 { 100 {
102 private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpConnection.class); 101 private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpConnection.class);
103 102
104 private static final int UNKNOWN = -2; 103 private static final int UNKNOWN = -2;
105 private static final ThreadLocal<AbstractHttpConnection> __currentConnection = new ThreadLocal<AbstractHttpConnection>(); 104 private static final ThreadLocal<AbstractHttpConnection> __currentConnection = new ThreadLocal<AbstractHttpConnection>();
106 105
107 private int _requests; 106 private int _requests;
108 107
109 protected final Connector _connector; 108 protected final Connector _connector;
110 protected final Server _server; 109 protected final Server _server;
111 protected final HttpURI _uri; 110 protected final HttpURI _uri;
112 111
113 protected final Parser _parser; 112 protected final Parser _parser;
114 protected final HttpFields _requestFields; 113 protected final HttpFields _requestFields;
115 protected final Request _request; 114 protected final Request _request;
116 protected volatile ServletInputStream _in; 115 protected volatile ServletInputStream _in;
117 116
118 protected final Generator _generator; 117 protected final Generator _generator;
119 protected final HttpFields _responseFields; 118 protected final HttpFields _responseFields;
120 protected final Response _response; 119 protected final Response _response;
121 protected volatile Output _out; 120 protected volatile Output _out;
122 protected volatile OutputWriter _writer; 121 protected volatile OutputWriter _writer;
123 protected volatile PrintWriter _printWriter; 122 protected volatile PrintWriter _printWriter;
124 123
125 int _include; 124 int _include;
126 125
127 private Object _associatedObject; // associated object 126 private Object _associatedObject; // associated object
128 127
129 private int _version = UNKNOWN; 128 private int _version = UNKNOWN;
130 129
131 private String _charset; 130 private String _charset;
132 private boolean _expect = false; 131 private boolean _expect = false;
133 private boolean _expect100Continue = false; 132 private boolean _expect100Continue = false;
134 private boolean _expect102Processing = false; 133 private boolean _expect102Processing = false;
135 private boolean _head = false; 134 private boolean _head = false;
136 private boolean _host = false; 135 private boolean _host = false;
137 private boolean _delayedHandling=false; 136 private boolean _delayedHandling=false;
138 private boolean _earlyEOF = false; 137 private boolean _earlyEOF = false;
139 138
140 /* ------------------------------------------------------------ */ 139 /* ------------------------------------------------------------ */
141 public static AbstractHttpConnection getCurrentConnection() 140 public static AbstractHttpConnection getCurrentConnection()
142 { 141 {
143 return __currentConnection.get(); 142 return __currentConnection.get();
144 } 143 }
145 144
146 /* ------------------------------------------------------------ */ 145 /* ------------------------------------------------------------ */
147 protected static void setCurrentConnection(AbstractHttpConnection connection) 146 protected static void setCurrentConnection(AbstractHttpConnection connection)
148 { 147 {
149 __currentConnection.set(connection); 148 __currentConnection.set(connection);
150 } 149 }
151 150
152 /* ------------------------------------------------------------ */ 151 /* ------------------------------------------------------------ */
153 public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server) 152 public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server)
154 { 153 {
155 super(endpoint); 154 super(endpoint);
156 _uri = StringUtil.__UTF8.equals(URIUtil.__CHARSET)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET); 155 _uri = StringUtil.__UTF8.equals(URIUtil.__CHARSET)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
157 _connector = connector; 156 _connector = connector;
158 HttpBuffers ab = (HttpBuffers)_connector; 157 HttpBuffers ab = (HttpBuffers)_connector;
159 _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler()); 158 _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
160 _requestFields = new HttpFields(); 159 _requestFields = new HttpFields();
161 _responseFields = new HttpFields(); 160 _responseFields = new HttpFields();
162 _request = new Request(this); 161 _request = new Request(this);
163 _response = new Response(this); 162 _response = new Response(this);
164 _generator = newHttpGenerator(ab.getResponseBuffers(), endpoint); 163 _generator = newHttpGenerator(ab.getResponseBuffers(), endpoint);
165 _generator.setSendServerVersion(server.getSendServerVersion()); 164 _generator.setSendServerVersion(server.getSendServerVersion());
166 _server = server; 165 _server = server;
167 } 166 }
168 167
169 /* ------------------------------------------------------------ */ 168 /* ------------------------------------------------------------ */
170 protected AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server, 169 protected AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server,
171 Parser parser, Generator generator, Request request) 170 Parser parser, Generator generator, Request request)
172 { 171 {
173 super(endpoint); 172 super(endpoint);
174 173
175 _uri = URIUtil.__CHARSET.equals(StringUtil.__UTF8)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET); 174 _uri = URIUtil.__CHARSET.equals(StringUtil.__UTF8)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
176 _connector = connector; 175 _connector = connector;
177 _parser = parser; 176 _parser = parser;
178 _requestFields = new HttpFields(); 177 _requestFields = new HttpFields();
179 _responseFields = new HttpFields(); 178 _responseFields = new HttpFields();
180 _request = request; 179 _request = request;
181 _response = new Response(this); 180 _response = new Response(this);
182 _generator = generator; 181 _generator = generator;
183 _generator.setSendServerVersion(server.getSendServerVersion()); 182 _generator.setSendServerVersion(server.getSendServerVersion());
184 _server = server; 183 _server = server;
185 } 184 }
186 185
187 protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endpoint, HttpParser.EventHandler requestHandler) 186 protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endpoint, HttpParser.EventHandler requestHandler)
188 { 187 {
189 return new HttpParser(requestBuffers, endpoint, requestHandler); 188 return new HttpParser(requestBuffers, endpoint, requestHandler);
190 } 189 }
191 190
192 protected HttpGenerator newHttpGenerator(Buffers responseBuffers, EndPoint endPoint) 191 protected HttpGenerator newHttpGenerator(Buffers responseBuffers, EndPoint endPoint)
193 { 192 {
194 return new HttpGenerator(responseBuffers, endPoint); 193 return new HttpGenerator(responseBuffers, endPoint);
195 } 194 }
196 195
197 /* ------------------------------------------------------------ */ 196 /* ------------------------------------------------------------ */
198 /** 197 /**
199 * @return the parser used by this connection 198 * @return the parser used by this connection
200 */ 199 */
201 public Parser getParser() 200 public Parser getParser()
202 { 201 {
203 return _parser; 202 return _parser;
204 } 203 }
205 204
206 /* ------------------------------------------------------------ */ 205 /* ------------------------------------------------------------ */
207 /** 206 /**
208 * @return the number of requests handled by this connection 207 * @return the number of requests handled by this connection
209 */ 208 */
210 public int getRequests() 209 public int getRequests()
211 { 210 {
212 return _requests; 211 return _requests;
213 } 212 }
214 213
215 /* ------------------------------------------------------------ */ 214 /* ------------------------------------------------------------ */
216 public Server getServer() 215 public Server getServer()
217 { 216 {
218 return _server; 217 return _server;
219 } 218 }
220 219
221 /* ------------------------------------------------------------ */ 220 /* ------------------------------------------------------------ */
222 /** 221 /**
223 * @return Returns the associatedObject. 222 * @return Returns the associatedObject.
224 */ 223 */
225 public Object getAssociatedObject() 224 public Object getAssociatedObject()
226 { 225 {
227 return _associatedObject; 226 return _associatedObject;
228 } 227 }
229 228
230 /* ------------------------------------------------------------ */ 229 /* ------------------------------------------------------------ */
231 /** 230 /**
232 * @param associatedObject The associatedObject to set. 231 * @param associatedObject The associatedObject to set.
233 */ 232 */
234 public void setAssociatedObject(Object associatedObject) 233 public void setAssociatedObject(Object associatedObject)
235 { 234 {
236 _associatedObject = associatedObject; 235 _associatedObject = associatedObject;
237 } 236 }
238 237
239 /* ------------------------------------------------------------ */ 238 /* ------------------------------------------------------------ */
240 /** 239 /**
241 * @return Returns the connector. 240 * @return Returns the connector.
242 */ 241 */
243 public Connector getConnector() 242 public Connector getConnector()
244 { 243 {
245 return _connector; 244 return _connector;
246 } 245 }
247 246
248 /* ------------------------------------------------------------ */ 247 /* ------------------------------------------------------------ */
249 /** 248 /**
250 * @return Returns the requestFields. 249 * @return Returns the requestFields.
251 */ 250 */
252 public HttpFields getRequestFields() 251 public HttpFields getRequestFields()
253 { 252 {
254 return _requestFields; 253 return _requestFields;
255 } 254 }
256 255
257 /* ------------------------------------------------------------ */ 256 /* ------------------------------------------------------------ */
258 /** 257 /**
259 * @return Returns the responseFields. 258 * @return Returns the responseFields.
260 */ 259 */
261 public HttpFields getResponseFields() 260 public HttpFields getResponseFields()
262 { 261 {
263 return _responseFields; 262 return _responseFields;
264 } 263 }
265 264
266 /* ------------------------------------------------------------ */ 265 /* ------------------------------------------------------------ */
267 /** 266 /**
268 * Find out if the request supports CONFIDENTIAL security. 267 * Find out if the request supports CONFIDENTIAL security.
269 * @param request the incoming HTTP request 268 * @param request the incoming HTTP request
270 * @return the result of calling {@link Connector#isConfidential(Request)}, or false 269 * @return the result of calling {@link Connector#isConfidential(Request)}, or false
271 * if there is no connector 270 * if there is no connector
272 */ 271 */
273 public boolean isConfidential(Request request) 272 public boolean isConfidential(Request request)
274 { 273 {
275 return _connector != null && _connector.isConfidential(request); 274 return _connector != null && _connector.isConfidential(request);
276 } 275 }
277 276
278 /* ------------------------------------------------------------ */ 277 /* ------------------------------------------------------------ */
279 /** 278 /**
280 * Find out if the request supports INTEGRAL security. 279 * Find out if the request supports INTEGRAL security.
281 * @param request the incoming HTTP request 280 * @param request the incoming HTTP request
282 * @return the result of calling {@link Connector#isIntegral(Request)}, or false 281 * @return the result of calling {@link Connector#isIntegral(Request)}, or false
283 * if there is no connector 282 * if there is no connector
284 */ 283 */
285 public boolean isIntegral(Request request) 284 public boolean isIntegral(Request request)
286 { 285 {
287 return _connector != null && _connector.isIntegral(request); 286 return _connector != null && _connector.isIntegral(request);
288 } 287 }
289 288
290 /* ------------------------------------------------------------ */ 289 /* ------------------------------------------------------------ */
291 /** 290 /**
292 * @return <code>false</code> (this method is not yet implemented) 291 * @return <code>false</code> (this method is not yet implemented)
293 */ 292 */
294 public boolean getResolveNames() 293 public boolean getResolveNames()
295 { 294 {
296 return _connector.getResolveNames(); 295 return _connector.getResolveNames();
297 } 296 }
298 297
299 /* ------------------------------------------------------------ */ 298 /* ------------------------------------------------------------ */
300 /** 299 /**
301 * @return Returns the request. 300 * @return Returns the request.
302 */ 301 */
303 public Request getRequest() 302 public Request getRequest()
304 { 303 {
305 return _request; 304 return _request;
306 } 305 }
307 306
308 /* ------------------------------------------------------------ */ 307 /* ------------------------------------------------------------ */
309 /** 308 /**
310 * @return Returns the response. 309 * @return Returns the response.
311 */ 310 */
312 public Response getResponse() 311 public Response getResponse()
313 { 312 {
314 return _response; 313 return _response;
315 } 314 }
316 315
317 /* ------------------------------------------------------------ */ 316 /* ------------------------------------------------------------ */
318 /** 317 /**
319 * Get the inputStream from the connection. 318 * Get the inputStream from the connection.
320 * <p> 319 * <p>
321 * If the associated response has the Expect header set to 100 Continue, 320 * If the associated response has the Expect header set to 100 Continue,
322 * then accessing the input stream indicates that the handler/servlet 321 * then accessing the input stream indicates that the handler/servlet
323 * is ready for the request body and thus a 100 Continue response is sent. 322 * is ready for the request body and thus a 100 Continue response is sent.
324 * 323 *
325 * @return The input stream for this connection. 324 * @return The input stream for this connection.
326 * The stream will be created if it does not already exist. 325 * The stream will be created if it does not already exist.
327 * @throws IOException if the input stream cannot be retrieved 326 * @throws IOException if the input stream cannot be retrieved
328 */ 327 */
329 public ServletInputStream getInputStream() throws IOException 328 public ServletInputStream getInputStream() throws IOException
330 { 329 {
331 // If the client is expecting 100 CONTINUE, then send it now. 330 // If the client is expecting 100 CONTINUE, then send it now.
332 if (_expect100Continue) 331 if (_expect100Continue)
333 { 332 {
334 // is content missing? 333 // is content missing?
335 if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2) 334 if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
336 { 335 {
337 if (_generator.isCommitted()) 336 if (_generator.isCommitted())
338 throw new IllegalStateException("Committed before 100 Continues"); 337 throw new IllegalStateException("Committed before 100 Continues");
339 338
340 ((HttpGenerator)_generator).send1xx(HttpStatus.CONTINUE_100); 339 ((HttpGenerator)_generator).send1xx(HttpStatus.CONTINUE_100);
341 } 340 }
342 _expect100Continue=false; 341 _expect100Continue=false;
343 } 342 }
344 343
345 if (_in == null) 344 if (_in == null)
346 _in = new HttpInput(AbstractHttpConnection.this); 345 _in = new HttpInput(AbstractHttpConnection.this);
347 return _in; 346 return _in;
348 } 347 }
349 348
350 /* ------------------------------------------------------------ */ 349 /* ------------------------------------------------------------ */
351 /** 350 /**
352 * @return The output stream for this connection. The stream will be created if it does not already exist. 351 * @return The output stream for this connection. The stream will be created if it does not already exist.
353 */ 352 */
354 public ServletOutputStream getOutputStream() 353 public ServletOutputStream getOutputStream()
355 { 354 {
356 if (_out == null) 355 if (_out == null)
357 _out = new Output(); 356 _out = new Output();
358 return _out; 357 return _out;
359 } 358 }
360 359
361 /* ------------------------------------------------------------ */ 360 /* ------------------------------------------------------------ */
362 /** 361 /**
363 * @param encoding the PrintWriter encoding 362 * @param encoding the PrintWriter encoding
364 * @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it 363 * @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it
365 * does not already exist. 364 * does not already exist.
366 */ 365 */
367 public PrintWriter getPrintWriter(String encoding) 366 public PrintWriter getPrintWriter(String encoding)
368 { 367 {
369 getOutputStream(); 368 getOutputStream();
370 if (_writer==null) 369 if (_writer==null)
371 { 370 {
372 _writer=new OutputWriter(); 371 _writer=new OutputWriter();
373 if (_server.isUncheckedPrintWriter()) 372 if (_server.isUncheckedPrintWriter())
374 _printWriter=new UncheckedPrintWriter(_writer); 373 _printWriter=new UncheckedPrintWriter(_writer);
375 else 374 else
376 _printWriter = new PrintWriter(_writer) 375 _printWriter = new PrintWriter(_writer)
377 { 376 {
378 public void close() 377 public void close()
379 { 378 {
380 synchronized (lock) 379 synchronized (lock)
381 { 380 {
382 try 381 try
383 { 382 {
384 out.close(); 383 out.close();
385 } 384 }
386 catch (IOException e) 385 catch (IOException e)
387 { 386 {
388 setError(); 387 setError();
389 } 388 }
390 } 389 }
391 } 390 }
392 }; 391 };
393 } 392 }
394 _writer.setCharacterEncoding(encoding); 393 _writer.setCharacterEncoding(encoding);
395 return _printWriter; 394 return _printWriter;
396 } 395 }
397 396
398 /* ------------------------------------------------------------ */ 397 /* ------------------------------------------------------------ */
399 public boolean isResponseCommitted() 398 public boolean isResponseCommitted()
400 { 399 {
401 return _generator.isCommitted(); 400 return _generator.isCommitted();
402 } 401 }
403 402
404 /* ------------------------------------------------------------ */ 403 /* ------------------------------------------------------------ */
405 public boolean isEarlyEOF() 404 public boolean isEarlyEOF()
406 { 405 {
407 return _earlyEOF; 406 return _earlyEOF;
408 } 407 }
409 408
410 /* ------------------------------------------------------------ */ 409 /* ------------------------------------------------------------ */
411 public void reset() 410 public void reset()
412 { 411 {
413 _parser.reset(); 412 _parser.reset();
414 _parser.returnBuffers(); // TODO maybe only on unhandle 413 _parser.returnBuffers(); // TODO maybe only on unhandle
415 _requestFields.clear(); 414 _requestFields.clear();
416 _request.recycle(); 415 _request.recycle();
417 _generator.reset(); 416 _generator.reset();
418 _generator.returnBuffers();// TODO maybe only on unhandle 417 _generator.returnBuffers();// TODO maybe only on unhandle
419 _responseFields.clear(); 418 _responseFields.clear();
420 _response.recycle(); 419 _response.recycle();
421 _uri.clear(); 420 _uri.clear();
422 _writer=null; 421 _writer=null;
423 _earlyEOF = false; 422 _earlyEOF = false;
424 } 423 }
425 424
426 /* ------------------------------------------------------------ */ 425 /* ------------------------------------------------------------ */
427 protected void handleRequest() throws IOException 426 protected void handleRequest() throws IOException
428 { 427 {
429 boolean error = false; 428 boolean error = false;
430 429
431 String threadName=null; 430 String threadName=null;
432 Throwable async_exception=null; 431 Throwable async_exception=null;
433 try 432 try
434 { 433 {
435 if (LOG.isDebugEnabled()) 434 if (LOG.isDebugEnabled())
436 { 435 {
437 threadName=Thread.currentThread().getName(); 436 threadName=Thread.currentThread().getName();
438 Thread.currentThread().setName(threadName+" - "+_uri); 437 Thread.currentThread().setName(threadName+" - "+_uri);
439 } 438 }
440 439
441 440
442 // Loop here to handle async request redispatches. 441 // Loop here to handle async request redispatches.
443 // The loop is controlled by the call to async.unhandle in the 442 // The loop is controlled by the call to async.unhandle in the
444 // finally block below. If call is from a non-blocking connector, 443 // finally block below. If call is from a non-blocking connector,
445 // then the unhandle will return false only if an async dispatch has 444 // then the unhandle will return false only if an async dispatch has
446 // already happened when unhandle is called. For a blocking connector, 445 // already happened when unhandle is called. For a blocking connector,
447 // the wait for the asynchronous dispatch or timeout actually happens 446 // the wait for the asynchronous dispatch or timeout actually happens
448 // within the call to unhandle(). 447 // within the call to unhandle().
449 448
450 final Server server=_server; 449 final Server server=_server;
451 boolean was_continuation=_request._async.isContinuation(); 450 boolean was_continuation=_request._async.isContinuation();
452 boolean handling=_request._async.handling() && server!=null && server.isRunning(); 451 boolean handling=_request._async.handling() && server!=null && server.isRunning();
453 while (handling) 452 while (handling)
454 { 453 {
455 _request.setHandled(false); 454 _request.setHandled(false);
456 455
457 String info=null; 456 String info=null;
458 try 457 try
459 { 458 {
460 _uri.getPort(); 459 _uri.getPort();
461 String path = null; 460 String path = null;
462 461
463 try 462 try
464 { 463 {
465 path = _uri.getDecodedPath(); 464 path = _uri.getDecodedPath();
466 } 465 }
467 catch (Exception e) 466 catch (Exception e)
468 { 467 {
469 LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1"); 468 LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1");
470 LOG.trace("",e); 469 LOG.trace("",e);
471 path = _uri.getDecodedPath(StringUtil.__ISO_8859_1); 470 path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
472 } 471 }
473 472
474 info=URIUtil.canonicalPath(path); 473 info=URIUtil.canonicalPath(path);
475 if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT)) 474 if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT))
476 { 475 {
477 if (path==null && _uri.getScheme()!=null && _uri.getHost()!=null) 476 if (path==null && _uri.getScheme()!=null && _uri.getHost()!=null)
478 { 477 {
479 info="/"; 478 info="/";
480 _request.setRequestURI(""); 479 _request.setRequestURI("");
481 } 480 }
482 else 481 else
483 throw new HttpException(400); 482 throw new HttpException(400);
484 } 483 }
485 _request.setPathInfo(info); 484 _request.setPathInfo(info);
486 485
487 if (_out!=null) 486 if (_out!=null)
488 _out.reopen(); 487 _out.reopen();
489 488
490 if (_request._async.isInitial()) 489 if (_request._async.isInitial())
491 { 490 {
492 _request.setDispatcherType(DispatcherType.REQUEST); 491 _request.setDispatcherType(DispatcherType.REQUEST);
493 _connector.customize(_endp, _request); 492 _connector.customize(_endp, _request);
494 server.handle(this); 493 server.handle(this);
495 } 494 }
496 else 495 else
497 { 496 {
498 if (_request._async.isExpired()&&!was_continuation) 497 if (_request._async.isExpired()&&!was_continuation)
499 { 498 {
500 async_exception = (Throwable)_request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); 499 async_exception = (Throwable)_request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
501 _response.setStatus(500,async_exception==null?"Async Timeout":"Async Exception"); 500 _response.setStatus(500,async_exception==null?"Async Timeout":"Async Exception");
502 _request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500)); 501 _request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500));
503 _request.setAttribute(RequestDispatcher.ERROR_MESSAGE, _response.getReason()); 502 _request.setAttribute(RequestDispatcher.ERROR_MESSAGE, _response.getReason());
504 _request.setDispatcherType(DispatcherType.ERROR); 503 _request.setDispatcherType(DispatcherType.ERROR);
505 } 504 }
506 else 505 else
507 _request.setDispatcherType(DispatcherType.ASYNC); 506 _request.setDispatcherType(DispatcherType.ASYNC);
508 server.handleAsync(this); 507 server.handleAsync(this);
509 } 508 }
510 } 509 }
511 catch (ContinuationThrowable e) 510 catch (ContinuationThrowable e)
512 { 511 {
513 LOG.trace("",e); 512 LOG.trace("",e);
514 } 513 }
515 catch (EofException e) 514 catch (EofException e)
516 { 515 {
517 async_exception=e; 516 async_exception=e;
518 LOG.debug("",e); 517 LOG.debug("",e);
519 error=true; 518 error=true;
520 _request.setHandled(true); 519 _request.setHandled(true);
521 if (!_response.isCommitted()) 520 if (!_response.isCommitted())
522 _generator.sendError(500, null, null, true); 521 _generator.sendError(500, null, null, true);
523 } 522 }
524 catch (RuntimeIOException e) 523 catch (RuntimeIOException e)
525 { 524 {
526 async_exception=e; 525 async_exception=e;
527 LOG.debug("",e); 526 LOG.debug("",e);
528 error=true; 527 error=true;
529 _request.setHandled(true); 528 _request.setHandled(true);
530 } 529 }
531 catch (HttpException e) 530 catch (HttpException e)
532 { 531 {
533 LOG.debug("",e); 532 LOG.debug("",e);
534 error=true; 533 error=true;
535 _request.setHandled(true); 534 _request.setHandled(true);
536 _response.sendError(e.getStatus(), e.getReason()); 535 _response.sendError(e.getStatus(), e.getReason());
537 } 536 }
538 catch (Throwable e) 537 catch (Throwable e)
539 { 538 {
540 async_exception=e; 539 async_exception=e;
541 LOG.warn(String.valueOf(_uri),e); 540 LOG.warn(String.valueOf(_uri),e);
542 error=true; 541 error=true;
543 _request.setHandled(true); 542 _request.setHandled(true);
544 _generator.sendError(info==null?400:500, null, null, true); 543 _generator.sendError(info==null?400:500, null, null, true);
545 544
546 } 545 }
547 finally 546 finally
548 { 547 {
549 // Complete async requests 548 // Complete async requests
550 if (error && _request.isAsyncStarted()) 549 if (error && _request.isAsyncStarted())
551 _request.getAsyncContinuation().errorComplete(); 550 _request.getAsyncContinuation().errorComplete();
552 551
553 was_continuation=_request._async.isContinuation(); 552 was_continuation=_request._async.isContinuation();
554 handling = !_request._async.unhandle() && server.isRunning() && _server!=null; 553 handling = !_request._async.unhandle() && server.isRunning() && _server!=null;
555 } 554 }
556 } 555 }
557 } 556 }
558 finally 557 finally
559 { 558 {
560 if (threadName!=null) 559 if (threadName!=null)
561 Thread.currentThread().setName(threadName); 560 Thread.currentThread().setName(threadName);
562 561
563 if (_request._async.isUncompleted()) 562 if (_request._async.isUncompleted())
564 { 563 {
565 564
566 _request._async.doComplete(async_exception); 565 _request._async.doComplete(async_exception);
567 566
568 if (_expect100Continue) 567 if (_expect100Continue)
569 { 568 {
570 LOG.debug("100 continues not sent"); 569 LOG.debug("100 continues not sent");
571 // We didn't send 100 continues, but the latest interpretation 570 // We didn't send 100 continues, but the latest interpretation
572 // of the spec (see httpbis) is that the client will either 571 // of the spec (see httpbis) is that the client will either
573 // send the body anyway, or close. So we no longer need to 572 // send the body anyway, or close. So we no longer need to
574 // do anything special here other than make the connection not persistent 573 // do anything special here other than make the connection not persistent
575 _expect100Continue = false; 574 _expect100Continue = false;
576 if (!_response.isCommitted()) 575 if (!_response.isCommitted())
577 _generator.setPersistent(false); 576 _generator.setPersistent(false);
578 } 577 }
579 578
580 if(_endp.isOpen()) 579 if(_endp.isOpen())
581 { 580 {
582 if (error) 581 if (error)
583 { 582 {
584 _endp.shutdownOutput(); 583 _endp.shutdownOutput();
585 _generator.setPersistent(false); 584 _generator.setPersistent(false);
586 if (!_generator.isComplete()) 585 if (!_generator.isComplete())
587 _response.complete(); 586 _response.complete();
588 } 587 }
589 else 588 else
590 { 589 {
591 if (!_response.isCommitted() && !_request.isHandled()) 590 if (!_response.isCommitted() && !_request.isHandled())
592 _response.sendError(HttpServletResponse.SC_NOT_FOUND); 591 _response.sendError(HttpServletResponse.SC_NOT_FOUND);
593 _response.complete(); 592 _response.complete();
594 if (_generator.isPersistent()) 593 if (_generator.isPersistent())
595 _connector.persist(_endp); 594 _connector.persist(_endp);
596 } 595 }
597 } 596 }
598 else 597 else
599 { 598 {
600 _response.complete(); 599 _response.complete();
601 } 600 }
602 601
603 _request.setHandled(true); 602 _request.setHandled(true);
604 } 603 }
605 } 604 }
606 } 605 }
607 606
608 /* ------------------------------------------------------------ */ 607 /* ------------------------------------------------------------ */
609 public abstract Connection handle() throws IOException; 608 public abstract Connection handle() throws IOException;
610 609
611 /* ------------------------------------------------------------ */ 610 /* ------------------------------------------------------------ */
612 public void commitResponse(boolean last) throws IOException 611 public void commitResponse(boolean last) throws IOException
613 { 612 {
614 if (!_generator.isCommitted()) 613 if (!_generator.isCommitted())
615 { 614 {
616 _generator.setResponse(_response.getStatus(), _response.getReason()); 615 _generator.setResponse(_response.getStatus(), _response.getReason());
617 try 616 try
618 { 617 {
619 // If the client was expecting 100 continues, but we sent something 618 // If the client was expecting 100 continues, but we sent something
620 // else, then we need to close the connection 619 // else, then we need to close the connection
621 if (_expect100Continue && _response.getStatus()!=100) 620 if (_expect100Continue && _response.getStatus()!=100)
622 _generator.setPersistent(false); 621 _generator.setPersistent(false);
623 _generator.completeHeader(_responseFields, last); 622 _generator.completeHeader(_responseFields, last);
624 } 623 }
625 catch(RuntimeException e) 624 catch(RuntimeException e)
626 { 625 {
627 LOG.warn("header full: " + e); 626 LOG.warn("header full: " + e);
628 627
629 _response.reset(); 628 _response.reset();
630 _generator.reset(); 629 _generator.reset();
631 _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null); 630 _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
632 _generator.completeHeader(_responseFields,Generator.LAST); 631 _generator.completeHeader(_responseFields,Generator.LAST);
633 _generator.complete(); 632 _generator.complete();
634 throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500); 633 throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
635 } 634 }
636 635
637 } 636 }
638 if (last) 637 if (last)
639 _generator.complete(); 638 _generator.complete();
640 } 639 }
641 640
642 /* ------------------------------------------------------------ */ 641 /* ------------------------------------------------------------ */
643 public void completeResponse() throws IOException 642 public void completeResponse() throws IOException
644 { 643 {
645 if (!_generator.isCommitted()) 644 if (!_generator.isCommitted())
646 { 645 {
647 _generator.setResponse(_response.getStatus(), _response.getReason()); 646 _generator.setResponse(_response.getStatus(), _response.getReason());
648 try 647 try
649 { 648 {
650 _generator.completeHeader(_responseFields, Generator.LAST); 649 _generator.completeHeader(_responseFields, Generator.LAST);
651 } 650 }
652 catch(RuntimeException e) 651 catch(RuntimeException e)
653 { 652 {
654 LOG.warn("header full: "+e); 653 LOG.warn("header full: "+e);
655 LOG.debug("",e); 654 LOG.debug("",e);
656 655
657 _response.reset(); 656 _response.reset();
658 _generator.reset(); 657 _generator.reset();
659 _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null); 658 _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
660 _generator.completeHeader(_responseFields,Generator.LAST); 659 _generator.completeHeader(_responseFields,Generator.LAST);
661 _generator.complete(); 660 _generator.complete();
662 throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500); 661 throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
663 } 662 }
664 } 663 }
665 664
666 _generator.complete(); 665 _generator.complete();
667 } 666 }
668 667
669 /* ------------------------------------------------------------ */ 668 /* ------------------------------------------------------------ */
670 public void flushResponse() throws IOException 669 public void flushResponse() throws IOException
671 { 670 {
672 try 671 try
673 { 672 {
674 commitResponse(Generator.MORE); 673 commitResponse(Generator.MORE);
675 _generator.flushBuffer(); 674 _generator.flushBuffer();
676 } 675 }
677 catch(IOException e) 676 catch(IOException e)
678 { 677 {
679 throw (e instanceof EofException) ? e:new EofException(e); 678 throw (e instanceof EofException) ? e:new EofException(e);
680 } 679 }
681 } 680 }
682 681
683 /* ------------------------------------------------------------ */ 682 /* ------------------------------------------------------------ */
684 public Generator getGenerator() 683 public Generator getGenerator()
685 { 684 {
686 return _generator; 685 return _generator;
687 } 686 }
688 687
689 /* ------------------------------------------------------------ */ 688 /* ------------------------------------------------------------ */
690 public boolean isIncluding() 689 public boolean isIncluding()
691 { 690 {
692 return _include>0; 691 return _include>0;
693 } 692 }
694 693
695 /* ------------------------------------------------------------ */ 694 /* ------------------------------------------------------------ */
696 public void include() 695 public void include()
697 { 696 {
698 _include++; 697 _include++;
699 } 698 }
700 699
701 /* ------------------------------------------------------------ */ 700 /* ------------------------------------------------------------ */
702 public void included() 701 public void included()
703 { 702 {
704 _include--; 703 _include--;
705 if (_out!=null) 704 if (_out!=null)
706 _out.reopen(); 705 _out.reopen();
707 } 706 }
708 707
709 /* ------------------------------------------------------------ */ 708 /* ------------------------------------------------------------ */
710 public boolean isIdle() 709 public boolean isIdle()
711 { 710 {
712 return _generator.isIdle() && (_parser.isIdle() || _delayedHandling); 711 return _generator.isIdle() && (_parser.isIdle() || _delayedHandling);
713 } 712 }
714 713
715 /* ------------------------------------------------------------ */ 714 /* ------------------------------------------------------------ */
716 /** 715 /**
717 * @see org.eclipse.jetty.io.Connection#isSuspended() 716 * @see org.eclipse.jetty.io.Connection#isSuspended()
718 */ 717 */
719 public boolean isSuspended() 718 public boolean isSuspended()
720 { 719 {
721 return _request.getAsyncContinuation().isSuspended(); 720 return _request.getAsyncContinuation().isSuspended();
722 } 721 }
723 722
724 /* ------------------------------------------------------------ */ 723 /* ------------------------------------------------------------ */
725 public void onClose() 724 public void onClose()
726 { 725 {
727 LOG.debug("closed {}",this); 726 LOG.debug("closed {}",this);
728 } 727 }
729 728
730 /* ------------------------------------------------------------ */ 729 /* ------------------------------------------------------------ */
731 public boolean isExpecting100Continues() 730 public boolean isExpecting100Continues()
732 { 731 {
733 return _expect100Continue; 732 return _expect100Continue;
734 } 733 }
735 734
736 /* ------------------------------------------------------------ */ 735 /* ------------------------------------------------------------ */
737 public boolean isExpecting102Processing() 736 public boolean isExpecting102Processing()
738 { 737 {
739 return _expect102Processing; 738 return _expect102Processing;
740 } 739 }
741 740
742 /* ------------------------------------------------------------ */ 741 /* ------------------------------------------------------------ */
743 public int getMaxIdleTime() 742 public int getMaxIdleTime()
744 { 743 {
745 if (_connector.isLowResources() && _endp.getMaxIdleTime()==_connector.getMaxIdleTime()) 744 if (_connector.isLowResources() && _endp.getMaxIdleTime()==_connector.getMaxIdleTime())
746 return _connector.getLowResourceMaxIdleTime(); 745 return _connector.getLowResourceMaxIdleTime();
747 if (_endp.getMaxIdleTime()>0) 746 if (_endp.getMaxIdleTime()>0)
748 return _endp.getMaxIdleTime(); 747 return _endp.getMaxIdleTime();
749 return _connector.getMaxIdleTime(); 748 return _connector.getMaxIdleTime();
750 } 749 }
751 750
752 /* ------------------------------------------------------------ */ 751 /* ------------------------------------------------------------ */
753 public String toString() 752 public String toString()
754 { 753 {
755 return String.format("%s,g=%s,p=%s,r=%d", 754 return String.format("%s,g=%s,p=%s,r=%d",
756 super.toString(), 755 super.toString(),
757 _generator, 756 _generator,
758 _parser, 757 _parser,
759 _requests); 758 _requests);
760 } 759 }
761 760
762 /* ------------------------------------------------------------ */ 761 /* ------------------------------------------------------------ */
763 protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException 762 protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
764 { 763 {
765 uri=uri.asImmutableBuffer(); 764 uri=uri.asImmutableBuffer();
766 765
767 _host = false; 766 _host = false;
768 _expect = false; 767 _expect = false;
769 _expect100Continue=false; 768 _expect100Continue=false;
770 _expect102Processing=false; 769 _expect102Processing=false;
771 _delayedHandling=false; 770 _delayedHandling=false;
772 _charset=null; 771 _charset=null;
773 772
774 if(_request.getTimeStamp()==0) 773 if(_request.getTimeStamp()==0)
775 _request.setTimeStamp(System.currentTimeMillis()); 774 _request.setTimeStamp(System.currentTimeMillis());
776 _request.setMethod(method.toString()); 775 _request.setMethod(method.toString());
777 776
778 try 777 try
779 { 778 {
780 _head=false; 779 _head=false;
781 switch (HttpMethods.CACHE.getOrdinal(method)) 780 switch (HttpMethods.CACHE.getOrdinal(method))
782 { 781 {
783 case HttpMethods.CONNECT_ORDINAL: 782 case HttpMethods.CONNECT_ORDINAL:
784 _uri.parseConnect(uri.array(), uri.getIndex(), uri.length()); 783 _uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
785 break; 784 break;
786 785
787 case HttpMethods.HEAD_ORDINAL: 786 case HttpMethods.HEAD_ORDINAL:
788 _head=true; 787 _head=true;
789 _uri.parse(uri.array(), uri.getIndex(), uri.length()); 788 _uri.parse(uri.array(), uri.getIndex(), uri.length());
790 break; 789 break;
791 790
792 default: 791 default:
793 _uri.parse(uri.array(), uri.getIndex(), uri.length()); 792 _uri.parse(uri.array(), uri.getIndex(), uri.length());
794 } 793 }
795 794
796 _request.setUri(_uri); 795 _request.setUri(_uri);
797 796
798 if (version==null) 797 if (version==null)
799 { 798 {
800 _request.setProtocol(HttpVersions.HTTP_0_9); 799 _request.setProtocol(HttpVersions.HTTP_0_9);
801 _version=HttpVersions.HTTP_0_9_ORDINAL; 800 _version=HttpVersions.HTTP_0_9_ORDINAL;
802 } 801 }
803 else 802 else
804 { 803 {
805 version= HttpVersions.CACHE.get(version); 804 version= HttpVersions.CACHE.get(version);
806 if (version==null) 805 if (version==null)
807 throw new HttpException(HttpStatus.BAD_REQUEST_400,null); 806 throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
808 _version = HttpVersions.CACHE.getOrdinal(version); 807 _version = HttpVersions.CACHE.getOrdinal(version);
809 if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL; 808 if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
810 _request.setProtocol(version.toString()); 809 _request.setProtocol(version.toString());
811 } 810 }
812 } 811 }
813 catch (Exception e) 812 catch (Exception e)
814 { 813 {
815 LOG.debug("",e); 814 LOG.debug("",e);
816 if (e instanceof HttpException) 815 if (e instanceof HttpException)
817 throw (HttpException)e; 816 throw (HttpException)e;
818 throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e); 817 throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e);
819 } 818 }
820 } 819 }
821 820
822 /* ------------------------------------------------------------ */ 821 /* ------------------------------------------------------------ */
823 protected void parsedHeader(Buffer name, Buffer value) throws IOException 822 protected void parsedHeader(Buffer name, Buffer value) throws IOException
824 { 823 {
825 int ho = HttpHeaders.CACHE.getOrdinal(name); 824 int ho = HttpHeaders.CACHE.getOrdinal(name);
826 switch (ho) 825 switch (ho)
827 { 826 {
828 case HttpHeaders.HOST_ORDINAL: 827 case HttpHeaders.HOST_ORDINAL:
829 // TODO check if host matched a host in the URI. 828 // TODO check if host matched a host in the URI.
830 _host = true; 829 _host = true;
831 break; 830 break;
832 831
833 case HttpHeaders.EXPECT_ORDINAL: 832 case HttpHeaders.EXPECT_ORDINAL:
834 if (_version>=HttpVersions.HTTP_1_1_ORDINAL) 833 if (_version>=HttpVersions.HTTP_1_1_ORDINAL)
835 { 834 {
836 value = HttpHeaderValues.CACHE.lookup(value); 835 value = HttpHeaderValues.CACHE.lookup(value);
837 switch(HttpHeaderValues.CACHE.getOrdinal(value)) 836 switch(HttpHeaderValues.CACHE.getOrdinal(value))
838 { 837 {
839 case HttpHeaderValues.CONTINUE_ORDINAL: 838 case HttpHeaderValues.CONTINUE_ORDINAL:
840 _expect100Continue=_generator instanceof HttpGenerator; 839 _expect100Continue=_generator instanceof HttpGenerator;
841 break; 840 break;
842 841
843 case HttpHeaderValues.PROCESSING_ORDINAL: 842 case HttpHeaderValues.PROCESSING_ORDINAL:
844 _expect102Processing=_generator instanceof HttpGenerator; 843 _expect102Processing=_generator instanceof HttpGenerator;
845 break; 844 break;
846 845
847 default: 846 default:
848 String[] values = value.toString().split(","); 847 String[] values = value.toString().split(",");
849 for (int i=0;values!=null && i<values.length;i++) 848 for (int i=0;values!=null && i<values.length;i++)
850 { 849 {
851 CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim()); 850 CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
852 if (cb==null) 851 if (cb==null)
853 _expect=true; 852 _expect=true;
854 else 853 else
855 { 854 {
856 switch(cb.getOrdinal()) 855 switch(cb.getOrdinal())
857 { 856 {
858 case HttpHeaderValues.CONTINUE_ORDINAL: 857 case HttpHeaderValues.CONTINUE_ORDINAL:
859 _expect100Continue=_generator instanceof HttpGenerator; 858 _expect100Continue=_generator instanceof HttpGenerator;
860 break; 859 break;
861 case HttpHeaderValues.PROCESSING_ORDINAL: 860 case HttpHeaderValues.PROCESSING_ORDINAL:
862 _expect102Processing=_generator instanceof HttpGenerator; 861 _expect102Processing=_generator instanceof HttpGenerator;
863 break; 862 break;
864 default: 863 default:
865 _expect=true; 864 _expect=true;
866 } 865 }
867 } 866 }
868 } 867 }
869 } 868 }
870 } 869 }
871 break; 870 break;
872 871
873 case HttpHeaders.ACCEPT_ENCODING_ORDINAL: 872 case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
874 case HttpHeaders.USER_AGENT_ORDINAL: 873 case HttpHeaders.USER_AGENT_ORDINAL:
875 value = HttpHeaderValues.CACHE.lookup(value); 874 value = HttpHeaderValues.CACHE.lookup(value);
876 break; 875 break;
877 876
878 case HttpHeaders.CONTENT_TYPE_ORDINAL: 877 case HttpHeaders.CONTENT_TYPE_ORDINAL:
879 value = MimeTypes.CACHE.lookup(value); 878 value = MimeTypes.CACHE.lookup(value);
880 _charset=MimeTypes.getCharsetFromContentType(value); 879 _charset=MimeTypes.getCharsetFromContentType(value);
881 break; 880 break;
882 } 881 }
883 882
884 _requestFields.add(name, value); 883 _requestFields.add(name, value);
885 } 884 }
886 885
887 /* ------------------------------------------------------------ */ 886 /* ------------------------------------------------------------ */
888 protected void headerComplete() throws IOException 887 protected void headerComplete() throws IOException
889 { 888 {
890 // Handle idle race 889 // Handle idle race
891 if (_endp.isOutputShutdown()) 890 if (_endp.isOutputShutdown())
892 { 891 {
893 _endp.close(); 892 _endp.close();
894 return; 893 return;
895 } 894 }
896 895
897 _requests++; 896 _requests++;
898 _generator.setVersion(_version); 897 _generator.setVersion(_version);
899 switch (_version) 898 switch (_version)
900 { 899 {
901 case HttpVersions.HTTP_0_9_ORDINAL: 900 case HttpVersions.HTTP_0_9_ORDINAL:
902 break; 901 break;
903 case HttpVersions.HTTP_1_0_ORDINAL: 902 case HttpVersions.HTTP_1_0_ORDINAL:
904 _generator.setHead(_head); 903 _generator.setHead(_head);
905 if (_parser.isPersistent()) 904 if (_parser.isPersistent())
906 { 905 {
907 _responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER); 906 _responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
908 _generator.setPersistent(true); 907 _generator.setPersistent(true);
909 } 908 }
910 else if (HttpMethods.CONNECT.equals(_request.getMethod())) 909 else if (HttpMethods.CONNECT.equals(_request.getMethod()))
911 { 910 {
912 _generator.setPersistent(true); 911 _generator.setPersistent(true);
913 _parser.setPersistent(true); 912 _parser.setPersistent(true);
914 } 913 }
915 914
916 if (_server.getSendDateHeader()) 915 if (_server.getSendDateHeader())
917 _generator.setDate(_request.getTimeStampBuffer()); 916 _generator.setDate(_request.getTimeStampBuffer());
918 break; 917 break;
919 918
920 case HttpVersions.HTTP_1_1_ORDINAL: 919 case HttpVersions.HTTP_1_1_ORDINAL:
921 _generator.setHead(_head); 920 _generator.setHead(_head);
922 921
923 if (!_parser.isPersistent()) 922 if (!_parser.isPersistent())
924 { 923 {
925 _responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER); 924 _responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
926 _generator.setPersistent(false); 925 _generator.setPersistent(false);
927 } 926 }
928 if (_server.getSendDateHeader()) 927 if (_server.getSendDateHeader())
929 _generator.setDate(_request.getTimeStampBuffer()); 928 _generator.setDate(_request.getTimeStampBuffer());
930 929
931 if (!_host) 930 if (!_host)
932 { 931 {
933 LOG.debug("!host {}",this); 932 LOG.debug("!host {}",this);
934 _generator.setResponse(HttpStatus.BAD_REQUEST_400, null); 933 _generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
935 _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER); 934 _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
936 _generator.completeHeader(_responseFields, true); 935 _generator.completeHeader(_responseFields, true);
937 _generator.complete(); 936 _generator.complete();
938 return; 937 return;
939 } 938 }
940 939
941 if (_expect) 940 if (_expect)
942 { 941 {
943 LOG.debug("!expectation {}",this); 942 LOG.debug("!expectation {}",this);
944 _generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null); 943 _generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
945 _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER); 944 _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
946 _generator.completeHeader(_responseFields, true); 945 _generator.completeHeader(_responseFields, true);
947 _generator.complete(); 946 _generator.complete();
948 return; 947 return;
949 } 948 }
950 949
951 break; 950 break;
952 default: 951 default:
953 } 952 }
954 953
955 if(_charset!=null) 954 if(_charset!=null)
956 _request.setCharacterEncodingUnchecked(_charset); 955 _request.setCharacterEncodingUnchecked(_charset);
957 956
958 // Either handle now or wait for first content 957 // Either handle now or wait for first content
959 if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue) 958 if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
960 handleRequest(); 959 handleRequest();
961 else 960 else
962 _delayedHandling=true; 961 _delayedHandling=true;
963 } 962 }
964 963
965 /* ------------------------------------------------------------ */ 964 /* ------------------------------------------------------------ */
966 protected void content(Buffer buffer) throws IOException 965 protected void content(Buffer buffer) throws IOException
967 { 966 {
968 if (_delayedHandling) 967 if (_delayedHandling)
969 { 968 {
970 _delayedHandling=false; 969 _delayedHandling=false;
971 handleRequest(); 970 handleRequest();
972 } 971 }
973 } 972 }
974 973
975 /* ------------------------------------------------------------ */ 974 /* ------------------------------------------------------------ */
976 public void messageComplete(long contentLength) throws IOException 975 public void messageComplete(long contentLength) throws IOException
977 { 976 {
978 if (_delayedHandling) 977 if (_delayedHandling)
979 { 978 {
980 _delayedHandling=false; 979 _delayedHandling=false;
981 handleRequest(); 980 handleRequest();
982 } 981 }
983 } 982 }
984 983
985 /* ------------------------------------------------------------ */ 984 /* ------------------------------------------------------------ */
986 public void earlyEOF() 985 public void earlyEOF()
987 { 986 {
988 _earlyEOF = true; 987 _earlyEOF = true;
989 } 988 }
990 989
991 /* ------------------------------------------------------------ */ 990 /* ------------------------------------------------------------ */
992 /* ------------------------------------------------------------ */ 991 /* ------------------------------------------------------------ */
993 /* ------------------------------------------------------------ */ 992 /* ------------------------------------------------------------ */
994 private class RequestHandler extends HttpParser.EventHandler 993 private class RequestHandler extends HttpParser.EventHandler
995 { 994 {
996 /* 995 /*
997 * 996 *
998 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startRequest(org.eclipse.io.Buffer, 997 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startRequest(org.eclipse.io.Buffer,
999 * org.eclipse.io.Buffer, org.eclipse.io.Buffer) 998 * org.eclipse.io.Buffer, org.eclipse.io.Buffer)
1000 */ 999 */
1001 @Override 1000 @Override
1002 public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException 1001 public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
1003 { 1002 {
1004 AbstractHttpConnection.this.startRequest(method, uri, version); 1003 AbstractHttpConnection.this.startRequest(method, uri, version);
1005 } 1004 }
1006 1005
1007 /* 1006 /*
1008 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer) 1007 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer)
1009 */ 1008 */
1010 @Override 1009 @Override
1011 public void parsedHeader(Buffer name, Buffer value) throws IOException 1010 public void parsedHeader(Buffer name, Buffer value) throws IOException
1012 { 1011 {
1013 AbstractHttpConnection.this.parsedHeader(name, value); 1012 AbstractHttpConnection.this.parsedHeader(name, value);
1014 } 1013 }
1015 1014
1016 /* 1015 /*
1017 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#headerComplete() 1016 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#headerComplete()
1018 */ 1017 */
1019 @Override 1018 @Override
1020 public void headerComplete() throws IOException 1019 public void headerComplete() throws IOException
1021 { 1020 {
1022 AbstractHttpConnection.this.headerComplete(); 1021 AbstractHttpConnection.this.headerComplete();
1023 } 1022 }
1024 1023
1025 /* ------------------------------------------------------------ */ 1024 /* ------------------------------------------------------------ */
1026 /* 1025 /*
1027 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#content(int, org.eclipse.io.Buffer) 1026 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#content(int, org.eclipse.io.Buffer)
1028 */ 1027 */
1029 @Override 1028 @Override
1030 public void content(Buffer ref) throws IOException 1029 public void content(Buffer ref) throws IOException
1031 { 1030 {
1032 AbstractHttpConnection.this.content(ref); 1031 AbstractHttpConnection.this.content(ref);
1033 } 1032 }
1034 1033
1035 /* ------------------------------------------------------------ */ 1034 /* ------------------------------------------------------------ */
1036 /* 1035 /*
1037 * (non-Javadoc) 1036 * (non-Javadoc)
1038 * 1037 *
1039 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#messageComplete(int) 1038 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#messageComplete(int)
1040 */ 1039 */
1041 @Override 1040 @Override
1042 public void messageComplete(long contentLength) throws IOException 1041 public void messageComplete(long contentLength) throws IOException
1043 { 1042 {
1044 AbstractHttpConnection.this.messageComplete(contentLength); 1043 AbstractHttpConnection.this.messageComplete(contentLength);
1045 } 1044 }
1046 1045
1047 /* ------------------------------------------------------------ */ 1046 /* ------------------------------------------------------------ */
1048 /* 1047 /*
1049 * (non-Javadoc) 1048 * (non-Javadoc)
1050 * 1049 *
1051 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startResponse(org.eclipse.io.Buffer, int, 1050 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startResponse(org.eclipse.io.Buffer, int,
1052 * org.eclipse.io.Buffer) 1051 * org.eclipse.io.Buffer)
1053 */ 1052 */
1054 @Override 1053 @Override
1055 public void startResponse(Buffer version, int status, Buffer reason) 1054 public void startResponse(Buffer version, int status, Buffer reason)
1056 { 1055 {
1057 if (LOG.isDebugEnabled()) 1056 if (LOG.isDebugEnabled())
1058 LOG.debug("Bad request!: "+version+" "+status+" "+reason); 1057 LOG.debug("Bad request!: "+version+" "+status+" "+reason);
1059 } 1058 }
1060 1059
1061 /* ------------------------------------------------------------ */ 1060 /* ------------------------------------------------------------ */
1062 /* 1061 /*
1063 * (non-Javadoc) 1062 * (non-Javadoc)
1064 * 1063 *
1065 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#earlyEOF() 1064 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#earlyEOF()
1066 */ 1065 */
1067 @Override 1066 @Override
1068 public void earlyEOF() 1067 public void earlyEOF()
1069 { 1068 {
1070 AbstractHttpConnection.this.earlyEOF(); 1069 AbstractHttpConnection.this.earlyEOF();
1071 } 1070 }
1072 } 1071 }
1073 1072
1074 /* ------------------------------------------------------------ */ 1073 /* ------------------------------------------------------------ */
1075 /* ------------------------------------------------------------ */ 1074 /* ------------------------------------------------------------ */
1076 /* ------------------------------------------------------------ */ 1075 /* ------------------------------------------------------------ */
1077 public class Output extends HttpOutput 1076 public class Output extends HttpOutput
1078 { 1077 {
1079 Output() 1078 Output()
1080 { 1079 {
1081 super(AbstractHttpConnection.this); 1080 super(AbstractHttpConnection.this);
1082 } 1081 }
1083 1082
1084 /* ------------------------------------------------------------ */ 1083 /* ------------------------------------------------------------ */
1085 /* 1084 /*
1086 * @see java.io.OutputStream#close() 1085 * @see java.io.OutputStream#close()
1087 */ 1086 */
1088 @Override 1087 @Override
1089 public void close() throws IOException 1088 public void close() throws IOException
1090 { 1089 {
1091 if (isClosed()) 1090 if (isClosed())
1092 return; 1091 return;
1093 1092
1094 if (!isIncluding() && !super._generator.isCommitted()) 1093 if (!isIncluding() && !super._generator.isCommitted())
1095 commitResponse(Generator.LAST); 1094 commitResponse(Generator.LAST);
1096 else 1095 else
1097 flushResponse(); 1096 flushResponse();
1098 1097
1099 super.close(); 1098 super.close();
1100 } 1099 }
1101 1100
1102 1101
1103 /* ------------------------------------------------------------ */ 1102 /* ------------------------------------------------------------ */
1104 /* 1103 /*
1105 * @see java.io.OutputStream#flush() 1104 * @see java.io.OutputStream#flush()
1106 */ 1105 */
1107 @Override 1106 @Override
1108 public void flush() throws IOException 1107 public void flush() throws IOException
1109 { 1108 {
1110 if (!super._generator.isCommitted()) 1109 if (!super._generator.isCommitted())
1111 commitResponse(Generator.MORE); 1110 commitResponse(Generator.MORE);
1112 super.flush(); 1111 super.flush();
1113 } 1112 }
1114 1113
1115 /* ------------------------------------------------------------ */ 1114 /* ------------------------------------------------------------ */
1116 /* 1115 /*
1117 * @see javax.servlet.ServletOutputStream#print(java.lang.String) 1116 * @see javax.servlet.ServletOutputStream#print(java.lang.String)
1118 */ 1117 */
1119 @Override 1118 @Override
1120 public void print(String s) throws IOException 1119 public void print(String s) throws IOException
1121 { 1120 {
1122 if (isClosed()) 1121 if (isClosed())
1123 throw new IOException("Closed"); 1122 throw new IOException("Closed");
1124 PrintWriter writer=getPrintWriter(null); 1123 PrintWriter writer=getPrintWriter(null);
1125 writer.print(s); 1124 writer.print(s);
1126 } 1125 }
1127 1126
1128 /* ------------------------------------------------------------ */ 1127 /* ------------------------------------------------------------ */
1129 public void sendResponse(Buffer response) throws IOException 1128 public void sendResponse(Buffer response) throws IOException
1130 { 1129 {
1131 ((HttpGenerator)super._generator).sendResponse(response); 1130 ((HttpGenerator)super._generator).sendResponse(response);
1132 } 1131 }
1133 1132
1134 /* ------------------------------------------------------------ */ 1133 /* ------------------------------------------------------------ */
1135 public void sendContent(Object content) throws IOException 1134 public void sendContent(Object content) throws IOException
1136 { 1135 {
1137 Resource resource=null; 1136 Resource resource=null;
1138 1137
1139 if (isClosed()) 1138 if (isClosed())
1140 throw new IOException("Closed"); 1139 throw new IOException("Closed");
1141 1140
1142 if (super._generator.isWritten()) 1141 if (super._generator.isWritten())
1143 throw new IllegalStateException("!empty"); 1142 throw new IllegalStateException("!empty");
1144 1143
1145 // Convert HTTP content to content 1144 if (content instanceof Resource)
1146 if (content instanceof HttpContent) 1145 {
1147 { 1146 resource=(Resource)content;
1148 HttpContent httpContent = (HttpContent) content; 1147 _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified());
1149 Buffer contentType = httpContent.getContentType(); 1148 content=resource.getInputStream();
1150 if (contentType != null && !_responseFields.containsKey(HttpHeaders.CONTENT_TYPE_BUFFER)) 1149 }
1151 { 1150
1152 String enc = _response.getSetCharacterEncoding(); 1151 // Process content.
1153 if(enc==null) 1152 if (content instanceof Buffer)
1154 _responseFields.add(HttpHeaders.CONTENT_TYPE_BUFFER, contentType); 1153 {
1155 else 1154 super._generator.addContent((Buffer) content, Generator.LAST);
1156 { 1155 commitResponse(Generator.LAST);
1157 if(contentType instanceof CachedBuffer) 1156 }
1158 { 1157 else if (content instanceof InputStream)
1159 CachedBuffer content_type = ((CachedBuffer)contentType).getAssociate(enc); 1158 {
1160 if(content_type!=null) 1159 InputStream in = (InputStream)content;
1161 _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, content_type); 1160
1162 else 1161 try
1163 { 1162 {
1164 _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, 1163 int max = super._generator.prepareUncheckedAddContent();
1165 contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= ")); 1164 Buffer buffer = super._generator.getUncheckedBuffer();
1166 } 1165
1167 } 1166 int len=buffer.readFrom(in,max);
1168 else 1167
1169 { 1168 while (len>=0)
1170 _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, 1169 {
1171 contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= ")); 1170 super._generator.completeUncheckedAddContent();
1172 } 1171 _out.flush();
1173 } 1172
1174 } 1173 max = super._generator.prepareUncheckedAddContent();
1175 if (httpContent.getContentLength() > 0) 1174 buffer = super._generator.getUncheckedBuffer();
1176 _responseFields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER, httpContent.getContentLength()); 1175 len=buffer.readFrom(in,max);
1177 Buffer lm = httpContent.getLastModified(); 1176 }
1178 long lml=httpContent.getResource().lastModified(); 1177 super._generator.completeUncheckedAddContent();
1179 if (lm != null) 1178 _out.flush();
1180 { 1179 }
1181 _responseFields.put(HttpHeaders.LAST_MODIFIED_BUFFER, lm); 1180 finally
1182 } 1181 {
1183 else if (httpContent.getResource()!=null) 1182 if (resource!=null)
1184 { 1183 resource.release();
1185 if (lml!=-1) 1184 else
1186 _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, lml); 1185 in.close();
1187 } 1186 }
1188 1187 }
1189 Buffer etag=httpContent.getETag(); 1188 else
1190 if (etag!=null) 1189 throw new IllegalArgumentException("unknown content type?");
1191 _responseFields.put(HttpHeaders.ETAG_BUFFER,etag); 1190
1192 1191
1193 1192 }
1194 boolean direct=_connector instanceof NIOConnector && ((NIOConnector)_connector).getUseDirectBuffers() && !(_connector instanceof SslConnector); 1193 }
1195 content = direct?httpContent.getDirectBuffer():httpContent.getIndirectBuffer(); 1194
1196 if (content==null) 1195 /* ------------------------------------------------------------ */
1197 content=httpContent.getInputStream(); 1196 /* ------------------------------------------------------------ */
1198 } 1197 /* ------------------------------------------------------------ */
1199 else if (content instanceof Resource) 1198 public class OutputWriter extends HttpWriter
1200 { 1199 {
1201 resource=(Resource)content; 1200 OutputWriter()
1202 _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified()); 1201 {
1203 content=resource.getInputStream(); 1202 super(AbstractHttpConnection.this._out);
1204 } 1203 }
1205 1204 }
1206 // Process content.
1207 if (content instanceof Buffer)
1208 {
1209 super._generator.addContent((Buffer) content, Generator.LAST);
1210 commitResponse(Generator.LAST);
1211 }
1212 else if (content instanceof InputStream)
1213 {
1214 InputStream in = (InputStream)content;
1215
1216 try
1217 {
1218 int max = super._generator.prepareUncheckedAddContent();
1219 Buffer buffer = super._generator.getUncheckedBuffer();
1220
1221 int len=buffer.readFrom(in,max);
1222
1223 while (len>=0)
1224 {
1225 super._generator.completeUncheckedAddContent();
1226 _out.flush();
1227
1228 max = super._generator.prepareUncheckedAddContent();
1229 buffer = super._generator.getUncheckedBuffer();
1230 len=buffer.readFrom(in,max);
1231 }
1232 super._generator.completeUncheckedAddContent();
1233 _out.flush();
1234 }
1235 finally
1236 {
1237 if (resource!=null)
1238 resource.release();
1239 else
1240 in.close();
1241 }
1242 }
1243 else
1244 throw new IllegalArgumentException("unknown content type?");
1245
1246
1247 }
1248 }
1249
1250 /* ------------------------------------------------------------ */
1251 /* ------------------------------------------------------------ */
1252 /* ------------------------------------------------------------ */
1253 public class OutputWriter extends HttpWriter
1254 {
1255 OutputWriter()
1256 {
1257 super(AbstractHttpConnection.this._out);
1258 }
1259 }
1260 1205
1261 1206
1262 } 1207 }