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.PrintWriter;
18 import java.util.Collections;
19 import java.util.Enumeration;
20 import java.util.Locale;
21
22 import javax.servlet.ServletOutputStream;
23 import javax.servlet.http.Cookie;
24 import javax.servlet.http.HttpServletResponse;
25 import javax.servlet.http.HttpSession;
26
27 import org.eclipse.jetty.http.HttpCookie;
28 import org.eclipse.jetty.http.HttpFields;
29 import org.eclipse.jetty.http.HttpGenerator;
30 import org.eclipse.jetty.http.HttpHeaderValues;
31 import org.eclipse.jetty.http.HttpHeaders;
32 import org.eclipse.jetty.http.HttpStatus;
33 import org.eclipse.jetty.http.HttpURI;
34 import org.eclipse.jetty.http.HttpVersions;
35 import org.eclipse.jetty.http.MimeTypes;
36 import org.eclipse.jetty.io.BufferCache.CachedBuffer;
37 import org.eclipse.jetty.server.handler.ContextHandler;
38 import org.eclipse.jetty.server.handler.ErrorHandler;
39 import org.eclipse.jetty.util.ByteArrayISO8859Writer;
40 import org.eclipse.jetty.util.IO;
41 import org.eclipse.jetty.util.QuotedStringTokenizer;
42 import org.eclipse.jetty.util.StringUtil;
43 import org.eclipse.jetty.util.URIUtil;
44 import org.eclipse.jetty.util.log.Log;
45
46
47
48
49
50
51
52
53
54
55 public class Response implements HttpServletResponse
56 {
57 public static final int
58 NONE=0,
59 STREAM=1,
60 WRITER=2;
61
62
63
64
65
66
67 public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include.";
68
69 private static final PrintWriter __nullPrintWriter;
70 private static final ServletOutputStream __nullServletOut;
71
72 static
73 {
74 __nullPrintWriter = new PrintWriter(IO.getNullWriter());
75 __nullServletOut = new NullOutput();
76 }
77
78 private final HttpConnection _connection;
79 private int _status=SC_OK;
80 private String _reason;
81 private Locale _locale;
82 private String _mimeType;
83 private CachedBuffer _cachedMimeType;
84 private String _characterEncoding;
85 private boolean _explicitEncoding;
86 private String _contentType;
87 private int _outputState;
88 private PrintWriter _writer;
89
90
91
92
93
94 public Response(HttpConnection connection)
95 {
96 _connection=connection;
97 }
98
99
100
101
102
103
104 protected void recycle()
105 {
106 _status=SC_OK;
107 _reason=null;
108 _locale=null;
109 _mimeType=null;
110 _cachedMimeType=null;
111 _characterEncoding=null;
112 _explicitEncoding=false;
113 _contentType=null;
114 _outputState=NONE;
115 _writer=null;
116 }
117
118
119
120
121
122 public void addCookie(HttpCookie cookie)
123 {
124 _connection.getResponseFields().addSetCookie(cookie);
125 }
126
127
128
129
130
131 public void addCookie(Cookie cookie)
132 {
133 _connection.getResponseFields().addSetCookie(cookie.getName(),
134 cookie.getValue(),
135 cookie.getDomain(),
136 cookie.getPath(),
137 cookie.getMaxAge(),
138 cookie.getComment(),
139 cookie.getSecure(),
140 false,
141 cookie.getVersion());
142 }
143
144
145
146
147
148 public boolean containsHeader(String name)
149 {
150 return _connection.getResponseFields().containsKey(name);
151 }
152
153
154
155
156
157 public String encodeURL(String url)
158 {
159 Request request=_connection.getRequest();
160 SessionManager sessionManager = request.getSessionManager();
161 if (sessionManager==null)
162 return url;
163 String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix();
164 if (sessionURLPrefix==null)
165 return url;
166
167 if (url==null)
168 return null;
169
170 if (request.isRequestedSessionIdFromCookie())
171 {
172 int prefix=url.indexOf(sessionURLPrefix);
173 if (prefix!=-1)
174 {
175 int suffix=url.indexOf("?",prefix);
176 if (suffix<0)
177 suffix=url.indexOf("#",prefix);
178
179 if (suffix<=prefix)
180 return url.substring(0,prefix);
181 return url.substring(0,prefix)+url.substring(suffix);
182 }
183 return url;
184 }
185
186
187 HttpSession session=request.getSession(false);
188
189
190 if (session == null)
191 return url;
192
193
194
195 if (!sessionManager.isValid(session))
196 return url;
197
198 String id=sessionManager.getNodeId(session);
199
200
201
202
203 int prefix=url.indexOf(sessionURLPrefix);
204 if (prefix!=-1)
205 {
206 int suffix=url.indexOf("?",prefix);
207 if (suffix<0)
208 suffix=url.indexOf("#",prefix);
209
210 if (suffix<=prefix)
211 return url.substring(0,prefix+sessionURLPrefix.length())+id;
212 return url.substring(0,prefix+sessionURLPrefix.length())+id+
213 url.substring(suffix);
214 }
215
216
217 int suffix=url.indexOf('?');
218 if (suffix<0)
219 suffix=url.indexOf('#');
220 if (suffix<0)
221 return url+sessionURLPrefix+id;
222 return url.substring(0,suffix)+
223 sessionURLPrefix+id+url.substring(suffix);
224 }
225
226
227
228
229
230 public String encodeRedirectURL(String url)
231 {
232 return encodeURL(url);
233 }
234
235
236
237
238
239 public String encodeUrl(String url)
240 {
241 return encodeURL(url);
242 }
243
244
245
246
247
248 public String encodeRedirectUrl(String url)
249 {
250 return encodeURL(url);
251 }
252
253
254
255
256
257 public void sendError(int code, String message) throws IOException
258 {
259 if (_connection.isIncluding())
260 return;
261
262 if (isCommitted())
263 Log.warn("Committed before "+code+" "+message);
264
265 resetBuffer();
266 _characterEncoding=null;
267 setHeader(HttpHeaders.EXPIRES,null);
268 setHeader(HttpHeaders.LAST_MODIFIED,null);
269 setHeader(HttpHeaders.CACHE_CONTROL,null);
270 setHeader(HttpHeaders.CONTENT_TYPE,null);
271 setHeader(HttpHeaders.CONTENT_LENGTH,null);
272
273 _outputState=NONE;
274 setStatus(code,message);
275
276 if (message==null)
277 message=HttpStatus.getMessage(code);
278
279
280 if (code!=SC_NO_CONTENT &&
281 code!=SC_NOT_MODIFIED &&
282 code!=SC_PARTIAL_CONTENT &&
283 code>=SC_OK)
284 {
285 Request request = _connection.getRequest();
286
287 ErrorHandler error_handler = null;
288 ContextHandler.Context context = request.getContext();
289 if (context!=null)
290 error_handler=context.getContextHandler().getErrorHandler();
291 if (error_handler!=null)
292 {
293
294 request.setAttribute(Dispatcher.ERROR_STATUS_CODE,new Integer(code));
295 request.setAttribute(Dispatcher.ERROR_MESSAGE, message);
296 request.setAttribute(Dispatcher.ERROR_REQUEST_URI, request.getRequestURI());
297 request.setAttribute(Dispatcher.ERROR_SERVLET_NAME,request.getServletName());
298
299 error_handler.handle(null,_connection.getRequest(),_connection.getRequest(),this );
300 }
301 else
302 {
303 setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store");
304 setContentType(MimeTypes.TEXT_HTML_8859_1);
305 ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048);
306 if (message != null)
307 {
308 message= StringUtil.replace(message, "&", "&");
309 message= StringUtil.replace(message, "<", "<");
310 message= StringUtil.replace(message, ">", ">");
311 }
312 String uri= request.getRequestURI();
313 if (uri!=null)
314 {
315 uri= StringUtil.replace(uri, "&", "&");
316 uri= StringUtil.replace(uri, "<", "<");
317 uri= StringUtil.replace(uri, ">", ">");
318 }
319
320 writer.write("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n");
321 writer.write("<title>Error ");
322 writer.write(Integer.toString(code));
323 writer.write(' ');
324 if (message==null)
325 message=HttpStatus.getMessage(code);
326 writer.write(message);
327 writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: ");
328 writer.write(Integer.toString(code));
329 writer.write("</h2>\n<p>Problem accessing ");
330 writer.write(uri);
331 writer.write(". Reason:\n<pre> ");
332 writer.write(message);
333 writer.write("</pre>");
334 writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>");
335
336 for (int i= 0; i < 20; i++)
337 writer.write("\n ");
338 writer.write("\n</body>\n</html>\n");
339
340 writer.flush();
341 setContentLength(writer.size());
342 writer.writeTo(getOutputStream());
343 writer.destroy();
344 }
345 }
346 else if (code!=SC_PARTIAL_CONTENT)
347 {
348 _connection.getRequestFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
349 _connection.getRequestFields().remove(HttpHeaders.CONTENT_LENGTH_BUFFER);
350 _characterEncoding=null;
351 _mimeType=null;
352 _cachedMimeType=null;
353 }
354
355 complete();
356 }
357
358
359
360
361
362 public void sendError(int sc) throws IOException
363 {
364 if (sc==102)
365 sendProcessing();
366 else
367 sendError(sc,null);
368 }
369
370
371
372
373
374
375
376
377
378 public void sendProcessing() throws IOException
379 {
380 if (_connection.isExpecting102Processing() && !isCommitted())
381 ((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102);
382 }
383
384
385
386
387
388 public void sendRedirect(String location) throws IOException
389 {
390 if (_connection.isIncluding())
391 return;
392
393 if (location==null)
394 throw new IllegalArgumentException();
395
396 if (!URIUtil.hasScheme(location))
397 {
398 StringBuilder buf = _connection.getRequest().getRootURL();
399 if (location.startsWith("/"))
400 buf.append(location);
401 else
402 {
403 String path=_connection.getRequest().getRequestURI();
404 String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path);
405 location=URIUtil.addPaths(parent,location);
406 if(location==null)
407 throw new IllegalStateException("path cannot be above root");
408 if (!location.startsWith("/"))
409 buf.append('/');
410 buf.append(location);
411 }
412
413 location=buf.toString();
414 HttpURI uri = new HttpURI(location);
415 String path=uri.getDecodedPath();
416 String canonical=URIUtil.canonicalPath(path);
417 if (canonical==null)
418 throw new IllegalArgumentException();
419 if (!canonical.equals(path))
420 {
421 buf = _connection.getRequest().getRootURL();
422 buf.append(canonical);
423 if (uri.getQuery()!=null)
424 {
425 buf.append('?');
426 buf.append(uri.getQuery());
427 }
428 if (uri.getFragment()!=null)
429 {
430 buf.append('#');
431 buf.append(uri.getFragment());
432 }
433 location=buf.toString();
434 }
435 }
436 resetBuffer();
437
438 setHeader(HttpHeaders.LOCATION,location);
439 setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
440 complete();
441
442 }
443
444
445
446
447
448 public void setDateHeader(String name, long date)
449 {
450 if (!_connection.isIncluding())
451 _connection.getResponseFields().putDateField(name, date);
452 }
453
454
455
456
457
458 public void addDateHeader(String name, long date)
459 {
460 if (!_connection.isIncluding())
461 _connection.getResponseFields().addDateField(name, date);
462 }
463
464
465
466
467
468 public void setHeader(String name, String value)
469 {
470 if (_connection.isIncluding())
471 {
472 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
473 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
474 else
475 return;
476 }
477 _connection.getResponseFields().put(name, value);
478 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
479 {
480 if (value==null)
481 _connection._generator.setContentLength(-1);
482 else
483 _connection._generator.setContentLength(Long.parseLong(value));
484 }
485 }
486
487
488
489
490 public String getHeader(String name)
491 {
492 return _connection.getResponseFields().getStringField(name);
493 }
494
495
496
497
498 public Enumeration getHeaders(String name)
499 {
500 Enumeration e = _connection.getResponseFields().getValues(name);
501 if (e==null)
502 return Collections.enumeration(Collections.EMPTY_LIST);
503 return e;
504 }
505
506
507
508
509
510 public void addHeader(String name, String value)
511 {
512 if (_connection.isIncluding())
513 {
514 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
515 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
516 else
517 return;
518 }
519
520 _connection.getResponseFields().add(name, value);
521 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
522 _connection._generator.setContentLength(Long.parseLong(value));
523 }
524
525
526
527
528
529 public void setIntHeader(String name, int value)
530 {
531 if (!_connection.isIncluding())
532 {
533 _connection.getResponseFields().putLongField(name, value);
534 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
535 _connection._generator.setContentLength(value);
536 }
537 }
538
539
540
541
542
543 public void addIntHeader(String name, int value)
544 {
545 if (!_connection.isIncluding())
546 {
547 _connection.getResponseFields().addLongField(name, value);
548 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
549 _connection._generator.setContentLength(value);
550 }
551 }
552
553
554
555
556
557 public void setStatus(int sc)
558 {
559 setStatus(sc,null);
560 }
561
562
563
564
565
566 public void setStatus(int sc, String sm)
567 {
568 if (sc<=0)
569 throw new IllegalArgumentException();
570 if (!_connection.isIncluding())
571 {
572 _status=sc;
573 _reason=sm;
574 }
575 }
576
577
578
579
580
581 public String getCharacterEncoding()
582 {
583 if (_characterEncoding==null)
584 _characterEncoding=StringUtil.__ISO_8859_1;
585 return _characterEncoding;
586 }
587
588
589 String getSetCharacterEncoding()
590 {
591 return _characterEncoding;
592 }
593
594
595
596
597
598 public String getContentType()
599 {
600 return _contentType;
601 }
602
603
604
605
606
607 public ServletOutputStream getOutputStream() throws IOException
608 {
609 if (_outputState!=NONE && _outputState!=STREAM)
610 throw new IllegalStateException("WRITER");
611
612 _outputState=STREAM;
613 return _connection.getOutputStream();
614 }
615
616
617 public boolean isWriting()
618 {
619 return _outputState==WRITER;
620 }
621
622
623 public boolean isOutputing()
624 {
625 return _outputState!=NONE;
626 }
627
628
629
630
631
632 public PrintWriter getWriter() throws IOException
633 {
634 if (_outputState!=NONE && _outputState!=WRITER)
635 throw new IllegalStateException("STREAM");
636
637
638 if (_writer==null)
639 {
640
641 String encoding = _characterEncoding;
642
643 if (encoding==null)
644 {
645
646 if(_mimeType!=null)
647 encoding = null;
648
649 if (encoding==null)
650 encoding = StringUtil.__ISO_8859_1;
651
652 setCharacterEncoding(encoding);
653 }
654
655
656 _writer = _connection.getPrintWriter(encoding);
657 }
658 _outputState=WRITER;
659 return _writer;
660 }
661
662
663
664
665
666 public void setCharacterEncoding(String encoding)
667 {
668 if (_connection.isIncluding())
669 return;
670
671 if (this._outputState==0 && !isCommitted())
672 {
673 _explicitEncoding=true;
674
675 if (encoding==null)
676 {
677
678 if (_characterEncoding!=null)
679 {
680 _characterEncoding=null;
681 if (_cachedMimeType!=null)
682 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType);
683 else
684 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_mimeType);
685 }
686 }
687 else
688 {
689
690 _characterEncoding=encoding;
691 if (_contentType!=null)
692 {
693 int i0=_contentType.indexOf(';');
694 if (i0<0)
695 {
696 _contentType=null;
697 if(_cachedMimeType!=null)
698 {
699 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
700 if (content_type!=null)
701 {
702 _contentType=content_type.toString();
703 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
704 }
705 }
706
707 if (_contentType==null)
708 {
709 _contentType = _mimeType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
710 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
711 }
712 }
713 else
714 {
715 int i1=_contentType.indexOf("charset=",i0);
716 if (i1<0)
717 {
718 _contentType = _contentType+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
719 }
720 else
721 {
722 int i8=i1+8;
723 int i2=_contentType.indexOf(" ",i8);
724 if (i2<0)
725 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quote(_characterEncoding,";= ");
726 else
727 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quote(_characterEncoding,";= ")+_contentType.substring(i2);
728 }
729 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
730 }
731 }
732 }
733 }
734 }
735
736
737
738
739
740 public void setContentLength(int len)
741 {
742
743
744
745 if (isCommitted() || _connection.isIncluding())
746 return;
747 _connection._generator.setContentLength(len);
748 if (len>=0)
749 {
750 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
751 if (_connection._generator.isContentWritten())
752 {
753 if (_outputState==WRITER)
754 _writer.close();
755 else if (_outputState==STREAM)
756 {
757 try
758 {
759 getOutputStream().close();
760 }
761 catch(IOException e)
762 {
763 throw new RuntimeException(e);
764 }
765 }
766 }
767 }
768 }
769
770
771
772
773
774 public void setLongContentLength(long len)
775 {
776
777
778
779 if (isCommitted() || _connection.isIncluding())
780 return;
781 _connection._generator.setContentLength(len);
782 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
783 }
784
785
786
787
788
789 public void setContentType(String contentType)
790 {
791 if (isCommitted() || _connection.isIncluding())
792 return;
793
794
795
796
797
798 if (contentType==null)
799 {
800 if (_locale==null)
801 _characterEncoding=null;
802 _mimeType=null;
803 _cachedMimeType=null;
804 _contentType=null;
805 _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
806 }
807 else
808 {
809
810 int i0=contentType.indexOf(';');
811
812 if (i0>0)
813 {
814
815
816
817 _mimeType=contentType.substring(0,i0).trim();
818 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
819
820
821 int i1=contentType.indexOf("charset=",i0+1);
822 if (i1>=0)
823 {
824 _explicitEncoding=true;
825 int i8=i1+8;
826 int i2 = contentType.indexOf(' ',i8);
827
828 if (_outputState==WRITER)
829 {
830
831 if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
832 {
833 if (_cachedMimeType!=null)
834 {
835 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
836 if (content_type!=null)
837 {
838 _contentType=content_type.toString();
839 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
840 }
841 else
842 {
843 _contentType=_mimeType+";charset="+_characterEncoding;
844 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
845 }
846 }
847 else
848 {
849 _contentType=_mimeType+";charset="+_characterEncoding;
850 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
851 }
852 }
853 else if (i2<0)
854 {
855 _contentType=contentType.substring(0,i1)+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
856 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
857 }
858 else
859 {
860 _contentType=contentType.substring(0,i1)+contentType.substring(i2)+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
861 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
862 }
863 }
864 else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
865 {
866
867 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
868 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
869
870 if (_cachedMimeType!=null)
871 {
872 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
873 if (content_type!=null)
874 {
875 _contentType=content_type.toString();
876 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
877 }
878 else
879 {
880 _contentType=contentType;
881 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
882 }
883 }
884 else
885 {
886 _contentType=contentType;
887 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
888 }
889 }
890 else if (i2>0)
891 {
892 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2));
893 _contentType=contentType;
894 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
895 }
896 else
897 {
898 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
899 _contentType=contentType;
900 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
901 }
902 }
903 else
904 {
905 _cachedMimeType=null;
906 _contentType=_characterEncoding==null?contentType:contentType+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
907 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
908 }
909 }
910 else
911 {
912 _mimeType=contentType;
913 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
914
915 if (_characterEncoding!=null)
916 {
917 if (_cachedMimeType!=null)
918 {
919 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
920 if (content_type!=null)
921 {
922 _contentType=content_type.toString();
923 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
924 }
925 else
926 {
927 _contentType=_mimeType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
928 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
929 }
930 }
931 else
932 {
933 _contentType=contentType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
934 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
935 }
936 }
937 else if (_cachedMimeType!=null)
938 {
939 _contentType=_cachedMimeType.toString();
940 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType);
941 }
942 else
943 {
944 _contentType=contentType;
945 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
946 }
947 }
948 }
949 }
950
951
952
953
954
955 public void setBufferSize(int size)
956 {
957 if (isCommitted() || getContentCount()>0)
958 throw new IllegalStateException("Committed or content written");
959 _connection.getGenerator().increaseContentBufferSize(size);
960 }
961
962
963
964
965
966 public int getBufferSize()
967 {
968 return _connection.getGenerator().getContentBufferSize();
969 }
970
971
972
973
974
975 public void flushBuffer() throws IOException
976 {
977 _connection.flushResponse();
978 }
979
980
981
982
983
984 public void reset()
985 {
986 resetBuffer();
987 fwdReset();
988 _status=200;
989 _reason=null;
990
991 HttpFields response_fields=_connection.getResponseFields();
992
993 response_fields.clear();
994 String connection=_connection.getRequestFields().getStringField(HttpHeaders.CONNECTION_BUFFER);
995 if (connection!=null)
996 {
997 String[] values = connection.split(",");
998 for (int i=0;values!=null && i<values.length;i++)
999 {
1000 CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim());
1001
1002 if (cb!=null)
1003 {
1004 switch(cb.getOrdinal())
1005 {
1006 case HttpHeaderValues.CLOSE_ORDINAL:
1007 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
1008 break;
1009
1010 case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
1011 if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol()))
1012 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE);
1013 break;
1014 case HttpHeaderValues.TE_ORDINAL:
1015 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.TE);
1016 break;
1017 }
1018 }
1019 }
1020 }
1021 }
1022
1023
1024
1025
1026
1027 public void fwdReset()
1028 {
1029 resetBuffer();
1030 _mimeType=null;
1031 _cachedMimeType=null;
1032 _contentType=null;
1033 _characterEncoding=null;
1034 _explicitEncoding=false;
1035 _locale=null;
1036 _outputState=NONE;
1037 _writer=null;
1038 }
1039
1040
1041
1042
1043
1044 public void resetBuffer()
1045 {
1046 if (isCommitted())
1047 throw new IllegalStateException("Committed");
1048 _connection.getGenerator().resetBuffer();
1049 }
1050
1051
1052
1053
1054
1055 public boolean isCommitted()
1056 {
1057 return _connection.isResponseCommitted();
1058 }
1059
1060
1061
1062
1063
1064
1065 public void setLocale(Locale locale)
1066 {
1067 if (locale == null || isCommitted() ||_connection.isIncluding())
1068 return;
1069
1070 _locale = locale;
1071 _connection.getResponseFields().put(HttpHeaders.CONTENT_LANGUAGE_BUFFER,locale.toString().replace('_','-'));
1072
1073 if (_explicitEncoding || _outputState!=0 )
1074 return;
1075
1076 if (_connection.getRequest().getContext()==null)
1077 return;
1078
1079 String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale);
1080
1081 if (charset!=null && charset.length()>0)
1082 {
1083 _characterEncoding=charset;
1084
1085
1086 String type=getContentType();
1087 if (type!=null)
1088 {
1089 _characterEncoding=charset;
1090 int semi=type.indexOf(';');
1091 if (semi<0)
1092 {
1093 _mimeType=type;
1094 _contentType= type += ";charset="+charset;
1095 }
1096 else
1097 {
1098 _mimeType=type.substring(0,semi);
1099 _contentType= _mimeType += ";charset="+charset;
1100 }
1101
1102 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
1103 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
1104 }
1105 }
1106 }
1107
1108
1109
1110
1111
1112 public Locale getLocale()
1113 {
1114 if (_locale==null)
1115 return Locale.getDefault();
1116 return _locale;
1117 }
1118
1119
1120
1121
1122
1123
1124 public int getStatus()
1125 {
1126 return _status;
1127 }
1128
1129
1130
1131
1132
1133
1134 public String getReason()
1135 {
1136 return _reason;
1137 }
1138
1139
1140
1141
1142 public void complete()
1143 throws IOException
1144 {
1145 _connection.completeResponse();
1146 }
1147
1148
1149
1150
1151
1152 public long getContentCount()
1153 {
1154 if (_connection==null || _connection.getGenerator()==null)
1155 return -1;
1156 return _connection.getGenerator().getContentWritten();
1157 }
1158
1159
1160 public HttpFields getHttpFields()
1161 {
1162 return _connection.getResponseFields();
1163 }
1164
1165
1166 @Override
1167 public String toString()
1168 {
1169 return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+
1170 _connection.getResponseFields().toString();
1171 }
1172
1173
1174
1175
1176 private static class NullOutput extends ServletOutputStream
1177 {
1178 @Override
1179 public void write(int b) throws IOException
1180 {
1181 }
1182
1183 @Override
1184 public void print(String s) throws IOException
1185 {
1186 }
1187
1188 @Override
1189 public void println(String s) throws IOException
1190 {
1191 }
1192
1193 @Override
1194 public void write(byte[] b, int off, int len) throws IOException
1195 {
1196 }
1197
1198 }
1199
1200 }