/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed 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 au.gov.ga.earthsci.worldwind.common.downloader; import gov.nasa.worldwind.retrieve.HTTPRetriever; import gov.nasa.worldwind.retrieve.RetrievalPostProcessor; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.Proxy; import java.net.ProxySelector; import java.net.URL; import java.net.URLConnection; import java.nio.ByteBuffer; import java.util.List; /** * Extension of {@link HTTPRetriever} which implements {@link ExtendedRetriever} * . * <p/> * Allows modification dates to be set on read, and uses the java * {@link ProxySelector} mechanism rather than the WWIO configuration mechanism. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) * @author James Navin (james.navin@ga.gov.au) */ public class ExtendedHTTPRetriever extends HTTPRetriever implements ExtendedRetriever { private Long ifModifiedSince; private Exception error; private boolean unzip; public ExtendedHTTPRetriever(URL url, Long ifModifiedSince, RetrievalPostProcessor postProcessor) { this(url, ifModifiedSince, postProcessor, true); } public ExtendedHTTPRetriever(URL url, Long ifModifiedSince, RetrievalPostProcessor postProcessor, boolean unzip) { super(url, postProcessor); this.ifModifiedSince = ifModifiedSince; this.unzip = unzip; } @Override protected ByteBuffer doRead(URLConnection connection) throws Exception { // Overridden to catch exceptions and set the modification date in the URLConnection if (ifModifiedSince != null) connection.setIfModifiedSince(ifModifiedSince.longValue()); try { ByteBuffer buffer = super.doRead(connection); if (buffer == null && !isOk() && !isNotModified()) { throw new HttpException(getResponseCode() + ": " + getResponseMessage(), getResponseCode()); } return buffer; } catch (Exception e) { error = e; throw e; } } @Override protected URLConnection openConnection() throws IOException { // Overridden to use the Java proxy selector mechanism rather than the World Wind WWIO configuration // This gives access to the nonProxyHosts mechanism for bypassing proxies for internal addresses // Falls back to the original behaviour if the proxy selector mechanism fails try { List<Proxy> proxies = ProxySelector.getDefault().select(url.toURI()); this.connection = this.url.openConnection(proxies.get(0)); this.connection.setConnectTimeout(this.connectTimeout); this.connection.setReadTimeout(this.readTimeout); return connection; } catch (Exception e) { // If the proxy selector failed, revert to superclass behaviour return super.openConnection(); } } /** * Was the response status code from the server a HTTP_OK (200)? * * @return True if the http server returned status 200 */ public boolean isOk() { return getResponseCode() == HttpURLConnection.HTTP_OK; } @Override public boolean isNotModified() { return getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED; } @Override public Exception getError() { return error; } @Override protected ByteBuffer readZipStream(InputStream inputStream, URL url) throws IOException { if (unzip) { return super.readZipStream(inputStream, url); } return readNonSpecificStream(inputStream, getConnection()); } }