Author: pcraveiro
Date: 2012-03-26 17:53:57 -0400 (Mon, 26 Mar 2012)
New Revision: 1540
Added:
console/trunk/app/src/main/java/org/jboss/
console/trunk/app/src/main/java/org/jboss/as/
console/trunk/app/src/main/java/org/jboss/as/console/
console/trunk/app/src/main/java/org/jboss/as/console/client/
console/trunk/app/src/main/java/org/jboss/as/console/client/core/
console/trunk/app/src/main/java/org/jboss/as/console/client/core/BootstrapContext.java
console/trunk/app/src/main/java/org/jboss/as/console/server/
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/HttpClient.java
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/ProxyConfig.java
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/RedirectException.java
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxy.java
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxyServlet.java
console/trunk/app/src/main/resources/gwt-proxy.properties
console/trunk/app/src/main/resources/logout.properties
console/trunk/app/src/main/resources/upload-proxy.properties
Modified:
console/trunk/app/src/main/java/org/picketlink/as/console/application/Development.gwt.xml
console/trunk/app/src/main/webapp/WEB-INF/web.xml
Log:
Added more features.
Added:
console/trunk/app/src/main/java/org/jboss/as/console/client/core/BootstrapContext.java
===================================================================
---
console/trunk/app/src/main/java/org/jboss/as/console/client/core/BootstrapContext.java
(rev 0)
+++
console/trunk/app/src/main/java/org/jboss/as/console/client/core/BootstrapContext.java 2012-03-26
21:53:57 UTC (rev 1540)
@@ -0,0 +1,200 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.jboss.as.console.client.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.jboss.as.console.client.shared.Preferences;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Window;
+import com.gwtplatform.mvp.client.proxy.PlaceRequest;
+
+/**
+ * @author <a href="mailto:psilva@redhat.com">Pedro Silva</a>
+ * @since Mar 22, 2012
+ */
+public class BootstrapContext implements ApplicationProperties {
+
+ private Map<String,String> ctx = new HashMap<String,String>();
+
+ private static final String[] persistentProperties = new String[] {
+ //STANDALONE
+ };
+ private String initialPlace = null;
+
+ @Inject
+ public BootstrapContext() {
+ /*String token = History.getToken();
+ if(token!=null && !token.equals("") &&
!token.equals(NameTokens.signInPage))
+ setProperty(INITIAL_TOKEN, token);
+ */
+ loadPersistedProperties();
+
+// String domainApi = !GWT.isScript() ? getBaseUrl()+"management" :
"http://127.0.0.1:8080/picketlink-console-application-1.0.0-SNAPSHOT/app/proxy";
+// setProperty(DOMAIN_API, domainApi);
+//
+//
+// String deploymentApi = !GWT.isScript() ?
getBaseUrl()+"management/add-content" :
"http://127.0.0.1:8080/picketlink-console-application-1.0.0-SNAPSHOT/app/upload";
+// setProperty(DEPLOYMENT_API, deploymentApi);
+//
+// String logoutApi = !GWT.isScript() ? getBaseUrl()+"logout" :
"http://127.0.0.1:8080/picketlink-console-application-1.0.0-SNAPSHOT/app/logout";
+// setProperty(LOGOUT_API, logoutApi);
+
+ String domainApi = GWT.isScript() ? getBaseUrl()+"management" :
"http://127.0.0.1:8888/app/proxy";
+ setProperty(DOMAIN_API, domainApi);
+
+
+ String deploymentApi = GWT.isScript() ?
getBaseUrl()+"management/add-content" :
"http://127.0.0.1:8888/app/upload";
+ setProperty(DEPLOYMENT_API, deploymentApi);
+
+ String logoutApi = GWT.isScript() ? getBaseUrl()+"logout" :
"http://127.0.0.1:8888/app/logout";
+ setProperty(LOGOUT_API, logoutApi);
+
+ //Log.info("Domain API Endpoint: " + domainApi);
+ }
+
+ private String getBaseUrl() {
+ // extract host
+// String base = GWT.getHostPageBaseURL();
+// return extractHttpEndpointUrl(base);
+ return "http://localhost:9990/";
+ }
+
+ public static String extractHttpEndpointUrl(String base) {
+ String protocol = base.substring(0, base.indexOf("//")+2);
+ String remainder = base.substring(base.indexOf(protocol)+protocol.length(),
base.length());
+
+ String host = null;
+ String port = null;
+
+ int portDelim = remainder.indexOf(":");
+ if(portDelim !=-1 )
+ {
+ host = remainder.substring(0, portDelim);
+ String portRemainder = remainder.substring(portDelim+1, remainder.length());
+ if(portRemainder.indexOf("/")!=-1)
+ {
+ port = portRemainder.substring(0, portRemainder.indexOf("/"));
+ }
+ else
+ {
+ port = portRemainder;
+ }
+ }
+ else
+ {
+ host = remainder.substring(0, remainder.indexOf("/"));
+ port = "80";
+ }
+
+ // default url
+ return protocol + host + ":" + port + "/";
+ }
+
+ private void loadPersistedProperties() {
+ for(String key : persistentProperties)
+ {
+ String pref = Preferences.get(key);
+ if(pref!=null)
+ setProperty(key, pref);
+ }
+ }
+
+ @Override
+ public void setProperty(String key, String value)
+ {
+ if(isPersistent(key))
+ Preferences.set(key, value);
+
+ ctx.put(key, value);
+ }
+
+ @Override
+ public String getProperty(String key)
+ {
+ return ctx.get(key);
+ }
+
+ @Override
+ public boolean hasProperty(String key)
+ {
+ return getProperty(key)!=null;
+ }
+
+ public PlaceRequest getDefaultPlace() {
+
+ PlaceRequest defaultPlace = getProperty(STANDALONE).equals("true") ?
+ new PlaceRequest(NameTokens.StandaloneServerPresenter) : new
PlaceRequest(NameTokens.DomainRuntimePresenter);
+ return defaultPlace;
+ }
+
+ @Override
+ public void removeProperty(String key) {
+
+ if(isPersistent(key))
+ Preferences.clear(key);
+
+ ctx.remove(key);
+ }
+
+ boolean isPersistent(String key)
+ {
+ boolean b = false;
+ for(String s : persistentProperties)
+ {
+ if(s.equals(key))
+ {
+ b=true;
+ break;
+ }
+ }
+
+ return b;
+
+ }
+
+ @Override
+ public boolean isStandalone() {
+ return getProperty(BootstrapContext.STANDALONE).equals("true");
+ }
+
+ public void setInitialPlace(String nameToken) {
+ this.initialPlace = nameToken;
+ }
+
+ public String getInitialPlace() {
+ return initialPlace;
+ }
+
+ public String getLogoutUrl() {
+ String url = getProperty(LOGOUT_API);
+
+ if(!GWT.isScript())
+ url += "?gwt.codesvr=" +
Window.Location.getParameter("gwt.codesvr");
+ return url;
+ }
+}
Added: console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/HttpClient.java
===================================================================
--- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/HttpClient.java
(rev 0)
+++
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/HttpClient.java 2012-03-26
21:53:57 UTC (rev 1540)
@@ -0,0 +1,361 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.jboss.as.console.server.proxy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Security;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * @author Yutaka Yoshida, Greg Murray, Heiko Braun
+ *
+ * Minimum set of HTTPclient supporting both http and https.
+ * It's aslo capable of POST, but it doesn't provide doGet because
+ * the caller can just read the inputstream.
+ */
+public class HttpClient {
+
+ private static Logger logger;
+ private String proxyHost = null;
+ private int proxyPort = -1;
+ private boolean isHttps = false;
+ private boolean isProxy = false;
+ private HttpURLConnection urlConnection = null;
+ private Map headers;
+
+ private String setCookieHeader;
+
+ private XmlHttpProxy.CookieCallback callback;
+
+ /**
+ * @param phost PROXY host name
+ * @param pport PROXY port string
+ * @param url URL string
+ * @param headers Map
+ */
+ public HttpClient(
+ String phost,
+ int pport,
+ String url,
+ Map headers,
+ String method,
+ XmlHttpProxy.CookieCallback callback)
+ throws MalformedURLException
+ {
+ this.callback = callback;
+
+ if (phost != null && pport != -1)
+ {
+ this.isProxy = true;
+ }
+
+ this.proxyHost = phost;
+ this.proxyPort = pport;
+
+ if (url.trim().startsWith("https:")) {
+ isHttps = true;
+ }
+
+ this.urlConnection = getURLConnection(url);
+ try {
+ this.urlConnection.setRequestMethod(method);
+ } catch (java.net.ProtocolException pe) {
+ HttpClient.getLogger().severe("Unable protocol method to " + method
+ " : " + pe);
+ }
+ this.headers = headers;
+ writeHeaders(headers);
+
+ }
+
+ private void writeHeaders(Map headers)
+ {
+ if(this.callback!=null)
+ {
+ Map<String, XmlHttpProxy.Cookie> cookies = callback.getCookies();
+ Iterator it = cookies.keySet().iterator();
+ while(it.hasNext())
+ {
+ XmlHttpProxy.Cookie c = cookies.get(it.next());
+ if(headers==null) headers = new HashMap();
+ headers.put(
+ "Cookie", c.name + "=" + c.value // + ";
Path=" + c.path
+ );
+ }
+
+ }
+ // set headers
+ if (headers != null) {
+ Iterator it = headers.keySet().iterator();
+ if (it != null) {
+ while (it.hasNext()) {
+ String key = (String)it.next();
+ String value = (String)headers.get(key);
+ //System.out.println("Set Request Header: "+key +
"->"+value);
+ this.urlConnection.setRequestProperty (key, value);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param phost PROXY host name
+ * @param pport PROXY port string
+ * @param url URL string
+ * @param headers Map
+ * @param userName string
+ * @param password string
+ */
+ public HttpClient(String phost,
+ int pport,
+ String url,
+ Map headers,
+ String method,
+ String userName,
+ String password,
+ XmlHttpProxy.CookieCallback callback)
+ throws MalformedURLException {
+
+ this.callback = callback;
+
+ try
+ {
+ if (phost != null && pport != -1) {
+ this.isProxy = true;
+ }
+
+ this.proxyHost = phost;
+ this.proxyPort = pport;
+ if (url.trim().startsWith("https:")) {
+ isHttps = true;
+ }
+ this.urlConnection = getURLConnection(url);
+ try {
+ this.urlConnection.setRequestMethod(method);
+ } catch (java.net.ProtocolException pe) {
+ HttpClient.getLogger().severe("Unable protocol method to " +
method + " : " + pe);
+ }
+ // set basic authentication information
+ String auth = userName + ":" + password;
+ String encoded = new sun.misc.BASE64Encoder().encode (auth.getBytes());
+ // set basic authorization
+ this.urlConnection.setRequestProperty ("Authorization", "Basic
" + encoded);
+ this.headers = headers;
+ writeHeaders(headers);
+ } catch (Exception ex) {
+ HttpClient.getLogger().severe("Unable to set basic authorization for
" + userName + " : " +ex);
+ }
+ }
+
+ /**
+ * private method to get the URLConnection
+ * @param str URL string
+ */
+ private HttpURLConnection getURLConnection(String str)
+ throws MalformedURLException {
+ try {
+
+ if (isHttps) {
+ /* when communicating with the server which has unsigned or invalid
+ * certificate (https), SSLException or IOException is thrown.
+ * the following line is a hack to avoid that
+ */
+ Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+ System.setProperty("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
+ if (isProxy) {
+ System.setProperty("https.proxyHost", proxyHost);
+ System.setProperty("https.proxyPort", proxyPort +
"");
+ }
+ }
+ else
+ {
+ if (isProxy)
+ {
+ System.setProperty("http.proxyHost", proxyHost);
+ System.setProperty("http.proxyPort", proxyPort +
"");
+ }
+ }
+
+ URL url = new URL(str);
+ HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+
+ // if this header has not been set by a request set the user agent.
+ if (headers == null ||
+ (headers != null && headers.get("user-agent") ==
null)) {
+ // set user agent to mimic a common browser
+ String ua="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET
CLR 1.1.4322)";
+ uc.setRequestProperty("user-agent", ua);
+ }
+
+ uc.setInstanceFollowRedirects(false);
+
+ return uc;
+ }
+ catch (MalformedURLException me)
+ {
+ throw new MalformedURLException(str + " is not a valid URL");
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Unknown error creating UrlConnection: "
+ e);
+ }
+ }
+
+ public String getSetCookieHeader()
+ {
+ return setCookieHeader;
+ }
+
+ public int getResponseCode() {
+ try {
+ return this.urlConnection.getResponseCode();
+ } catch (IOException e) {
+ throw new RuntimeException("No response code", e);
+ }
+ }
+ /**
+ * returns the inputstream from URLConnection
+ * @return InputStream
+ */
+ public InputStream getInputStream() {
+ try
+ {
+ int responseCode = this.urlConnection.getResponseCode();
+
+ try
+ {
+ // HACK: manually follow redirects, for the login to work
+ // HTTPUrlConnection auto redirect doesn't respect the provided
headers
+ if(responseCode ==302)
+ {
+ HttpClient redirectClient =
+ new HttpClient(proxyHost,proxyPort,
urlConnection.getHeaderField("Location"),
+ headers, urlConnection.getRequestMethod(),
callback);
+ redirectClient.getInputStream().close();
+ }
+ }
+ catch (Throwable e)
+ {
+ System.out.println("Following redirect failed");
+ }
+
+ setCookieHeader = this.urlConnection.getHeaderField("Set-Cookie");
+
+
+ InputStream in = responseCode != HttpURLConnection.HTTP_OK ?
+ this.urlConnection.getErrorStream() :
this.urlConnection.getInputStream();
+
+ return in;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * return the OutputStream from URLConnection
+ * @return OutputStream
+ */
+ public OutputStream getOutputStream() {
+
+ try {
+ return (this.urlConnection.getOutputStream());
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * posts data to the inputstream and returns the InputStream.
+ *
+ * @param postData data to be posted. must be url-encoded already.
+ * @param contentType allows you to set the contentType of the request.
+ * @param authHeader
+ * @return InputStream input stream from URLConnection
+ */
+ public InputStream doPost(byte[] postData, String contentType, String authHeader) {
+ this.urlConnection.setDoOutput(true);
+ if (contentType != null) this.urlConnection.setRequestProperty(
"Content-type", contentType );
+ if (authHeader!= null) this.urlConnection.setRequestProperty(
"Authorization", authHeader);
+
+ OutputStream out = null;
+ try {
+ out = this.getOutputStream();
+ if(out!=null)
+ {
+ out.write(postData);
+ out.flush();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }finally {
+ if(out!=null)
+ try {
+ out.close();
+ } catch (IOException e) {
+ //
+ }
+ }
+
+
+ return (this.getInputStream());
+ }
+
+ public String getContentEncoding() {
+ if (this.urlConnection == null) return null;
+ return (this.urlConnection.getContentEncoding());
+ }
+ public int getContentLength() {
+ if (this.urlConnection == null) return -1;
+ return (this.urlConnection.getContentLength());
+ }
+ public String getContentType() {
+ if (this.urlConnection == null) return null;
+ return (this.urlConnection.getContentType());
+ }
+ public long getDate() {
+ if (this.urlConnection == null) return -1;
+ return (this.urlConnection.getDate());
+ }
+ public String getHeader(String name) {
+ if (this.urlConnection == null) return null;
+ return (this.urlConnection.getHeaderField(name));
+ }
+ public long getIfModifiedSince() {
+ if (this.urlConnection == null) return -1;
+ return (this.urlConnection.getIfModifiedSince());
+ }
+
+ public static Logger getLogger() {
+ if (logger == null) {
+ logger = Logger.getLogger("jmaki.xhp.Log");
+ }
+ return logger;
+ }
+
+
+}
\ No newline at end of file
Added: console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/ProxyConfig.java
===================================================================
--- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/ProxyConfig.java
(rev 0)
+++
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/ProxyConfig.java 2012-03-26
21:53:57 UTC (rev 1540)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.jboss.as.console.server.proxy;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author: Heiko Braun <hbraun(a)redhat.com>
+ * @date: Apr 21, 2010
+ */
+public class ProxyConfig
+{
+ private Map<String,Object> rootConfig;
+
+ public final static String SERVICES = "services";
+ public final static String ID = "id";
+ public final static String URL = "url";
+ public final static String CONTENT_TYPE = "contentType";
+ public final static String PASSTHROUGH = "passthrough";
+
+ protected ProxyConfig(Map<String,Object> rootConfig)
+ {
+ this.rootConfig = rootConfig;
+ }
+
+ private static ProxyConfig parse(String json)
+ {
+ /*JSONDecoder decoder = new JSONDecoder(json);
+ ProxyConfig config = new ProxyConfig((Map<String,Object>)decoder.parse());
+ return config; */
+
+ throw new RuntimeException("Not implemented");
+ }
+
+ public static ProxyConfig parse(InputStream in)
+ {
+ return parse(inputStreamToString(in));
+ }
+
+ public List<Map<String,Object>> getServices()
+ {
+ Map<String,Object> root =
(Map<String,Object>)rootConfig.get("xhp");
+ return (List)root.get(SERVICES);
+ }
+
+ private static String inputStreamToString(InputStream in)
+ {
+ try
+ {
+ BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(in));
+ StringBuilder stringBuilder = new StringBuilder();
+ String line = null;
+
+ while ((line = bufferedReader.readLine()) != null) {
+ stringBuilder.append(line + "\n");
+ }
+
+ bufferedReader.close();
+ return stringBuilder.toString();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Failed to parse input stream", e);
+ }
+ }
+}
Added:
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/RedirectException.java
===================================================================
---
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/RedirectException.java
(rev 0)
+++
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/RedirectException.java 2012-03-26
21:53:57 UTC (rev 1540)
@@ -0,0 +1,20 @@
+package org.jboss.as.console.server.proxy;
+
+import java.io.IOException;
+
+/**
+ * @author Heiko Braun
+ * @date 12/14/11
+ */
+public class RedirectException extends IOException {
+
+ String location;
+
+ public RedirectException(String location) {
+ this.location = location;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+}
Added:
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxy.java
===================================================================
--- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxy.java
(rev 0)
+++
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxy.java 2012-03-26
21:53:57 UTC (rev 1540)
@@ -0,0 +1,495 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.jboss.as.console.server.proxy;
+
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * @author Greg Murray
+ * @author Heiko Braun
+ */
+public class XmlHttpProxy {
+
+ public static String GET = "GET";
+ public static String POST = "POST";
+ public static String DELETE = "DELETE";
+ public static String PUT = "PUT";
+
+ private String userName = null;
+ private String password = null;
+ private static Logger logger;
+ private String proxyHost = "";
+ int proxyPort = -1;
+ private Object config;
+ private static String USAGE = "Usage: -url service_URL -id service_key [-url
or -id required] -xslurl xsl_url [optional] -format json|xml [optional]
-callback[optional] -config [optional] -resources base_directory_containing XSL
stylesheets [optional]";
+ private String authHeader;
+
+ public XmlHttpProxy() {}
+
+ private String contentType = "application/json";
+
+ private Map<String, Cookie> cookies = new HashMap<String, Cookie>();
+
+ int status = -1;
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public interface CookieCallback
+ {
+ Map<String, Cookie> getCookies();
+ }
+
+ public XmlHttpProxy(String proxyHost, int proxyPort) {
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ }
+
+ public XmlHttpProxy(String proxyHost, int proxyPort,
+ String userName, String password) {
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ this.userName = userName;
+ this.password = password;
+ }
+
+ /**
+ * This method will go out and make the call and it will apply an XSLT Transformation
with the
+ * set of parameters provided.
+ *
+ * @param urlString - The URL which you are looking up
+ * @param out - The OutputStream to which the resulting document is written
+ * @param xslInputStream - An input Stream to an XSL style sheet that is provided to
the XSLT processor. If set to null there will be no transformation
+ * @param paramsMap - A Map of parameters that are feed to the XSLT Processor. These
params may be used when generating content. This may be set to null if no parameters are
necessary.
+ * @param method - The HTTP method used.
+ *
+ */
+ public void processRequest(String urlString,
+ OutputStream out,
+ InputStream xslInputStream,
+ Map paramsMap,
+ Map headers,
+ String method,
+ String userName,
+ String password) throws IOException, MalformedURLException
{
+ doProcess(urlString, out, xslInputStream, paramsMap, headers,method, null,null,
userName,password);
+ }
+ /**
+ * This method will go out and make the call and it will apply an XSLT Transformation
with the
+ * set of parameters provided.
+ *
+ * @param urlString - The URL which you are looking up
+ * @param out - The OutputStream to which the resulting document is written
+ * @param authHeader
+ *
+ */
+ public void doPost(String urlString,
+ OutputStream out,
+ InputStream xslInputStream,
+ Map paramsMap,
+ Map headers,
+ byte[] postData,
+ String postContentType,
+ String userName,
+ String password, String authHeader) throws IOException,
MalformedURLException {
+ this.authHeader = authHeader;
+ doProcess(urlString, out, xslInputStream, paramsMap, headers, XmlHttpProxy.POST,
postData, postContentType, userName, password);
+ }
+
+ /**
+ * This method will go out and make the call and it will apply an XSLT Transformation
with the
+ * set of parameters provided.
+ *
+ * @param urlString - The URL which you are looking up
+ * @param out - The OutputStream to which the resulting document is written
+ * @param xslInputStream - An input Stream to an XSL style sheet that is provided to
the XSLT processor. If set to null there will be no transformation
+ * @param paramsMap - A Map of parameters that are feed to the XSLT Processor. These
params may be used when generating content. This may be set to null if no parameters are
necessary.
+ * @param method - the HTTP method used.
+ * @param postData - A String of the bodyContent to be posted. A doPost will be used
if this is parameter is not null.
+ * @param postContentType - The request contentType used when posting data. Will not
be set if this parameter is null.
+ * @param userName - userName used for basic authorization
+ * @param password - password used for basic authorization
+ */
+ public void doProcess(String urlString,
+ OutputStream out,
+ InputStream xslInputStream,
+ Map paramsMap,
+ Map headers,
+ String method,
+ byte[] postData,
+ String postContentType,
+ String userName,
+ String password) throws IOException, MalformedURLException {
+
+ if (paramsMap == null) {
+ paramsMap = new HashMap();
+ }
+
+ String format = (String)paramsMap.get("format");
+ if (format == null) {
+ format = "xml";
+ }
+
+ InputStream in = null;
+ BufferedOutputStream os = null;
+
+ HttpClient httpclient = null;
+
+ CookieCallback callback = new CookieCallback()
+ {
+
+ public Map<String, Cookie> getCookies()
+ {
+ return accessCookies();
+ }
+ };
+
+ if (userName != null && password != null)
+ {
+ httpclient = new HttpClient(proxyHost, proxyPort, urlString, headers, method,
userName, password, callback);
+ }
+ else
+ {
+ httpclient = new HttpClient(proxyHost, proxyPort, urlString, headers, method,
callback);
+ }
+
+ // post data determines whether we are going to do a get or a post
+ if (postData == null) {
+ in = httpclient.getInputStream();
+ } else {
+ in = httpclient.doPost(postData, postContentType, authHeader);
+ }
+
+ // Set-Cookie header
+ if(httpclient.getSetCookieHeader()!=null)
+ {
+ String cookie = httpclient.getSetCookieHeader();
+ System.out.println("'Set-Cookie' header: "+ cookie);
+ String[] values = cookie.split(";");
+
+ Cookie c = new Cookie();
+ for(String v : values)
+ {
+ String[] tuple = v.split("=");
+ if("Path".equals( tuple[0].trim()))
+ c.path = tuple[1];
+ else
+ {
+ c.name = tuple[0].trim();
+ c.value = tuple[1];
+ }
+ }
+
+
+ List<String> toBeRemoved = new ArrayList<String>();
+ Iterator it = cookies.keySet().iterator();
+ while(it.hasNext())
+ {
+ Cookie exists = cookies.get(it.next());
+ if(exists.name.equals(c.name))
+ {
+ String msg = exists.value.equals(c.value) ?
+ "Replace with same value: "+exists.value :
+ "Replace with different value: "+exists.value
+"->"+c.value;
+
+ System.out.println("Cookie '"+exists.name+"'
exists: " + msg);
+ // avoid doubles
+ toBeRemoved.add(exists.name);
+ }
+ }
+
+ // clean up
+ for(String s : toBeRemoved)
+ {
+ cookies.remove(s);
+ }
+
+ cookies.put(c.name, c);
+ }
+
+ if(null==in)
+ {
+ int responseCode = httpclient.getResponseCode();
+ if(401== responseCode || 403==responseCode)
+ {
+ // authentication required
+ throw new AuthenticationException(responseCode,
httpclient.getHeader("WWW-Authenticate"));
+ }
+ else if(307==responseCode)
+ {
+ // redirect
+ throw new RedirectException(httpclient.getHeader("Location"));
+ }
+ else
+ {
+ throw new IOException("Failed to open input stream, status:
"+responseCode);
+ }
+ }
+
+ // read the encoding from the incoming document and default to UTF-8
+ // if an encoding is not provided
+ String ce = httpclient.getContentEncoding();
+ if (ce == null) {
+ String ct = httpclient.getContentType();
+ if (ct != null) {
+ int idx = ct.lastIndexOf("charset=");
+ if (idx >= 0) {
+ ce = ct.substring(idx+8);
+ } else {
+ ce = "UTF-8";
+ }
+ } else {
+ ce = "UTF-8";
+ }
+ }
+ // get the content type
+ this.contentType = httpclient.getContentType();
+ this.status = httpclient.getResponseCode();
+
+ // write out the content type
+ //http://www.ietf.org/rfc/rfc4627.txt
+
+ try {
+
+ // response stream
+
+ byte[] buffer = new byte[1024];
+ int read = 0;
+ if (xslInputStream == null) {
+ while (true) {
+ read = in.read(buffer);
+ if (read <= 0) break;
+ out.write(buffer, 0, read );
+ }
+ } else {
+ transform(in, xslInputStream, paramsMap, out, ce);
+ }
+ } catch (Exception e) {
+ getLogger().severe("XmlHttpProxy transformation error: " + e);
+ } finally {
+ try {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.flush();
+ out.close();
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
+
+ private Map<String,Cookie> accessCookies()
+ {
+ return cookies;
+ }
+
+ /**
+ * Do the XSLT transformation
+ */
+ public void transform( InputStream xmlIS,
+ InputStream xslIS,
+ Map params,
+ OutputStream result,
+ String encoding) {
+ try {
+ TransformerFactory trFac = TransformerFactory.newInstance();
+ Transformer transformer = trFac.newTransformer(new StreamSource(xslIS));
+ Iterator it = params.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String)it.next();
+ transformer.setParameter(key, (String)params.get(key));
+ }
+ transformer.setOutputProperty("encoding", encoding);
+ transformer.transform(new StreamSource(xmlIS), new StreamResult(result));
+ } catch (Exception e) {
+ getLogger().severe("XmlHttpProxy: Exception with xslt " + e);
+ }
+ }
+
+ /**
+ *
+ * CLI to the XmlHttpProxy
+ */
+ /* public static void main(String[] args)
+ throws IOException, MalformedURLException {
+
+ getLogger().info("XmlHttpProxy 1.8");
+ XmlHttpProxy xhp = new XmlHttpProxy();
+
+ if (args.length == 0) {
+ System.out.println(USAGE);
+ }
+
+ String method = XmlHttpProxy.GET;
+ InputStream xslInputStream = null;
+ String serviceKey = null;
+ String urlString = null;
+ String xslURLString = null;
+ String format = "xml";
+ String callback = null;
+ String urlParams = null;
+ String configURLString = "xhp.json";
+ String resourceBase = "file:src/conf/META-INF/resources/xsl/";
+ String username = null;
+ String password = null;
+
+ // read in the arguments
+ int index = 0;
+ while (index < args.length) {
+ if (args[index].toLowerCase().equals("-url") && index + 1 <
args.length) {
+ urlString = args[++index];
+ } else if (args[index].toLowerCase().equals("-key") && index + 1
< args.length) {
+ serviceKey = args[++index];
+ } else if (args[index].toLowerCase().equals("-id") && index + 1
< args.length) {
+ serviceKey = args[++index];
+ } else if (args[index].toLowerCase().equals("-callback") &&
index + 1 < args.length) {
+ callback = args[++index];
+ } else if (args[index].toLowerCase().equals("-xslurl") && index
+ 1 < args.length) {
+ xslURLString = args[++index];
+ } else if (args[index].toLowerCase().equals("-method") && index
+ 1 < args.length) {
+ method = args[++index];
+ } else if (args[index].toLowerCase().equals("-username") &&
index + 1 < args.length) {
+ username = args[++index];
+ } else if (args[index].toLowerCase().equals("-password") &&
index + 1 < args.length) {
+ password = args[++index];
+ } else if (args[index].toLowerCase().equals("-urlparams") &&
index + 1 < args.length) {
+ urlParams = args[++index];
+ } else if (args[index].toLowerCase().equals("-config") && index
+ 1 < args.length) {
+ configURLString = args[++index];
+ } else if (args[index].toLowerCase().equals("-resources") &&
index + 1 < args.length) {
+ resourceBase = args[++index];
+ }
+ index++;
+ }
+
+ if (serviceKey != null) {
+ try {
+ InputStream is = (new URL(configURLString)).openStream();
+ JSONObject services = loadServices(is);
+ JSONObject service = services.getJSONObject(serviceKey);
+ // default to the service default if no url parameters are specified
+ if (urlParams == null && service.has("defaultURLParams")) {
+ urlParams = service.getString("defaultURLParams");
+ }
+ String serviceURL = service.getString("url");
+ // build the URL properly
+ if (urlParams != null && serviceURL.indexOf("?") == -1){
+ serviceURL += "?";
+ } else if (urlParams != null){
+ serviceURL += "&";
+ }
+ String apiKey = "";
+ if (service.has("apikey")) apiKey =
service.getString("apikey");
+ urlString = serviceURL + apiKey + "&" + urlParams;
+ if (service.has("xslStyleSheet")) {
+ xslURLString = service.getString("xslStyleSheet");
+ // check if the url is correct of if to load from the classpath
+
+ }
+ } catch (Exception ex) {
+ getLogger().severe("XmlHttpProxy Error loading service: " + ex);
+ System.exit(1);
+ }
+ } else if (urlString == null) {
+ System.out.println(USAGE);
+ System.exit(1);
+ }
+ // The parameters are feed to the XSL Stylsheet during transformation.
+ // These parameters can provided data or conditional information.
+ Map paramsMap = new HashMap();
+ if (format != null) {
+ paramsMap.put("format", format);
+ }
+ if (callback != null) {
+ paramsMap.put("callback", callback);
+ }
+
+ if (xslURLString != null) {
+ URL xslURL = new URL(xslURLString);
+ if (xslURL != null) {
+ xslInputStream = xslURL.openStream();
+ } else {
+ getLogger().severe("Error: Unable to locate XSL at URL " +
xslURLString);
+ }
+ }
+ xhp.processRequest(urlString, System.out, xslInputStream, paramsMap, null, method,
username, password);
+ } */
+
+ public static Logger getLogger() {
+ if (logger == null) {
+ logger = Logger.getLogger(XmlHttpProxy.class.getName());
+ }
+ return logger;
+ }
+
+ public static ProxyConfig loadServices(InputStream is)
+ {
+ return ProxyConfig.parse(is);
+ }
+
+ public class Cookie
+ {
+ String name;
+ String value;
+ String path;
+ }
+
+
+ public class AuthenticationException extends IOException {
+ int code;
+ String authHeader;
+
+ public AuthenticationException(int code, String authHeader) {
+ this.code = code;
+ this.authHeader = authHeader;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getAuthHeader() {
+ return authHeader;
+ }
+ }
+}
\ No newline at end of file
Added:
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxyServlet.java
===================================================================
---
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxyServlet.java
(rev 0)
+++
console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHttpProxyServlet.java 2012-03-26
21:53:57 UTC (rev 1540)
@@ -0,0 +1,631 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+package org.jboss.as.console.server.proxy;
+
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.PropertyResourceBundle;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Used to access services in hosted mode that
+ * deployed to an external container. I.e. JBoss AS.<p/>
+ *
+ * Usage (web.xml):<br>
+ *
+ * <pre>
+ * <servlet>
+ * <servlet-name>gwtProxy</servlet-name>
+ * <description>GWT Proxy</description>
+ *
<servlet-class>org.jboss.as.console.server.proxy.XmlHttpProxyServlet</servlet-class>
+ * <init-param>
+ * <param-name>config.name</param-name>
+ * <param-value>gwt-proxy.json</param-value>
+ * </init-param>
+ * <load-on-startup>1</load-on-startup>
+ * </servlet>
+ *
+ * <servlet-mapping>
+ * <servlet-name>gwtProxy</servlet-name>
+ * <url-pattern>/app/proxy/*</url-pattern>
+ * </servlet-mapping>
+ *
+ * </pre>
+ *
+ * <p/>
+ *
+ * gwt-proxy.properties:<br>
+ * <pre>
+ * service.id=domain-api
+ * service.url=http://127.0.0.1:9990/domain-api
+ * service.passThrough=true
+ * </pre>
+ *
+ * @author Greg Murray
+ * @author Heiko Braun
+ */
+public class XmlHttpProxyServlet extends HttpServlet
+{
+
+ public static String REMOTE_USER = "REMOTE_USER";
+
+ private static String XHP_LAST_MODIFIED = "xhp_last_modified_key";
+ private static String DEFAULT_CONFIG = "gwt-proxy.properties";
+
+ private static boolean allowXDomain = false;
+ private static boolean requireSession = false;
+ private static boolean createSession = false;
+ private static String defaultContentType =
"application/dmr-encoded;charset=UTF-8";
+ private static boolean rDebug = false;
+ private Logger logger = null;
+ private XmlHttpProxy xhp = null;
+ private ServletContext ctx;
+ private List<Map<String,Object>> services = null;
+ private String resourcesDir = "/resources/";
+ private String classpathResourcesDir = "/META-INF/resources/";
+ private String headerToken = "jmaki-";
+ private String testToken = "xtest-";
+
+ private static String testUser;
+ private static String testPass;
+
+ private static String setCookie;
+ private String configResource = null;
+ private String authHeader;
+
+ public XmlHttpProxyServlet() {
+ if (rDebug) {
+ logger = getLogger();
+ }
+
+ }
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ ctx = config.getServletContext();
+ // set the response content type
+ if (ctx.getInitParameter("responseContentType") != null) {
+ defaultContentType = ctx.getInitParameter("responseContentType");
+ }
+ // allow for resources dir over-ride at the xhp level otherwise allow
+ // for the jmaki level resources
+ if (ctx.getInitParameter("jmaki-xhp-resources") != null) {
+ resourcesDir = ctx.getInitParameter("jmaki-xhp-resources");
+ } else if (ctx.getInitParameter("jmaki-resources") != null) {
+ resourcesDir = ctx.getInitParameter("jmaki-resources");
+ }
+ // allow for resources dir over-ride
+ if (ctx.getInitParameter("jmaki-classpath-resources") != null) {
+ classpathResourcesDir =
ctx.getInitParameter("jmaki-classpath-resources");
+ }
+ String requireSessionString = ctx.getInitParameter("requireSession");
+ if (requireSessionString == null) requireSessionString =
ctx.getInitParameter("jmaki-requireSession");
+ if (requireSessionString != null) {
+ if ("false".equals(requireSessionString)) {
+ requireSession = false;
+ getLogger().severe("XmlHttpProxyServlet: intialization. Session
requirement disabled.");
+ } else if ("true".equals(requireSessionString)) {
+ requireSession = true;
+ getLogger().severe("XmlHttpProxyServlet: intialization. Session
requirement enabled.");
+ }
+ }
+ String xdomainString = ctx.getInitParameter("allowXDomain");
+ if (xdomainString == null) xdomainString =
ctx.getInitParameter("jmaki-allowXDomain");
+ if (xdomainString != null) {
+ if ("true".equals(xdomainString)) {
+ allowXDomain = true;
+ getLogger().severe("XmlHttpProxyServlet: intialization. xDomain
access is enabled.");
+ } else if ("false".equals(xdomainString)) {
+ allowXDomain = false;
+ getLogger().severe("XmlHttpProxyServlet: intialization. xDomain
access is disabled.");
+ }
+ }
+ String createSessionString =
ctx.getInitParameter("jmaki-createSession");
+ if (createSessionString != null) {
+ if ("true".equals(createSessionString)) {
+ createSession = true;
+ getLogger().severe("XmlHttpProxyServlet: intialization. create
session is enabled.");
+ } else if ("false".equals(xdomainString)) {
+ createSession = false;
+ getLogger().severe("XmlHttpProxyServlet: intialization. create
session is disabled.");
+ }
+ }
+ // if there is a proxyHost and proxyPort specified create an HttpClient with the
proxy
+ String proxyHost = ctx.getInitParameter("proxyHost");
+ String proxyPortString = ctx.getInitParameter("proxyPort");
+ if (proxyHost != null && proxyPortString != null) {
+ int proxyPort = 8080;
+ try {
+ proxyPort= new Integer(proxyPortString).intValue();
+ xhp = new XmlHttpProxy(proxyHost, proxyPort);
+ } catch (NumberFormatException nfe) {
+ getLogger().severe("XmlHttpProxyServlet: intialization error. The
proxyPort must be a number");
+ throw new ServletException("XmlHttpProxyServlet: intialization
error. The proxyPort must be a number");
+ }
+ } else {
+ xhp = new XmlHttpProxy();
+ }
+
+ // config override
+ String servletName = config.getServletName();
+ String configName = config.getInitParameter("config.name");
+ configResource = configName!=null ? configName : DEFAULT_CONFIG;
+ //System.out.println("Configure "+servletName + " through
"+configResource);
+ }
+
+ private void getServices(HttpServletResponse res)
+ {
+ services = new ArrayList<Map<String,Object>>();
+
+ InputStream is = XmlHttpProxyServlet.class.getClassLoader()
+ .getResourceAsStream(configResource);
+
+ if(null==is)
+ throw new IllegalStateException("Failed to load proxy configuration:
"+configResource);
+
+ try {
+ PropertyResourceBundle bundle = new PropertyResourceBundle(is);
+ HashMap<String, Object> serviceConfig = new HashMap<String,
Object>();
+ serviceConfig.put(ProxyConfig.ID, "default");
+ serviceConfig.put(ProxyConfig.URL,
bundle.getString("service.url"));
+ serviceConfig.put(ProxyConfig.PASSTHROUGH,
Boolean.valueOf(bundle.getString("service.passthrough")));
+ services.add(serviceConfig);
+
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to load proxy configuration");
+
+ }
+
+ }
+
+ public void doDelete(HttpServletRequest req, HttpServletResponse res) {
+ doProcess(req,res, XmlHttpProxy.DELETE);
+ }
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res) {
+ doProcess(req,res, XmlHttpProxy.GET);
+ }
+
+ public void doPost(HttpServletRequest req, HttpServletResponse res) {
+ doProcess(req,res, XmlHttpProxy.POST);
+ }
+
+ /* (non-Javadoc)
+ * @see
javax.servlet.http.HttpServlet#doOptions(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ protected void doOptions(HttpServletRequest arg0, HttpServletResponse arg1) throws
ServletException, IOException {
+ doProcess(arg0,arg1, XmlHttpProxy.POST);
+ }
+
+ public void doPut(HttpServletRequest req, HttpServletResponse res) {
+ doProcess(req,res, XmlHttpProxy.PUT);
+ }
+
+ public void doProcess(HttpServletRequest req, HttpServletResponse res, String
method)
+ {
+
+ boolean isPost = XmlHttpProxy.POST.equals(method);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] bodyContent = null;
+
+ OutputStream out = null;
+ PrintWriter writer = null;
+
+ try {
+
+ BufferedInputStream in = new BufferedInputStream(req.getInputStream());
+ int next = in.read();
+ while (next > -1) {
+ bos.write(next);
+ next = in.read();
+ }
+
+ bodyContent = bos.toByteArray();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try
+ {
+ HttpSession session = null;
+ // it really does not make sense to use create session with require session
as
+ // the create session will always result in a session created and the
requireSession
+ // will always succeed. Leaving the logic for now.
+ if (createSession) {
+ session = req.getSession(true);
+ }
+ if (requireSession) {
+ // check to see if there was a session created for this request
+ // if not assume it was from another domain and blow up
+ // Wrap this to prevent Portlet exeptions
+ session = req.getSession(false);
+ if (session == null) {
+ res.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ }
+ // check if the services have been loaded or if they need to be reloaded
+ if (services == null || configUpdated()) {
+ getServices(res);
+ }
+ String urlString = null;
+ String xslURLString = null;
+ String userName = null;
+ String password = null;
+ String format = "json";
+ String callback = req.getParameter("callback");
+ String urlParams = req.getParameter("urlparams");
+ String countString = req.getParameter("count");
+ boolean passthrough = false;
+ // encode the url to prevent spaces from being passed along
+ if (urlParams != null) {
+ urlParams = urlParams.replace(' ', '+');
+ }
+ // get the headers to pass through
+ Map headers = null;
+ authHeader = null;
+
+ // Forward all request headers starting with the header token jmaki-
+ // and chop off the jmaki-
+ Enumeration hnum = req.getHeaderNames();
+
+ // test hack
+
+ while (hnum.hasMoreElements()) {
+ String name = (String)hnum.nextElement();
+ if (name.startsWith(headerToken))
+ {
+ if (headers == null) headers = new HashMap();
+
+ String value = "";
+ // handle multi-value headers
+ Enumeration vnum = req.getHeaders(name);
+ while (vnum.hasMoreElements()) {
+ value += (String)vnum.nextElement();
+ if (vnum.hasMoreElements()) value += ";";
+ }
+ String sname = name.substring(headerToken.length(), name.length());
+ headers.put(sname,value);
+ }
+ else if (name.equals("Accept"))
+ {
+ if (headers == null) headers = new HashMap();
+
+ String value = "";
+ // handle multi-value headers
+ Enumeration vnum = req.getHeaders(name);
+ while (vnum.hasMoreElements()) {
+ value += (String)vnum.nextElement();
+ if (vnum.hasMoreElements()) value += ";";
+ }
+ headers.put(name,value);
+ }
+ else if(name.startsWith(testToken))
+ {
+ // hack test capabilities for authentication
+ if("xtest-user".equals(name)) testUser =
req.getHeader("xtest-user");
+ if("xtest-pass".equals(name)) testPass =
req.getHeader("xtest-pass");
+ }
+
+ // auth header
+ else if(name.equalsIgnoreCase("Authorization"))
+ {
+ if (headers == null) {
+ headers = new HashMap();
+ }
+ // hack test capabilities for authentication
+ authHeader = req.getHeader("Authorization");
+ headers.put("Authorization", authHeader);
+ }
+ }
+
+ try
+ {
+ String actualServiceKey = "default";
+ Map<String,Object> service = null;
+ for(Map svc : services)
+ {
+ if(svc.get(ProxyConfig.ID).equals(actualServiceKey))
+ {
+ service = svc;
+ break;
+ }
+ }
+ if (service!=null)
+ {
+
+ String serviceURL = (String)service.get(ProxyConfig.URL);
+ if(null==serviceURL)
+ throw new IllegalArgumentException(configResource+": service
url is mising");
+
+ if (service.containsKey(ProxyConfig.PASSTHROUGH))
+ passthrough = (Boolean)service.get(ProxyConfig.PASSTHROUGH);
+
+
+ if(null==testUser)
+ {
+ //System.out.println("Ignore service configuration
credentials");
+ if (service.containsKey("username")) userName =
(String)service.get("username");
+ if (service.containsKey("password")) password =
(String)service.get("password");
+ }
+ else
+ {
+ userName = testUser;
+ password = testPass;
+ }
+
+ String apikey = "";
+ if (service.containsKey("apikey")) apikey =
(String)service.get("apikey");
+ if (service.containsKey("xslStyleSheet")) xslURLString =
(String)service.get("xslStyleSheet");
+
+ // default to the service default if no url parameters are specified
+ if(!passthrough)
+ {
+ if (urlParams == null &&
service.containsKey("defaultURLParams")) {
+ urlParams =
(String)service.get("defaultURLParams");
+ }
+
+ // build the URL
+ if (urlParams != null &&
serviceURL.indexOf("?") == -1){
+ serviceURL += "?";
+ } else if (urlParams != null) {
+ serviceURL += "&";
+ }
+
+ urlString = serviceURL + apikey;
+ if (urlParams != null) urlString += "&" +
urlParams;
+ }
+
+ if(passthrough)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(serviceURL);
+
+ // override service url and url params
+ String path = req.getRequestURI();
+ String servletPath = req.getServletPath();
+ path =
path.substring(path.indexOf(servletPath)+servletPath.length(), path.length());
+
+ StringTokenizer tok = new StringTokenizer(path, "/");
+ while(tok.hasMoreTokens())
+ {
+ String token = tok.nextToken();
+ if(token.indexOf(";")!=-1)
+ sb.append("/").append(token); //
;JSESSIONID=XYZ
+ else
+
sb.append("/").append(URLEncoder.encode(token));
+ }
+
+ if(req.getQueryString()!=null)
+ sb.append("?").append(req.getQueryString());
+
+ urlString = sb.toString();
+ }
+ }
+ else
+ {
+ writer = res.getWriter();
+ writer.write("XmlHttpProxyServlet Error : service for id
'" + actualServiceKey + "' not found.");
+ writer.flush();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ getLogger().severe("XmlHttpProxyServlet Error loading service:
" + ex);
+ res.setStatus(500);
+ }
+
+ Map paramsMap = new HashMap();
+ paramsMap.put("format", format);
+ // do not allow for xdomain unless the context level setting is enabled.
+ if (callback != null && allowXDomain) {
+ paramsMap.put("callback", callback);
+ }
+ if (countString != null) {
+ paramsMap.put("count", countString);
+ }
+
+ InputStream xslInputStream = null;
+
+ if (urlString == null) {
+ writer = res.getWriter();
+ writer.write("XmlHttpProxyServlet parameters: id[Required]
urlparams[Optional] format[Optional] callback[Optional]");
+ writer.flush();
+ return;
+ }
+ // support for session properties and also authentication name
+ if (urlString.indexOf("${") != -1) {
+ urlString = processURL(urlString, req, res);
+ }
+
+ out = res.getOutputStream();
+
+ if (!isPost)
+ {
+ xhp.processRequest(urlString, out, xslInputStream, paramsMap, headers,
method, userName, password);
+ }
+ else
+ {
+ if (bodyContent == null)
+ getLogger().info("XmlHttpProxyServlet attempting to post to url
" + urlString + " with no body content");
+ xhp.doPost(urlString, out, xslInputStream, paramsMap, headers,
bodyContent, req.getContentType(), userName, password, authHeader);
+ }
+
+ res.setContentType(xhp.getContentType());
+ res.setStatus(xhp.getStatus());
+
+ }
+ catch (Exception iox)
+ {
+ if(iox instanceof XmlHttpProxy.AuthenticationException)
+ {
+ XmlHttpProxy.AuthenticationException authEx =
(XmlHttpProxy.AuthenticationException)iox;
+ res.setHeader("WWW-Authenticate", authEx.getAuthHeader());
+ res.setStatus(authEx.getCode());
+ }
+ /*else if(iox instanceof RedirectException)
+ {
+ RedirectException redirect = (RedirectException)iox;
+
+ String redir = redirect.getLocation();
+ if(redir.equals("/")) redir+="App.html";
+ redir+="?gwt.codesvr=127.0.0.1:9997";
+
+ System.out.println(">> "+ redir);
+ res.setHeader("Location", redir);
+ res.setStatus(307);
+ } */
+ else
+ {
+ iox.printStackTrace();
+ getLogger().severe("XmlHttpProxyServlet: caught " + iox);
+
+ res.setStatus(500);
+ }
+ /*try {
+ writer = res.getWriter();
+ writer.write("XmlHttpProxyServlet error loading service for " +
serviceKey + " . Please notify the administrator.");
+ writer.flush();
+ } catch (java.io.IOException ix) {
+ ix.printStackTrace();
+ }*/
+ return;
+ }
+ finally
+ {
+ try
+ {
+ if (out != null) out.close();
+ if (writer != null) writer.close();
+ } catch (java.io.IOException iox){}
+ }
+ }
+
+ /* Allow for a EL style replacements in the serviceURL
+ *
+ * The constant REMOTE_USER will replace the contents of ${REMOTE_USER}
+ * with the return value of request.getRemoteUserver() if it is not null
+ * otherwise the ${REMOTE_USER} is replaced with a blank.
+ *
+ * If you use ${session.somekey} the ${session.somekey} will be replaced with
+ * the String value of the session varialble somekey or blank if the session key
+ * does not exist.
+ *
+ */
+ private String processURL(String url, HttpServletRequest req, HttpServletResponse
res) {
+ String serviceURL = url;
+ int start = url.indexOf("${");
+ int end = url.indexOf("}", start);
+ if (end != -1) {
+ String prop = url.substring(start + 2, end).trim();
+ // no matter what we will remove the ${}
+ // default to blank like the JSP EL
+ String replace = "";
+ if (REMOTE_USER.equals(prop)) {
+ if (req.getRemoteUser() != null) replace = req.getRemoteUser();
+ }
+ if (prop.toLowerCase().startsWith("session.")) {
+ String sessionKey = prop.substring("session.".length(),
prop.length());
+ if (req.getSession().getAttribute(sessionKey) != null) {
+ // force to a string
+ replace = req.getSession().getAttribute(sessionKey).toString();
+ }
+ }
+ serviceURL = serviceURL.substring(0, start) +
+ replace +
+ serviceURL.substring(end + 1, serviceURL.length());
+ }
+ // call recursively to process more than one instance of a ${ in the serviceURL
+ if (serviceURL.indexOf("${") != -1) serviceURL = processURL(serviceURL,
req, res);
+ return serviceURL;
+ }
+
+ /**
+ * Check to see if the configuration file has been updated so that it may be
reloaded.
+ */
+ private boolean configUpdated() {
+ try {
+ URL url = ctx.getResource(resourcesDir + configResource);
+ URLConnection con;
+ if (url == null) return false ;
+ con = url.openConnection();
+ long lastModified = con.getLastModified();
+ long XHP_LAST_MODIFIEDModified = 0;
+ if (ctx.getAttribute(XHP_LAST_MODIFIED) != null) {
+ XHP_LAST_MODIFIEDModified =
((Long)ctx.getAttribute(XHP_LAST_MODIFIED)).longValue();
+ } else {
+ ctx.setAttribute(XHP_LAST_MODIFIED, new Long(lastModified));
+ return false;
+ }
+ if (XHP_LAST_MODIFIEDModified < lastModified) {
+ ctx.setAttribute(XHP_LAST_MODIFIED, new Long(lastModified));
+ return true;
+ }
+ } catch (Exception ex) {
+ getLogger().severe("XmlHttpProxyServlet error checking configuration:
" + ex);
+ }
+ return false;
+ }
+
+ public Logger getLogger() {
+ if (logger == null) {
+ logger = Logger.getLogger("jmaki.services.xhp.Log");
+
+ // TODO: the logger breaks the GWT tests, because it writes to stderr
+ // we'll turn it off for now.
+ //System.out.println("WARN: XHP proxy logging is turned off");
+ logger.setLevel(Level.OFF);
+ }
+ return logger;
+ }
+
+ private void logMessage(String message) {
+ if (rDebug) {
+ getLogger().info(message);
+ }
+ }
+}
\ No newline at end of file
Modified:
console/trunk/app/src/main/java/org/picketlink/as/console/application/Development.gwt.xml
===================================================================
---
console/trunk/app/src/main/java/org/picketlink/as/console/application/Development.gwt.xml 2012-03-26
20:35:04 UTC (rev 1539)
+++
console/trunk/app/src/main/java/org/picketlink/as/console/application/Development.gwt.xml 2012-03-26
21:53:57 UTC (rev 1540)
@@ -21,7 +21,7 @@
<inherits name="org.picketlink.as.console.application.App" />
- <set-property name="user.agent" value="gecko1_8" />
+ <set-property name="user.agent" value="safari,gecko1_8" />
<set-property name="locale" value="default" />
</module>
Added: console/trunk/app/src/main/resources/gwt-proxy.properties
===================================================================
--- console/trunk/app/src/main/resources/gwt-proxy.properties (rev
0)
+++ console/trunk/app/src/main/resources/gwt-proxy.properties 2012-03-26 21:53:57 UTC (rev
1540)
@@ -0,0 +1,22 @@
+#
+# JBoss, Home of Professional Open Source
+# Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+# as indicated by the @author tags. All rights reserved.
+# See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License, v. 2.1.
+# This program is distributed in the hope that it will be useful, but WITHOUT A
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+# You should have received a copy of the GNU Lesser General Public License,
+# v.2.1 along with this distribution; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+service.id=domain-api
+service.url=http://127.0.0.1:9990/management
+service.passthrough=true
\ No newline at end of file
Added: console/trunk/app/src/main/resources/logout.properties
===================================================================
--- console/trunk/app/src/main/resources/logout.properties (rev
0)
+++ console/trunk/app/src/main/resources/logout.properties 2012-03-26 21:53:57 UTC (rev
1540)
@@ -0,0 +1,22 @@
+#
+# JBoss, Home of Professional Open Source
+# Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+# as indicated by the @author tags. All rights reserved.
+# See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License, v. 2.1.
+# This program is distributed in the hope that it will be useful, but WITHOUT A
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+# You should have received a copy of the GNU Lesser General Public License,
+# v.2.1 along with this distribution; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+service.id=logout-api
+service.url=http://127.0.0.1:9990/logout
+service.passthrough=true
\ No newline at end of file
Added: console/trunk/app/src/main/resources/upload-proxy.properties
===================================================================
--- console/trunk/app/src/main/resources/upload-proxy.properties
(rev 0)
+++ console/trunk/app/src/main/resources/upload-proxy.properties 2012-03-26 21:53:57 UTC
(rev 1540)
@@ -0,0 +1,22 @@
+#
+# JBoss, Home of Professional Open Source
+# Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+# as indicated by the @author tags. All rights reserved.
+# See the copyright.txt in the distribution for a
+# full listing of individual contributors.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License, v. 2.1.
+# This program is distributed in the hope that it will be useful, but WITHOUT A
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+# You should have received a copy of the GNU Lesser General Public License,
+# v.2.1 along with this distribution; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+service.id=deployment-api
+service.url=http://127.0.0.1:9990/management/add-content
+service.passthrough=true
\ No newline at end of file
Modified: console/trunk/app/src/main/webapp/WEB-INF/web.xml
===================================================================
--- console/trunk/app/src/main/webapp/WEB-INF/web.xml 2012-03-26 20:35:04 UTC (rev 1539)
+++ console/trunk/app/src/main/webapp/WEB-INF/web.xml 2012-03-26 21:53:57 UTC (rev 1540)
@@ -1,38 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
-<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
+ version="2.5">
- <servlet>
- <servlet-name>gwtProxy</servlet-name>
-
<servlet-class>org.jboss.as.console.server.proxy.XmlHttpProxyServlet</servlet-class>
- <init-param>
- <param-name>config.name</param-name>
- <param-value>gwt-proxy.properties</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
+ <context-param>
+ <param-name>proxyHost</param-name>
+ <param-value>localhost</param-value>
+ </context-param>
- <servlet>
- <servlet-name>uploadProxy</servlet-name>
-
<servlet-class>org.jboss.as.console.server.proxy.XmlHttpProxyServlet</servlet-class>
- <init-param>
- <param-name>config.name</param-name>
- <param-value>upload-proxy.properties</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
+ <context-param>
+ <param-name>proxyPort</param-name>
+ <param-value>9990</param-value>
+ </context-param>
- <servlet-mapping>
- <servlet-name>gwtProxy</servlet-name>
- <url-pattern>/app/proxy/*</url-pattern>
- </servlet-mapping>
+ <servlet>
+ <servlet-name>gwtProxy</servlet-name>
+ <servlet-class>org.jboss.as.console.server.proxy.XmlHttpProxyServlet</servlet-class>
+ <init-param>
+ <param-name>config.name</param-name>
+ <param-value>gwt-proxy.properties</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
- <servlet-mapping>
- <servlet-name>uploadProxy</servlet-name>
- <url-pattern>/app/upload/*</url-pattern>
- </servlet-mapping>
+ <servlet>
+ <servlet-name>uploadProxy</servlet-name>
+ <servlet-class>org.jboss.as.console.server.proxy.XmlHttpProxyServlet</servlet-class>
+ <init-param>
+ <param-name>config.name</param-name>
+ <param-value>upload-proxy.properties</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>gwtProxy</servlet-name>
+ <url-pattern>/app/proxy/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>uploadProxy</servlet-name>
+ <url-pattern>/app/upload/*</url-pattern>
+ </servlet-mapping>
+
+ <!--security-constraint> <web-resource-collection>
<web-resource-name>PicketLinkConsole</web-resource-name>
+ <url-pattern>/*</url-pattern> </web-resource-collection>
<auth-constraint>
+ <role-name>manager</role-name> </auth-constraint>
</security-constraint>
+ <login-config> <auth-method>BASIC</auth-method>
<realm-name>ManagementRealm</realm-name>
+ </login-config -->
+
</web-app>