From picketlink-commits at lists.jboss.org Mon Mar 26 17:54:01 2012 Content-Type: multipart/mixed; boundary="===============5698536778713525984==" MIME-Version: 1.0 From: picketlink-commits at lists.jboss.org To: picketlink-commits at lists.jboss.org Subject: [picketlink-commits] Picketlink SVN: r1540 - in console/trunk/app/src/main: java/org/jboss and 9 other directories. Date: Mon, 26 Mar 2012 17:54:00 -0400 Message-ID: <201203262154.q2QLs0fg029583@svn01.web.mwc.hst.phx2.redhat.com> --===============5698536778713525984== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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/Bootstr= apContext.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/HttpCl= ient.java console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/ProxyC= onfig.java console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Redire= ctException.java console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHtt= pProxy.java console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHtt= pProxyServlet.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/De= velopment.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/Boo= tstrapContext.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/jboss/as/console/client/core/Bootst= rapContext.java (rev 0) +++ console/trunk/app/src/main/java/org/jboss/as/console/client/core/Bootst= rapContext.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 Pedro Silva + * @since Mar 22, 2012 + */ +public class BootstrapContext implements ApplicationProperties { + + private Map ctx =3D new HashMap(); + + private static final String[] persistentProperties =3D new String[] { + //STANDALONE + }; + private String initialPlace =3D null; + + @Inject + public BootstrapContext() { + /*String token =3D History.getToken(); + if(token!=3Dnull && !token.equals("") && !token.equals(NameTokens.= signInPage)) + setProperty(INITIAL_TOKEN, token); + */ + loadPersistedProperties(); + +// String domainApi =3D !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 =3D !GWT.isScript() ? getBaseUrl()+"managem= ent/add-content" : "http://127.0.0.1:8080/picketlink-console-application-1.= 0.0-SNAPSHOT/app/upload"; +// setProperty(DEPLOYMENT_API, deploymentApi); +// +// String logoutApi =3D !GWT.isScript() ? getBaseUrl()+"logout" : "= http://127.0.0.1:8080/picketlink-console-application-1.0.0-SNAPSHOT/app/log= out"; +// setProperty(LOGOUT_API, logoutApi); + + String domainApi =3D GWT.isScript() ? getBaseUrl()+"management" : = "http://127.0.0.1:8888/app/proxy"; + setProperty(DOMAIN_API, domainApi); + + + String deploymentApi =3D GWT.isScript() ? getBaseUrl()+"management= /add-content" : "http://127.0.0.1:8888/app/upload"; + setProperty(DEPLOYMENT_API, deploymentApi); + + String logoutApi =3D GWT.isScript() ? getBaseUrl()+"logout" : "htt= p://127.0.0.1:8888/app/logout"; + setProperty(LOGOUT_API, logoutApi); + + //Log.info("Domain API Endpoint: " + domainApi); + } + + private String getBaseUrl() { + // extract host +// String base =3D GWT.getHostPageBaseURL(); +// return extractHttpEndpointUrl(base); + return "http://localhost:9990/"; + } + + public static String extractHttpEndpointUrl(String base) { + String protocol =3D base.substring(0, base.indexOf("//")+2); + String remainder =3D base.substring(base.indexOf(protocol)+protoco= l.length(), base.length()); + + String host =3D null; + String port =3D null; + + int portDelim =3D remainder.indexOf(":"); + if(portDelim !=3D-1 ) + { + host =3D remainder.substring(0, portDelim); + String portRemainder =3D remainder.substring(portDelim+1, rema= inder.length()); + if(portRemainder.indexOf("/")!=3D-1) + { + port =3D portRemainder.substring(0, portRemainder.indexOf(= "/")); + } + else + { + port =3D portRemainder; + } + } + else + { + host =3D remainder.substring(0, remainder.indexOf("/")); + port =3D "80"; + } + + // default url + return protocol + host + ":" + port + "/"; + } + + private void loadPersistedProperties() { + for(String key : persistentProperties) + { + String pref =3D Preferences.get(key); + if(pref!=3Dnull) + 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)!=3Dnull; + } + + public PlaceRequest getDefaultPlace() { + + PlaceRequest defaultPlace =3D getProperty(STANDALONE).equals("tru= e") ? + new PlaceRequest(NameTokens.StandaloneServerPresenter) : n= ew 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 =3D false; + for(String s : persistentProperties) + { + if(s.equals(key)) + { + b=3Dtrue; + break; + } + } + + return b; + + } + + @Override + public boolean isStandalone() { + return getProperty(BootstrapContext.STANDALONE).equals("true"); + } + + public void setInitialPlace(String nameToken) { + this.initialPlace =3D nameToken; + } + + public String getInitialPlace() { + return initialPlace; + } + + public String getLogoutUrl() { + String url =3D getProperty(LOGOUT_API); + + if(!GWT.isScript()) + url +=3D "?gwt.codesvr=3D" + Window.Location.getParameter("gwt= .codesvr"); + return url; + } +} Added: console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Ht= tpClient.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/HttpC= lient.java (rev 0) +++ console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/HttpC= lient.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 WIT= HOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNE= SS 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 Licens= e, + * 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 =3D null; + private int proxyPort =3D -1; + private boolean isHttps =3D false; + private boolean isProxy =3D false; + private HttpURLConnection urlConnection =3D 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 =3D callback; + + if (phost !=3D null && pport !=3D -1) + { + this.isProxy =3D true; + } + + this.proxyHost =3D phost; + this.proxyPort =3D pport; + + if (url.trim().startsWith("https:")) { + isHttps =3D true; + } + + this.urlConnection =3D getURLConnection(url); + try { + this.urlConnection.setRequestMethod(method); + } catch (java.net.ProtocolException pe) { + HttpClient.getLogger().severe("Unable protocol method to " + m= ethod + " : " + pe); + } + this.headers =3D headers; + writeHeaders(headers); + + } + + private void writeHeaders(Map headers) + { + if(this.callback!=3Dnull) + { + Map cookies =3D callback.getCooki= es(); + Iterator it =3D cookies.keySet().iterator(); + while(it.hasNext()) + { + XmlHttpProxy.Cookie c =3D cookies.get(it.next()); + if(headers=3D=3Dnull) headers =3D new HashMap(); + headers.put( + "Cookie", c.name + "=3D" + c.value // + "; Path=3D= " + c.path + ); + } + + } + // set headers + if (headers !=3D null) { + Iterator it =3D headers.keySet().iterator(); + if (it !=3D null) { + while (it.hasNext()) { + String key =3D (String)it.next(); + String value =3D (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 =3D callback; + + try + { + if (phost !=3D null && pport !=3D -1) { + this.isProxy =3D true; + } + + this.proxyHost =3D phost; + this.proxyPort =3D pport; + if (url.trim().startsWith("https:")) { + isHttps =3D true; + } + this.urlConnection =3D 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 =3D userName + ":" + password; + String encoded =3D new sun.misc.BASE64Encoder().encode (auth.g= etBytes()); + // set basic authorization + this.urlConnection.setRequestProperty ("Authorization", "Basic= " + encoded); + this.headers =3D headers; + writeHeaders(headers); + } catch (Exception ex) { + HttpClient.getLogger().severe("Unable to set basic authorizati= on 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 o= r invalid + * certificate (https), SSLException or IOException is thro= wn. + * the following line is a hack to avoid that + */ + Security.addProvider(new com.sun.net.ssl.internal.ssl.Prov= ider()); + 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 =3D new URL(str); + HttpURLConnection uc =3D (HttpURLConnection)url.openConnection= (); + + // if this header has not been set by a request set the user a= gent. + if (headers =3D=3D null || + (headers !=3D null && headers.get("user-agent") =3D= =3D null)) { + // set user agent to mimic a common browser + String ua=3D"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 UrlConnecti= on: " + 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 =3D this.urlConnection.getResponseCode(); + + try + { + // HACK: manually follow redirects, for the login to work + // HTTPUrlConnection auto redirect doesn't respect the pro= vided headers + if(responseCode =3D=3D302) + { + HttpClient redirectClient =3D + new HttpClient(proxyHost,proxyPort, urlConnect= ion.getHeaderField("Location"), + headers, urlConnection.getRequestMetho= d(), callback); + redirectClient.getInputStream().close(); + } + } + catch (Throwable e) + { + System.out.println("Following redirect failed"); + } + + setCookieHeader =3D this.urlConnection.getHeaderField("Set-Coo= kie"); + + + InputStream in =3D responseCode !=3D HttpURLConnection.HTTP_OK= ? + this.urlConnection.getErrorStream() : this.urlConnecti= on.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 !=3D null) this.urlConnection.setRequestProperty( = "Content-type", contentType ); + if (authHeader!=3D null) this.urlConnection.setRequestProperty( "A= uthorization", authHeader); + + OutputStream out =3D null; + try { + out =3D this.getOutputStream(); + if(out!=3Dnull) + { + out.write(postData); + out.flush(); + } + } catch (IOException e) { + e.printStackTrace(); + }finally { + if(out!=3Dnull) + try { + out.close(); + } catch (IOException e) { + // + } + } + + + return (this.getInputStream()); + } + + public String getContentEncoding() { + if (this.urlConnection =3D=3D null) return null; + return (this.urlConnection.getContentEncoding()); + } + public int getContentLength() { + if (this.urlConnection =3D=3D null) return -1; + return (this.urlConnection.getContentLength()); + } + public String getContentType() { + if (this.urlConnection =3D=3D null) return null; + return (this.urlConnection.getContentType()); + } + public long getDate() { + if (this.urlConnection =3D=3D null) return -1; + return (this.urlConnection.getDate()); + } + public String getHeader(String name) { + if (this.urlConnection =3D=3D null) return null; + return (this.urlConnection.getHeaderField(name)); + } + public long getIfModifiedSince() { + if (this.urlConnection =3D=3D null) return -1; + return (this.urlConnection.getIfModifiedSince()); + } + + public static Logger getLogger() { + if (logger =3D=3D null) { + logger =3D 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/Pr= oxyConfig.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Proxy= Config.java (rev 0) +++ console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Proxy= Config.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 WIT= HOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNE= SS 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 Licens= e, + * 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 + * @date: Apr 21, 2010 + */ +public class ProxyConfig +{ + private Map rootConfig; + + public final static String SERVICES =3D "services"; + public final static String ID =3D "id"; + public final static String URL =3D "url"; + public final static String CONTENT_TYPE =3D "contentType"; + public final static String PASSTHROUGH =3D "passthrough"; + + protected ProxyConfig(Map rootConfig) + { + this.rootConfig =3D rootConfig; + } + + private static ProxyConfig parse(String json) + { + /*JSONDecoder decoder =3D new JSONDecoder(json); + ProxyConfig config =3D new ProxyConfig((Map)decoder.par= se()); + return config; */ + + throw new RuntimeException("Not implemented"); + } + + public static ProxyConfig parse(InputStream in) + { + return parse(inputStreamToString(in)); + } + + public List> getServices() + { + Map root =3D (Map)rootConfig.get("xh= p"); + return (List)root.get(SERVICES); + } + + private static String inputStreamToString(InputStream in) + { + try + { + BufferedReader bufferedReader =3D new BufferedReader(new Input= StreamReader(in)); + StringBuilder stringBuilder =3D new StringBuilder(); + String line =3D null; + + while ((line =3D bufferedReader.readLine()) !=3D 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/Re= directException.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Redir= ectException.java (rev 0) +++ console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Redir= ectException.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 =3D location; + } + + public String getLocation() { + return location; + } +} Added: console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/Xm= lHttpProxy.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHt= tpProxy.java (rev 0) +++ console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHt= tpProxy.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 WIT= HOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNE= SS 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 Licens= e, + * 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 =3D "GET"; + public static String POST =3D "POST"; + public static String DELETE =3D "DELETE"; + public static String PUT =3D "PUT"; + + private String userName =3D null; + private String password =3D null; + private static Logger logger; + private String proxyHost =3D ""; + int proxyPort =3D -1; + private Object config; + private static String USAGE =3D "Usage: -url service_URL -id service= _key [-url or -id required] -xslurl xsl_url [optional] -format json|xml [op= tional] -callback[optional] -config [optional] -resources base_directory_co= ntaining XSL stylesheets [optional]"; + private String authHeader; + + public XmlHttpProxy() {} + + private String contentType =3D "application/json"; + + private Map cookies =3D new HashMap(); + + int status =3D -1; + + public String getContentType() { + return contentType; + } + + public int getStatus() { + return status; + } + + public interface CookieCallback + { + Map getCookies(); + } + + public XmlHttpProxy(String proxyHost, int proxyPort) { + this.proxyHost =3D proxyHost; + this.proxyPort =3D proxyPort; + } + + public XmlHttpProxy(String proxyHost, int proxyPort, + String userName, String password) { + this.proxyHost =3D proxyHost; + this.proxyPort =3D proxyPort; + this.userName =3D userName; + this.password =3D 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 wr= itten + * @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 transfor= mation + * @param paramsMap - A Map of parameters that are feed to the XSLT P= rocessor. 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, Malfor= medURLException { + doProcess(urlString, out, xslInputStream, paramsMap, headers,metho= d, 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 wr= itten + * @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 IOExcept= ion, MalformedURLException { + this.authHeader =3D authHeader; + doProcess(urlString, out, xslInputStream, paramsMap, headers, XmlH= ttpProxy.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 wr= itten + * @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 transfor= mation + * @param paramsMap - A Map of parameters that are feed to the XSLT Pr= ocessor. 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 doPos= t 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, MalformedUR= LException { + + if (paramsMap =3D=3D null) { + paramsMap =3D new HashMap(); + } + + String format =3D (String)paramsMap.get("format"); + if (format =3D=3D null) { + format =3D "xml"; + } + + InputStream in =3D null; + BufferedOutputStream os =3D null; + + HttpClient httpclient =3D null; + + CookieCallback callback =3D new CookieCallback() + { + + public Map getCookies() + { + return accessCookies(); + } + }; + + if (userName !=3D null && password !=3D null) + { + httpclient =3D new HttpClient(proxyHost, proxyPort, urlString,= headers, method, userName, password, callback); + } + else + { + httpclient =3D new HttpClient(proxyHost, proxyPort, urlString,= headers, method, callback); + } + + // post data determines whether we are going to do a get or a post + if (postData =3D=3D null) { + in =3D httpclient.getInputStream(); + } else { + in =3D httpclient.doPost(postData, postContentType, authHeader= ); + } + + // Set-Cookie header + if(httpclient.getSetCookieHeader()!=3Dnull) + { + String cookie =3D httpclient.getSetCookieHeader(); + System.out.println("'Set-Cookie' header: "+ cookie); + String[] values =3D cookie.split(";"); + + Cookie c =3D new Cookie(); + for(String v : values) + { + String[] tuple =3D v.split("=3D"); + if("Path".equals( tuple[0].trim())) + c.path =3D tuple[1]; + else + { + c.name =3D tuple[0].trim(); + c.value =3D tuple[1]; + } + } + + + List toBeRemoved =3D new ArrayList(); + Iterator it =3D cookies.keySet().iterator(); + while(it.hasNext()) + { + Cookie exists =3D cookies.get(it.next()); + if(exists.name.equals(c.name)) + { + String msg =3D 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=3D=3Din) + { + int responseCode =3D httpclient.getResponseCode(); + if(401=3D=3D responseCode || 403=3D=3DresponseCode) + { + // authentication required + throw new AuthenticationException(responseCode, httpclient= .getHeader("WWW-Authenticate")); + } + else if(307=3D=3DresponseCode) + { + // 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 =3D httpclient.getContentEncoding(); + if (ce =3D=3D null) { + String ct =3D httpclient.getContentType(); + if (ct !=3D null) { + int idx =3D ct.lastIndexOf("charset=3D"); + if (idx >=3D 0) { + ce =3D ct.substring(idx+8); + } else { + ce =3D "UTF-8"; + } + } else { + ce =3D "UTF-8"; + } + } + // get the content type + this.contentType =3D httpclient.getContentType(); + this.status =3D httpclient.getResponseCode(); + + // write out the content type + //http://www.ietf.org/rfc/rfc4627.txt + + try { + + // response stream + + byte[] buffer =3D new byte[1024]; + int read =3D 0; + if (xslInputStream =3D=3D null) { + while (true) { + read =3D in.read(buffer); + if (read <=3D 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 !=3D null) { + in.close(); + } + if (out !=3D null) { + out.flush(); + out.close(); + } + } catch (Exception e) { + // do nothing + } + } + } + + private Map accessCookies() + { + return cookies; + } + + /** + * Do the XSLT transformation + */ + public void transform( InputStream xmlIS, + InputStream xslIS, + Map params, + OutputStream result, + String encoding) { + try { + TransformerFactory trFac =3D TransformerFactory.newInstance(); + Transformer transformer =3D trFac.newTransformer(new StreamSou= rce(xslIS)); + Iterator it =3D params.keySet().iterator(); + while (it.hasNext()) { + String key =3D (String)it.next(); + transformer.setParameter(key, (String)params.get(key)); + } + transformer.setOutputProperty("encoding", encoding); + transformer.transform(new StreamSource(xmlIS), new StreamResul= t(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 =3D new XmlHttpProxy(); + + if (args.length =3D=3D 0) { + System.out.println(USAGE); + } + + String method =3D XmlHttpProxy.GET; + InputStream xslInputStream =3D null; + String serviceKey =3D null; + String urlString =3D null; + String xslURLString =3D null; + String format =3D "xml"; + String callback =3D null; + String urlParams =3D null; + String configURLString =3D "xhp.json"; + String resourceBase =3D "file:src/conf/META-INF/resources/xsl/"; + String username =3D null; + String password =3D null; + + // read in the arguments + int index =3D 0; + while (index < args.length) { + if (args[index].toLowerCase().equals("-url") && index + 1 < args.le= ngth) { + urlString =3D args[++index]; + } else if (args[index].toLowerCase().equals("-key") && index + 1 < = args.length) { + serviceKey =3D args[++index]; + } else if (args[index].toLowerCase().equals("-id") && index + 1 < a= rgs.length) { + serviceKey =3D args[++index]; + } else if (args[index].toLowerCase().equals("-callback") && index += 1 < args.length) { + callback =3D args[++index]; + } else if (args[index].toLowerCase().equals("-xslurl") && index + = 1 < args.length) { + xslURLString =3D args[++index]; + } else if (args[index].toLowerCase().equals("-method") && index + 1= < args.length) { + method =3D args[++index]; + } else if (args[index].toLowerCase().equals("-username") && index += 1 < args.length) { + username =3D args[++index]; + } else if (args[index].toLowerCase().equals("-password") && index += 1 < args.length) { + password =3D args[++index]; + } else if (args[index].toLowerCase().equals("-urlparams") && index = + 1 < args.length) { + urlParams =3D args[++index]; + } else if (args[index].toLowerCase().equals("-config") && index + 1= < args.length) { + configURLString =3D args[++index]; + } else if (args[index].toLowerCase().equals("-resources") && index = + 1 < args.length) { + resourceBase =3D args[++index]; + } + index++; + } + + if (serviceKey !=3D null) { + try { + InputStream is =3D (new URL(configURLString)).openStream(); + JSONObject services =3D loadServices(is); + JSONObject service =3D services.getJSONObject(serviceKey); + // default to the service default if no url parameters are specifi= ed + if (urlParams =3D=3D null && service.has("defaultURLParams")) { + urlParams =3D service.getString("defaultURLParams"); + } + String serviceURL =3D service.getString("url"); + // build the URL properly + if (urlParams !=3D null && serviceURL.indexOf("?") =3D=3D -1){ + serviceURL +=3D "?"; + } else if (urlParams !=3D null){ + serviceURL +=3D "&"; + } + String apiKey =3D ""; + if (service.has("apikey")) apiKey =3D service.getString("apikey"); + urlString =3D serviceURL + apiKey + "&" + urlParams; + if (service.has("xslStyleSheet")) { + xslURLString =3D 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 =3D=3D 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 =3D new HashMap(); + if (format !=3D null) { + paramsMap.put("format", format); + } + if (callback !=3D null) { + paramsMap.put("callback", callback); + } + + if (xslURLString !=3D null) { + URL xslURL =3D new URL(xslURLString); + if (xslURL !=3D null) { + xslInputStream =3D xslURL.openStream(); + } else { + getLogger().severe("Error: Unable to locate XSL at URL " + xslURL= String); + } + } + xhp.processRequest(urlString, System.out, xslInputStream, paramsMap, = null, method, username, password); + } */ + + public static Logger getLogger() { + if (logger =3D=3D null) { + logger =3D 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 =3D code; + this.authHeader =3D 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/Xm= lHttpProxyServlet.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHt= tpProxyServlet.java (rev 0) +++ console/trunk/app/src/main/java/org/jboss/as/console/server/proxy/XmlHt= tpProxyServlet.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 WIT= HOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNE= SS 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 Licens= e, + * 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.

+ * + * Usage (web.xml):
+ * + *

+ *   <servlet>
+ *       <servlet-name>gwtProxy</servlet-name>
+ *       <description>GWT Proxy</description>
+ *       <servlet-class>org.jboss.as.console.server.proxy.XmlHttpProxyS=
ervlet</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>
+ *
+ * 
+ * + *

+ * + * gwt-proxy.properties:
+ *

+ *    service.id=3Ddomain-api
+ *    service.url=3Dhttp://127.0.0.1:9990/domain-api
+ *    service.passThrough=3Dtrue
+ * 
+ * + * @author Greg Murray + * @author Heiko Braun + */ +public class XmlHttpProxyServlet extends HttpServlet +{ + + public static String REMOTE_USER =3D "REMOTE_USER"; + + private static String XHP_LAST_MODIFIED =3D "xhp_last_modified_key"; + private static String DEFAULT_CONFIG =3D "gwt-proxy.properties"; + + private static boolean allowXDomain =3D false; + private static boolean requireSession =3D false; + private static boolean createSession =3D false; + private static String defaultContentType =3D "application/dmr-encoded;= charset=3DUTF-8"; + private static boolean rDebug =3D false; + private Logger logger =3D null; + private XmlHttpProxy xhp =3D null; + private ServletContext ctx; + private List> services =3D null; + private String resourcesDir =3D "/resources/"; + private String classpathResourcesDir =3D "/META-INF/resources/"; + private String headerToken =3D "jmaki-"; + private String testToken =3D "xtest-"; + + private static String testUser; + private static String testPass; + + private static String setCookie; + private String configResource =3D null; + private String authHeader; + + public XmlHttpProxyServlet() { + if (rDebug) { + logger =3D getLogger(); + } + + } + + public void init(ServletConfig config) throws ServletException { + super.init(config); + ctx =3D config.getServletContext(); + // set the response content type + if (ctx.getInitParameter("responseContentType") !=3D null) { + defaultContentType =3D ctx.getInitParameter("responseContentTy= pe"); + } + // allow for resources dir over-ride at the xhp level otherwise al= low + // for the jmaki level resources + if (ctx.getInitParameter("jmaki-xhp-resources") !=3D null) { + resourcesDir =3D ctx.getInitParameter("jmaki-xhp-resources"); + } else if (ctx.getInitParameter("jmaki-resources") !=3D null) { + resourcesDir =3D ctx.getInitParameter("jmaki-resources"); + } + // allow for resources dir over-ride + if (ctx.getInitParameter("jmaki-classpath-resources") !=3D null) { + classpathResourcesDir =3D ctx.getInitParameter("jmaki-classpat= h-resources"); + } + String requireSessionString =3D ctx.getInitParameter("requireSessi= on"); + if (requireSessionString =3D=3D null) requireSessionString =3D ctx= .getInitParameter("jmaki-requireSession"); + if (requireSessionString !=3D null) { + if ("false".equals(requireSessionString)) { + requireSession =3D false; + getLogger().severe("XmlHttpProxyServlet: intialization. Se= ssion requirement disabled."); + } else if ("true".equals(requireSessionString)) { + requireSession =3D true; + getLogger().severe("XmlHttpProxyServlet: intialization. Se= ssion requirement enabled."); + } + } + String xdomainString =3D ctx.getInitParameter("allowXDomain"); + if (xdomainString =3D=3D null) xdomainString =3D ctx.getInitParame= ter("jmaki-allowXDomain"); + if (xdomainString !=3D null) { + if ("true".equals(xdomainString)) { + allowXDomain =3D true; + getLogger().severe("XmlHttpProxyServlet: intialization. xD= omain access is enabled."); + } else if ("false".equals(xdomainString)) { + allowXDomain =3D false; + getLogger().severe("XmlHttpProxyServlet: intialization. xD= omain access is disabled."); + } + } + String createSessionString =3D ctx.getInitParameter("jmaki-createS= ession"); + if (createSessionString !=3D null) { + if ("true".equals(createSessionString)) { + createSession =3D true; + getLogger().severe("XmlHttpProxyServlet: intialization. cr= eate session is enabled."); + } else if ("false".equals(xdomainString)) { + createSession =3D false; + getLogger().severe("XmlHttpProxyServlet: intialization. cr= eate session is disabled."); + } + } + // if there is a proxyHost and proxyPort specified create an HttpC= lient with the proxy + String proxyHost =3D ctx.getInitParameter("proxyHost"); + String proxyPortString =3D ctx.getInitParameter("proxyPort"); + if (proxyHost !=3D null && proxyPortString !=3D null) { + int proxyPort =3D 8080; + try { + proxyPort=3D new Integer(proxyPortString).intValue(); + xhp =3D new XmlHttpProxy(proxyHost, proxyPort); + } catch (NumberFormatException nfe) { + getLogger().severe("XmlHttpProxyServlet: intialization err= or. The proxyPort must be a number"); + throw new ServletException("XmlHttpProxyServlet: intializa= tion error. The proxyPort must be a number"); + } + } else { + xhp =3D new XmlHttpProxy(); + } + + // config override + String servletName =3D config.getServletName(); + String configName =3D config.getInitParameter("config.name"); + configResource =3D configName!=3Dnull ? configName : DEFAULT_CONFI= G; + //System.out.println("Configure "+servletName + " through "+config= Resource); + } + + private void getServices(HttpServletResponse res) + { + services =3D new ArrayList>(); + + InputStream is =3D XmlHttpProxyServlet.class.getClassLoader() + .getResourceAsStream(configResource); + + if(null=3D=3Dis) + throw new IllegalStateException("Failed to load proxy configur= ation: "+configResource); + + try { + PropertyResourceBundle bundle =3D new PropertyResourceBundle(i= s); + HashMap serviceConfig =3D new HashMap(); + serviceConfig.put(ProxyConfig.ID, "default"); + serviceConfig.put(ProxyConfig.URL, bundle.getString("service.u= rl")); + serviceConfig.put(ProxyConfig.PASSTHROUGH, Boolean.valueOf(bun= dle.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.Ht= tpServletRequest, 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 =3D XmlHttpProxy.POST.equals(method); + + ByteArrayOutputStream bos =3D new ByteArrayOutputStream(); + byte[] bodyContent =3D null; + + OutputStream out =3D null; + PrintWriter writer =3D null; + + try { + + BufferedInputStream in =3D new BufferedInputStream(req.getInpu= tStream()); + int next =3D in.read(); + while (next > -1) { + bos.write(next); + next =3D in.read(); + } + + bodyContent =3D bos.toByteArray(); + + } catch (IOException e) { + e.printStackTrace(); + } + + try + { + HttpSession session =3D null; + // it really does not make sense to use create session with re= quire 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 =3D req.getSession(true); + } + if (requireSession) { + // check to see if there was a session created for this re= quest + // if not assume it was from another domain and blow up + // Wrap this to prevent Portlet exeptions + session =3D req.getSession(false); + if (session =3D=3D null) { + res.setStatus(HttpServletResponse.SC_FORBIDDEN); + return; + } + } + // check if the services have been loaded or if they need to b= e reloaded + if (services =3D=3D null || configUpdated()) { + getServices(res); + } + String urlString =3D null; + String xslURLString =3D null; + String userName =3D null; + String password =3D null; + String format =3D "json"; + String callback =3D req.getParameter("callback"); + String urlParams =3D req.getParameter("urlparams"); + String countString =3D req.getParameter("count"); + boolean passthrough =3D false; + // encode the url to prevent spaces from being passed along + if (urlParams !=3D null) { + urlParams =3D urlParams.replace(' ', '+'); + } + // get the headers to pass through + Map headers =3D null; + authHeader =3D null; + + // Forward all request headers starting with the header token = jmaki- + // and chop off the jmaki- + Enumeration hnum =3D req.getHeaderNames(); + + // test hack + + while (hnum.hasMoreElements()) { + String name =3D (String)hnum.nextElement(); + if (name.startsWith(headerToken)) + { + if (headers =3D=3D null) headers =3D new HashMap(); + + String value =3D ""; + // handle multi-value headers + Enumeration vnum =3D req.getHeaders(name); + while (vnum.hasMoreElements()) { + value +=3D (String)vnum.nextElement(); + if (vnum.hasMoreElements()) value +=3D ";"; + } + String sname =3D name.substring(headerToken.length(), = name.length()); + headers.put(sname,value); + } + else if (name.equals("Accept")) + { + if (headers =3D=3D null) headers =3D new HashMap(); + + String value =3D ""; + // handle multi-value headers + Enumeration vnum =3D req.getHeaders(name); + while (vnum.hasMoreElements()) { + value +=3D (String)vnum.nextElement(); + if (vnum.hasMoreElements()) value +=3D ";"; + } + headers.put(name,value); + } + else if(name.startsWith(testToken)) + { + // hack test capabilities for authentication + if("xtest-user".equals(name)) testUser =3D req.getHead= er("xtest-user"); + if("xtest-pass".equals(name)) testPass =3D req.getHead= er("xtest-pass"); + } + + // auth header + else if(name.equalsIgnoreCase("Authorization")) + { + if (headers =3D=3D null) { + headers =3D new HashMap(); + } + // hack test capabilities for authentication + authHeader =3D req.getHeader("Authorization"); + headers.put("Authorization", authHeader); + } + } + + try + { + String actualServiceKey =3D "default"; + Map service =3D null; + for(Map svc : services) + { + if(svc.get(ProxyConfig.ID).equals(actualServiceKey)) + { + service =3D svc; + break; + } + } + if (service!=3Dnull) + { + + String serviceURL =3D (String)service.get(ProxyConfig.= URL); + if(null=3D=3DserviceURL) + throw new IllegalArgumentException(configResource+= ": service url is mising"); + + if (service.containsKey(ProxyConfig.PASSTHROUGH)) + passthrough =3D (Boolean)service.get(ProxyConfig.P= ASSTHROUGH); + + + if(null=3D=3DtestUser) + { + //System.out.println("Ignore service configuration= credentials"); + if (service.containsKey("username")) userName =3D = (String)service.get("username"); + if (service.containsKey("password")) password =3D = (String)service.get("password"); + } + else + { + userName =3D testUser; + password =3D testPass; + } + + String apikey =3D ""; + if (service.containsKey("apikey")) apikey =3D (String)= service.get("apikey"); + if (service.containsKey("xslStyleSheet")) xslURLString= =3D (String)service.get("xslStyleSheet"); + + // default to the service default if no url parameters= are specified + if(!passthrough) + { + if (urlParams =3D=3D null && service.containsKey("= defaultURLParams")) { + urlParams =3D (String)service.get("defaultURLP= arams"); + } + + // build the URL + if (urlParams !=3D null && serviceURL.indexOf("?")= =3D=3D -1){ + serviceURL +=3D "?"; + } else if (urlParams !=3D null) { + serviceURL +=3D "&"; + } + + urlString =3D serviceURL + apikey; + if (urlParams !=3D null) urlString +=3D "&" + urlP= arams; + } + + if(passthrough) + { + StringBuffer sb =3D new StringBuffer(); + sb.append(serviceURL); + + // override service url and url params + String path =3D req.getRequestURI(); + String servletPath =3D req.getServletPath(); + path =3D path.substring(path.indexOf(servletPath)+= servletPath.length(), path.length()); + + StringTokenizer tok =3D new StringTokenizer(path, = "/"); + while(tok.hasMoreTokens()) + { + String token =3D tok.nextToken(); + if(token.indexOf(";")!=3D-1) + sb.append("/").append(token); // ;JSESS= IONID=3DXYZ + else + sb.append("/").append(URLEncoder.encode(to= ken)); + } + + if(req.getQueryString()!=3Dnull) + sb.append("?").append(req.getQueryString()); + + urlString =3D sb.toString(); + } + } + else + { + writer =3D res.getWriter(); + writer.write("XmlHttpProxyServlet Error : service for = id '" + actualServiceKey + "' not found."); + writer.flush(); + return; + } + } + catch (Exception ex) + { + getLogger().severe("XmlHttpProxyServlet Error loading serv= ice: " + ex); + res.setStatus(500); + } + + Map paramsMap =3D new HashMap(); + paramsMap.put("format", format); + // do not allow for xdomain unless the context level setting i= s enabled. + if (callback !=3D null && allowXDomain) { + paramsMap.put("callback", callback); + } + if (countString !=3D null) { + paramsMap.put("count", countString); + } + + InputStream xslInputStream =3D null; + + if (urlString =3D=3D null) { + writer =3D 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("${") !=3D -1) { + urlString =3D processURL(urlString, req, res); + } + + out =3D res.getOutputStream(); + + if (!isPost) + { + xhp.processRequest(urlString, out, xslInputStream, paramsM= ap, headers, method, userName, password); + } + else + { + if (bodyContent =3D=3D null) + getLogger().info("XmlHttpProxyServlet attempting to po= st to url " + urlString + " with no body content"); + xhp.doPost(urlString, out, xslInputStream, paramsMap, head= ers, 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 =3D (XmlHttpPr= oxy.AuthenticationException)iox; + res.setHeader("WWW-Authenticate", authEx.getAuthHeader()); + res.setStatus(authEx.getCode()); + } + /*else if(iox instanceof RedirectException) + { + RedirectException redirect =3D (RedirectException)iox; + + String redir =3D redirect.getLocation(); + if(redir.equals("/")) redir+=3D"App.html"; + redir+=3D"?gwt.codesvr=3D127.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 =3D 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 !=3D null) out.close(); + if (writer !=3D 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 nu= ll + * otherwise the ${REMOTE_USER} is replaced with a blank. + * + * If you use ${session.somekey} the ${session.somekey} will be replac= ed with + * the String value of the session varialble somekey or blank if the s= ession key + * does not exist. + * + */ + private String processURL(String url, HttpServletRequest req, HttpServ= letResponse res) { + String serviceURL =3D url; + int start =3D url.indexOf("${"); + int end =3D url.indexOf("}", start); + if (end !=3D -1) { + String prop =3D url.substring(start + 2, end).trim(); + // no matter what we will remove the ${} + // default to blank like the JSP EL + String replace =3D ""; + if (REMOTE_USER.equals(prop)) { + if (req.getRemoteUser() !=3D null) replace =3D req.getRemo= teUser(); + } + if (prop.toLowerCase().startsWith("session.")) { + String sessionKey =3D prop.substring("session.".length(), = prop.length()); + if (req.getSession().getAttribute(sessionKey) !=3D null) { + // force to a string + replace =3D req.getSession().getAttribute(sessionKey).= toString(); + } + } + serviceURL =3D serviceURL.substring(0, start) + + replace + + serviceURL.substring(end + 1, serviceURL.length()); + } + // call recursively to process more than one instance of a ${ in t= he serviceURL + if (serviceURL.indexOf("${") !=3D -1) serviceURL =3D processURL(se= rviceURL, 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 =3D ctx.getResource(resourcesDir + configResource); + URLConnection con; + if (url =3D=3D null) return false ; + con =3D url.openConnection(); + long lastModified =3D con.getLastModified(); + long XHP_LAST_MODIFIEDModified =3D 0; + if (ctx.getAttribute(XHP_LAST_MODIFIED) !=3D null) { + XHP_LAST_MODIFIEDModified =3D ((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 configu= ration: " + ex); + } + return false; + } + + public Logger getLogger() { + if (logger =3D=3D null) { + logger =3D 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/applica= tion/Development.gwt.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/java/org/picketlink/as/console/application/D= evelopment.gwt.xml 2012-03-26 20:35:04 UTC (rev 1539) +++ console/trunk/app/src/main/java/org/picketlink/as/console/application/D= evelopment.gwt.xml 2012-03-26 21:53:57 UTC (rev 1540) @@ -21,7 +21,7 @@ = = - + = Added: console/trunk/app/src/main/resources/gwt-proxy.properties =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 WITH= OUT A +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES= S 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=3Ddomain-api +service.url=3Dhttp://127.0.0.1:9990/management +service.passthrough=3Dtrue \ No newline at end of file Added: console/trunk/app/src/main/resources/logout.properties =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 WITH= OUT A +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES= S 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=3Dlogout-api +service.url=3Dhttp://127.0.0.1:9990/logout +service.passthrough=3Dtrue \ No newline at end of file Added: console/trunk/app/src/main/resources/upload-proxy.properties =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 WITH= OUT A +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES= S 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=3Ddeployment-api +service.url=3Dhttp://127.0.0.1:9990/management/add-content +service.passthrough=3Dtrue \ No newline at end of file Modified: console/trunk/app/src/main/webapp/WEB-INF/web.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- console/trunk/app/src/main/webapp/WEB-INF/web.xml 2012-03-26 20:35:04 U= TC (rev 1539) +++ console/trunk/app/src/main/webapp/WEB-INF/web.xml 2012-03-26 21:53:57 U= TC (rev 1540) @@ -1,38 +1,53 @@ - + version=3D"2.5"> = - - gwtProxy - org.jboss.as.console.server.proxy.XmlHttpProxyServl= et - - config.name - gwt-proxy.properties - - 1 - + + proxyHost + localhost + = - - uploadProxy - org.jboss.as.console.server.proxy.XmlHttpProxyServl= et - - config.name - upload-proxy.properties - - 1 - + + proxyPort + 9990 + = - - gwtProxy - /app/proxy/* - + + gwtProxy + org.jboss.as.console.server.proxy.XmlHttpProxyServlet + + config.name + gwt-proxy.properties + + 1 + = - - uploadProxy - /app/upload/* - + + uploadProxy + org.jboss.as.console.server.proxy.XmlHttpProxyServlet + + config.name + upload-proxy.properties + + 1 + = + + gwtProxy + /app/proxy/* + + + + uploadProxy + /app/upload/* + + + + --===============5698536778713525984==--