/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package fedora.server.security.servletfilters.pubcookie; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.Map; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Node; import org.w3c.tidy.Tidy; //import fedora.server.security.servletfilters.HttpTidyConnect; /** * @author Bill Niebel */ public class ConnectPubcookie { private final Log log = LogFactory.getLog(ConnectPubcookie.class); private boolean completedFully = false; private Node responseDocument = null; private Cookie[] responseCookies = null; Header[] responseCookies2 = null; public final boolean completedFully() { return completedFully; } public final Node getResponseDocument() { return responseDocument; } public final Cookie[] getResponseCookies() { log.debug(this.getClass().getName() + ".getResponseCookies() " + "cookies are:"); for (Cookie element : responseCookies) { log.debug(this.getClass().getName() + ".getResponseCookies() " + "cookie==" + element); } return responseCookies; } private static final HttpMethodBase setup(HttpClient client, URL url, Map requestParameters, Cookie[] requestCookies) { LogFactory.getLog(ConnectPubcookie.class).debug(ConnectPubcookie.class .getName() + ".setup()"); HttpMethodBase method = null; if (requestParameters == null) { LogFactory.getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " requestParameters == null"); method = new GetMethod(url.toExternalForm()); //GetMethod is superclass to ExpectContinueMethod, so we don't require method.setUseExpectHeader(false); LogFactory.getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " after getting method"); } else { LogFactory.getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " requestParameters != null"); method = new PostMethod(url.toExternalForm()); // "http://localhost:8080/" LogFactory.getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " after getting method"); //XXX method.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false); //new way //XXX method.getParams().setIntParameter(HttpMethodParams.SO_TIMEOUT, 10000); //XXX method.getParams().setVersion(HttpVersion.HTTP_0_9); //or HttpVersion.HTTP_1_0 HttpVersion.HTTP_1_1 LogFactory.getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " after setting USE_EXPECT_CONTINUE"); //PostMethod is subclass of ExpectContinueMethod, so we require here: //((PostMethod)method).setUseExpectHeader(false); //client.setTimeout(30000); // increased from 10000 as temp fix; 2005-03-17 wdn5e //HttpClientParams httpClientParams = new HttpClientParams(); //httpClientParams.setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, true); //old way //httpClientParams.setIntParameter(HttpMethodParams.SO_TIMEOUT, 30000); LogFactory .getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " A"); Part[] parts = new Part[requestParameters.size()]; Iterator iterator = requestParameters.keySet().iterator(); for (int i = 0; iterator.hasNext(); i++) { String fieldName = (String) iterator.next(); String fieldValue = (String) requestParameters.get(fieldName); StringPart stringPart = new StringPart(fieldName, fieldValue); parts[i] = stringPart; LogFactory.getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " part[" + i + "]==" + fieldName + "=" + fieldValue); ((PostMethod) method).addParameter(fieldName, fieldValue); //old way } LogFactory .getLog(ConnectPubcookie.class) .debug(ConnectPubcookie.class.getName() + ".setup()" + " B"); //XXX MultipartRequestEntity multipartRequestEntity = new MultipartRequestEntity(parts, method.getParams()); // ((PostMethod)method).setRequestEntity(multipartRequestEntity); //new way } //method.getParams().setCookiePolicy(CookiePolicy.RFC_2109); HttpState state = client.getState(); for (Cookie cookie : requestCookies) { state.addCookie(cookie); } //method.setFollowRedirects(true); this is disallowed at runtime, so redirect won't be honored LogFactory.getLog(ConnectPubcookie.class).debug(ConnectPubcookie.class .getName() + ".setup()" + " C"); LogFactory.getLog(ConnectPubcookie.class).debug(ConnectPubcookie.class .getName() + ".setup()" + " method==" + method); LogFactory.getLog(ConnectPubcookie.class).debug(ConnectPubcookie.class .getName() + ".setup()" + " method==" + method.toString()); return method; } public final void connect(String urlString, Map requestParameters, Cookie[] requestCookies, String truststoreLocation, String truststorePassword) { log.debug(this.getClass().getName() + ".connect() " + " url==" + urlString + " requestParameters==" + requestParameters + " requestCookies==" + requestCookies); responseCookies2 = null; URL url = null; try { url = new URL(urlString); } catch (MalformedURLException mue) { log.error(this.getClass().getName() + ".connect() " + "bad configured url==" + urlString); } if (urlString.startsWith("https:") && null != truststoreLocation && !"".equals(truststoreLocation) && null != truststorePassword && !"".equals(truststorePassword)) { log.debug("setting " + FilterPubcookie.TRUSTSTORE_LOCATION_KEY + " to " + truststoreLocation); System.setProperty(FilterPubcookie.TRUSTSTORE_LOCATION_KEY, truststoreLocation); log.debug("setting " + FilterPubcookie.TRUSTSTORE_PASSWORD_KEY + " to " + truststorePassword); System.setProperty(FilterPubcookie.TRUSTSTORE_PASSWORD_KEY, truststorePassword); log.debug("setting " + FilterPubcookie.KEYSTORE_LOCATION_KEY + " to " + truststoreLocation); System.setProperty(FilterPubcookie.KEYSTORE_LOCATION_KEY, truststoreLocation); log.debug("setting " + FilterPubcookie.KEYSTORE_PASSWORD_KEY + " to " + truststorePassword); System.setProperty(FilterPubcookie.KEYSTORE_PASSWORD_KEY, truststorePassword); System.setProperty("javax.net.debug", "ssl,handshake,data,trustmanager"); } else { log.debug("DIAGNOSTIC urlString==" + urlString); log.debug("didn't set " + FilterPubcookie.TRUSTSTORE_LOCATION_KEY + " to " + truststoreLocation); log.debug("didn't set " + FilterPubcookie.TRUSTSTORE_PASSWORD_KEY + " to " + truststorePassword); } /* * log.debug("\n-a-"); Protocol easyhttps = null; try { easyhttps = new * Protocol("https", (ProtocolSocketFactory) new * EasySSLProtocolSocketFactory(), 443); } catch (Throwable t) { * log.debug(t); log.debug(t.getMessage()); if (t.getCause() != null) * log.debug(t.getCause().getMessage()); } log.debug("\n-b-"); * Protocol.registerProtocol("https", easyhttps); log.debug("\n-c-"); */ HttpClient client = new HttpClient(); log.debug(this.getClass().getName() + ".connect() " + " b4 calling setup"); log.debug(this.getClass().getName() + ".connect() requestCookies==" + requestCookies); HttpMethodBase method = setup(client, url, requestParameters, requestCookies); log.debug(this.getClass().getName() + ".connect() " + " after calling setup"); int statusCode = 0; try { log.debug(this.getClass().getName() + ".connect() " + " b4 calling executeMethod"); client.executeMethod(method); log.debug(this.getClass().getName() + ".connect() " + " after calling executeMethod"); statusCode = method.getStatusCode(); log.debug(this.getClass().getName() + ".connect() " + "(with configured url) statusCode==" + statusCode); } catch (Exception e) { log.error(this.getClass().getName() + ".connect() " + "failed original connect, url==" + urlString); log.error(e); log.error(e.getMessage()); if (e.getCause() != null) { log.error(e.getCause().getMessage()); } e.printStackTrace(); } log.debug(this.getClass().getName() + ".connect() " + " status code==" + statusCode); if (302 == statusCode) { Header redirectHeader = method.getResponseHeader("Location"); if (redirectHeader != null) { String redirectString = redirectHeader.getValue(); if (redirectString != null) { URL redirectURL = null; try { redirectURL = new URL(redirectString); method = setup(client, redirectURL, requestParameters, requestCookies); } catch (MalformedURLException mue) { log.error(this.getClass().getName() + ".connect() " + "bad redirect, url==" + urlString); } statusCode = 0; try { client.executeMethod(method); statusCode = method.getStatusCode(); log.debug(this.getClass().getName() + ".connect() " + "(on redirect) statusCode==" + statusCode); } catch (Exception e) { log.error(this.getClass().getName() + ".connect() " + "failed redirect connect"); } } } } if (statusCode == 200) { // this is either the original, non-302, status code or the status code after redirect log.debug(this.getClass().getName() + ".connect() " + "status code 200"); String content = null; try { log.debug(this.getClass().getName() + ".connect() " + "b4 gRBAS()"); content = method.getResponseBodyAsString(); log.debug(this.getClass().getName() + ".connect() " + "after gRBAS() content==" + content); } catch (IOException e) { log.error(this.getClass().getName() + ".connect() " + "couldn't get content"); return; } if (content == null) { log.error(this.getClass().getName() + ".connect() content==null"); return; } else { log.debug(this.getClass().getName() + ".connect() content != null, about to new Tidy"); Tidy tidy = null; try { tidy = new Tidy(); } catch (Throwable t) { log.debug("new Tidy didn't"); log.debug(t); log.debug(t.getMessage()); if (t != null) { log.debug(t.getCause().getMessage()); } } log.debug(this.getClass().getName() + ".connect() after newing Tidy, tidy==" + tidy); byte[] inputBytes = content.getBytes(); log.debug(this.getClass().getName() + ".connect() A1"); ByteArrayInputStream inputStream = new ByteArrayInputStream(inputBytes); log.debug(this.getClass().getName() + ".connect() A2"); responseDocument = tidy.parseDOM(inputStream, null); //use returned root node as only output log.debug(this.getClass().getName() + ".connect() A3"); } log.debug(this.getClass().getName() + ".connect() " + "b4 getState()"); HttpState state = client.getState(); log.debug(this.getClass().getName() + ".connect() state==" + state); try { responseCookies2 = method.getRequestHeaders(); log.debug(this.getClass().getName() + ".connect() just got headers"); for (Header element : responseCookies2) { log.debug(this.getClass().getName() + ".connect() header==" + element); } responseCookies = state.getCookies(); log.debug(this.getClass().getName() + ".connect() responseCookies==" + responseCookies); } catch (Throwable t) { log.error(this.getClass().getName() + ".connect() exception==" + t.getMessage()); if (t.getCause() != null) { log.error(this.getClass().getName() + ".connect() cause==" + t.getCause().getMessage()); } } completedFully = true; log.debug(this.getClass().getName() + ".connect() completedFully==" + completedFully); } } }