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