Mercurial Hosting > luan
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 } |