Source Code Cross Referenced for CWebProxy.java in  » Portal » uPortal_rel-2-6-1-GA » org » jasig » portal » channels » webproxy » 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 » Portal » uPortal_rel 2 6 1 GA » org.jasig.portal.channels.webproxy 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Copyright 2002, 2005 The JA-SIG Collaborative.  All rights reserved.
0002:         *  See license distributed with this file and
0003:         *  available online at http://www.uportal.org/license.html
0004:         */
0005:
0006:        package org.jasig.portal.channels.webproxy;
0007:
0008:        import java.io.BufferedOutputStream;
0009:        import java.io.ByteArrayOutputStream;
0010:        import java.io.FileOutputStream;
0011:        import java.io.FileNotFoundException;
0012:        import java.io.IOException;
0013:        import java.io.InputStream;
0014:        import java.io.OutputStream;
0015:        import java.io.PrintWriter;
0016:        import java.io.UnsupportedEncodingException;
0017:        import java.net.HttpURLConnection;
0018:        import java.net.URI;
0019:        import java.net.URISyntaxException;
0020:        import java.net.URL;
0021:        import java.net.URLConnection;
0022:        import java.net.URLEncoder;
0023:        import java.util.Date;
0024:        import java.util.Enumeration;
0025:        import java.util.HashMap;
0026:        import java.util.HashSet;
0027:        import java.util.Map;
0028:        import java.util.StringTokenizer;
0029:
0030:        import javax.xml.parsers.DocumentBuilder;
0031:        import javax.xml.parsers.DocumentBuilderFactory;
0032:
0033:        import org.jasig.portal.ChannelCacheKey;
0034:        import org.jasig.portal.ChannelRuntimeData;
0035:        import org.jasig.portal.ChannelRuntimeProperties;
0036:        import org.jasig.portal.ChannelStaticData;
0037:        import org.jasig.portal.GeneralRenderingException;
0038:        import org.jasig.portal.IChannel;
0039:        import org.jasig.portal.IMimeResponse;
0040:        import org.jasig.portal.ICacheable;
0041:        import org.jasig.portal.MediaManager;
0042:        import org.jasig.portal.PortalEvent;
0043:        import org.jasig.portal.PortalException;
0044:        import org.jasig.portal.ResourceMissingException;
0045:        import org.jasig.portal.properties.PropertiesManager;
0046:        import org.jasig.portal.security.IPerson;
0047:        import org.jasig.portal.security.LocalConnectionContext;
0048:        import org.apache.commons.logging.Log;
0049:        import org.apache.commons.logging.LogFactory;
0050:        import org.jasig.portal.utils.AbsoluteURLFilter;
0051:        import org.jasig.portal.utils.CookieCutter;
0052:        import org.jasig.portal.utils.DTDResolver;
0053:        import org.jasig.portal.utils.ResourceLoader;
0054:        import org.jasig.portal.utils.XSLT;
0055:        import org.jasig.portal.utils.uri.BlockedUriException;
0056:        import org.jasig.portal.utils.uri.IUriScrutinizer;
0057:        import org.jasig.portal.utils.uri.PrefixUriScrutinizer;
0058:        import org.w3c.dom.Document;
0059:        import org.w3c.tidy.Tidy;
0060:        import org.xml.sax.ContentHandler;
0061:
0062:        /**
0063:         * <p>A channel which transforms and interacts with dynamic XML or HTML.
0064:         *    See docs/website/developers/channel_docs/reference/CwebProxy.html
0065:         *    for full documentation.
0066:         * </p>
0067:         *
0068:         *<p>Static and Runtime Channel Parameters:
0069:         *   These parameters can be configured both as ChannelStaticData parameters and as 
0070:         *   ChannelRuntimeData parameters.
0071:         *   These static parameters can be updated by equivalent
0072:         *    Runtime parameters.  Caching parameters can also be changed temporarily.
0073:         *    Cache defaults and IPerson restrictions are loaded first from properties,
0074:         *    and overridden by static data if there.
0075:         *</p>
0076:         *<ol>
0077:         *  <li>"cw_xml" - a URI for the source XML document.  By default, must be an
0078:         *      http:// or https:// URI, though this requirement is configurable via
0079:         *      ChannelStaticData parameters.
0080:         *  <li>"cw_xslTitle" - a title representing the stylesheet (optional)
0081:         *                  <i>If no title parameter is specified, a default
0082:         *                  stylesheet will be chosen according to the media</i>
0083:         *  <li>"cw_cacheDefaultMode" - Default caching mode.
0084:         *          <i>May be <code>none</code> (normally don't cache), or
0085:         *          <code>all</code> (cache everything).</i>
0086:         *  <li>"cw_cacheDefaultTimeout" - Default timeout in seconds.
0087:         *  <li>"cw_cacheMode" - override default for this request only.
0088:         *          <i>Primarily intended as a runtime parameter, but can
0089:         *              used statically to override the first instance.</i>
0090:         *  <li>"cw_cacheTimeout" - override default for this request only.
0091:         *          <i>Primarily intended as a runtime parameter, but can
0092:         *              be used statically to override the first instance.</i>
0093:         *</ol>
0094:         *
0095:         * <p>Static Channel Parameters:
0096:         These parameters can be configured only as ChannelStaticData parameters.
0097:         They can no longer (as of uPortal 2.5.1) be changed at runtime.  This closes
0098:         some serious security vulnerabilities wherein the Adversary would manipulate
0099:         these parameters at runtime to access resources on the local filesystem.
0100:         * </p>
0101:         * <ol>
0102:         *  <li>"cw_ssl" - a URI specifying the corresponding .ssl (stylesheet list) file
0103:         *  <li>"cw_xsl" - a URI specifying the stylesheet to use
0104:         *                  <i>If <code>cw_xsl</code> is supplied, <code>cw_ssl</code>
0105:         *                  and <code>cw_xslTitle</code> will be ignored.</i>
0106:         *  <li>"cw_passThrough" - indicates how RunTimeData is to be passed through.
0107:         *                  <i>If <code>cw_passThrough</code> is supplied, and not set
0108:         *          to "all" or "application", additional RunTimeData
0109:         *          parameters not starting with "cw_" or "upc_" will be
0110:         *          passed as request parameters to the XML URI.  If
0111:         *          <code>cw_passThrough</code> is set to "marked", this will
0112:         *          happen only if there is also a RunTimeData parameter of
0113:         *          <code>cw_inChannelLink</code>.  "application" is intended
0114:         *          to keep application-specific links in the channel, while
0115:         *          "all" should keep all links in the channel.  This
0116:         *          distinction is handled entirely in the URL Filters.</i>
0117:         *  <li>"cw_tidy" - output from <code>xmlUri</code> will be passed though Jtidy
0118:         *  <li>"cw_info" - a URI to be called for the <code>info</code> event.
0119:         *  <li>"cw_help" - a URI to be called for the <code>help</code> event.
0120:         *  <li>"cw_edit" - a URI to be called for the <code>edit</code> event.
0121:         *  <li>"cw_person" - IPerson attributes to pass.
0122:         *          <i>A comma-separated list of IPerson attributes to
0123:         *          pass to the back end application.  The static data
0124:         *          value will be passed on </i>all<i> requests except some
0125:         *          refresh requests.</i>
0126:         *  <li>"cw_personAllow" - Restrict IPerson attribute passing to this list.
0127:         *          <i>A comma-separated list of IPerson attributes that
0128:         *          may be passed via cw_person.  An empty or non-existent
0129:         *          value means use the default value from the corresponding
0130:         *          property.  The special value "*" means all attributes
0131:         *          are allowed.  The value "!*" means none are allowed.
0132:         *          Static data only.</i>
0133:         *  <li>"upc_localConnContext" - LocalConnectionContext implementation class.
0134:         *                  <i>The name of a class to use when data sent to the
0135:         *                  backend application needs to be modified or added
0136:         *                  to suit local needs.  Static data only.</i>
0137:         *  <li>"cw_allow_uri_prefixes" - permitted URI prefixes.
0138:         *         <i>Optional static data only parameter specifying allowable prefixes
0139:         *            for URIs accessed by this channel.  This channel will only use
0140:         *            URIs with these prefixes for obtaining XML and XSLT for use in
0141:         *            rendering.  Whitespace delimit allowed prefixes.  Effectively
0142:         *            defaults to "http:// https://"; do not allow "file:/" lightly.</i>
0143:         *       </li>
0144:         *  <li>"cw_block_uri_prefixes" - blocked URI prefixes.
0145:         *         <i>Optional static data only parameter further restricting which
0146:         *            URIs this channel will use to obtain XML and XSLT.  This channel
0147:         *            will not use URIs matching prefixes specified in this whitespace-
0148:         *            delimited parameter.  Effectively defaults to "".</i>
0149:         *  </li>
0150:         *  <li>"cw_restrict_xmlUri_inStaticData" - Optional parameter specifying whether 
0151:         *                  the xmlUri should be restricted according to the allow and
0152:         *                  deny prefix rules above as presented in ChannelStaticData
0153:         *                  or just as presented in ChannelRuntimeData.  "true" means
0154:         *                  both ChannelStaticData and ChannelRuntimeData will be restricted.
0155:         *                  Any other value or the parameter not being present means 
0156:         *                  only ChannelRuntimeData will be restricted.  It is important
0157:         *                  to set this value to true when using subscribe-time
0158:         *                  channel parameter configuration of the xmlUri.
0159:         *  </li>
0160:         * </ol>
0161:         * <p>Runtime Channel Parameters:</p>
0162:         *    The following parameters are runtime-only.
0163:         * </p>
0164:         * <ol>
0165:         *  <li>"cw_reset" - an instruction to return to reset internal variables.
0166:         *         <i>The value <code>return</code> resets <code>cw_xml</code>
0167:         *         to its last value before changed by button events.  The
0168:         *         value "reset" returns all variables to the static data
0169:         *         values.</i>
0170:         *  <li>"cw_download" - use download worker for this link or form
0171:         *                 <i>any link or form that contains this parameter will be
0172:         *                 handled by the download worker, if the pass-through mode
0173:         *                 is set to rewrite the link or form.  This allows downloads
0174:         *                 from the proxied site to be delivered via the portal,
0175:         *                 primarily useful if the download requires verification
0176:         *                 of a session referenced by a proxied cookie</i>
0177:         *
0178:         * </ol>
0179:         * <p>This channel can be used for all XML formats with appropriate stylesheets.
0180:         *    All static data parameters as well as additional runtime data parameters
0181:         *    passed to this channel via HttpRequest will in turn be passed on to the
0182:         *    XSLT stylesheet as stylesheet parameters.  They can be read in the
0183:         *    stylesheet as follows:
0184:         *    <code>&lt;xsl:param
0185:         *    name="yourParamName"&gt;aDefaultValue&lt;/xsl:param&gt;</code>
0186:         * </p>
0187:         * @author Andrew Draskoy, andrew@mun.ca
0188:         * @author Sarah Arnott, sarnott@mun.ca
0189:         * @version $Revision: 42283 $
0190:         */
0191:        public class CWebProxy implements  IChannel, ICacheable, IMimeResponse
0192:
0193:        {
0194:            private static final Log log = LogFactory.getLog(CWebProxy.class);
0195:            private static final Log accessLog = LogFactory
0196:                    .getLog(CWebProxy.class + ".access");
0197:
0198:            /**
0199:             * The name of the optional ChannelStaticData parameter the value of 
0200:             * which will be a String containing a whitespace-delimited list of allowable
0201:             * URI prefixes for URIs from which the configured CWebProxy instance will
0202:             * obtain XML and XSLT.  Defaults to allowing all URIs of the http://
0203:             * and https:// methods.
0204:             */
0205:            public static final String ALLOW_URI_PREFIXES_PARAM = "cw_allow_uri_prefixes";
0206:
0207:            /**
0208:             * The name of the optional ChannelStaticData parameter the value of which
0209:             * will be a String containing a whitespace-delimited list of explicitly
0210:             * blocked URI prefixes for URIs from which the configured CWebProxy 
0211:             * instance will not obtain XML and XSLT.  URIs matching these prefixes
0212:             * will not be used even if they also match an allow prefix specified in
0213:             * ALLOW_URI_PREFIXES_PARAM.
0214:             */
0215:            public static final String BLOCK_URI_PREFIXES_PARAM = "cw_block_uri_prefixes";
0216:
0217:            /**
0218:             * The name of the optional ChannelStaticData parameter the value of which
0219:             * will be the String "true" to convey that the xmlUri should be restricted
0220:             * as received from both ChannelStaticData and CHannelRuntimeData and 
0221:             * any other value to convey that it should be restricted only as received
0222:             * from ChannelRuntimeData.  
0223:             * 
0224:             * CWebProxy should be configured to restrict xmlUri from ChannelStaticData
0225:             * in the case where the xmlUri is a subscribe-time configurable parameter.
0226:             */
0227:            public static final String RESTRICT_STATIC_XMLURI_PREFIXES_PARAM = "cw_restrict_xmlUri_inStaticData";
0228:
0229:            private static final MediaManager MEDIAMANAGER = MediaManager
0230:                    .getMediaManager();
0231:            // to prepend to the system-wide cache key
0232:            static final String systemCacheId = "org.jasig.portal.channels.webproxy.CWebProxy";
0233:            static PrintWriter devNull;
0234:
0235:            ChannelState chanState;
0236:
0237:            static {
0238:                try {
0239:                    devNull = getErrout();
0240:                } catch (FileNotFoundException fnfe) {
0241:                    /* Ignore */
0242:                }
0243:            }
0244:
0245:            /**
0246:             * All state variables are stored in this inner class.
0247:             * It would probably be an improvement to extract this inner class into its own
0248:             * fully fledged class in the cwebproxy package, thereby enforcing that its 
0249:             * properties are only accessed via getter and setter methods that would 
0250:             * need to be added.
0251:             */
0252:            private class ChannelState {
0253:                private String publishId;
0254:                private IPerson iperson;
0255:                private String person;
0256:                private String personAllow;
0257:                private HashSet personAllow_set;
0258:                private String fullxmlUri;
0259:
0260:                /**
0261:                 * URI of the source of XML this CWebProxy instance will render in response
0262:                 * to a recent button press (channel control button, e.g. "help").
0263:                 */
0264:                private String buttonxmlUri;
0265:
0266:                /**
0267:                 * URI of the source of XML this CWebProxy instance will render.
0268:                 * Do not set this field directly.  Instead, access it via the setter 
0269:                 * method.
0270:                 */
0271:                private String xmlUri;
0272:                private String key;
0273:                private String passThrough;
0274:                private String tidy;
0275:
0276:                /**
0277:                 * URI of the stylesheet selector this channel will use to select its 
0278:                 * XSLT.
0279:                 */
0280:                private String sslUri;
0281:                private String xslTitle;
0282:
0283:                /**
0284:                 * URI of the XSLT this channel will use to select its XSLT.
0285:                 */
0286:                private String xslUri;
0287:
0288:                /**
0289:                 * URI of the XML this channel will use to render its info mode.
0290:                 */
0291:                private String infoUri;
0292:
0293:                /**
0294:                 * URI of the XML this channel will use to render its help mode.
0295:                 */
0296:                private String helpUri;
0297:
0298:                /**
0299:                 * URI of the XML this channel will use to render its edit mode.
0300:                 */
0301:                private String editUri;
0302:
0303:                private String cacheDefaultMode;
0304:                private String cacheMode;
0305:                private String reqParameters;
0306:                private long cacheDefaultTimeout;
0307:                private long cacheTimeout;
0308:                private ChannelRuntimeData runtimeData;
0309:                private CookieCutter cookieCutter;
0310:                private URLConnection connHolder;
0311:                private LocalConnectionContext localConnContext;
0312:                private int refresh;
0313:
0314:                /**
0315:                 * The default scrutinizer is one that allows only http: and https: URIs.
0316:                 * Non-null.  Constructor enforces initialization to a non-null.
0317:                 */
0318:                private final IUriScrutinizer uriScrutinizer;
0319:
0320:                public ChannelState(IUriScrutinizer uriScrutinizerArg) {
0321:                    if (uriScrutinizerArg == null) {
0322:                        throw new IllegalArgumentException(
0323:                                "Cannot instantiate CWebProxy ChannelState with a null URI srutinizer.");
0324:                    }
0325:                    this .uriScrutinizer = uriScrutinizerArg;
0326:
0327:                    fullxmlUri = buttonxmlUri = xmlUri = key = passThrough = sslUri = null;
0328:                    xslTitle = xslUri = infoUri = helpUri = editUri = tidy = null;
0329:                    cacheMode = null;
0330:                    iperson = null;
0331:                    publishId = null;
0332:                    refresh = -1;
0333:                    cacheTimeout = cacheDefaultTimeout = PropertiesManager
0334:                            .getPropertyAsLong("org.jasig.portal.channels.webproxy.CWebProxy.cache_default_timeout");
0335:                    cacheMode = cacheDefaultMode = PropertiesManager
0336:                            .getProperty("org.jasig.portal.channels.webproxy.CWebProxy.cache_default_mode");
0337:                    personAllow = PropertiesManager
0338:                            .getProperty("org.jasig.portal.channels.webproxy.CWebProxy.person_allow");
0339:                    runtimeData = null;
0340:                    cookieCutter = new CookieCutter();
0341:                    localConnContext = null;
0342:                }
0343:
0344:                /**
0345:                 * Set the xmlUri channel state property, applying URI acceptance logic
0346:                 * before accepting the parameter.
0347:                 * @param uriArg URI of XML source, or null
0348:                 * @throws IllegalArgumentException if the uriArg is not in URI syntax or is
0349:                 * a non-URI classpath-relative path which doesn't map to an actually existing resource.
0350:                 * @throws BlockedUriException if the URI is unacceptable for reasons of policy
0351:                 * @since uPortal 2.5.1
0352:                 */
0353:                public void setXmlUri(String uriArg) {
0354:                    if (uriArg != null && !"".equals(uriArg)) {
0355:                        // resolve partial relative path fragments per ResourceLoader
0356:                        try {
0357:                            URL resourceUrl = ResourceLoader.getResourceAsURL(
0358:                                    this .getClass(), uriArg);
0359:                            uriArg = resourceUrl.toExternalForm();
0360:                        } catch (ResourceMissingException rme) {
0361:                            IllegalArgumentException iae = new IllegalArgumentException(
0362:                                    "Resource [" + uriArg + "] missing.");
0363:                            iae.initCause(rme);
0364:                            throw iae;
0365:                        }
0366:
0367:                        try {
0368:                            this .uriScrutinizer.scrutinize(new URI(uriArg));
0369:                            this .xmlUri = uriArg;
0370:                        } catch (URISyntaxException e) {
0371:                            IllegalArgumentException iae = new IllegalArgumentException(
0372:                                    "Value [" + uriArg + "]had bad URI syntax.");
0373:                            iae.initCause(e);
0374:                            throw iae;
0375:                        }
0376:                    }
0377:                    // if uriArg was null do nothing.
0378:
0379:                }
0380:
0381:            }
0382:
0383:            public CWebProxy() {
0384:            }
0385:
0386:            /**
0387:             * Passes ChannelStaticData to the channel.
0388:             * This is done during channel instantiation time.
0389:             * see org.jasig.portal.ChannelStaticData
0390:             * @param sd channel static data
0391:             * @see ChannelStaticData
0392:             */
0393:            public void setStaticData(ChannelStaticData sd)
0394:                    throws PortalException {
0395:
0396:                // detect static data configuration for URI scrutinizer
0397:
0398:                String allowUriPrefixesParam = sd
0399:                        .getParameter(ALLOW_URI_PREFIXES_PARAM);
0400:                String denyUriPrefixesParam = sd
0401:                        .getParameter(BLOCK_URI_PREFIXES_PARAM);
0402:
0403:                // store the scrutinizer into channel state
0404:                IUriScrutinizer uriScrutinizer = PrefixUriScrutinizer
0405:                        .instanceFromParameters(allowUriPrefixesParam,
0406:                                denyUriPrefixesParam);
0407:                ChannelState state = new ChannelState(uriScrutinizer);
0408:
0409:                // determine whether we should restrict what URIs we accept as the xmlUri from
0410:                // ChannelStaticData
0411:                String scrutinizeXmlUriAsStaticDataString = sd
0412:                        .getParameter(RESTRICT_STATIC_XMLURI_PREFIXES_PARAM);
0413:                boolean scrutinizeXmlUriAsStaticData = "true"
0414:                        .equals(scrutinizeXmlUriAsStaticDataString);
0415:
0416:                String xmlUriParam = sd.getParameter("cw_xml");
0417:                if (scrutinizeXmlUriAsStaticData) {
0418:                    // apply configured xmlUri restrictions
0419:                    state.setXmlUri(xmlUriParam);
0420:                } else {
0421:                    // set the field directly to avoid applying xmlUri restrictions
0422:                    state.xmlUri = xmlUriParam;
0423:                }
0424:
0425:                state.iperson = sd.getPerson();
0426:                state.publishId = sd.getChannelPublishId();
0427:                state.person = sd.getParameter("cw_person");
0428:                String personAllow = sd.getParameter("cw_personAllow");
0429:                if (personAllow != null && (!personAllow.trim().equals("")))
0430:                    state.personAllow = personAllow;
0431:                // state.personAllow could have been set by a property or static data
0432:                if (state.personAllow != null
0433:                        && (!state.personAllow.trim().equals("!*"))) {
0434:                    state.personAllow_set = new HashSet();
0435:                    StringTokenizer st = new StringTokenizer(state.personAllow,
0436:                            ",");
0437:                    if (st != null) {
0438:                        while (st.hasMoreElements()) {
0439:                            String pName = st.nextToken();
0440:                            if (pName != null) {
0441:                                pName = pName.trim();
0442:                                if (!pName.equals(""))
0443:                                    state.personAllow_set.add(pName);
0444:                            }
0445:                        }
0446:                    }
0447:                }
0448:
0449:                state.sslUri = sd.getParameter("cw_ssl");
0450:                state.xslTitle = sd.getParameter("cw_xslTitle");
0451:                state.xslUri = sd.getParameter("cw_xsl");
0452:                state.fullxmlUri = sd.getParameter("cw_xml");
0453:
0454:                state.passThrough = sd.getParameter("cw_passThrough");
0455:                state.tidy = sd.getParameter("cw_tidy");
0456:
0457:                state.infoUri = sd.getParameter("cw_info");
0458:                state.helpUri = sd.getParameter("cw_help");
0459:                state.editUri = sd.getParameter("cw_edit");
0460:
0461:                state.key = state.xmlUri;
0462:
0463:                String cacheMode = sd.getParameter("cw_cacheDefaultMode");
0464:                if (cacheMode != null && !cacheMode.trim().equals(""))
0465:                    state.cacheDefaultMode = cacheMode;
0466:                cacheMode = sd.getParameter("cw_cacheMode");
0467:                if (cacheMode != null && !cacheMode.trim().equals(""))
0468:                    state.cacheMode = cacheMode;
0469:                else
0470:                    state.cacheMode = state.cacheDefaultMode;
0471:
0472:                String cacheTimeout = sd.getParameter("cw_cacheDefaultTimeout");
0473:                if (cacheTimeout != null && !cacheTimeout.trim().equals(""))
0474:                    state.cacheDefaultTimeout = Long.parseLong(cacheTimeout);
0475:                cacheTimeout = sd.getParameter("cw_cacheTimeout");
0476:                if (cacheTimeout != null && !cacheTimeout.trim().equals(""))
0477:                    state.cacheTimeout = Long.parseLong(cacheTimeout);
0478:                else
0479:                    state.cacheTimeout = state.cacheDefaultTimeout;
0480:
0481:                String connContext = sd.getParameter("upc_localConnContext");
0482:                if (connContext != null && !connContext.trim().equals("")) {
0483:                    try {
0484:                        state.localConnContext = (LocalConnectionContext) Class
0485:                                .forName(connContext).newInstance();
0486:                        state.localConnContext.init(sd);
0487:                    } catch (Exception e) {
0488:                        log
0489:                                .error(
0490:                                        "CWebProxy: Cannot initialize LocalConnectionContext: ",
0491:                                        e);
0492:                    }
0493:                }
0494:
0495:                chanState = state;
0496:            }
0497:
0498:            /**
0499:             * Passes ChannelRuntimeData to the channel.
0500:             * This function is called prior to the renderXML() call.
0501:             * @param rd channel runtime data
0502:             * @see ChannelRuntimeData
0503:             */
0504:            public void setRuntimeData(ChannelRuntimeData rd) {
0505:                ChannelState state = chanState;
0506:                if (state == null) {
0507:                    log.debug("CWebProxy:setRuntimeData() : no entry in state");
0508:                } else {
0509:                    state.runtimeData = rd;
0510:                    if (rd.isEmpty() && (state.refresh != -1)) {
0511:                        // A refresh-- State remains the same.
0512:                        if (state.buttonxmlUri != null) {
0513:                            state.key = state.buttonxmlUri;
0514:                            state.fullxmlUri = state.buttonxmlUri;
0515:                            state.refresh = 0;
0516:                        } else {
0517:                            if (state.refresh == 0)
0518:                                state.key = state.fullxmlUri;
0519:                            state.fullxmlUri = state.xmlUri;
0520:                            state.refresh = 1;
0521:                        }
0522:                    } else {
0523:
0524:                        state.refresh = 0;
0525:
0526:                        String xmlUri = state.runtimeData
0527:                                .getParameter("cw_xml");
0528:                        if (xmlUri != null) {
0529:                            state.setXmlUri(xmlUri);
0530:                            // don't need an explicit reset if a new URI is provided.
0531:                            state.buttonxmlUri = null;
0532:                        }
0533:
0534:                        // prior to uPortal 2.5.1, CWebProxy allowed several other parameters
0535:                        // to  be set via channel runtime data.  These features were removed
0536:                        // to close security vulnerabilities.  Some (very few) uPortal deployments
0537:                        // will need to add these features back in or otherwise address them.
0538:
0539:                        String xslTitle = state.runtimeData
0540:                                .getParameter("cw_xslTitle");
0541:                        if (xslTitle != null)
0542:                            state.xslTitle = xslTitle;
0543:
0544:                        String passThrough = state.runtimeData
0545:                                .getParameter("cw_passThrough");
0546:                        if (passThrough != null)
0547:                            state.passThrough = passThrough;
0548:
0549:                        String cacheTimeout = state.runtimeData
0550:                                .getParameter("cw_cacheDefaultTimeout");
0551:                        if (cacheTimeout != null)
0552:                            state.cacheDefaultTimeout = Long
0553:                                    .parseLong(cacheTimeout);
0554:
0555:                        cacheTimeout = state.runtimeData
0556:                                .getParameter("cw_cacheTimeout");
0557:                        if (cacheTimeout != null)
0558:                            state.cacheTimeout = Long.parseLong(cacheTimeout);
0559:                        else
0560:                            state.cacheTimeout = state.cacheDefaultTimeout;
0561:
0562:                        String cacheDefaultMode = state.runtimeData
0563:                                .getParameter("cw_cacheDefaultMode");
0564:                        if (cacheDefaultMode != null) {
0565:                            state.cacheDefaultMode = cacheDefaultMode;
0566:                        }
0567:
0568:                        String cacheMode = state.runtimeData
0569:                                .getParameter("cw_cacheMode");
0570:                        if (cacheMode != null) {
0571:                            state.cacheMode = cacheMode;
0572:                        } else
0573:                            state.cacheMode = state.cacheDefaultMode;
0574:
0575:                        // reset is a one-time thing.
0576:                        String reset = state.runtimeData
0577:                                .getParameter("cw_reset");
0578:                        if (reset != null) {
0579:                            if (reset.equalsIgnoreCase("return")) {
0580:                                state.buttonxmlUri = null;
0581:                            }
0582:                        }
0583:
0584:                        if (state.buttonxmlUri != null)
0585:                            state.fullxmlUri = state.buttonxmlUri;
0586:                        else {
0587:                            //log.debug("CWebProxy: xmlUri is " + state.xmlUri);
0588:
0589:                            // pass IPerson atts independent of the value of cw_passThrough
0590:                            StringBuffer newXML = new StringBuffer();
0591:                            String appendchar = "";
0592:
0593:                            // here add in attributes according to cw_person
0594:                            if (state.person != null
0595:                                    && state.personAllow_set != null) {
0596:                                StringTokenizer st = new StringTokenizer(
0597:                                        state.person, ",");
0598:                                if (st != null) {
0599:                                    while (st.hasMoreElements()) {
0600:                                        String pName = st.nextToken();
0601:                                        if ((pName != null)
0602:                                                && (!pName.trim().equals(""))) {
0603:                                            if (state.personAllow.trim()
0604:                                                    .equals("*")
0605:                                                    || state.personAllow_set
0606:                                                            .contains(pName)) {
0607:                                                newXML.append(appendchar);
0608:                                                appendchar = "&";
0609:                                                newXML.append(pName);
0610:                                                newXML.append("=");
0611:                                                // note, this only gets the first one if it's a
0612:                                                // java.util.Vector.  Should check
0613:                                                String pVal = (String) state.iperson
0614:                                                        .getAttribute(pName);
0615:                                                if (pVal != null)
0616:                                                    try {
0617:                                                        newXML
0618:                                                                .append(URLEncoder
0619:                                                                        .encode(
0620:                                                                                pVal,
0621:                                                                                "UTF-8"));
0622:                                                    } catch (UnsupportedEncodingException e) {
0623:                                                        throw new RuntimeException(
0624:                                                                e);
0625:                                                    }
0626:                                            } else {
0627:                                                if (log.isInfoEnabled())
0628:                                                    log
0629:                                                            .info("CWebProxy: request to pass "
0630:                                                                    + pName
0631:                                                                    + " denied.");
0632:                                            }
0633:                                        }
0634:                                    }
0635:                                }
0636:                            }
0637:                            // end cw_person code
0638:
0639:                            // Is this a case where we need to pass request parameters to the xmlURI?
0640:                            if (state.passThrough != null
0641:                                    && !state.passThrough
0642:                                            .equalsIgnoreCase("none")
0643:                                    && (state.passThrough
0644:                                            .equalsIgnoreCase("all")
0645:                                            || state.passThrough
0646:                                                    .equalsIgnoreCase("application") || rd
0647:                                            .getParameter("cw_inChannelLink") != null)) {
0648:                                // keyword and parameter processing
0649:                                // NOTE: if both exist, only keywords are appended
0650:                                String keywords = rd.getKeywords();
0651:                                if (keywords != null) {
0652:                                    if (appendchar.equals("&"))
0653:                                        newXML.append("&keywords=" + keywords);
0654:                                    else
0655:                                        newXML.append(keywords);
0656:                                } else {
0657:                                    // want all runtime parameters not specific to WebProxy
0658:                                    Enumeration e = rd.getParameterNames();
0659:                                    if (e != null) {
0660:                                        while (e.hasMoreElements()) {
0661:                                            String pName = (String) e
0662:                                                    .nextElement();
0663:                                            if (!pName.startsWith("cw_")
0664:                                                    && !pName
0665:                                                            .startsWith("upc_")
0666:                                                    && !pName.trim().equals("")) {
0667:                                                String[] value_array = rd
0668:                                                        .getParameterValues(pName);
0669:                                                int i = 0;
0670:                                                while (i < value_array.length) {
0671:                                                    newXML.append(appendchar);
0672:                                                    appendchar = "&";
0673:                                                    newXML.append(pName);
0674:                                                    newXML.append("=");
0675:                                                    try {
0676:                                                        newXML
0677:                                                                .append(URLEncoder
0678:                                                                        .encode(
0679:                                                                                value_array[i++]
0680:                                                                                        .trim(),
0681:                                                                                "UTF-8"));
0682:                                                    } catch (UnsupportedEncodingException e1) {
0683:                                                        throw new RuntimeException(
0684:                                                                e1);
0685:                                                    }
0686:                                                }
0687:                                            }
0688:                                        }
0689:                                    }
0690:                                }
0691:                            }
0692:
0693:                            state.reqParameters = newXML.toString();
0694:                            state.fullxmlUri = state.xmlUri;
0695:                            if (!state.runtimeData.getHttpRequestMethod()
0696:                                    .equals("POST")) {
0697:                                if ((state.reqParameters != null)
0698:                                        && (!state.reqParameters.trim().equals(
0699:                                                ""))) {
0700:                                    appendchar = (state.xmlUri.indexOf('?') == -1) ? "?"
0701:                                            : "&";
0702:                                    state.fullxmlUri = state.fullxmlUri
0703:                                            + appendchar + state.reqParameters;
0704:                                }
0705:                                state.reqParameters = null;
0706:                            }
0707:
0708:                            //log.debug("CWebProxy: fullxmlUri now: " + state.fullxmlUri);
0709:                        }
0710:
0711:                        // set key for cache based on request parameters
0712:                        // NOTE: POST requests are not idempotent and therefore are not
0713:                        // retrievable from the cache
0714:                        if (!state.runtimeData.getHttpRequestMethod().equals(
0715:                                "POST"))
0716:                            state.key = state.fullxmlUri;
0717:                        else
0718:                            //generate a unique string as key
0719:                            state.key = String.valueOf((new Date()).getTime());
0720:
0721:                    }
0722:                }
0723:            }
0724:
0725:            /**
0726:             * Process portal events.  Currently supported events are
0727:             * EDIT_BUTTON_EVENT, HELP_BUTTON_EVENT, ABOUT_BUTTON_EVENT,
0728:             * and SESSION_DONE.  The button events work by changing the xmlUri.
0729:             * The new Uri's content should contain a link that will refer back
0730:             * to the old one at the end of its task.
0731:             * @param ev the event
0732:             */
0733:            public void receiveEvent(PortalEvent ev) {
0734:                ChannelState state = chanState;
0735:                if (state == null) {
0736:                    log.debug("CWebProxy:receiveEvent() : no entry in state");
0737:                } else {
0738:                    int evnum = ev.getEventNumber();
0739:
0740:                    switch (evnum) {
0741:                    case PortalEvent.EDIT_BUTTON_EVENT:
0742:                        if (state.editUri != null)
0743:                            state.buttonxmlUri = state.editUri;
0744:                        break;
0745:                    case PortalEvent.HELP_BUTTON_EVENT:
0746:                        if (state.helpUri != null)
0747:                            state.buttonxmlUri = state.helpUri;
0748:                        break;
0749:                    case PortalEvent.ABOUT_BUTTON_EVENT:
0750:                        if (state.infoUri != null)
0751:                            state.buttonxmlUri = state.infoUri;
0752:                        break;
0753:                    default:
0754:                        break;
0755:                    }
0756:                }
0757:            }
0758:
0759:            /**
0760:             * Acquires ChannelRuntimeProperites from the channel.
0761:             * This function may be called by the portal framework throughout the session.
0762:             * @see ChannelRuntimeProperties
0763:             */
0764:            public ChannelRuntimeProperties getRuntimeProperties() {
0765:                ChannelRuntimeProperties rp = new ChannelRuntimeProperties();
0766:
0767:                // determine if such channel is registered
0768:                if (chanState == null) {
0769:                    rp.setWillRender(false);
0770:                    log
0771:                            .debug("CWebProxy:getRuntimeProperties() : no entry in state");
0772:                }
0773:                return rp;
0774:            }
0775:
0776:            /**
0777:             * Ask channel to render its content.
0778:             * @param out the SAX ContentHandler to output content to
0779:             */
0780:            public void renderXML(ContentHandler out) throws PortalException {
0781:                ChannelState state = chanState;
0782:                if (state == null) {
0783:                    log.debug("CWebProxy:renderXML() : no entry in state");
0784:                } else {
0785:                    Document xml = null;
0786:                    String tidiedXml = null;
0787:                    try {
0788:                        if (state.tidy != null && state.tidy.equals("on"))
0789:                            tidiedXml = getTidiedXml(state.fullxmlUri, state);
0790:                        else
0791:                            xml = getXml(state.fullxmlUri, state);
0792:                    } catch (Exception e) {
0793:                        throw new GeneralRenderingException(
0794:                                "Problem retrieving contents of "
0795:                                        + state.fullxmlUri
0796:                                        + ".  Please restart channel. ", e,
0797:                                false, true);
0798:                    }
0799:
0800:                    state.runtimeData.put("baseActionURL", state.runtimeData
0801:                            .getBaseActionURL());
0802:                    state.runtimeData.put("downloadActionURL",
0803:                            state.runtimeData.getBaseWorkerURL("download"));
0804:
0805:                    // Runtime data parameters are handed to the stylesheet.
0806:                    // Add any static data parameters so it gets a full set of variables.
0807:                    // We may wish to remove this feature since we don't need it for
0808:                    // the default stylesheets now.
0809:                    if (state.xmlUri != null)
0810:                        state.runtimeData.put("cw_xml", state.xmlUri);
0811:                    if (state.sslUri != null)
0812:                        state.runtimeData.put("cw_ssl", state.sslUri);
0813:                    if (state.xslTitle != null)
0814:                        state.runtimeData.put("cw_xslTitle", state.xslTitle);
0815:                    if (state.xslUri != null)
0816:                        state.runtimeData.put("cw_xsl", state.xslUri);
0817:                    if (state.passThrough != null)
0818:                        state.runtimeData.put("cw_passThrough",
0819:                                state.passThrough);
0820:                    if (state.tidy != null)
0821:                        state.runtimeData.put("cw_tidy", state.tidy);
0822:                    if (state.infoUri != null)
0823:                        state.runtimeData.put("cw_info", state.infoUri);
0824:                    if (state.helpUri != null)
0825:                        state.runtimeData.put("cw_help", state.helpUri);
0826:                    if (state.editUri != null)
0827:                        state.runtimeData.put("cw_edit", state.editUri);
0828:                    if (state.person != null)
0829:                        state.runtimeData.put("cw_person", state.person);
0830:                    if (state.personAllow != null)
0831:                        state.runtimeData.put("cw_personAllow",
0832:                                state.personAllow);
0833:
0834:                    XSLT xslt = XSLT.getTransformer(this , state.runtimeData
0835:                            .getLocales());
0836:                    if (tidiedXml != null)
0837:                        xslt.setXML(tidiedXml);
0838:                    else
0839:                        xslt.setXML(xml);
0840:                    if (state.xslUri != null
0841:                            && (!state.xslUri.trim().equals("")))
0842:                        xslt.setXSL(state.xslUri);
0843:                    else
0844:                        xslt.setXSL(state.sslUri, state.xslTitle,
0845:                                state.runtimeData.getBrowserInfo());
0846:
0847:                    // Determine mime type
0848:                    MediaManager mm = MEDIAMANAGER;
0849:                    String media = mm.getMedia(state.runtimeData
0850:                            .getBrowserInfo());
0851:                    String mimeType = mm.getReturnMimeType(media);
0852:                    if (MediaManager.UNKNOWN.equals(mimeType)) {
0853:                        String accept = state.runtimeData.getBrowserInfo()
0854:                                .getHeader("accept");
0855:                        if (accept != null && accept.indexOf("text/html") != -1) {
0856:                            mimeType = "text/html";
0857:                        }
0858:                    }
0859:
0860:                    CWebProxyURLFilter filter2 = CWebProxyURLFilter
0861:                            .newCWebProxyURLFilter(mimeType, state.runtimeData,
0862:                                    out);
0863:                    AbsoluteURLFilter filter1 = AbsoluteURLFilter
0864:                            .newAbsoluteURLFilter(mimeType, state.xmlUri,
0865:                                    filter2);
0866:
0867:                    xslt.setTarget(filter1);
0868:
0869:                    xslt.setStylesheetParameters(state.runtimeData);
0870:                    xslt.transform();
0871:                }
0872:            }
0873:
0874:            /**
0875:             * Get the contents of a URI as a Document object.  This is used if tidy
0876:             * is not set or equals 'off'.
0877:             * Also includes support for cookies.
0878:             * @param uri the URI
0879:             * @return the data pointed to by a URI as a Document object
0880:             */
0881:            private Document getXml(String uri, ChannelState state)
0882:                    throws Exception {
0883:                long start = System.currentTimeMillis();
0884:                int status = 0;
0885:
0886:                Document doc = null;
0887:                try {
0888:                    URLConnection urlConnect = getConnection(uri, state);
0889:                    if (urlConnect instanceof  HttpURLConnection) {
0890:                        status = ((HttpURLConnection) urlConnect)
0891:                                .getResponseCode();
0892:                    }
0893:                    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
0894:                            .newInstance();
0895:                    docBuilderFactory.setNamespaceAware(false);
0896:                    DocumentBuilder docBuilder = docBuilderFactory
0897:                            .newDocumentBuilder();
0898:                    DTDResolver dtdResolver = new DTDResolver();
0899:                    docBuilder.setEntityResolver(dtdResolver);
0900:                    InputStream is = null;
0901:                    try {
0902:                        is = urlConnect.getInputStream();
0903:                        doc = docBuilder.parse(is);
0904:                    } finally {
0905:                        try {
0906:                            is.close();
0907:                        } catch (Exception e) {
0908:                            // ignore
0909:                        }
0910:                    }
0911:
0912:                } finally {
0913:                    long elapsedTimeMillis = System.currentTimeMillis() - start;
0914:                    logAccess(uri, state, status, elapsedTimeMillis);
0915:                }
0916:                return doc;
0917:            }
0918:
0919:            private void logAccess(String uri, ChannelState state, int status,
0920:                    long elapsedTimeMillis) {
0921:                // trim off request parameters
0922:                int index = uri.indexOf("?");
0923:                if (index >= 0) {
0924:                    uri = uri.substring(0, index);
0925:                }
0926:                // trim off extra spaces and replace needed spaces with %20
0927:                uri = uri.trim().replaceAll(" ", "%20");
0928:                accessLog.info("logAccess: " + state.publishId + " "
0929:                        + state.iperson.getAttribute(IPerson.USERNAME) + " "
0930:                        + uri + " " + status + " " + elapsedTimeMillis / 1000F);
0931:            }
0932:
0933:            /**
0934:             * Get the contents of a URI as a String but send it through tidy first.
0935:             * Also includes support for cookies.
0936:             * @param uri the URI
0937:             * @return the data pointed to by a URI as a String
0938:             */
0939:            private String getTidiedXml(String uri, ChannelState state)
0940:                    throws Exception {
0941:                long start = System.currentTimeMillis();
0942:                String tidiedXml = null;
0943:                int status = 0;
0944:
0945:                try {
0946:                    URLConnection urlConnect = getConnection(uri, state);
0947:                    if (urlConnect instanceof  HttpURLConnection) {
0948:                        status = ((HttpURLConnection) urlConnect)
0949:                                .getResponseCode();
0950:                    }
0951:
0952:                    // get character encoding from Content-Type header
0953:                    String encoding = null;
0954:                    String ct = urlConnect.getContentType();
0955:                    int i;
0956:                    if (ct != null && (i = ct.indexOf("charset=")) != -1) {
0957:                        encoding = ct.substring(i + 8).trim();
0958:                        if ((i = encoding.indexOf(";")) != -1)
0959:                            encoding = encoding.substring(0, i).trim();
0960:                        if (encoding.indexOf("\"") != -1)
0961:                            encoding = encoding.substring(1,
0962:                                    encoding.length() + 1);
0963:                    }
0964:
0965:                    Tidy tidy = new Tidy();
0966:
0967:                    tidy.setXHTML(true);
0968:                    tidy.setDocType("omit");
0969:                    tidy.setQuiet(true);
0970:                    tidy.setShowWarnings(false);
0971:                    tidy.setNumEntities(true);
0972:                    tidy.setWord2000(true);
0973:
0974:                    // If charset is specified in header, set JTidy's
0975:                    // character encoding  to either UTF-8, ISO-8859-1
0976:                    // or ISO-2022 accordingly (NOTE that these are
0977:                    // the only character encoding sets that are supported in
0978:                    // JTidy).  If character encoding is not specified,
0979:                    // UTF-8 is the default.
0980:                    if (encoding != null) {
0981:                        if (encoding.toLowerCase().equals("iso-8859-1"))
0982:                            tidy
0983:                                    .setCharEncoding(org.w3c.tidy.Configuration.LATIN1);
0984:                        else if (encoding.toLowerCase().equals("iso-2022-jp"))
0985:                            tidy
0986:                                    .setCharEncoding(org.w3c.tidy.Configuration.ISO2022);
0987:                        else
0988:                            tidy
0989:                                    .setCharEncoding(org.w3c.tidy.Configuration.UTF8);
0990:                    } else {
0991:                        tidy.setCharEncoding(org.w3c.tidy.Configuration.UTF8);
0992:                    }
0993:
0994:                    tidy.setErrout(devNull);
0995:
0996:                    ByteArrayOutputStream stream = new ByteArrayOutputStream(
0997:                            1024);
0998:                    BufferedOutputStream out = new BufferedOutputStream(stream);
0999:
1000:                    tidy.parse(urlConnect.getInputStream(), out);
1001:                    tidiedXml = stream.toString();
1002:                    stream.close();
1003:                    out.close();
1004:
1005:                    if (tidy.getParseErrors() > 0)
1006:                        throw new GeneralRenderingException(
1007:                                "Unable to convert input document to XHTML");
1008:                } finally {
1009:                    long elapsedTimeMillis = System.currentTimeMillis() - start;
1010:                    logAccess(uri, state, status, elapsedTimeMillis);
1011:                }
1012:                return tidiedXml;
1013:            }
1014:
1015:            private URLConnection getConnection(String uri, ChannelState state)
1016:                    throws Exception {
1017:                // before making the connection, ensure all spaces in the URI are encoded
1018:                // (Note that URLEncoder.encode(String uri) cannot be used because
1019:                // this method encodes everything, including forward slashes and
1020:                // forward slashes are used for determining if the URL is
1021:                // relative or absolute)
1022:
1023:                uri = uri.trim().replaceAll(" ", "%20");
1024:
1025:                URL url;
1026:                if (state.localConnContext != null)
1027:                    url = ResourceLoader.getResourceAsURL(this .getClass(),
1028:                            state.localConnContext.getDescriptor(uri,
1029:                                    state.runtimeData));
1030:                else
1031:                    url = ResourceLoader.getResourceAsURL(this .getClass(), uri);
1032:
1033:                // get info from url for cookies
1034:                String domain = url.getHost().trim();
1035:                String path = url.getPath();
1036:                if (path.indexOf("/") != -1) {
1037:                    if (path.lastIndexOf("/") != 0)
1038:                        path = path.substring(0, path.lastIndexOf("/"));
1039:                }
1040:                String port = Integer.toString(url.getPort());
1041:
1042:                //get connection
1043:                URLConnection urlConnect = url.openConnection();
1044:                String protocol = url.getProtocol();
1045:
1046:                if (protocol.equals("http") || protocol.equals("https")) {
1047:                    if (domain != null && path != null) {
1048:                        //prepare the connection by setting properties and sending data
1049:                        HttpURLConnection httpUrlConnect = (HttpURLConnection) urlConnect;
1050:                        httpUrlConnect.setInstanceFollowRedirects(false);
1051:                        //send any cookie headers to proxied application
1052:                        if (state.cookieCutter.cookiesExist())
1053:                            state.cookieCutter.sendCookieHeader(httpUrlConnect,
1054:                                    domain, path, port);
1055:                        //set connection properties if request method was post
1056:                        if (state.runtimeData.getHttpRequestMethod().equals(
1057:                                "POST")) {
1058:                            if ((state.reqParameters != null)
1059:                                    && (!state.reqParameters.trim().equals(""))) {
1060:                                httpUrlConnect.setRequestMethod("POST");
1061:                                httpUrlConnect.setAllowUserInteraction(false);
1062:                                httpUrlConnect.setDoOutput(true);
1063:                            }
1064:                        }
1065:
1066:                        //send local data, if required
1067:                        //can call getOutputStream in sendLocalData (ie. to send post params)
1068:                        //(getOutputStream can be called twice on an HttpURLConnection)
1069:                        if (state.localConnContext != null) {
1070:                            try {
1071:                                state.localConnContext.sendLocalData(
1072:                                        httpUrlConnect, state.runtimeData);
1073:                            } catch (Exception e) {
1074:                                log
1075:                                        .error(
1076:                                                "CWebProxy: Unable to send data through "
1077:                                                        + state.runtimeData
1078:                                                                .getParameter("upc_localConnContext"),
1079:                                                e);
1080:                            }
1081:                        }
1082:
1083:                        //send the request parameters by post, if required
1084:                        //at this point, set or send methods cannot be called on the connection
1085:                        //object (they must be called before sendLocalData)
1086:                        if (state.runtimeData.getHttpRequestMethod().equals(
1087:                                "POST")) {
1088:                            if ((state.reqParameters != null)
1089:                                    && (!state.reqParameters.trim().equals(""))) {
1090:                                PrintWriter post = new PrintWriter(
1091:                                        httpUrlConnect.getOutputStream());
1092:                                post.print(state.reqParameters);
1093:                                post.flush();
1094:                                post.close();
1095:                                state.reqParameters = null;
1096:                            }
1097:                        }
1098:
1099:                        //receive cookie headers
1100:                        state.cookieCutter.storeCookieHeader(httpUrlConnect,
1101:                                domain, path, port);
1102:
1103:                        int status = httpUrlConnect.getResponseCode();
1104:                        String location = httpUrlConnect
1105:                                .getHeaderField("Location");
1106:                        switch (status) {
1107:                        case HttpURLConnection.HTTP_NOT_FOUND:
1108:                            throw new ResourceMissingException(httpUrlConnect
1109:                                    .getURL().toExternalForm(), "",
1110:                                    "HTTP Status-Code 404: Not Found");
1111:                        case HttpURLConnection.HTTP_FORBIDDEN:
1112:                            throw new ResourceMissingException(httpUrlConnect
1113:                                    .getURL().toExternalForm(), "",
1114:                                    "HTTP Status-Code 403: Forbidden");
1115:                        case HttpURLConnection.HTTP_INTERNAL_ERROR:
1116:                            throw new ResourceMissingException(httpUrlConnect
1117:                                    .getURL().toExternalForm(), "",
1118:                                    "HTTP Status-Code 500: Internal Server Error");
1119:                        case HttpURLConnection.HTTP_NO_CONTENT:
1120:                            throw new ResourceMissingException(httpUrlConnect
1121:                                    .getURL().toExternalForm(), "",
1122:                                    "HTTP Status-Code 204: No Content");
1123:                            /*
1124:                             * Note: these cases apply to http status codes 302 and 303
1125:                             * this will handle automatic redirection to a new GET URL
1126:                             */
1127:                        case HttpURLConnection.HTTP_MOVED_TEMP:
1128:                            httpUrlConnect.disconnect();
1129:                            httpUrlConnect = (HttpURLConnection) getConnection(
1130:                                    location, state);
1131:                            break;
1132:                        case HttpURLConnection.HTTP_SEE_OTHER:
1133:                            httpUrlConnect.disconnect();
1134:                            httpUrlConnect = (HttpURLConnection) getConnection(
1135:                                    location, state);
1136:                            break;
1137:                        /*
1138:                         * Note: this cases apply to http status code 301
1139:                         * it will handle the automatic redirection of GET requests.
1140:                         * The spec calls for a POST redirect to be verified manually by the user
1141:                         * Rather than bypass this security restriction, we will throw an exception
1142:                         */
1143:                        case HttpURLConnection.HTTP_MOVED_PERM:
1144:                            if (state.runtimeData.getHttpRequestMethod()
1145:                                    .equals("GET")) {
1146:                                httpUrlConnect.disconnect();
1147:                                httpUrlConnect = (HttpURLConnection) getConnection(
1148:                                        location, state);
1149:                            } else {
1150:                                throw new ResourceMissingException(
1151:                                        httpUrlConnect.getURL()
1152:                                                .toExternalForm(), "",
1153:                                        "HTTP Status-Code 301: POST Redirection currently not supported");
1154:                            }
1155:                            break;
1156:                        default:
1157:                            break;
1158:                        }
1159:
1160:                        return (URLConnection) httpUrlConnect;
1161:                    }
1162:                }
1163:                return urlConnect;
1164:            }
1165:
1166:            public ChannelCacheKey generateKey() {
1167:                ChannelState state = chanState;
1168:
1169:                if (state == null) {
1170:                    log.debug("CWebProxy:generateKey() : no entry in state");
1171:                    return null;
1172:                }
1173:
1174:                if (state.cacheMode.equalsIgnoreCase("none"))
1175:                    return null;
1176:                // else if http see first if caching is on or off.  if it's on,
1177:                // store the validity time in the state, cache it, and further
1178:                // resolve later with isValid.
1179:                // check cache-control, no-cache, must-revalidate, max-age,
1180:                // Date & Expires, expiry in past
1181:                // for 1.0 check pragma for no-cache
1182:                // add a warning to docs about not a full http 1.1 impl.
1183:
1184:                ChannelCacheKey k = new ChannelCacheKey();
1185:                StringBuffer sbKey = new StringBuffer(1024);
1186:
1187:                // Only INSTANCE scope is currently supported.
1188:                k.setKeyScope(ChannelCacheKey.INSTANCE_KEY_SCOPE);
1189:
1190:                sbKey.append("sslUri:").append(state.sslUri).append(", ");
1191:
1192:                // xslUri may either be specified as a parameter to this channel
1193:                // or we will get it by looking in the stylesheet list file
1194:                String xslUriForKey = state.xslUri;
1195:                try {
1196:                    if (xslUriForKey == null) {
1197:                        String sslUri = ResourceLoader.getResourceAsURLString(
1198:                                this .getClass(), state.sslUri);
1199:                        xslUriForKey = XSLT.getStylesheetURI(sslUri,
1200:                                state.runtimeData.getBrowserInfo());
1201:                    }
1202:                } catch (Exception e) {
1203:                    xslUriForKey = "Not attainable: " + e;
1204:                }
1205:
1206:                sbKey.append("xslUri:").append(xslUriForKey).append(", ");
1207:                sbKey.append("key:").append(state.key).append(", ");
1208:                sbKey.append("passThrough:").append(state.passThrough).append(
1209:                        ", ");
1210:                sbKey.append("tidy:").append(state.tidy).append(", ");
1211:                sbKey.append("person:").append(state.person);
1212:                k.setKey(sbKey.toString());
1213:                k.setKeyValidity(new Long(System.currentTimeMillis()));
1214:                //log.debug("CWebProxy:generateKey("
1215:                //      + uid + ") : cachekey=\"" + sbKey.toString() + "\"");
1216:                return k;
1217:            }
1218:
1219:            static PrintWriter getErrout() throws FileNotFoundException {
1220:                if (System.getProperty("os.name").indexOf("Windows") != -1)
1221:                    return new PrintWriter(new FileOutputStream("nul"));
1222:                else
1223:                    return new PrintWriter(new FileOutputStream("/dev/null"));
1224:            }
1225:
1226:            public boolean isCacheValid(Object validity) {
1227:                if (!(validity instanceof  Long))
1228:                    return false;
1229:
1230:                ChannelState state = chanState;
1231:
1232:                if (state == null) {
1233:                    log.debug("CWebProxy:isCacheValid() : no entry in state");
1234:                    return false;
1235:                } else {
1236:                    return (System.currentTimeMillis()
1237:                            - ((Long) validity).longValue() < state.cacheTimeout * 1000);
1238:                }
1239:            }
1240:
1241:            public String getContentType() {
1242:                return chanState.connHolder.getContentType();
1243:            }
1244:
1245:            public InputStream getInputStream() throws IOException {
1246:                InputStream rs = chanState.connHolder.getInputStream();
1247:                chanState.connHolder = null;
1248:                return rs;
1249:            }
1250:
1251:            public void downloadData(OutputStream out) throws IOException {
1252:                throw (new IOException(
1253:                        "CWebProxy: downloadData method not supported - use getInputStream only"));
1254:            }
1255:
1256:            public String getName() {
1257:                return "proxyDL";
1258:            }
1259:
1260:            public Map getHeaders() {
1261:                ChannelState state = chanState;
1262:                try {
1263:                    state.connHolder = getConnection(state.fullxmlUri, state);
1264:                } catch (Exception e) {
1265:                    log.error(e, e);
1266:                }
1267:                Map rhdrs = new HashMap();
1268:                int i = 0;
1269:                while (state.connHolder.getHeaderFieldKey(i) != null) {
1270:                    rhdrs.put(state.connHolder.getHeaderFieldKey(i),
1271:                            state.connHolder.getHeaderField(i));
1272:                    i++;
1273:                }
1274:                return rhdrs;
1275:            }
1276:
1277:            public void reportDownloadError(Exception e) {
1278:                // We really should report this to the user somehow??
1279:                log.error(e.getMessage(), e);
1280:            }
1281:
1282:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.