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