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