| 1 17 18 19 package org.apache.catalina.connector; 20 21 22 import java.io.IOException ; 23 import java.io.OutputStream ; 24 import java.io.PrintWriter ; 25 import java.net.MalformedURLException ; 26 import java.security.AccessController ; 27 import java.security.PrivilegedAction ; 28 import java.security.PrivilegedActionException ; 29 import java.security.PrivilegedExceptionAction ; 30 import java.text.SimpleDateFormat ; 31 import java.util.ArrayList ; 32 import java.util.Enumeration ; 33 import java.util.Locale ; 34 import java.util.TimeZone ; 35 import java.util.Vector ; 36 37 import javax.servlet.ServletOutputStream ; 38 import javax.servlet.http.Cookie ; 39 import javax.servlet.http.HttpServletResponse ; 40 41 import org.apache.catalina.Context; 42 import org.apache.catalina.Globals; 43 import org.apache.catalina.Session; 44 import org.apache.catalina.Wrapper; 45 import org.apache.catalina.security.SecurityUtil; 46 import org.apache.catalina.util.CharsetMapper; 47 import org.apache.catalina.util.DateTool; 48 import org.apache.catalina.util.StringManager; 49 import org.apache.tomcat.util.buf.CharChunk; 50 import org.apache.tomcat.util.buf.UEncoder; 51 import org.apache.tomcat.util.http.FastHttpDateFormat; 52 import org.apache.tomcat.util.http.MimeHeaders; 53 import org.apache.tomcat.util.http.ServerCookie; 54 import org.apache.tomcat.util.net.URL; 55 56 63 64 public class Response 65 implements HttpServletResponse { 66 67 68 70 static { 71 URL.isSchemeChar('c'); 73 } 74 75 public Response() { 76 urlEncoder.addSafeCharacter('/'); 77 } 78 79 80 82 83 86 protected static final String info = 87 "org.apache.coyote.tomcat5.CoyoteResponse/1.0"; 88 89 90 93 protected static StringManager sm = 94 StringManager.getManager(Constants.Package); 95 96 97 99 102 protected SimpleDateFormat format = null; 103 104 105 107 108 111 protected Connector connector; 112 113 116 public Connector getConnector() { 117 return (this.connector); 118 } 119 120 125 public void setConnector(Connector connector) { 126 this.connector = connector; 127 if("AJP/1.3".equals(connector.getProtocol())) { 128 outputBuffer = new OutputBuffer(8184); 130 } else { 131 outputBuffer = new OutputBuffer(); 132 } 133 outputStream = new CoyoteOutputStream(outputBuffer); 134 writer = new CoyoteWriter(outputBuffer); 135 } 136 137 138 141 protected org.apache.coyote.Response coyoteResponse; 142 143 148 public void setCoyoteResponse(org.apache.coyote.Response coyoteResponse) { 149 this.coyoteResponse = coyoteResponse; 150 outputBuffer.setResponse(coyoteResponse); 151 } 152 153 156 public org.apache.coyote.Response getCoyoteResponse() { 157 return (coyoteResponse); 158 } 159 160 161 164 public Context getContext() { 165 return (request.getContext()); 166 } 167 168 176 public void setContext(Context context) { 177 request.setContext(context); 178 } 179 180 181 184 protected OutputBuffer outputBuffer; 185 186 187 190 protected CoyoteOutputStream outputStream; 191 192 193 196 protected CoyoteWriter writer; 197 198 199 202 protected boolean appCommitted = false; 203 204 205 208 protected boolean included = false; 209 210 211 214 private boolean isCharacterEncodingSet = false; 215 216 219 protected boolean error = false; 220 221 222 225 protected ArrayList cookies = new ArrayList (); 226 227 228 231 protected boolean usingOutputStream = false; 232 233 234 237 protected boolean usingWriter = false; 238 239 240 243 protected UEncoder urlEncoder = new UEncoder(); 244 245 246 249 protected CharChunk redirectURLCC = new CharChunk(); 250 251 252 254 255 259 public void recycle() { 260 261 outputBuffer.recycle(); 262 usingOutputStream = false; 263 usingWriter = false; 264 appCommitted = false; 265 included = false; 266 error = false; 267 isCharacterEncodingSet = false; 268 269 cookies.clear(); 270 271 if (Constants.SECURITY || Connector.RECYCLE_FACADES) { 272 if (facade != null) { 273 facade.clear(); 274 facade = null; 275 } 276 if (outputStream != null) { 277 outputStream.clear(); 278 outputStream = null; 279 } 280 if (writer != null) { 281 writer.clear(); 282 writer = null; 283 } 284 } else { 285 writer.recycle(); 286 } 287 288 } 289 290 291 294 public void clearEncoders() { 295 outputBuffer.clearEncoders(); 296 } 297 298 299 301 302 305 public int getContentCount() { 306 return outputBuffer.getContentWritten(); 307 } 308 309 310 315 public void setAppCommitted(boolean appCommitted) { 316 this.appCommitted = appCommitted; 317 } 318 319 320 323 public boolean isAppCommitted() { 324 return (this.appCommitted || isCommitted() || isSuspended() 325 || ((getContentLength() > 0) 326 && (getContentCount() >= getContentLength()))); 327 } 328 329 330 333 public boolean getIncluded() { 334 return included; 335 } 336 337 338 344 public void setIncluded(boolean included) { 345 this.included = included; 346 } 347 348 349 354 public String getInfo() { 355 return (info); 356 } 357 358 359 362 protected Request request = null; 363 364 367 public org.apache.catalina.connector.Request getRequest() { 368 return (this.request); 369 } 370 371 376 public void setRequest(org.apache.catalina.connector.Request request) { 377 this.request = (Request) request; 378 } 379 380 381 384 protected ResponseFacade facade = null; 385 386 390 public HttpServletResponse getResponse() { 391 if (facade == null) { 392 facade = new ResponseFacade(this); 393 } 394 return (facade); 395 } 396 397 398 401 public OutputStream getStream() { 402 if (outputStream == null) { 403 outputStream = new CoyoteOutputStream(outputBuffer); 404 } 405 return outputStream; 406 } 407 408 409 414 public void setStream(OutputStream stream) { 415 } 417 418 419 424 public void setSuspended(boolean suspended) { 425 outputBuffer.setSuspended(suspended); 426 } 427 428 429 432 public boolean isSuspended() { 433 return outputBuffer.isSuspended(); 434 } 435 436 437 440 public boolean isClosed() { 441 return outputBuffer.isClosed(); 442 } 443 444 445 448 public void setError() { 449 error = true; 450 } 451 452 453 456 public boolean isError() { 457 return error; 458 } 459 460 461 467 public ServletOutputStream createOutputStream() 468 throws IOException { 469 if (outputStream == null) { 471 outputStream = new CoyoteOutputStream(outputBuffer); 472 } 473 return outputStream; 474 } 475 476 477 483 public void finishResponse() 484 throws IOException { 485 outputBuffer.close(); 487 } 488 489 490 493 public int getContentLength() { 494 return (coyoteResponse.getContentLength()); 495 } 496 497 498 502 public String getContentType() { 503 return (coyoteResponse.getContentType()); 504 } 505 506 507 519 public PrintWriter getReporter() throws IOException { 520 if (outputBuffer.isNew()) { 521 outputBuffer.checkConverter(); 522 if (writer == null) { 523 writer = new CoyoteWriter(outputBuffer); 524 } 525 return writer; 526 } else { 527 return null; 528 } 529 } 530 531 532 534 535 540 public void flushBuffer() 541 throws IOException { 542 outputBuffer.flush(); 543 } 544 545 546 549 public int getBufferSize() { 550 return outputBuffer.getBufferSize(); 551 } 552 553 554 557 public String getCharacterEncoding() { 558 return (coyoteResponse.getCharacterEncoding()); 559 } 560 561 562 569 public ServletOutputStream getOutputStream() 570 throws IOException { 571 572 if (usingWriter) 573 throw new IllegalStateException  574 (sm.getString("coyoteResponse.getOutputStream.ise")); 575 576 usingOutputStream = true; 577 if (outputStream == null) { 578 outputStream = new CoyoteOutputStream(outputBuffer); 579 } 580 return outputStream; 581 582 } 583 584 585 588 public Locale getLocale() { 589 return (coyoteResponse.getLocale()); 590 } 591 592 593 600 public PrintWriter getWriter() 601 throws IOException { 602 603 if (usingOutputStream) 604 throw new IllegalStateException  605 (sm.getString("coyoteResponse.getWriter.ise")); 606 607 if (Globals.STRICT_SERVLET_COMPLIANCE) { 608 620 setCharacterEncoding(getCharacterEncoding()); 621 } 622 623 usingWriter = true; 624 outputBuffer.checkConverter(); 625 if (writer == null) { 626 writer = new CoyoteWriter(outputBuffer); 627 } 628 return writer; 629 630 } 631 632 633 636 public boolean isCommitted() { 637 return (coyoteResponse.isCommitted()); 638 } 639 640 641 647 public void reset() { 648 649 if (included) 650 return; 652 coyoteResponse.reset(); 653 outputBuffer.reset(); 654 } 655 656 657 663 public void resetBuffer() { 664 665 if (isCommitted()) 666 throw new IllegalStateException  667 (sm.getString("coyoteResponse.resetBuffer.ise")); 668 669 outputBuffer.reset(); 670 671 } 672 673 674 682 public void setBufferSize(int size) { 683 684 if (isCommitted() || !outputBuffer.isNew()) 685 throw new IllegalStateException  686 (sm.getString("coyoteResponse.setBufferSize.ise")); 687 688 outputBuffer.setBufferSize(size); 689 690 } 691 692 693 698 public void setContentLength(int length) { 699 700 if (isCommitted()) 701 return; 702 703 if (included) 705 return; 706 707 if (usingWriter) 708 return; 709 710 coyoteResponse.setContentLength(length); 711 712 } 713 714 715 720 public void setContentType(String type) { 721 722 if (isCommitted()) 723 return; 724 725 if (included) 727 return; 728 729 if (usingWriter) { 731 if (type != null) { 732 int index = type.indexOf(";"); 733 if (index != -1) { 734 type = type.substring(0, index); 735 } 736 } 737 } 738 739 coyoteResponse.setContentType(type); 740 741 if (type != null) { 743 int index = type.indexOf(";"); 744 if (index != -1) { 745 int len = type.length(); 746 index++; 747 while (index < len && Character.isSpace(type.charAt(index))) { 748 index++; 749 } 750 if (index+7 < len 751 && type.charAt(index) == 'c' 752 && type.charAt(index+1) == 'h' 753 && type.charAt(index+2) == 'a' 754 && type.charAt(index+3) == 'r' 755 && type.charAt(index+4) == 's' 756 && type.charAt(index+5) == 'e' 757 && type.charAt(index+6) == 't' 758 && type.charAt(index+7) == '=') { 759 isCharacterEncodingSet = true; 760 } 761 } 762 } 763 } 764 765 766 773 public void setCharacterEncoding(String charset) { 774 775 if (isCommitted()) 776 return; 777 778 if (included) 780 return; 781 782 if (usingWriter) 785 return; 786 787 coyoteResponse.setCharacterEncoding(charset); 788 isCharacterEncodingSet = true; 789 } 790 791 792 793 799 public void setLocale(Locale locale) { 800 801 if (isCommitted()) 802 return; 803 804 if (included) 806 return; 807 808 coyoteResponse.setLocale(locale); 809 810 if (usingWriter) 813 return; 814 815 if (isCharacterEncodingSet) { 816 return; 817 } 818 819 CharsetMapper cm = getContext().getCharsetMapper(); 820 String charset = cm.getCharset( locale ); 821 if ( charset != null ){ 822 coyoteResponse.setCharacterEncoding(charset); 823 } 824 825 } 826 827 828 830 831 835 public Cookie [] getCookies() { 836 return ((Cookie []) cookies.toArray(new Cookie [cookies.size()])); 837 } 838 839 840 848 public String getHeader(String name) { 849 return coyoteResponse.getMimeHeaders().getHeader(name); 850 } 851 852 853 857 public String [] getHeaderNames() { 858 859 MimeHeaders headers = coyoteResponse.getMimeHeaders(); 860 int n = headers.size(); 861 String [] result = new String [n]; 862 for (int i = 0; i < n; i++) { 863 result[i] = headers.getName(i).toString(); 864 } 865 return result; 866 867 } 868 869 870 877 public String [] getHeaderValues(String name) { 878 879 Enumeration enumeration = coyoteResponse.getMimeHeaders().values(name); 880 Vector result = new Vector (); 881 while (enumeration.hasMoreElements()) { 882 result.addElement(enumeration.nextElement()); 883 } 884 String [] resultArray = new String [result.size()]; 885 result.copyInto(resultArray); 886 return resultArray; 887 888 } 889 890 891 895 public String getMessage() { 896 return coyoteResponse.getMessage(); 897 } 898 899 900 903 public int getStatus() { 904 return coyoteResponse.getStatus(); 905 } 906 907 908 915 public void reset(int status, String message) { 916 reset(); 917 setStatus(status, message); 918 } 919 920 921 923 924 930 public void addCookie(final Cookie cookie) { 931 932 if (included) 934 return; 935 936 addCookieInternal(cookie); 937 938 } 939 940 941 947 public void addCookieInternal(final Cookie cookie) { 948 949 if (isCommitted()) 950 return; 951 952 cookies.add(cookie); 953 954 final StringBuffer sb = new StringBuffer (); 955 if (SecurityUtil.isPackageProtectionEnabled()) { 956 AccessController.doPrivileged(new PrivilegedAction () { 957 public Object run(){ 958 ServerCookie.appendCookieValue 959 (sb, cookie.getVersion(), cookie.getName(), 960 cookie.getValue(), cookie.getPath(), 961 cookie.getDomain(), cookie.getComment(), 962 cookie.getMaxAge(), cookie.getSecure()); 963 return null; 964 } 965 }); 966 } else { 967 ServerCookie.appendCookieValue 968 (sb, cookie.getVersion(), cookie.getName(), cookie.getValue(), 969 cookie.getPath(), cookie.getDomain(), cookie.getComment(), 970 cookie.getMaxAge(), cookie.getSecure()); 971 } 972 973 addHeader("Set-Cookie", sb.toString()); 977 978 } 979 980 981 987 public void addDateHeader(String name, long value) { 988 989 if (isCommitted()) 990 return; 991 992 if (included) { 994 return; 995 } 996 997 if (format == null) { 998 format = new SimpleDateFormat (DateTool.HTTP_RESPONSE_DATE_HEADER, 999 Locale.US); 1000 format.setTimeZone(TimeZone.getTimeZone("GMT")); 1001 } 1002 1003 addHeader(name, FastHttpDateFormat.formatDate(value, format)); 1004 1005 } 1006 1007 1008 1014 public void addHeader(String name, String value) { 1015 1016 |