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())
383 {
384 Generator g = _connection.getGenerator();
385 if (g instanceof HttpGenerator)
386 {
387 HttpGenerator generator = (HttpGenerator)g;
388 boolean was_persistent=generator.isPersistent();
389 generator.setResponse(102,null);
390 generator.completeHeader(null,true);
391 generator.setPersistent(true);
392 generator.complete();
393 generator.flushBuffer();
394 generator.reset(false);
395 generator.setPersistent(was_persistent);
396 }
397 }
398 }
399
400
401
402
403
404 public void sendRedirect(String location) throws IOException
405 {
406 if (_connection.isIncluding())
407 return;
408
409 if (location==null)
410 throw new IllegalArgumentException();
411
412 if (!URIUtil.hasScheme(location))
413 {
414 StringBuilder buf = _connection.getRequest().getRootURL();
415 if (location.startsWith("/"))
416 buf.append(location);
417 else
418 {
419 String path=_connection.getRequest().getRequestURI();
420 String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path);
421 location=URIUtil.addPaths(parent,location);
422 if(location==null)
423 throw new IllegalStateException("path cannot be above root");
424 if (!location.startsWith("/"))
425 buf.append('/');
426 buf.append(location);
427 }
428
429 location=buf.toString();
430 HttpURI uri = new HttpURI(location);
431 String path=uri.getDecodedPath();
432 String canonical=URIUtil.canonicalPath(path);
433 if (canonical==null)
434 throw new IllegalArgumentException();
435 if (!canonical.equals(path))
436 {
437 buf = _connection.getRequest().getRootURL();
438 buf.append(canonical);
439 if (uri.getQuery()!=null)
440 {
441 buf.append('?');
442 buf.append(uri.getQuery());
443 }
444 if (uri.getFragment()!=null)
445 {
446 buf.append('#');
447 buf.append(uri.getFragment());
448 }
449 location=buf.toString();
450 }
451 }
452 resetBuffer();
453
454 setHeader(HttpHeaders.LOCATION,location);
455 setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
456 complete();
457
458 }
459
460
461
462
463
464 public void setDateHeader(String name, long date)
465 {
466 if (!_connection.isIncluding())
467 _connection.getResponseFields().putDateField(name, date);
468 }
469
470
471
472
473
474 public void addDateHeader(String name, long date)
475 {
476 if (!_connection.isIncluding())
477 _connection.getResponseFields().addDateField(name, date);
478 }
479
480
481
482
483
484 public void setHeader(String name, String value)
485 {
486 if (_connection.isIncluding())
487 {
488 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
489 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
490 else
491 return;
492 }
493 _connection.getResponseFields().put(name, value);
494 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
495 {
496 if (value==null)
497 _connection._generator.setContentLength(-1);
498 else
499 _connection._generator.setContentLength(Long.parseLong(value));
500 }
501 }
502
503
504
505
506 public String getHeader(String name)
507 {
508 return _connection.getResponseFields().getStringField(name);
509 }
510
511
512
513
514 public Enumeration getHeaders(String name)
515 {
516 Enumeration e = _connection.getResponseFields().getValues(name);
517 if (e==null)
518 return Collections.enumeration(Collections.EMPTY_LIST);
519 return e;
520 }
521
522
523
524
525
526 public void addHeader(String name, String value)
527 {
528 if (_connection.isIncluding())
529 {
530 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
531 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
532 else
533 return;
534 }
535
536 _connection.getResponseFields().add(name, value);
537 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
538 _connection._generator.setContentLength(Long.parseLong(value));
539 }
540
541
542
543
544
545 public void setIntHeader(String name, int value)
546 {
547 if (!_connection.isIncluding())
548 {
549 _connection.getResponseFields().putLongField(name, value);
550 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
551 _connection._generator.setContentLength(value);
552 }
553 }
554
555
556
557
558
559 public void addIntHeader(String name, int value)
560 {
561 if (!_connection.isIncluding())
562 {
563 _connection.getResponseFields().addLongField(name, value);
564 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
565 _connection._generator.setContentLength(value);
566 }
567 }
568
569
570
571
572
573 public void setStatus(int sc)
574 {
575 setStatus(sc,null);
576 }
577
578
579
580
581
582 public void setStatus(int sc, String sm)
583 {
584 if (sc<=0)
585 throw new IllegalArgumentException();
586 if (!_connection.isIncluding())
587 {
588 _status=sc;
589 _reason=sm;
590 }
591 }
592
593
594
595
596
597 public String getCharacterEncoding()
598 {
599 if (_characterEncoding==null)
600 _characterEncoding=StringUtil.__ISO_8859_1;
601 return _characterEncoding;
602 }
603
604
605 String getSetCharacterEncoding()
606 {
607 return _characterEncoding;
608 }
609
610
611
612
613
614 public String getContentType()
615 {
616 return _contentType;
617 }
618
619
620
621
622
623 public ServletOutputStream getOutputStream() throws IOException
624 {
625 if (_outputState!=NONE && _outputState!=STREAM)
626 throw new IllegalStateException("WRITER");
627
628 _outputState=STREAM;
629 return _connection.getOutputStream();
630 }
631
632
633 public boolean isWriting()
634 {
635 return _outputState==WRITER;
636 }
637
638
639 public boolean isOutputing()
640 {
641 return _outputState!=NONE;
642 }
643
644
645
646
647
648 public PrintWriter getWriter() throws IOException
649 {
650 if (_outputState!=NONE && _outputState!=WRITER)
651 throw new IllegalStateException("STREAM");
652
653
654 if (_writer==null)
655 {
656
657 String encoding = _characterEncoding;
658
659 if (encoding==null)
660 {
661
662 if(_mimeType!=null)
663 encoding = null;
664
665 if (encoding==null)
666 encoding = StringUtil.__ISO_8859_1;
667
668 setCharacterEncoding(encoding);
669 }
670
671
672 _writer = _connection.getPrintWriter(encoding);
673 }
674 _outputState=WRITER;
675 return _writer;
676 }
677
678
679
680
681
682 public void setCharacterEncoding(String encoding)
683 {
684 if (_connection.isIncluding())
685 return;
686
687 if (this._outputState==0 && !isCommitted())
688 {
689 _explicitEncoding=true;
690
691 if (encoding==null)
692 {
693
694 if (_characterEncoding!=null)
695 {
696 _characterEncoding=null;
697 if (_cachedMimeType!=null)
698 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType);
699 else
700 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_mimeType);
701 }
702 }
703 else
704 {
705
706 _characterEncoding=encoding;
707 if (_contentType!=null)
708 {
709 int i0=_contentType.indexOf(';');
710 if (i0<0)
711 {
712 _contentType=null;
713 if(_cachedMimeType!=null)
714 {
715 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
716 if (content_type!=null)
717 {
718 _contentType=content_type.toString();
719 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
720 }
721 }
722
723 if (_contentType==null)
724 {
725 _contentType = _mimeType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
726 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
727 }
728 }
729 else
730 {
731 int i1=_contentType.indexOf("charset=",i0);
732 if (i1<0)
733 {
734 _contentType = _contentType+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
735 }
736 else
737 {
738 int i8=i1+8;
739 int i2=_contentType.indexOf(" ",i8);
740 if (i2<0)
741 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quote(_characterEncoding,";= ");
742 else
743 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quote(_characterEncoding,";= ")+_contentType.substring(i2);
744 }
745 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
746 }
747 }
748 }
749 }
750 }
751
752
753
754
755
756 public void setContentLength(int len)
757 {
758
759
760
761 if (isCommitted() || _connection.isIncluding())
762 return;
763 _connection._generator.setContentLength(len);
764 if (len>=0)
765 {
766 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
767 if (_connection._generator.isContentWritten())
768 {
769 if (_outputState==WRITER)
770 _writer.close();
771 else if (_outputState==STREAM)
772 {
773 try
774 {
775 getOutputStream().close();
776 }
777 catch(IOException e)
778 {
779 throw new RuntimeException(e);
780 }
781 }
782 }
783 }
784 }
785
786
787
788
789
790 public void setLongContentLength(long len)
791 {
792
793
794
795 if (isCommitted() || _connection.isIncluding())
796 return;
797 _connection._generator.setContentLength(len);
798 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
799 }
800
801
802
803
804
805 public void setContentType(String contentType)
806 {
807 if (isCommitted() || _connection.isIncluding())
808 return;
809
810
811
812
813
814 if (contentType==null)
815 {
816 if (_locale==null)
817 _characterEncoding=null;
818 _mimeType=null;
819 _cachedMimeType=null;
820 _contentType=null;
821 _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
822 }
823 else
824 {
825
826 int i0=contentType.indexOf(';');
827
828 if (i0>0)
829 {
830
831
832
833 _mimeType=contentType.substring(0,i0).trim();
834 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
835
836
837 int i1=contentType.indexOf("charset=",i0+1);
838 if (i1>=0)
839 {
840 _explicitEncoding=true;
841 int i8=i1+8;
842 int i2 = contentType.indexOf(' ',i8);
843
844 if (_outputState==WRITER)
845 {
846
847 if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
848 {
849 if (_cachedMimeType!=null)
850 {
851 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
852 if (content_type!=null)
853 {
854 _contentType=content_type.toString();
855 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
856 }
857 else
858 {
859 _contentType=_mimeType+";charset="+_characterEncoding;
860 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
861 }
862 }
863 else
864 {
865 _contentType=_mimeType+";charset="+_characterEncoding;
866 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
867 }
868 }
869 else if (i2<0)
870 {
871 _contentType=contentType.substring(0,i1)+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
872 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
873 }
874 else
875 {
876 _contentType=contentType.substring(0,i1)+contentType.substring(i2)+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
877 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
878 }
879 }
880 else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
881 {
882
883 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
884 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
885
886 if (_cachedMimeType!=null)
887 {
888 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
889 if (content_type!=null)
890 {
891 _contentType=content_type.toString();
892 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
893 }
894 else
895 {
896 _contentType=contentType;
897 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
898 }
899 }
900 else
901 {
902 _contentType=contentType;
903 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
904 }
905 }
906 else if (i2>0)
907 {
908 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2));
909 _contentType=contentType;
910 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
911 }
912 else
913 {
914 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
915 _contentType=contentType;
916 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
917 }
918 }
919 else
920 {
921 _cachedMimeType=null;
922 _contentType=_characterEncoding==null?contentType:contentType+" charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
923 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
924 }
925 }
926 else
927 {
928 _mimeType=contentType;
929 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
930
931 if (_characterEncoding!=null)
932 {
933 if (_cachedMimeType!=null)
934 {
935 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
936 if (content_type!=null)
937 {
938 _contentType=content_type.toString();
939 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
940 }
941 else
942 {
943 _contentType=_mimeType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
944 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
945 }
946 }
947 else
948 {
949 _contentType=contentType+";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= ");
950 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
951 }
952 }
953 else if (_cachedMimeType!=null)
954 {
955 _contentType=_cachedMimeType.toString();
956 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType);
957 }
958 else
959 {
960 _contentType=contentType;
961 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
962 }
963 }
964 }
965 }
966
967
968
969
970
971 public void setBufferSize(int size)
972 {
973 if (isCommitted() || getContentCount()>0)
974 throw new IllegalStateException("Committed or content written");
975 _connection.getGenerator().increaseContentBufferSize(size);
976 }
977
978
979
980
981
982 public int getBufferSize()
983 {
984 return _connection.getGenerator().getContentBufferSize();
985 }
986
987
988
989
990
991 public void flushBuffer() throws IOException
992 {
993 _connection.flushResponse();
994 }
995
996
997
998
999
1000 public void reset()
1001 {
1002 fwdReset();
1003 _status=200;
1004 _reason=null;
1005
1006 HttpFields response_fields=_connection.getResponseFields();
1007
1008 response_fields.clear();
1009 String connection=_connection.getRequestFields().getStringField(HttpHeaders.CONNECTION_BUFFER);
1010 if (connection!=null)
1011 {
1012 String[] values = connection.split(",");
1013 for (int i=0;values!=null && i<values.length;i++)
1014 {
1015 CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim());
1016
1017 if (cb!=null)
1018 {
1019 switch(cb.getOrdinal())
1020 {
1021 case HttpHeaderValues.CLOSE_ORDINAL:
1022 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
1023 break;
1024
1025 case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
1026 if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol()))
1027 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE);
1028 break;
1029 case HttpHeaderValues.TE_ORDINAL:
1030 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.TE);
1031 break;
1032 }
1033 }
1034 }
1035 }
1036
1037 if (_connection.getConnector().getServer().getSendDateHeader())
1038 {
1039 Request request=_connection.getRequest();
1040 response_fields.put(HttpHeaders.DATE_BUFFER, request.getTimeStampBuffer(),request.getTimeStamp());
1041 }
1042 }
1043
1044
1045
1046
1047
1048 public void fwdReset()
1049 {
1050 resetBuffer();
1051 _mimeType=null;
1052 _cachedMimeType=null;
1053 _contentType=null;
1054 _characterEncoding=null;
1055 _explicitEncoding=false;
1056 _locale=null;
1057 _outputState=NONE;
1058 _writer=null;
1059 }
1060
1061
1062
1063
1064
1065 public void resetBuffer()
1066 {
1067 if (isCommitted())
1068 throw new IllegalStateException("Committed");
1069 _connection.getGenerator().resetBuffer();
1070 }
1071
1072
1073
1074
1075
1076 public boolean isCommitted()
1077 {
1078 return _connection.isResponseCommitted();
1079 }
1080
1081
1082
1083
1084
1085
1086 public void setLocale(Locale locale)
1087 {
1088 if (locale == null || isCommitted() ||_connection.isIncluding())
1089 return;
1090
1091 _locale = locale;
1092 _connection.getResponseFields().put(HttpHeaders.CONTENT_LANGUAGE_BUFFER,locale.toString().replace('_','-'));
1093
1094 if (_explicitEncoding || _outputState!=0 )
1095 return;
1096
1097 if (_connection.getRequest().getContext()==null)
1098 return;
1099
1100 String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale);
1101
1102 if (charset!=null && charset.length()>0)
1103 {
1104 _characterEncoding=charset;
1105
1106
1107 String type=getContentType();
1108 if (type!=null)
1109 {
1110 _characterEncoding=charset;
1111 int semi=type.indexOf(';');
1112 if (semi<0)
1113 {
1114 _mimeType=type;
1115 _contentType= type += ";charset="+charset;
1116 }
1117 else
1118 {
1119 _mimeType=type.substring(0,semi);
1120 _contentType= _mimeType += ";charset="+charset;
1121 }
1122
1123 _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
1124 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
1125 }
1126 }
1127 }
1128
1129
1130
1131
1132
1133 public Locale getLocale()
1134 {
1135 if (_locale==null)
1136 return Locale.getDefault();
1137 return _locale;
1138 }
1139
1140
1141
1142
1143
1144
1145 public int getStatus()
1146 {
1147 return _status;
1148 }
1149
1150
1151
1152
1153
1154
1155 public String getReason()
1156 {
1157 return _reason;
1158 }
1159
1160
1161
1162
1163 public void complete()
1164 throws IOException
1165 {
1166 _connection.completeResponse();
1167 }
1168
1169
1170
1171
1172
1173 public long getContentCount()
1174 {
1175 if (_connection==null || _connection.getGenerator()==null)
1176 return -1;
1177 return _connection.getGenerator().getContentWritten();
1178 }
1179
1180
1181 public HttpFields getHttpFields()
1182 {
1183 return _connection.getResponseFields();
1184 }
1185
1186
1187 public String toString()
1188 {
1189 return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+
1190 _connection.getResponseFields().toString();
1191 }
1192
1193
1194
1195
1196 private static class NullOutput extends ServletOutputStream
1197 {
1198 public void write(int b) throws IOException
1199 {
1200 }
1201
1202 public void print(String s) throws IOException
1203 {
1204 }
1205
1206 public void println(String s) throws IOException
1207 {
1208 }
1209
1210 public void write(byte[] b, int off, int len) throws IOException
1211 {
1212 }
1213
1214 }
1215
1216 }