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