Source Code Cross Referenced for CoyoteResponse.java in  » Sevlet-Container » tomcat-catalina » org » apache » coyote » tomcat5 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Sevlet Container » tomcat catalina » org.apache.coyote.tomcat5 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999,2004 The Apache Software Foundation.
0003:         * 
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         * 
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         * 
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package org.apache.coyote.tomcat5;
0018:
0019:        import java.io.IOException;
0020:        import java.io.OutputStream;
0021:        import java.io.PrintWriter;
0022:        import java.net.MalformedURLException;
0023:        import java.security.AccessController;
0024:        import java.security.PrivilegedAction;
0025:        import java.security.PrivilegedActionException;
0026:        import java.security.PrivilegedExceptionAction;
0027:        import java.text.SimpleDateFormat;
0028:        import java.util.ArrayList;
0029:        import java.util.Enumeration;
0030:        import java.util.Locale;
0031:        import java.util.TimeZone;
0032:        import java.util.Vector;
0033:
0034:        import javax.servlet.ServletOutputStream;
0035:        import javax.servlet.ServletResponse;
0036:        import javax.servlet.http.Cookie;
0037:        import javax.servlet.http.HttpServletRequest;
0038:        import javax.servlet.http.HttpServletResponse;
0039:        import javax.servlet.http.HttpSession;
0040:
0041:        import org.apache.catalina.Connector;
0042:        import org.apache.catalina.Context;
0043:        import org.apache.catalina.HttpResponse;
0044:        import org.apache.catalina.Wrapper;
0045:        import org.apache.catalina.util.CharsetMapper;
0046:        import org.apache.catalina.util.DateTool;
0047:        import org.apache.catalina.util.StringManager;
0048:        import org.apache.coyote.Response;
0049:        import org.apache.tomcat.util.buf.CharChunk;
0050:        import org.apache.tomcat.util.buf.UEncoder;
0051:        import org.apache.tomcat.util.http.FastHttpDateFormat;
0052:        import org.apache.tomcat.util.http.MimeHeaders;
0053:        import org.apache.tomcat.util.http.ServerCookie;
0054:        import org.apache.tomcat.util.net.URL;
0055:        import org.apache.tomcat.util.compat.JdkCompat;
0056:
0057:        /**
0058:         * Wrapper object for the Coyote response.
0059:         *
0060:         * @author Remy Maucherat
0061:         * @author Craig R. McClanahan
0062:         * @version $Revision: 1.18.2.1 $ $Date: 2004/08/23 19:22:20 $
0063:         */
0064:
0065:        public class CoyoteResponse implements  HttpResponse,
0066:                HttpServletResponse {
0067:
0068:            // ----------------------------------------------------------- Constructors
0069:
0070:            public CoyoteResponse() {
0071:                urlEncoder.addSafeCharacter('/');
0072:            }
0073:
0074:            // ----------------------------------------------------- Class Variables
0075:
0076:            /**
0077:             * JDK compatibility support
0078:             */
0079:            private static final JdkCompat jdkCompat = JdkCompat.getJdkCompat();
0080:
0081:            /**
0082:             * Descriptive information about this Response implementation.
0083:             */
0084:            protected static final String info = "org.apache.coyote.tomcat5.CoyoteResponse/1.0";
0085:
0086:            /**
0087:             * The string manager for this package.
0088:             */
0089:            protected static StringManager sm = StringManager
0090:                    .getManager(Constants.Package);
0091:
0092:            // ----------------------------------------------------- Instance Variables
0093:
0094:            /**
0095:             * The date format we will use for creating date headers.
0096:             */
0097:            protected SimpleDateFormat format = null;
0098:
0099:            // ------------------------------------------------------------- Properties
0100:
0101:            /**
0102:             * Associated Catalina connector.
0103:             */
0104:            protected Connector connector;
0105:
0106:            /**
0107:             * Return the Connector through which this Request was received.
0108:             */
0109:            public Connector getConnector() {
0110:                return (this .connector);
0111:            }
0112:
0113:            /**
0114:             * Set the Connector through which this Request was received.
0115:             *
0116:             * @param connector The new connector
0117:             */
0118:            public void setConnector(Connector connector) {
0119:                this .connector = connector;
0120:            }
0121:
0122:            /**
0123:             * Coyote response.
0124:             */
0125:            protected Response coyoteResponse;
0126:
0127:            /**
0128:             * Set the Coyote response.
0129:             * 
0130:             * @param response The Coyote response
0131:             */
0132:            public void setCoyoteResponse(Response coyoteResponse) {
0133:                this .coyoteResponse = coyoteResponse;
0134:                outputBuffer.setResponse(coyoteResponse);
0135:            }
0136:
0137:            /**
0138:             * Get the Coyote response.
0139:             */
0140:            public Response getCoyoteResponse() {
0141:                return (coyoteResponse);
0142:            }
0143:
0144:            /**
0145:             * Return the Context within which this Request is being processed.
0146:             */
0147:            public Context getContext() {
0148:                return (request.getContext());
0149:            }
0150:
0151:            /**
0152:             * Set the Context within which this Request is being processed.  This
0153:             * must be called as soon as the appropriate Context is identified, because
0154:             * it identifies the value to be returned by <code>getContextPath()</code>,
0155:             * and thus enables parsing of the request URI.
0156:             *
0157:             * @param context The newly associated Context
0158:             */
0159:            public void setContext(Context context) {
0160:                request.setContext(context);
0161:            }
0162:
0163:            /**
0164:             * The associated output buffer.
0165:             */
0166:            protected OutputBuffer outputBuffer = new OutputBuffer();
0167:
0168:            /**
0169:             * The associated output stream.
0170:             */
0171:            protected CoyoteOutputStream outputStream = new CoyoteOutputStream(
0172:                    outputBuffer);
0173:
0174:            /**
0175:             * The associated writer.
0176:             */
0177:            protected CoyoteWriter writer = new CoyoteWriter(outputBuffer);
0178:
0179:            /**
0180:             * The application commit flag.
0181:             */
0182:            protected boolean appCommitted = false;
0183:
0184:            /**
0185:             * The included flag.
0186:             */
0187:            protected boolean included = false;
0188:
0189:            /**
0190:             * The characterEncoding flag
0191:             */
0192:            private boolean isCharacterEncodingSet = false;
0193:
0194:            /**
0195:             * The contextType flag
0196:             */
0197:            private boolean isContentTypeSet = false;
0198:
0199:            /**
0200:             * The error flag.
0201:             */
0202:            protected boolean error = false;
0203:
0204:            /**
0205:             * The set of Cookies associated with this Response.
0206:             */
0207:            protected ArrayList cookies = new ArrayList();
0208:
0209:            /**
0210:             * Using output stream flag.
0211:             */
0212:            protected boolean usingOutputStream = false;
0213:
0214:            /**
0215:             * Using writer flag.
0216:             */
0217:            protected boolean usingWriter = false;
0218:
0219:            /**
0220:             * URL encoder.
0221:             */
0222:            protected UEncoder urlEncoder = new UEncoder();
0223:
0224:            /**
0225:             * Recyclable buffer to hold the redirect URL.
0226:             */
0227:            protected CharChunk redirectURLCC = new CharChunk();
0228:
0229:            // --------------------------------------------------------- Public Methods
0230:
0231:            /**
0232:             * Release all object references, and initialize instance variables, in
0233:             * preparation for reuse of this object.
0234:             */
0235:            public void recycle() {
0236:
0237:                outputBuffer.recycle();
0238:                usingOutputStream = false;
0239:                usingWriter = false;
0240:                appCommitted = false;
0241:                included = false;
0242:                error = false;
0243:                isContentTypeSet = false;
0244:                isCharacterEncodingSet = false;
0245:
0246:                cookies.clear();
0247:
0248:                if (Constants.SECURITY) {
0249:                    if (facade != null) {
0250:                        facade.clear();
0251:                        facade = null;
0252:                    }
0253:                    if (outputStream != null) {
0254:                        outputStream.clear();
0255:                        outputStream = null;
0256:                    }
0257:                    if (writer != null) {
0258:                        writer.clear();
0259:                        writer = null;
0260:                    }
0261:                } else {
0262:                    writer.recycle();
0263:                }
0264:
0265:            }
0266:
0267:            // ------------------------------------------------------- Response Methods
0268:
0269:            /**
0270:             * Return the number of bytes actually written to the output stream.
0271:             */
0272:            public int getContentCount() {
0273:                return outputBuffer.getContentWritten();
0274:            }
0275:
0276:            /**
0277:             * Set the application commit flag.
0278:             * 
0279:             * @param appCommitted The new application committed flag value
0280:             */
0281:            public void setAppCommitted(boolean appCommitted) {
0282:                this .appCommitted = appCommitted;
0283:            }
0284:
0285:            /**
0286:             * Application commit flag accessor.
0287:             */
0288:            public boolean isAppCommitted() {
0289:                return (this .appCommitted || isCommitted() || isSuspended() || ((getContentLength() != -1) && (getContentCount() >= getContentLength())));
0290:            }
0291:
0292:            /**
0293:             * Return the "processing inside an include" flag.
0294:             */
0295:            public boolean getIncluded() {
0296:                return included;
0297:            }
0298:
0299:            /**
0300:             * Set the "processing inside an include" flag.
0301:             *
0302:             * @param included <code>true</code> if we are currently inside a
0303:             *  RequestDispatcher.include(), else <code>false</code>
0304:             */
0305:            public void setIncluded(boolean included) {
0306:                this .included = included;
0307:            }
0308:
0309:            /**
0310:             * Return descriptive information about this Response implementation and
0311:             * the corresponding version number, in the format
0312:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0313:             */
0314:            public String getInfo() {
0315:                return (info);
0316:            }
0317:
0318:            /**
0319:             * The request with which this response is associated.
0320:             */
0321:            protected CoyoteRequest request = null;
0322:
0323:            /**
0324:             * Return the Request with which this Response is associated.
0325:             */
0326:            public org.apache.catalina.Request getRequest() {
0327:                return (this .request);
0328:            }
0329:
0330:            /**
0331:             * Set the Request with which this Response is associated.
0332:             *
0333:             * @param request The new associated request
0334:             */
0335:            public void setRequest(org.apache.catalina.Request request) {
0336:                this .request = (CoyoteRequest) request;
0337:            }
0338:
0339:            /**
0340:             * The facade associated with this response.
0341:             */
0342:            protected CoyoteResponseFacade facade = null;
0343:
0344:            /**
0345:             * Return the <code>ServletResponse</code> for which this object
0346:             * is the facade.
0347:             */
0348:            public ServletResponse getResponse() {
0349:                if (facade == null) {
0350:                    facade = new CoyoteResponseFacade(this );
0351:                }
0352:                return (facade);
0353:            }
0354:
0355:            /**
0356:             * Return the output stream associated with this Response.
0357:             */
0358:            public OutputStream getStream() {
0359:                if (outputStream == null) {
0360:                    outputStream = new CoyoteOutputStream(outputBuffer);
0361:                }
0362:                return outputStream;
0363:            }
0364:
0365:            /**
0366:             * Set the output stream associated with this Response.
0367:             *
0368:             * @param stream The new output stream
0369:             */
0370:            public void setStream(OutputStream stream) {
0371:                // This method is evil
0372:            }
0373:
0374:            /**
0375:             * Set the suspended flag.
0376:             * 
0377:             * @param suspended The new suspended flag value
0378:             */
0379:            public void setSuspended(boolean suspended) {
0380:                outputBuffer.setSuspended(suspended);
0381:            }
0382:
0383:            /**
0384:             * Suspended flag accessor.
0385:             */
0386:            public boolean isSuspended() {
0387:                return outputBuffer.isSuspended();
0388:            }
0389:
0390:            /**
0391:             * Set the error flag.
0392:             */
0393:            public void setError() {
0394:                error = true;
0395:            }
0396:
0397:            /**
0398:             * Error flag accessor.
0399:             */
0400:            public boolean isError() {
0401:                return error;
0402:            }
0403:
0404:            /**
0405:             * Create and return a ServletOutputStream to write the content
0406:             * associated with this Response.
0407:             *
0408:             * @exception IOException if an input/output error occurs
0409:             */
0410:            public ServletOutputStream createOutputStream() throws IOException {
0411:                // Probably useless
0412:                if (outputStream == null) {
0413:                    outputStream = new CoyoteOutputStream(outputBuffer);
0414:                }
0415:                return outputStream;
0416:            }
0417:
0418:            /**
0419:             * Perform whatever actions are required to flush and close the output
0420:             * stream or writer, in a single operation.
0421:             *
0422:             * @exception IOException if an input/output error occurs
0423:             */
0424:            public void finishResponse() throws IOException {
0425:                // Writing leftover bytes
0426:                try {
0427:                    outputBuffer.close();
0428:                } catch (IOException e) {
0429:                    ;
0430:                } catch (Throwable t) {
0431:                    t.printStackTrace();
0432:                }
0433:            }
0434:
0435:            /**
0436:             * Return the content length that was set or calculated for this Response.
0437:             */
0438:            public int getContentLength() {
0439:                return (coyoteResponse.getContentLength());
0440:            }
0441:
0442:            /**
0443:             * Return the content type that was set or calculated for this response,
0444:             * or <code>null</code> if no content type was set.
0445:             */
0446:            public String getContentType() {
0447:                return (coyoteResponse.getContentType());
0448:            }
0449:
0450:            /**
0451:             * Return a PrintWriter that can be used to render error messages,
0452:             * regardless of whether a stream or writer has already been acquired.
0453:             *
0454:             * @return Writer which can be used for error reports. If the response is
0455:             * not an error report returned using sendError or triggered by an
0456:             * unexpected exception thrown during the servlet processing
0457:             * (and only in that case), null will be returned if the response stream
0458:             * has already been used.
0459:             *
0460:             * @exception IOException if an input/output error occurs
0461:             */
0462:            public PrintWriter getReporter() throws IOException {
0463:                if (outputBuffer.isNew()) {
0464:                    outputBuffer.checkConverter();
0465:                    if (writer == null) {
0466:                        writer = new CoyoteWriter(outputBuffer);
0467:                    }
0468:                    return writer;
0469:                } else {
0470:                    return null;
0471:                }
0472:            }
0473:
0474:            // ------------------------------------------------ ServletResponse Methods
0475:
0476:            /**
0477:             * Flush the buffer and commit this response.
0478:             *
0479:             * @exception IOException if an input/output error occurs
0480:             */
0481:            public void flushBuffer() throws IOException {
0482:                outputBuffer.flush();
0483:            }
0484:
0485:            /**
0486:             * Return the actual buffer size used for this Response.
0487:             */
0488:            public int getBufferSize() {
0489:                return outputBuffer.getBufferSize();
0490:            }
0491:
0492:            /**
0493:             * Return the character encoding used for this Response.
0494:             */
0495:            public String getCharacterEncoding() {
0496:                return (coyoteResponse.getCharacterEncoding());
0497:            }
0498:
0499:            /**
0500:             * Return the servlet output stream associated with this Response.
0501:             *
0502:             * @exception IllegalStateException if <code>getWriter</code> has
0503:             *  already been called for this response
0504:             * @exception IOException if an input/output error occurs
0505:             */
0506:            public ServletOutputStream getOutputStream() throws IOException {
0507:
0508:                if (usingWriter)
0509:                    throw new IllegalStateException(sm
0510:                            .getString("coyoteResponse.getOutputStream.ise"));
0511:
0512:                usingOutputStream = true;
0513:                if (outputStream == null) {
0514:                    outputStream = new CoyoteOutputStream(outputBuffer);
0515:                }
0516:                return outputStream;
0517:
0518:            }
0519:
0520:            /**
0521:             * Return the Locale assigned to this response.
0522:             */
0523:            public Locale getLocale() {
0524:                return (coyoteResponse.getLocale());
0525:            }
0526:
0527:            /**
0528:             * Return the writer associated with this Response.
0529:             *
0530:             * @exception IllegalStateException if <code>getOutputStream</code> has
0531:             *  already been called for this response
0532:             * @exception IOException if an input/output error occurs
0533:             */
0534:            public PrintWriter getWriter() throws IOException {
0535:
0536:                if (usingOutputStream)
0537:                    throw new IllegalStateException(sm
0538:                            .getString("coyoteResponse.getWriter.ise"));
0539:
0540:                /*
0541:                 * If the response's character encoding has not been specified as
0542:                 * described in <code>getCharacterEncoding</code> (i.e., the method
0543:                 * just returns the default value <code>ISO-8859-1</code>),
0544:                 * <code>getWriter</code> updates it to <code>ISO-8859-1</code>
0545:                 * (with the effect that a subsequent call to getContentType() will
0546:                 * include a charset=ISO-8859-1 component which will also be
0547:                 * reflected in the Content-Type response header, thereby satisfying
0548:                 * the Servlet spec requirement that containers must communicate the
0549:                 * character encoding used for the servlet response's writer to the
0550:                 * client).
0551:                 */
0552:                setCharacterEncoding(getCharacterEncoding());
0553:
0554:                usingWriter = true;
0555:                outputBuffer.checkConverter();
0556:                if (writer == null) {
0557:                    writer = new CoyoteWriter(outputBuffer);
0558:                }
0559:                return writer;
0560:
0561:            }
0562:
0563:            /**
0564:             * Has the output of this response already been committed?
0565:             */
0566:            public boolean isCommitted() {
0567:                return (coyoteResponse.isCommitted());
0568:            }
0569:
0570:            /**
0571:             * Clear any content written to the buffer.
0572:             *
0573:             * @exception IllegalStateException if this response has already
0574:             *  been committed
0575:             */
0576:            public void reset() {
0577:
0578:                if (included)
0579:                    return; // Ignore any call from an included servlet
0580:
0581:                coyoteResponse.reset();
0582:                outputBuffer.reset();
0583:            }
0584:
0585:            /**
0586:             * Reset the data buffer but not any status or header information.
0587:             *
0588:             * @exception IllegalStateException if the response has already
0589:             *  been committed
0590:             */
0591:            public void resetBuffer() {
0592:
0593:                if (isCommitted())
0594:                    throw new IllegalStateException(sm
0595:                            .getString("coyoteResponse.resetBuffer.ise"));
0596:
0597:                outputBuffer.reset();
0598:
0599:            }
0600:
0601:            /**
0602:             * Set the buffer size to be used for this Response.
0603:             *
0604:             * @param size The new buffer size
0605:             *
0606:             * @exception IllegalStateException if this method is called after
0607:             *  output has been committed for this response
0608:             */
0609:            public void setBufferSize(int size) {
0610:
0611:                if (isCommitted() || !outputBuffer.isNew())
0612:                    throw new IllegalStateException(sm
0613:                            .getString("coyoteResponse.setBufferSize.ise"));
0614:
0615:                outputBuffer.setBufferSize(size);
0616:
0617:            }
0618:
0619:            /**
0620:             * Set the content length (in bytes) for this Response.
0621:             *
0622:             * @param length The new content length
0623:             */
0624:            public void setContentLength(int length) {
0625:
0626:                if (isCommitted())
0627:                    return;
0628:
0629:                // Ignore any call from an included servlet
0630:                if (included)
0631:                    return;
0632:
0633:                if (usingWriter)
0634:                    return;
0635:
0636:                coyoteResponse.setContentLength(length);
0637:
0638:            }
0639:
0640:            /**
0641:             * Set the content type for this Response.
0642:             *
0643:             * @param type The new content type
0644:             */
0645:            public void setContentType(String type) {
0646:
0647:                if (isCommitted())
0648:                    return;
0649:
0650:                // Ignore any call from an included servlet
0651:                if (included)
0652:                    return;
0653:
0654:                // Ignore charset if getWriter() has already been called
0655:                if (usingWriter) {
0656:                    if (type != null) {
0657:                        int index = type.indexOf(";");
0658:                        if (index != -1) {
0659:                            type = type.substring(0, index);
0660:                        }
0661:                    }
0662:                }
0663:
0664:                coyoteResponse.setContentType(type);
0665:
0666:                // Check to see if content type contains charset
0667:                if (type != null) {
0668:                    int index = type.indexOf(";");
0669:                    if (index != -1) {
0670:                        int len = type.length();
0671:                        index++;
0672:                        while (index < len
0673:                                && Character.isSpace(type.charAt(index))) {
0674:                            index++;
0675:                        }
0676:                        if (index + 7 < len && type.charAt(index) == 'c'
0677:                                && type.charAt(index + 1) == 'h'
0678:                                && type.charAt(index + 2) == 'a'
0679:                                && type.charAt(index + 3) == 'r'
0680:                                && type.charAt(index + 4) == 's'
0681:                                && type.charAt(index + 5) == 'e'
0682:                                && type.charAt(index + 6) == 't'
0683:                                && type.charAt(index + 7) == '=') {
0684:                            isCharacterEncodingSet = true;
0685:                        }
0686:                    }
0687:                }
0688:
0689:                isContentTypeSet = true;
0690:            }
0691:
0692:            /*
0693:             * Overrides the name of the character encoding used in the body
0694:             * of the request. This method must be called prior to reading
0695:             * request parameters or reading input using getReader().
0696:             *
0697:             * @param charset String containing the name of the chararacter encoding.
0698:             */
0699:            public void setCharacterEncoding(String charset) {
0700:
0701:                if (isCommitted())
0702:                    return;
0703:
0704:                // Ignore any call from an included servlet
0705:                if (included)
0706:                    return;
0707:
0708:                // Ignore any call made after the getWriter has been invoked
0709:                // The default should be used
0710:                if (usingWriter)
0711:                    return;
0712:
0713:                coyoteResponse.setCharacterEncoding(charset);
0714:                isCharacterEncodingSet = true;
0715:            }
0716:
0717:            /**
0718:             * Set the Locale that is appropriate for this response, including
0719:             * setting the appropriate character encoding.
0720:             *
0721:             * @param locale The new locale
0722:             */
0723:            public void setLocale(Locale locale) {
0724:
0725:                if (isCommitted())
0726:                    return;
0727:
0728:                // Ignore any call from an included servlet
0729:                if (included)
0730:                    return;
0731:
0732:                coyoteResponse.setLocale(locale);
0733:
0734:                // Ignore any call made after the getWriter has been invoked.
0735:                // The default should be used
0736:                if (usingWriter)
0737:                    return;
0738:
0739:                if (isCharacterEncodingSet) {
0740:                    return;
0741:                }
0742:
0743:                CharsetMapper cm = getContext().getCharsetMapper();
0744:                String charset = cm.getCharset(locale);
0745:                if (charset != null) {
0746:                    coyoteResponse.setCharacterEncoding(charset);
0747:                }
0748:
0749:            }
0750:
0751:            // --------------------------------------------------- HttpResponse Methods
0752:
0753:            /**
0754:             * Return an array of all cookies set for this response, or
0755:             * a zero-length array if no cookies have been set.
0756:             */
0757:            public Cookie[] getCookies() {
0758:                return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()]));
0759:            }
0760:
0761:            /**
0762:             * Return the value for the specified header, or <code>null</code> if this
0763:             * header has not been set.  If more than one value was added for this
0764:             * name, only the first is returned; use getHeaderValues() to retrieve all
0765:             * of them.
0766:             *
0767:             * @param name Header name to look up
0768:             */
0769:            public String getHeader(String name) {
0770:                return coyoteResponse.getMimeHeaders().getHeader(name);
0771:            }
0772:
0773:            /**
0774:             * Return an array of all the header names set for this response, or
0775:             * a zero-length array if no headers have been set.
0776:             */
0777:            public String[] getHeaderNames() {
0778:
0779:                MimeHeaders headers = coyoteResponse.getMimeHeaders();
0780:                int n = headers.size();
0781:                String[] result = new String[n];
0782:                for (int i = 0; i < n; i++) {
0783:                    result[i] = headers.getName(i).toString();
0784:                }
0785:                return result;
0786:
0787:            }
0788:
0789:            /**
0790:             * Return an array of all the header values associated with the
0791:             * specified header name, or an zero-length array if there are no such
0792:             * header values.
0793:             *
0794:             * @param name Header name to look up
0795:             */
0796:            public String[] getHeaderValues(String name) {
0797:
0798:        Enumeration enum = coyoteResponse.getMimeHeaders().values(name);
0799:        Vector result = new Vector();
0800:        while (enum.hasMoreElements()) {
0801:            result.addElement(enum.nextElement());
0802:        }
0803:        String[] resultArray = new String[result.size()];
0804:        result.copyInto(resultArray);
0805:        return resultArray;
0806:
0807:    }
0808:
0809:            /**
0810:             * Return the error message that was set with <code>sendError()</code>
0811:             * for this Response.
0812:             */
0813:            public String getMessage() {
0814:                return coyoteResponse.getMessage();
0815:            }
0816:
0817:            /**
0818:             * Return the HTTP status code associated with this Response.
0819:             */
0820:            public int getStatus() {
0821:                return coyoteResponse.getStatus();
0822:            }
0823:
0824:            /**
0825:             * Reset this response, and specify the values for the HTTP status code
0826:             * and corresponding message.
0827:             *
0828:             * @exception IllegalStateException if this response has already been
0829:             *  committed
0830:             */
0831:            public void reset(int status, String message) {
0832:                reset();
0833:                setStatus(status, message);
0834:            }
0835:
0836:            // -------------------------------------------- HttpServletResponse Methods
0837:
0838:            /**
0839:             * Add the specified Cookie to those that will be included with
0840:             * this Response.
0841:             *
0842:             * @param cookie Cookie to be added
0843:             */
0844:            public void addCookie(final Cookie cookie) {
0845:
0846:                if (isCommitted())
0847:                    return;
0848:
0849:                // Ignore any call from an included servlet
0850:                if (included)
0851:                    return;
0852:
0853:                cookies.add(cookie);
0854:
0855:                final StringBuffer sb = new StringBuffer();
0856:                if (System.getSecurityManager() != null) {
0857:                    AccessController.doPrivileged(new PrivilegedAction() {
0858:                        public Object run() {
0859:                            ServerCookie.appendCookieValue(sb, cookie
0860:                                    .getVersion(), cookie.getName(), cookie
0861:                                    .getValue(), cookie.getPath(), cookie
0862:                                    .getDomain(), cookie.getComment(), cookie
0863:                                    .getMaxAge(), cookie.getSecure());
0864:                            return null;
0865:                        }
0866:                    });
0867:                } else {
0868:                    ServerCookie.appendCookieValue(sb, cookie.getVersion(),
0869:                            cookie.getName(), cookie.getValue(), cookie
0870:                                    .getPath(), cookie.getDomain(), cookie
0871:                                    .getComment(), cookie.getMaxAge(), cookie
0872:                                    .getSecure());
0873:                }
0874:
0875:                // the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
0876:                // RFC2965 is not supported by browsers and the Servlet spec
0877:                // asks for 2109.
0878:                addHeader("Set-Cookie", sb.toString());
0879:
0880:            }
0881:
0882:            /**
0883:             * Add the specified date header to the specified value.
0884:             *
0885:             * @param name Name of the header to set
0886:             * @param value Date value to be set
0887:             */
0888:            public void addDateHeader(String name, long value) {
0889:
0890:                if (isCommitted())
0891:                    return;
0892:
0893:                // Ignore any call from an included servlet
0894:                if (included) {
0895:                    return;
0896:                }
0897:
0898:                if (format == null) {
0899:                    format = new SimpleDateFormat(
0900:                            DateTool.HTTP_RESPONSE_DATE_HEADER, Locale.US);
0901:                    format.setTimeZone(TimeZone.getTimeZone("GMT"));
0902:                }
0903:
0904:                addHeader(name, FastHttpDateFormat.formatDate(value, format));
0905:
0906:            }
0907:
0908:            /**
0909:             * Add the specified header to the specified value.
0910:             *
0911:             * @param name Name of the header to set
0912:             * @param value Value to be set
0913:             */
0914:            public void addHeader(String name, String value) {
0915:
0916:                if (isCommitted())
0917:                    return;
0918:
0919:                // Ignore any call from an included servlet
0920:                if (included)
0921:                    return;
0922:
0923:                coyoteResponse.addHeader(name, value);
0924:
0925:            }
0926:
0927:            /**
0928:             * Add the specified integer header to the specified value.
0929:             *
0930:             * @param name Name of the header to set
0931:             * @param value Integer value to be set
0932:             */
0933:            public void addIntHeader(String name, int value) {
0934:
0935:                if (isCommitted())
0936:                    return;
0937:
0938:                // Ignore any call from an included servlet
0939:                if (included)
0940:                    return;
0941:
0942:                addHeader(name, "" + value);
0943:
0944:            }
0945:
0946:            /**
0947:             * Has the specified header been set already in this response?
0948:             *
0949:             * @param name Name of the header to check
0950:             */
0951:            public boolean containsHeader(String name) {
0952:                return coyoteResponse.containsHeader(name);
0953:            }
0954:
0955:            /**
0956:             * Encode the session identifier associated with this response
0957:             * into the specified redirect URL, if necessary.
0958:             *
0959:             * @param url URL to be encoded
0960:             */
0961:            public String encodeRedirectURL(String url) {
0962:
0963:                if (isEncodeable(toAbsolute(url))) {
0964:                    HttpServletRequest hreq = (HttpServletRequest) request
0965:                            .getRequest();
0966:                    return (toEncoded(url, hreq.getSession().getId()));
0967:                } else {
0968:                    return (url);
0969:                }
0970:
0971:            }
0972:
0973:            /**
0974:             * Encode the session identifier associated with this response
0975:             * into the specified redirect URL, if necessary.
0976:             *
0977:             * @param url URL to be encoded
0978:             *
0979:             * @deprecated As of Version 2.1 of the Java Servlet API, use
0980:             *  <code>encodeRedirectURL()</code> instead.
0981:             */
0982:            public String encodeRedirectUrl(String url) {
0983:                return (encodeRedirectURL(url));
0984:            }
0985:
0986:            /**
0987:             * Encode the session identifier associated with this response
0988:             * into the specified URL, if necessary.
0989:             *
0990:             * @param url URL to be encoded
0991:             */
0992:            public String encodeURL(String url) {
0993:
0994:                String absolute = toAbsolute(url);
0995:                if (isEncodeable(absolute)) {
0996:                    HttpServletRequest hreq = (HttpServletRequest) request
0997:                            .getRequest();
0998:
0999:                    // W3c spec clearly said 
1000:                    if (url.equalsIgnoreCase("")) {
1001:                        url = absolute;
1002:                    }
1003:                    return (toEncoded(url, hreq.getSession().getId()));
1004:                } else {
1005:                    return (url);
1006:                }
1007:
1008:            }
1009:
1010:            /**
1011:             * Encode the session identifier associated with this response
1012:             * into the specified URL, if necessary.
1013:             *
1014:             * @param url URL to be encoded
1015:             *
1016:             * @deprecated As of Version 2.1 of the Java Servlet API, use
1017:             *  <code>encodeURL()</code> instead.
1018:             */
1019:            public String encodeUrl(String url) {
1020:                return (encodeURL(url));
1021:            }
1022:
1023:            /**
1024:             * Send an acknowledgment of a request.
1025:             * 
1026:             * @exception IOException if an input/output error occurs
1027:             */
1028:            public void sendAcknowledgement() throws IOException {
1029:
1030:                if (isCommitted())
1031:                    return;
1032:
1033:                // Ignore any call from an included servlet
1034:                if (included)
1035:                    return;
1036:
1037:                coyoteResponse.acknowledge();
1038:
1039:            }
1040:
1041:            /**
1042:             * Send an error response with the specified status and a
1043:             * default message.
1044:             *
1045:             * @param status HTTP status code to send
1046:             *
1047:             * @exception IllegalStateException if this response has
1048:             *  already been committed
1049:             * @exception IOException if an input/output error occurs
1050:             */
1051:            public void sendError(int status) throws IOException {
1052:                sendError(status, null);
1053:            }
1054:
1055:            /**
1056:             * Send an error response with the specified status and message.
1057:             *
1058:             * @param status HTTP status code to send
1059:             * @param message Corresponding message to send
1060:             *
1061:             * @exception IllegalStateException if this response has
1062:             *  already been committed
1063:             * @exception IOException if an input/output error occurs
1064:             */
1065:            public void sendError(int status, String message)
1066:                    throws IOException {
1067:
1068:                if (isCommitted())
1069:                    throw new IllegalStateException(sm
1070:                            .getString("coyoteResponse.sendError.ise"));
1071:
1072:                // Ignore any call from an included servlet
1073:                if (included)
1074:                    return;
1075:
1076:                Wrapper wrapper = getRequest().getWrapper();
1077:                if (wrapper != null) {
1078:                    wrapper.incrementErrorCount();
1079:                }
1080:
1081:                setError();
1082:
1083:                coyoteResponse.setStatus(status);
1084:                coyoteResponse.setMessage(message);
1085:
1086:                // Clear any data content that has been buffered
1087:                resetBuffer();
1088:
1089:                // Cause the response to be finished (from the application perspective)
1090:                setSuspended(true);
1091:
1092:            }
1093:
1094:            /**
1095:             * Send a temporary redirect to the specified redirect location URL.
1096:             *
1097:             * @param location Location URL to redirect to
1098:             *
1099:             * @exception IllegalStateException if this response has
1100:             *  already been committed
1101:             * @exception IOException if an input/output error occurs
1102:             */
1103:            public void sendRedirect(String location) throws IOException {
1104:
1105:                if (isCommitted())
1106:                    throw new IllegalStateException(sm
1107:                            .getString("coyoteResponse.sendRedirect.ise"));
1108:
1109:                // Ignore any call from an included servlet
1110:                if (included)
1111:                    return;
1112:
1113:                // Clear any data content that has been buffered
1114:                resetBuffer();
1115:
1116:                // Generate a temporary redirect to the specified location
1117:                try {
1118:                    String absolute = toAbsolute(location);
1119:                    setStatus(SC_FOUND);
1120:                    setHeader("Location", absolute);
1121:                } catch (IllegalArgumentException e) {
1122:                    setStatus(SC_NOT_FOUND);
1123:                }
1124:
1125:                // Cause the response to be finished (from the application perspective)
1126:                setSuspended(true);
1127:
1128:            }
1129:
1130:            /**
1131:             * Set the specified date header to the specified value.
1132:             *
1133:             * @param name Name of the header to set
1134:             * @param value Date value to be set
1135:             */
1136:            public void setDateHeader(String name, long value) {
1137:
1138:                if (isCommitted())
1139:                    return;
1140:
1141:                // Ignore any call from an included servlet
1142:                if (included) {
1143:                    return;
1144:                }
1145:
1146:                if (format == null) {
1147:                    format = new SimpleDateFormat(
1148:                            DateTool.HTTP_RESPONSE_DATE_HEADER, Locale.US);
1149:                    format.setTimeZone(TimeZone.getTimeZone("GMT"));
1150:                }
1151:
1152:                setHeader(name, FastHttpDateFormat.formatDate(value, format));
1153:
1154:            }
1155:
1156:            /**
1157:             * Set the specified header to the specified value.
1158:             *
1159:             * @param name Name of the header to set
1160:             * @param value Value to be set
1161:             */
1162:            public void setHeader(String name, String value) {
1163:
1164:                if (isCommitted())
1165:                    return;
1166:
1167:                // Ignore any call from an included servlet
1168:                if (included)
1169:                    return;
1170:
1171:                coyoteResponse.setHeader(name, value);
1172:
1173:            }
1174:
1175:            /**
1176:             * Set the specified integer header to the specified value.
1177:             *
1178:             * @param name Name of the header to set
1179:             * @param value Integer value to be set
1180:             */
1181:            public void setIntHeader(String name, int value) {
1182:
1183:                if (isCommitted())
1184:                    return;
1185:
1186:                // Ignore any call from an included servlet
1187:                if (included)
1188:                    return;
1189:
1190:                setHeader(name, "" + value);
1191:
1192:            }
1193:
1194:            /**
1195:             * Set the HTTP status to be returned with this response.
1196:             *
1197:             * @param status The new HTTP status
1198:             */
1199:            public void setStatus(int status) {
1200:                setStatus(status, null);
1201:            }
1202:
1203:            /**
1204:             * Set the HTTP status and message to be returned with this response.
1205:             *
1206:             * @param status The new HTTP status
1207:             * @param message The associated text message
1208:             *
1209:             * @deprecated As of Version 2.1 of the Java Servlet API, this method
1210:             *  has been deprecated due to the ambiguous meaning of the message
1211:             *  parameter.
1212:             */
1213:            public void setStatus(int status, String message) {
1214:
1215:                if (isCommitted())
1216:                    return;
1217:
1218:                // Ignore any call from an included servlet
1219:                if (included)
1220:                    return;
1221:
1222:                coyoteResponse.setStatus(status);
1223:                coyoteResponse.setMessage(message);
1224:
1225:            }
1226:
1227:            // ------------------------------------------------------ Protected Methods
1228:
1229:            /**
1230:             * Return <code>true</code> if the specified URL should be encoded with
1231:             * a session identifier.  This will be true if all of the following
1232:             * conditions are met:
1233:             * <ul>
1234:             * <li>The request we are responding to asked for a valid session
1235:             * <li>The requested session ID was not received via a cookie
1236:             * <li>The specified URL points back to somewhere within the web
1237:             *     application that is responding to this request
1238:             * </ul>
1239:             *
1240:             * @param location Absolute URL to be validated
1241:             */
1242:            protected boolean isEncodeable(final String location) {
1243:
1244:                if (location == null)
1245:                    return (false);
1246:
1247:                // Is this an intra-document reference?
1248:                if (location.startsWith("#"))
1249:                    return (false);
1250:
1251:                // Are we in a valid session that is not using cookies?
1252:                final HttpServletRequest hreq = (HttpServletRequest) request
1253:                        .getRequest();
1254:                final HttpSession session = hreq.getSession(false);
1255:                if (session == null)
1256:                    return (false);
1257:                if (hreq.isRequestedSessionIdFromCookie())
1258:                    return (false);
1259:
1260:                if (System.getSecurityManager() != null) {
1261:                    return ((Boolean) AccessController
1262:                            .doPrivileged(new PrivilegedAction() {
1263:
1264:                                public Object run() {
1265:                                    return new Boolean(doIsEncodeable(hreq,
1266:                                            session, location));
1267:                                }
1268:                            })).booleanValue();
1269:                } else {
1270:                    return doIsEncodeable(hreq, session, location);
1271:                }
1272:            }
1273:
1274:            private boolean doIsEncodeable(HttpServletRequest hreq,
1275:                    HttpSession session, String location) {
1276:                // Is this a valid absolute URL?
1277:                URL url = null;
1278:                try {
1279:                    url = new URL(location);
1280:                } catch (MalformedURLException e) {
1281:                    return (false);
1282:                }
1283:
1284:                // Does this URL match down to (and including) the context path?
1285:                if (!hreq.getScheme().equalsIgnoreCase(url.getProtocol()))
1286:                    return (false);
1287:                if (!hreq.getServerName().equalsIgnoreCase(url.getHost()))
1288:                    return (false);
1289:                int serverPort = hreq.getServerPort();
1290:                if (serverPort == -1) {
1291:                    if ("https".equals(hreq.getScheme()))
1292:                        serverPort = 443;
1293:                    else
1294:                        serverPort = 80;
1295:                }
1296:                int urlPort = url.getPort();
1297:                if (urlPort == -1) {
1298:                    if ("https".equals(url.getProtocol()))
1299:                        urlPort = 443;
1300:                    else
1301:                        urlPort = 80;
1302:                }
1303:                if (serverPort != urlPort)
1304:                    return (false);
1305:
1306:                String contextPath = getContext().getPath();
1307:                if (contextPath != null) {
1308:                    String file = url.getFile();
1309:                    if ((file == null) || !file.startsWith(contextPath))
1310:                        return (false);
1311:                    if (file.indexOf(";jsessionid=" + session.getId()) >= 0)
1312:                        return (false);
1313:                }
1314:
1315:                // This URL belongs to our web application, so it is encodeable
1316:                return (true);
1317:
1318:            }
1319:
1320:            /**
1321:             * Convert (if necessary) and return the absolute URL that represents the
1322:             * resource referenced by this possibly relative URL.  If this URL is
1323:             * already absolute, return it unchanged.
1324:             *
1325:             * @param location URL to be (possibly) converted and then returned
1326:             *
1327:             * @exception IllegalArgumentException if a MalformedURLException is
1328:             *  thrown when converting the relative URL to an absolute one
1329:             */
1330:            private String toAbsolute(String location) {
1331:
1332:                if (location == null)
1333:                    return (location);
1334:
1335:                boolean leadingSlash = location.startsWith("/");
1336:
1337:                if (leadingSlash
1338:                        || (!leadingSlash && (location.indexOf("://") == -1))) {
1339:
1340:                    redirectURLCC.recycle();
1341:
1342:                    String scheme = request.getScheme();
1343:                    String name = request.getServerName();
1344:                    int port = request.getServerPort();
1345:
1346:                    try {
1347:                        redirectURLCC.append(scheme, 0, scheme.length());
1348:                        redirectURLCC.append("://", 0, 3);
1349:                        redirectURLCC.append(name, 0, name.length());
1350:                        if ((scheme.equals("http") && port != 80)
1351:                                || (scheme.equals("https") && port != 443)) {
1352:                            redirectURLCC.append(':');
1353:                            String portS = port + "";
1354:                            redirectURLCC.append(portS, 0, portS.length());
1355:                        }
1356:                        if (!leadingSlash) {
1357:                            String relativePath = request
1358:                                    .getDecodedRequestURI();
1359:                            int pos = relativePath.lastIndexOf('/');
1360:                            relativePath = relativePath.substring(0, pos);
1361:
1362:                            String encodedURI = null;
1363:                            final String frelativePath = relativePath;
1364:                            if (System.getSecurityManager() != null) {
1365:                                try {
1366:                                    encodedURI = (String) AccessController
1367:                                            .doPrivileged(new PrivilegedExceptionAction() {
1368:                                                public Object run()
1369:                                                        throws IOException {
1370:                                                    return urlEncoder
1371:                                                            .encodeURL(frelativePath);
1372:                                                }
1373:                                            });
1374:                                } catch (PrivilegedActionException pae) {
1375:                                    IllegalArgumentException iae = new IllegalArgumentException(
1376:                                            location);
1377:                                    jdkCompat.chainException(iae, pae
1378:                                            .getException());
1379:                                    throw iae;
1380:                                }
1381:                            } else {
1382:                                encodedURI = urlEncoder.encodeURL(relativePath);
1383:                            }
1384:                            redirectURLCC.append(encodedURI, 0, encodedURI
1385:                                    .length());
1386:                            redirectURLCC.append('/');
1387:                        }
1388:                        redirectURLCC.append(location, 0, location.length());
1389:                    } catch (IOException e) {
1390:                        IllegalArgumentException iae = new IllegalArgumentException(
1391:                                location);
1392:                        jdkCompat.chainException(iae, e);
1393:                        throw iae;
1394:                    }
1395:
1396:                    return redirectURLCC.toString();
1397:
1398:                } else {
1399:
1400:                    return (location);
1401:
1402:                }
1403:
1404:            }
1405:
1406:            /**
1407:             * Return the specified URL with the specified session identifier
1408:             * suitably encoded.
1409:             *
1410:             * @param url URL to be encoded with the session id
1411:             * @param sessionId Session id to be included in the encoded URL
1412:             */
1413:            private String toEncoded(String url, String sessionId) {
1414:
1415:                if ((url == null) || (sessionId == null))
1416:                    return (url);
1417:
1418:                String path = url;
1419:                String query = "";
1420:                String anchor = "";
1421:                int question = url.indexOf('?');
1422:                if (question >= 0) {
1423:                    path = url.substring(0, question);
1424:                    query = url.substring(question);
1425:                }
1426:                int pound = path.indexOf('#');
1427:                if (pound >= 0) {
1428:                    anchor = path.substring(pound);
1429:                    path = path.substring(0, pound);
1430:                }
1431:                StringBuffer sb = new StringBuffer(path);
1432:                if (sb.length() > 0) { // jsessionid can't be first.
1433:                    sb.append(";jsessionid=");
1434:                    sb.append(sessionId);
1435:                }
1436:                sb.append(anchor);
1437:                sb.append(query);
1438:                return (sb.toString());
1439:
1440:            }
1441:
1442:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.