org.opensaml.util.resource.HttpResource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openws Show documentation
Show all versions of openws Show documentation
The OpenWS library provides a growing set of tools to work with web services at a low level. These tools include
classes for creating and reading SOAP messages, transport-independent clients for connecting to web services,
and various transports for use with those clients.
The newest version!
/*
* Licensed to the University Corporation for Advanced Internet Development,
* Inc. (UCAID) under one or more contributor license agreements. See the
* NOTICE file distributed with this work for additional information regarding
* copyright ownership. The UCAID licenses this file to You under the Apache
* License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensaml.util.resource;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.httpclient.Header;
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.util.DateParseException;
import org.apache.commons.httpclient.util.DateUtil;
import org.joda.time.DateTime;
import org.joda.time.chrono.ISOChronology;
import org.opensaml.xml.util.DatatypeHelper;
/**
* A resource representing a file retrieved from a URL using Apache Commons HTTPClient.
*/
public class HttpResource extends AbstractFilteredResource {
/** HTTP URL of the resource. */
private String resourceUrl;
/** HTTP client. */
private HttpClient httpClient;
/**
* Constructor.
*
* @param resource HTTP(S) URL of the resource
*/
public HttpResource(String resource) {
super();
resourceUrl = DatatypeHelper.safeTrimOrNullString(resource);
if (resourceUrl == null) {
throw new IllegalArgumentException("Resource URL may not be null or empty");
}
httpClient = new HttpClient();
}
/**
* Constructor.
*
* @param resource HTTP(S) URL of the resource
* @param resourceFilter filter to apply to this resource
*
* @deprecated use {@link #setResourceFilter(ResourceFilter)} instead
*/
public HttpResource(String resource, ResourceFilter resourceFilter) {
super(resourceFilter);
resourceUrl = DatatypeHelper.safeTrimOrNullString(resource);
if (resourceUrl == null) {
throw new IllegalArgumentException("Resource URL may not be null or empty");
}
httpClient = new HttpClient();
}
/** {@inheritDoc} */
public boolean exists() throws ResourceException {
HeadMethod headMethod = new HeadMethod(resourceUrl);
headMethod.addRequestHeader("Connection", "close");
try {
httpClient.executeMethod(headMethod);
if (headMethod.getStatusCode() != HttpStatus.SC_OK) {
return false;
}
return true;
} catch (IOException e) {
throw new ResourceException("Unable to contact resource URL: " + resourceUrl, e);
} finally {
headMethod.releaseConnection();
}
}
/** {@inheritDoc} */
public InputStream getInputStream() throws ResourceException {
GetMethod getMethod = getResource();
try {
return new ConnectionClosingInputStream(getMethod, applyFilter(getMethod.getResponseBodyAsStream()));
} catch (IOException e) {
throw new ResourceException("Unable to read response", e);
}
}
/** {@inheritDoc} */
public DateTime getLastModifiedTime() throws ResourceException {
HeadMethod headMethod = new HeadMethod(resourceUrl);
headMethod.addRequestHeader("Connection", "close");
try {
httpClient.executeMethod(headMethod);
if (headMethod.getStatusCode() != HttpStatus.SC_OK) {
throw new ResourceException("Unable to retrieve resource URL " + resourceUrl
+ ", received HTTP status code " + headMethod.getStatusCode());
}
Header lastModifiedHeader = headMethod.getResponseHeader("Last-Modified");
if (lastModifiedHeader != null && !DatatypeHelper.isEmpty(lastModifiedHeader.getValue())) {
long lastModifiedTime = DateUtil.parseDate(lastModifiedHeader.getValue()).getTime();
return new DateTime(lastModifiedTime, ISOChronology.getInstanceUTC());
}
return new DateTime();
} catch (IOException e) {
throw new ResourceException("Unable to contact resource URL: " + resourceUrl, e);
} catch (DateParseException e) {
throw new ResourceException("Unable to parse last modified date for resource:" + resourceUrl, e);
} finally {
headMethod.releaseConnection();
}
}
/** {@inheritDoc} */
public String getLocation() {
return resourceUrl;
}
/** {@inheritDoc} */
public String toString() {
return getLocation();
}
/** {@inheritDoc} */
public int hashCode() {
return getLocation().hashCode();
}
/** {@inheritDoc} */
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof HttpResource) {
return getLocation().equals(((HttpResource) o).getLocation());
}
return false;
}
/**
* Gets remote resource.
*
* @return the remove resource
*
* @throws ResourceException thrown if the resource could not be fetched
*/
protected GetMethod getResource() throws ResourceException {
GetMethod getMethod = new GetMethod(resourceUrl);
getMethod.addRequestHeader("Connection", "close");
try {
httpClient.executeMethod(getMethod);
if (getMethod.getStatusCode() != HttpStatus.SC_OK) {
throw new ResourceException("Unable to retrieve resource URL " + resourceUrl
+ ", received HTTP status code " + getMethod.getStatusCode());
}
return getMethod;
} catch (IOException e) {
throw new ResourceException("Unable to contact resource URL: " + resourceUrl, e);
}
}
/**
* A wrapper around the {@link InputStream} returned by a {@link HttpMethod} that closes the stream and releases the
* HTTP connection when {@link #close()} is invoked.
*/
private static class ConnectionClosingInputStream extends InputStream {
/** HTTP method that was invoked. */
private final HttpMethod method;
/** Stream owned by the given HTTP method. */
private final InputStream stream;
/**
* Constructor.
*
* @param httpMethod HTTP method that was invoked
* @param returnedStream stream owned by the given HTTP method
*/
public ConnectionClosingInputStream(HttpMethod httpMethod, InputStream returnedStream) {
method = httpMethod;
stream = returnedStream;
}
/** {@inheritDoc} */
public int available() throws IOException {
return stream.available();
}
/** {@inheritDoc} */
public void close() throws IOException {
stream.close();
method.releaseConnection();
}
/** {@inheritDoc} */
public void mark(int readLimit) {
stream.mark(readLimit);
}
/** {@inheritDoc} */
public boolean markSupported() {
return stream.markSupported();
}
/** {@inheritDoc} */
public int read() throws IOException {
return stream.read();
}
/** {@inheritDoc} */
public int read(byte[] b) throws IOException {
return stream.read(b);
}
/** {@inheritDoc} */
public int read(byte[] b, int off, int len) throws IOException {
return stream.read(b, off, len);
}
/** {@inheritDoc} */
public synchronized void reset() throws IOException {
stream.reset();
}
/** {@inheritDoc} */
public long skip(long n) throws IOException {
return stream.skip(n);
}
}
}