content: package tim.prune.function.srtm;
  
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.URL;
  
  
  /**
   * High-resolution Srtm source, using 1-arcsecond data
   * instead of the low-resolution 3-arcsecond data
   * @author fperrin, activityworkshop
   */
  public class SrtmHighResSource extends SrtmSource
  {
  	/** Flag set to false if auth fails */
  	private boolean _enabled = true;
  	/** Auth string */
  	private final String _authString;
  
  	/** URL prefix for all tiles */
  	private static final String URL_PREFIX = "https://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11/";
  	/** Auth URL */
  	private static final String AUTH_HOST = "urs.earthdata.nasa.gov";
  
  	private static final int HTTP_CODE_OK = 200;
  	private static final int HTTP_CODE_REDIRECT = 302;
  	private static final int HTTP_CODE_NOTFOUND = 404;
  
  
  	/**
  	 * @param inDiskPath disk path, if any
  	 * @param inAuthString authentication string
  	 */
  	SrtmHighResSource(String inDiskPath, String inAuthString)
  	{
  		super(inDiskPath);
  		_authString = inAuthString;
  	}
  
  	@Override
  	public int getTilePixels() {
  		return 3601;
  	}
  
  	/**
  	 * @return the Url for the given tile
  	 */
  	@Override
  	public URL getUrl(SrtmTile inTile)
  	{
  		URL url = null;
  		try {
  			url = new URL(URL_PREFIX + getFilename(inTile));
  		} catch (MalformedURLException e) {} // ignore error, url stays null
  		return url;
  	}
  
  	@Override
  	public Result downloadTile(SrtmTile inTile) throws SrtmAuthException
  	{
  		final String authString = getAuthString();
  		if (authString == null || !_enabled) {return Result.NOT_ENABLED;}
  		try
  		{
  			// Retrieve a stream for the resource
  			URL url = getUrl(inTile);
  			InputStream inStream = getResource(url, authString);
  			if (writeFileFromStream(url, inStream)) {
  				return Result.DOWNLOADED;
  			}
  		}
  		catch (SrtmAuthException authExc)
  		{
  			_enabled = false;
  			throw authExc;
  		}
  		catch (Exception e) {}
  		return Result.DOWNLOAD_FAILED;
  	}
  
  	@Override
  	public String getFilename(SrtmTile inTile)
  	{
  		return inTile.getTileName() + ".SRTMGL1.hgt.zip";
  	}
  
  	/**
  	 * @return auth string, if possible
  	 */
  	private String getAuthString()
  	{
  		if (_authString == null) {
  			return null;
  		}
  		return "Basic " + _authString;
  	}
  
  	/**
  	 * Returns an input stream for a designated resource on a URS
  	 * authenticated remote server.
  	 * @param resourceUrl url to get
  	 * @param inAuthString username/password from config
  	 */
  	private static InputStream getResource(URL resourceUrl, String inAuthString)
  		throws Exception
  	{
  		// Method provided by:
  		//   https://wiki.earthdata.nasa.gov/display/EL/How+To+Access+Data+With+Java
  		int redirects = 0;
  		URL url = resourceUrl;
  		// Place an upper limit on the number of redirects we will follow
  		while( redirects < 10 )
  		{
  			++redirects;
  
  			// Configure a connection to the resource server and submit the
  			// request for our resource.
  			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  			connection.setRequestMethod("GET");
  			connection.setInstanceFollowRedirects(false);
  			connection.setUseCaches(false);
  			connection.setDoInput(true);
  
  			// If this is the URS server, add in the authentication header.
  			if (url.getHost().startsWith(AUTH_HOST))
  			{
  				connection.setDoOutput(true);
  				connection.setRequestProperty("Authorization", inAuthString);
  			}
  
  			// Execute the request and get the response status code.
  			int status = connection.getResponseCode();
  			if (status == HTTP_CODE_OK)
  			{
  				// OK means that we have got our resource
  				return connection.getInputStream();
  			}
  
  			if (status == HTTP_CODE_REDIRECT)
  			{
  				// 302 is a redirect, so we go round the loop again.
  				url = new URL(connection.getHeaderField("Location"));
  			}
  			else if (status == HTTP_CODE_NOTFOUND) {
  				throw new Exception("SRTM file not found");
  			}
  			else {
  				throw new SrtmAuthException(status);
  			}
  		}
  
  		// If we get here, we exceeded our redirect limit
  		throw new Exception("Redirection limit exceeded");
  	}
  }
  