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