/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.security.handler; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.HeadMethod; import org.apache.commons.httpclient.methods.InputStreamRequestEntity; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import java.io.*; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.InputStream; import java.io.Reader; import java.net.BindException; import java.net.URL; import java.util.HashMap; import java.util.Map.Entry; import de.cismet.commons.security.AccessHandler.ACCESS_HANDLER_TYPES; import de.cismet.commons.security.AccessHandler.ACCESS_METHODS; import de.cismet.commons.security.Tunnel; import de.cismet.commons.security.TunnelStore; import de.cismet.commons.security.exceptions.BadHttpStatusCodeException; import de.cismet.commons.security.exceptions.CannotReadFromURLException; /** * DOCUMENT ME! * * @author spuhl, thorsten * @version $Revision$, $Date$ */ public class DefaultHTTPAccessHandler extends HTTPBasedAccessHandler implements TunnelStore { //~ Static fields/initializers --------------------------------------------- public static ACCESS_METHODS[] SUPPORTED_ACCESS_METHODS = new ACCESS_METHODS[] { ACCESS_METHODS.GET_REQUEST, ACCESS_METHODS.POST_REQUEST }; public static final ACCESS_HANDLER_TYPES ACCESS_HANDLER_TYPE = ACCESS_HANDLER_TYPES.HTTP; //~ Instance fields -------------------------------------------------------- private final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(this.getClass()); private Tunnel tunnel = null; //~ Methods ---------------------------------------------------------------- @Override public InputStream doRequest(final URL url, final Reader requestParameter, final ACCESS_METHODS method, final HashMap<String, String> options) throws Exception { final HttpClient client = getSecurityEnabledHttpClient(url); final StringBuilder parameter = new StringBuilder(); final BufferedReader reader = new BufferedReader(requestParameter); String currentLine; while ((currentLine = reader.readLine()) != null) { parameter.append(currentLine); } HttpMethod httpMethod; if (log.isDebugEnabled()) { log.debug("Access method: '" + method + "'."); // NOI18N } if ((tunnel != null) && ((method == ACCESS_METHODS.GET_REQUEST) || (method == ACCESS_METHODS.POST_REQUEST) || (method == ACCESS_METHODS.HEAD_REQUEST)) && tunnel.isResponsible(method, url.toString())) { return tunnel.doRequest(url, new StringReader(parameter.toString()), method, options); } else { switch (method) { case POST_REQUEST_NO_TUNNEL: case POST_REQUEST: { httpMethod = new PostMethod(url.toString()); ((PostMethod)httpMethod).setRequestEntity(new StringRequestEntity( parameter.toString(), "text/xml", "UTF-8")); // NOI18N break; } case GET_REQUEST_NO_TUNNEL: case GET_REQUEST: { if (parameter.length() > 0) { if (log.isDebugEnabled()) { log.debug("HTTP GET: '" + url.toString() + "?" + parameter + "'."); // NOI18N } httpMethod = new GetMethod(url.toString() + "?" + parameter); // NOI18N } else { if (log.isDebugEnabled()) { log.debug("No parameters specified. HTTP GET: '" + url.toString() + "'."); // NOI18N } httpMethod = new GetMethod(url.toString()); } break; } case HEAD_REQUEST_NO_TUNNEL: case HEAD_REQUEST: { if (parameter.length() > 0) { if (log.isDebugEnabled()) { log.debug("HTTP HEAD: '" + url.toString() + "?" + parameter + "'."); // NOI18N } httpMethod = new HeadMethod(url.toString() + "?" + parameter); // NOI18N } else { if (log.isDebugEnabled()) { log.debug("No parameters specified. HTTP HEAD: '" + url.toString() + "'."); // NOI18N } httpMethod = new HeadMethod(url.toString()); } break; } default: { if (parameter.length() > 0) { if (log.isDebugEnabled()) { log.debug("No method specified, switching to '" + ACCESS_METHODS.GET_REQUEST + "'. URI used: '" + url.toString() + "?" + parameter + "'."); // NOI18N } // httpMethod = new PostMethod(url.toString()); ((PostMethod) httpMethod).setRequestEntity(new // StringRequestEntity(parameter.toString(), "text/xml", "UTF-8")); httpMethod = new GetMethod(url.toString() + "?" + parameter); // NOI18N } else { if (log.isDebugEnabled()) { log.debug("No method specified, switching to '" + ACCESS_METHODS.GET_REQUEST + "'. No parameters specified. URI used: '" + url.toString() + "'."); // NOI18N } httpMethod = new GetMethod(url.toString()); } } } if ((options != null) && !options.isEmpty()) { for (final Entry<String, String> option : options.entrySet()) { httpMethod.addRequestHeader(option.getKey(), option.getValue()); } } final boolean hasBound = false; while (!hasBound) { try { httpMethod.setDoAuthentication(true); final int statuscode = client.executeMethod(httpMethod); switch (statuscode) { case (HttpStatus.SC_UNAUTHORIZED): { if (log.isInfoEnabled()) { log.info("HTTP status code from server: SC_UNAUTHORIZED (" + HttpStatus.SC_UNAUTHORIZED + ")."); // NOI18N } throw new CannotReadFromURLException("You are not authorized to access this URL."); // NOI18N } case (HttpStatus.SC_OK): { if (log.isDebugEnabled()) { log.debug("HTTP status code from server: OK."); // NOI18N } if ((method == ACCESS_METHODS.HEAD_REQUEST) || (method == ACCESS_METHODS.HEAD_REQUEST_NO_TUNNEL)) { // returning the HTTP Header as InputStream, because some valid InputStream has to be // returned. The HTTP body can not be returned because it does not exist for HEAD // requests. final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(httpMethod.getRequestHeaders()); oos.flush(); oos.close(); final InputStream is = new ByteArrayInputStream(baos.toByteArray()); baos.close(); return is; } else { return new BufferedInputStream(httpMethod.getResponseBodyAsStream()); } } default: { if (log.isDebugEnabled()) { log.debug("Unhandled HTTP status code: " + statuscode + " (" + HttpStatus.getStatusText(statuscode) + ")"); // NOI18N } throw new BadHttpStatusCodeException(httpMethod.getURI().toString(), statuscode, HttpStatus.getStatusText(statuscode), httpMethod.getResponseBodyAsString()); // NOI18N } } } catch (BindException e) { if (log.isDebugEnabled()) { log.debug("Catched Bind Exception. Will try again in 50 ms", e); } Thread.sleep(50); } } } // throw new RuntimeException("Should never happen"); } @Override public InputStream doRequest(final URL url, final InputStream requestParameter, final HashMap<String, String> options) throws Exception { final HttpClient client = getSecurityEnabledHttpClient(url); final PostMethod postMethod = new PostMethod(url.toString()); log.fatal("request2", new Exception()); postMethod.setRequestEntity(new InputStreamRequestEntity(requestParameter)); if ((options != null) && !options.isEmpty()) { for (final Entry<String, String> option : options.entrySet()) { postMethod.addRequestHeader(option.getKey(), option.getValue()); } } boolean hasBound = false; while (!hasBound) { try { postMethod.setDoAuthentication(true); final int statuscode = client.executeMethod(postMethod); hasBound = true; switch (statuscode) { case (HttpStatus.SC_UNAUTHORIZED): { if (log.isInfoEnabled()) { log.info("HTTP status code from server: SC_UNAUTHORIZED (" + HttpStatus.SC_UNAUTHORIZED + ")."); // NOI18N } throw new CannotReadFromURLException("You are not authorized to access this URL."); // NOI18N } case (HttpStatus.SC_OK): { if (log.isDebugEnabled()) { log.debug("HTTP status code from server: OK."); // NOI18N } return new BufferedInputStream(postMethod.getResponseBodyAsStream()); } default: { if (log.isDebugEnabled()) { log.debug("Unhandled HTTP status code: " + statuscode + " (" + HttpStatus.getStatusText(statuscode) + ")."); // NOI18N } throw new BadHttpStatusCodeException(postMethod.getURI().toString(), statuscode, HttpStatus.getStatusText(statuscode), postMethod.getResponseBodyAsString()); // NOI18N } } } catch (BindException e) { if (log.isDebugEnabled()) { log.debug("Catched Bind Exception. Will try again in 50 ms", e); } Thread.sleep(50); } } throw new RuntimeException("Should never happen"); } @Override public boolean isAccessMethodSupported(final ACCESS_METHODS method) { for (final ACCESS_METHODS curMethod : SUPPORTED_ACCESS_METHODS) { if (curMethod == method) { return true; } } return false; } @Override public ACCESS_HANDLER_TYPES getHandlerType() { return ACCESS_HANDLER_TYPE; } @Override public Tunnel getTunnel() { return tunnel; } @Override public void setTunnel(final Tunnel tunnel) { this.tunnel = tunnel; } }