0N/A/*
0N/A * reserved comment block
0N/A * DO NOT REMOVE OR ALTER!
0N/A */
0N/A/*
0N/A * Copyright 1999-2004 The Apache Software Foundation.
0N/A *
0N/A * Licensed under the Apache License, Version 2.0 (the "License");
0N/A * you may not use this file except in compliance with the License.
0N/A * You may obtain a copy of the License at
0N/A *
0N/A * http://www.apache.org/licenses/LICENSE-2.0
0N/A *
0N/A * Unless required by applicable law or agreed to in writing, software
0N/A * distributed under the License is distributed on an "AS IS" BASIS,
0N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0N/A * See the License for the specific language governing permissions and
0N/A * limitations under the License.
0N/A *
0N/A */
0N/Apackage com.sun.org.apache.xml.internal.security.utils.resolver.implementations;
0N/A
0N/Aimport java.io.ByteArrayOutputStream;
0N/Aimport java.io.IOException;
0N/Aimport java.io.InputStream;
0N/Aimport java.net.MalformedURLException;
0N/Aimport java.net.URL;
0N/Aimport java.net.URLConnection;
0N/A
0N/Aimport com.sun.org.apache.xml.internal.utils.URI;
0N/Aimport com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.Base64;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
0N/Aimport org.w3c.dom.Attr;
0N/A
0N/A
0N/A/**
0N/A * A simple ResourceResolver for HTTP requests. This class handles only 'pure'
0N/A * HTTP URIs which means without a fragment. The Fragment handling is done by the
0N/A * {@link ResolverFragment} class.
0N/A * <BR>
0N/A * If the user has a corporate HTTP proxy which is to be used, the usage can be
0N/A * switched on by setting properties for the resolver:
0N/A * <PRE>
0N/A * resourceResolver.setProperty("http.proxy.host", "proxy.company.com");
0N/A * resourceResolver.setProperty("http.proxy.port", "8080");
0N/A *
0N/A * // if we need a password for the proxy
0N/A * resourceResolver.setProperty("http.proxy.username", "proxyuser3");
0N/A * resourceResolver.setProperty("http.proxy.password", "secretca");
0N/A * </PRE>
0N/A *
0N/A *
0N/A * @author $Author: mullan $
0N/A * @see <A HREF="http://www.javaworld.com/javaworld/javatips/jw-javatip42_p.html">Java Tip 42: Write Java apps that work with proxy-based firewalls</A>
0N/A * @see <A HREF="http://java.sun.com/j2se/1.4/docs/guide/net/properties.html">SUN J2SE docs for network properties</A>
0N/A * @see <A HREF="http://metalab.unc.edu/javafaq/javafaq.html#proxy">The JAVA FAQ Question 9.5: How do I make Java work with a proxy server?</A>
0N/A * $todo$ the proxy behaviour seems not to work; if a on-existing proxy is set, it works ?!?
0N/A */
0N/Apublic class ResolverDirectHTTP extends ResourceResolverSpi {
0N/A
0N/A /** {@link java.util.logging} logging facility */
0N/A static java.util.logging.Logger log =
0N/A java.util.logging.Logger.getLogger(
0N/A ResolverDirectHTTP.class.getName());
0N/A
0N/A /** Field properties[] */
661N/A private static final String properties[] =
661N/A { "http.proxy.host", "http.proxy.port",
661N/A "http.proxy.username",
661N/A "http.proxy.password",
661N/A "http.basic.username",
661N/A "http.basic.password" };
0N/A
0N/A /** Field HttpProxyHost */
0N/A private static final int HttpProxyHost = 0;
0N/A
0N/A /** Field HttpProxyPort */
0N/A private static final int HttpProxyPort = 1;
0N/A
0N/A /** Field HttpProxyUser */
0N/A private static final int HttpProxyUser = 2;
0N/A
0N/A /** Field HttpProxyPass */
0N/A private static final int HttpProxyPass = 3;
0N/A
0N/A /** Field HttpProxyUser */
0N/A private static final int HttpBasicUser = 4;
0N/A
0N/A /** Field HttpProxyPass */
0N/A private static final int HttpBasicPass = 5;
0N/A
661N/A public boolean engineIsThreadSafe() {
661N/A return true;
661N/A }
0N/A /**
0N/A * Method resolve
0N/A *
0N/A * @param uri
0N/A * @param BaseURI
0N/A *
0N/A * @throws ResourceResolverException
0N/A * @return
0N/A * $todo$ calculate the correct URI from the attribute and the BaseURI
0N/A */
0N/A public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
0N/A throws ResourceResolverException {
0N/A
0N/A try {
0N/A boolean useProxy = false;
0N/A String proxyHost =
0N/A engineGetProperty(ResolverDirectHTTP
0N/A .properties[ResolverDirectHTTP.HttpProxyHost]);
0N/A String proxyPort =
0N/A engineGetProperty(ResolverDirectHTTP
0N/A .properties[ResolverDirectHTTP.HttpProxyPort]);
0N/A
0N/A if ((proxyHost != null) && (proxyPort != null)) {
0N/A useProxy = true;
0N/A }
0N/A
0N/A String oldProxySet = null;
0N/A String oldProxyHost = null;
0N/A String oldProxyPort = null;
661N/A // switch on proxy usage
0N/A if (useProxy) {
0N/A if (log.isLoggable(java.util.logging.Level.FINE)) {
661N/A log.log(java.util.logging.Level.FINE, "Use of HTTP proxy enabled: " + proxyHost + ":"
661N/A + proxyPort);
0N/A }
0N/A oldProxySet = System.getProperty("http.proxySet");
0N/A oldProxyHost = System.getProperty("http.proxyHost");
0N/A oldProxyPort = System.getProperty("http.proxyPort");
0N/A System.setProperty("http.proxySet", "true");
0N/A System.setProperty("http.proxyHost", proxyHost);
0N/A System.setProperty("http.proxyPort", proxyPort);
0N/A }
0N/A
0N/A boolean switchBackProxy = ((oldProxySet != null)
0N/A && (oldProxyHost != null)
0N/A && (oldProxyPort != null));
0N/A
0N/A // calculate new URI
0N/A URI uriNew = getNewURI(uri.getNodeValue(), BaseURI);
0N/A
0N/A // if the URI contains a fragment, ignore it
0N/A URI uriNewNoFrag = new URI(uriNew);
0N/A
0N/A uriNewNoFrag.setFragment(null);
0N/A
0N/A URL url = new URL(uriNewNoFrag.toString());
0N/A URLConnection urlConnection = url.openConnection();
0N/A
0N/A {
0N/A
0N/A // set proxy pass
0N/A String proxyUser =
0N/A engineGetProperty(ResolverDirectHTTP
0N/A .properties[ResolverDirectHTTP.HttpProxyUser]);
0N/A String proxyPass =
0N/A engineGetProperty(ResolverDirectHTTP
0N/A .properties[ResolverDirectHTTP.HttpProxyPass]);
0N/A
0N/A if ((proxyUser != null) && (proxyPass != null)) {
0N/A String password = proxyUser + ":" + proxyPass;
0N/A String encodedPassword = Base64.encode(password.getBytes());
0N/A
0N/A // or was it Proxy-Authenticate ?
0N/A urlConnection.setRequestProperty("Proxy-Authorization",
0N/A encodedPassword);
0N/A }
0N/A }
0N/A
0N/A {
0N/A
0N/A // check if Basic authentication is required
0N/A String auth = urlConnection.getHeaderField("WWW-Authenticate");
0N/A
0N/A if (auth != null) {
0N/A
0N/A // do http basic authentication
0N/A if (auth.startsWith("Basic")) {
0N/A String user =
0N/A engineGetProperty(ResolverDirectHTTP
0N/A .properties[ResolverDirectHTTP.HttpBasicUser]);
0N/A String pass =
0N/A engineGetProperty(ResolverDirectHTTP
0N/A .properties[ResolverDirectHTTP.HttpBasicPass]);
0N/A
0N/A if ((user != null) && (pass != null)) {
0N/A urlConnection = url.openConnection();
0N/A
0N/A String password = user + ":" + pass;
0N/A String encodedPassword =
0N/A Base64.encode(password.getBytes());
0N/A
0N/A // set authentication property in the http header
0N/A urlConnection.setRequestProperty("Authorization",
0N/A "Basic "
0N/A + encodedPassword);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A String mimeType = urlConnection.getHeaderField("Content-Type");
0N/A InputStream inputStream = urlConnection.getInputStream();
0N/A ByteArrayOutputStream baos = new ByteArrayOutputStream();
0N/A byte buf[] = new byte[4096];
0N/A int read = 0;
0N/A int summarized = 0;
0N/A
0N/A while ((read = inputStream.read(buf)) >= 0) {
0N/A baos.write(buf, 0, read);
0N/A
0N/A summarized += read;
0N/A }
0N/A
661N/A log.log(java.util.logging.Level.FINE, "Fetched " + summarized + " bytes from URI "
661N/A + uriNew.toString());
0N/A
0N/A XMLSignatureInput result = new XMLSignatureInput(baos.toByteArray());
0N/A
0N/A // XMLSignatureInput result = new XMLSignatureInput(inputStream);
0N/A result.setSourceURI(uriNew.toString());
0N/A result.setMIMEType(mimeType);
0N/A
0N/A // switch off proxy usage
0N/A if (useProxy && switchBackProxy) {
0N/A System.setProperty("http.proxySet", oldProxySet);
0N/A System.setProperty("http.proxyHost", oldProxyHost);
0N/A System.setProperty("http.proxyPort", oldProxyPort);
0N/A }
0N/A
0N/A return result;
0N/A } catch (MalformedURLException ex) {
0N/A throw new ResourceResolverException("generic.EmptyMessage", ex, uri,
0N/A BaseURI);
0N/A } catch (IOException ex) {
0N/A throw new ResourceResolverException("generic.EmptyMessage", ex, uri,
0N/A BaseURI);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * We resolve http URIs <I>without</I> fragment...
0N/A *
0N/A * @param uri
0N/A * @param BaseURI
0N/A * @return true if can be resolved
0N/A */
0N/A public boolean engineCanResolve(Attr uri, String BaseURI) {
0N/A if (uri == null) {
661N/A log.log(java.util.logging.Level.FINE, "quick fail, uri == null");
661N/A
0N/A return false;
0N/A }
0N/A
0N/A String uriNodeValue = uri.getNodeValue();
0N/A
0N/A if (uriNodeValue.equals("") || (uriNodeValue.charAt(0)=='#')) {
661N/A log.log(java.util.logging.Level.FINE, "quick fail for empty URIs and local ones");
661N/A
0N/A return false;
0N/A }
0N/A
0N/A if (log.isLoggable(java.util.logging.Level.FINE)) {
661N/A log.log(java.util.logging.Level.FINE, "I was asked whether I can resolve " + uriNodeValue);
0N/A }
661N/A
0N/A if ( uriNodeValue.startsWith("http:") ||
661N/A (BaseURI!=null && BaseURI.startsWith("http:") )) {
0N/A if (log.isLoggable(java.util.logging.Level.FINE)) {
661N/A log.log(java.util.logging.Level.FINE, "I state that I can resolve " + uriNodeValue);
0N/A }
661N/A
0N/A return true;
0N/A }
0N/A
0N/A if (log.isLoggable(java.util.logging.Level.FINE)) {
661N/A log.log(java.util.logging.Level.FINE, "I state that I can't resolve " + uriNodeValue);
0N/A }
661N/A
0N/A return false;
0N/A }
0N/A
0N/A /**
0N/A * @inheritDoc
0N/A */
0N/A public String[] engineGetPropertyKeys() {
0N/A return (String[]) ResolverDirectHTTP.properties.clone();
0N/A }
0N/A
0N/A private URI getNewURI(String uri, String BaseURI)
0N/A throws URI.MalformedURIException {
0N/A
0N/A if ((BaseURI == null) || "".equals(BaseURI)) {
0N/A return new URI(uri);
0N/A }
0N/A return new URI(new URI(BaseURI), uri);
0N/A }
0N/A}