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