001: package org.pentaho.ui.servlet;
002:
003: /*
004: * Copyright 2005 Pentaho Corporation. All rights reserved.
005: * This software was developed by Pentaho Corporation and is provided under the terms
006: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
007: * this file except in compliance with the license. If you need a copy of the license,
008: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
009: * BI Platform. The Initial Developer is Pentaho Corporation.
010: *
011: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
012: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
013: * the license for the specific language governing your rights and limitations.
014: *
015: * @created Nov 18, 2005
016: * @author Doug Moran
017: *
018: */
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.net.URL;
023: import java.util.Iterator;
024: import java.util.Map;
025:
026: import javax.servlet.ServletConfig;
027: import javax.servlet.ServletException;
028: import javax.servlet.ServletOutputStream;
029: import javax.servlet.http.HttpServletRequest;
030: import javax.servlet.http.HttpServletResponse;
031:
032: import org.apache.commons.httpclient.Header;
033: import org.apache.commons.httpclient.HttpClient;
034: import org.apache.commons.httpclient.HttpException;
035: import org.apache.commons.httpclient.HttpMethod;
036: import org.apache.commons.httpclient.HttpStatus;
037: import org.apache.commons.httpclient.methods.PostMethod;
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040: import org.pentaho.core.session.IPentahoSession;
041: import org.pentaho.core.system.PentahoSystem;
042: import org.pentaho.messages.Messages;
043:
044: /**
045: *
046: * This servlet is used to Proxy a Servlet request to another server for
047: * processing and returns that result to the caller as if this Servlet actiually
048: * serviced it. Setup the proxy by editing the <b>web.xml</b> to map the
049: * servlet name you want to proxy to the Proxy Servlet class.
050: * <p>
051: *
052: * <pre>
053: * <servlet>
054: * <servlet-name>ViewAction</servlet-name>
055: * <servlet-class>com.pentaho.ui.servlet.ProxyServlet</servlet-class>
056: * <init-param>
057: * <param-name>ProxyURL</param-name>
058: * <param-value>http://my.remoteserver.com:8080/pentaho</param-value>
059: * </init-param>
060: * </servlet>
061: * </pre>
062: *
063: * In the above example, all requests to /ViewAction will be forwarded to the
064: * ViewAction Servlet running on the Pentaho server atmy.remoteserver.com:8080
065: *
066: * <p>
067: * NOTES:
068: * <p>
069: *
070: * For this to be useful, both Pentaho servers should be using the same database
071: * repository.
072: * <p>
073: * The recieving server should have the ProxyTrustingFilter enabled to handle
074: * authicentation.
075: * <p>
076: * This Servlet only works with GET requests. All requests in the Pentaho BI
077: * Platform are currently gets.
078: *
079: * @see com.pentaho.test.servlet.ProxyTrustingFilter
080: * @author Doug Moran
081: *
082: */
083: public class ProxyServlet extends ServletBase {
084:
085: /**
086: *
087: */
088: private static final long serialVersionUID = 4680027723733552639L;
089:
090: private static final Log logger = LogFactory
091: .getLog(ProxyServlet.class);
092:
093: public Log getLogger() {
094: return logger;
095: }
096:
097: String proxyURL = null; // "http://localhost:8080/pentaho";
098:
099: String errorURL = null; // The URL to redirect to if the user is invalid
100:
101: /**
102: * Base Constructor
103: */
104: public ProxyServlet() {
105: super ();
106: }
107:
108: public void init(ServletConfig servletConfig)
109: throws ServletException {
110: proxyURL = servletConfig.getInitParameter("ProxyURL"); //$NON-NLS-1$
111: if ((proxyURL == null)) {
112: error(Messages
113: .getString("ProxyServlet.ERROR_0001_NO_PROXY_URL_SPECIFIED")); //$NON-NLS-1$
114: } else {
115: proxyURL.trim();
116: try {
117: URL url = new URL(proxyURL); // Just doing this to verify
118: // it's good
119: info(Messages
120: .getString(
121: "ProxyServlet.INFO_0001_URL_SELECTED", url.toExternalForm())); // using 'url' to get rid of unused var compiler warning //$NON-NLS-1$
122: } catch (Throwable t) {
123: error(Messages
124: .getErrorString(
125: "ProxyServlet.ERROR_0002_INVALID_URL", proxyURL)); //$NON-NLS-1$
126: proxyURL = null;
127: }
128: }
129:
130: errorURL = servletConfig.getInitParameter("ErrorURL"); //$NON-NLS-1$
131: super .init(servletConfig);
132: }
133:
134: protected void setupSession(IPentahoSession userSession) {
135: PentahoSystem.sessionStartup(userSession);
136: }
137:
138: protected void removeUserSession(IPentahoSession userSession) {
139: userSession.destroy();
140: }
141:
142: protected void doProxy(HttpServletRequest request,
143: HttpServletResponse response) throws IOException {
144: if (proxyURL == null) { // Got nothing from web.xml
145: return;
146: }
147:
148: String servletPath = request.getServletPath();
149: // System .out.println( ">>>>>>>> REQ: " + request.getRequestURL().toString() ); //$NON-NLS-1$//$NON-NLS-2$
150: PentahoSystem.systemEntryPoint();
151: try {
152: String theUrl = proxyURL + servletPath;
153: PostMethod method = new PostMethod(theUrl);
154:
155: // Copy the parameters from the request to the proxy
156: // System .out.print( ">>>>>>>> PARAMS: " ); //$NON-NLS-1$
157: Map paramMap = request.getParameterMap();
158: Map.Entry entry;
159: String array[];
160: for (Iterator it = paramMap.entrySet().iterator(); it
161: .hasNext();) {
162: entry = (Map.Entry) it.next();
163: array = (String[]) entry.getValue();
164: for (int i = 0; i < array.length; ++i) {
165: method.addParameter((String) entry.getKey(),
166: array[i]);
167: // System.out.print( (String)entry.getKey() + "=" + array[i]
168: // + "&" ); //$NON-NLS-1$ //$NON-NLS-2$
169: }
170: }
171: // System.out.println( "" ); //$NON-NLS-1$
172:
173: // Just in case someone is trying to spoof the proxy
174: method.removeParameter("_TRUST_USER_"); //$NON-NLS-1$
175:
176: // Get the user from the session
177: IPentahoSession userSession = getPentahoSession(request);
178: String name = userSession.getName();
179:
180: // Add the trusted user from the session
181: if ((name != null) && (name.length() > 0)) {
182: method.addParameter("_TRUST_USER_", name); //$NON-NLS-1$
183: // System.out.println( ">>>>>>>> USR: " + name ); //$NON-NLS-1$
184: } else if ((errorURL != null)
185: && (errorURL.trim().length() > 0)) {
186: response.sendRedirect(errorURL);
187: // System.out.println( ">>>>>>>> REDIR: " + errorURL );
188: // //$NON-NLS-1$
189: return;
190: }
191:
192: // System.out.println( ">>>>>>>> PROXY: " + theUrl ); //$NON-NLS-1$
193: debug(Messages.getString(
194: "ProxyServlet.DEBUG_0001_OUTPUT_URL", theUrl)); //$NON-NLS-1$
195:
196: // Now do the request
197: HttpClient client = new HttpClient();
198:
199: try {
200: // Execute the method.
201: int statusCode = client.executeMethod(method);
202:
203: if (statusCode != HttpStatus.SC_OK) {
204: error(Messages
205: .getErrorString(
206: "ProxyServlet.ERROR_0003_REMOTE_HTTP_CALL_FAILED", method.getStatusLine().toString())); //$NON-NLS-1$
207: return;
208: }
209: setHeader("Content-Type", method, response); //$NON-NLS-1$
210: setHeader("Content-Length", method, response); //$NON-NLS-1$
211:
212: InputStream inStr = method.getResponseBodyAsStream();
213: ServletOutputStream outStr = response.getOutputStream();
214:
215: int inCnt = 0;
216: byte[] buf = new byte[2048];
217: while (-1 != (inCnt = inStr.read(buf))) {
218: outStr.write(buf, 0, inCnt);
219: }
220: } catch (HttpException e) {
221: error(
222: Messages
223: .getErrorString("ProxyServlet.ERROR_0004_PROTOCOL_FAILURE"), e); //$NON-NLS-1$
224: e.printStackTrace();
225: } catch (IOException e) {
226: error(
227: Messages
228: .getErrorString("ProxyServlet.ERROR_0005_TRANSPORT_FAILURE"), e); //$NON-NLS-1$
229: e.printStackTrace();
230: } finally {
231: method.releaseConnection();
232: }
233: } finally {
234: PentahoSystem.systemExitPoint();
235: }
236: }
237:
238: void setHeader(String headerStr, HttpMethod method,
239: HttpServletResponse response) {
240: Header header = method.getResponseHeader(headerStr);
241: if (header != null) {
242: response.setHeader(headerStr, header.getValue());
243: }
244: }
245:
246: protected void service(HttpServletRequest arg0,
247: HttpServletResponse arg1) throws ServletException,
248: IOException {
249: // TODO Auto-generated method stub
250: super .service(arg0, arg1);
251: }
252:
253: protected void doPost(HttpServletRequest request,
254: HttpServletResponse response) throws ServletException,
255: IOException {
256: doProxy(request, response);
257: }
258:
259: protected void doGet(HttpServletRequest request,
260: HttpServletResponse response) throws ServletException,
261: IOException {
262: doProxy(request, response);
263: }
264:
265: }
|