Blob Blame History Raw
diff -Nru thredds-4.3.18/cdm/pom.xml thredds-4.3.18-gil/cdm/pom.xml
--- thredds-4.3.18/cdm/pom.xml	2013-09-16 07:46:40.731501204 +0200
+++ thredds-4.3.18-gil/cdm/pom.xml	2013-09-16 07:48:00.294303813 +0200
@@ -36,8 +36,16 @@
 
     <!-- HTTP client -->
     <dependency>
-      <groupId>commons-httpclient</groupId>
-      <artifactId>commons-httpclient</artifactId>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpmime</artifactId>
     </dependency>
 
     <dependency>  <!-- replace commons-logging -->
diff -Nru thredds-4.3.18/cdm/src/main/java/thredds/util/HttpUriResolver.java thredds-4.3.18-gil/cdm/src/main/java/thredds/util/HttpUriResolver.java
--- thredds-4.3.18/cdm/src/main/java/thredds/util/HttpUriResolver.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/thredds/util/HttpUriResolver.java	2013-09-16 06:58:52.563136337 +0200
@@ -1,181 +1,179 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-package thredds.util;
-
-import ucar.nc2.util.net.HTTPException;
-import ucar.nc2.util.net.HTTPMethod;
-import ucar.nc2.util.net.HTTPSession;
-import org.apache.commons.httpclient.Header;
-
-import java.io.*;
-import java.net.URI;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.InflaterInputStream;
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * _more_
- *
- * @author edavis
- * @since 4.0
- */
-public class HttpUriResolver
-{
-  private org.slf4j.Logger logger =
-          org.slf4j.LoggerFactory.getLogger( HttpUriResolver.class );
-
-  private URI uri;
-  private int connectionTimeout;
-  private int socketTimeout;
-  private String contentEncoding = "gzip,deflate";
-  private boolean allowContentEncoding;
-  private boolean followRedirects;
-
-  private HTTPMethod method = null;
-  private Map<String,String> respHeaders;
-
-  HttpUriResolver( URI uri, int connectionTimeout, int socketTimeout,
-                          boolean allowContentEncoding,
-                          boolean followRedirects )
-  {
-    if ( ! uri.getScheme().equalsIgnoreCase( "http" ) )
-      throw new IllegalArgumentException( "Given a Non-HTTP URI [" + uri.toString() + "].");
-
-    this.uri = uri;
-    this.connectionTimeout = connectionTimeout;
-    this.socketTimeout = socketTimeout;
-    this.allowContentEncoding = allowContentEncoding;
-    this.followRedirects = followRedirects;
-  }
-
-    public void close()
-    {
-        if(method != null) method.close();
-    }
-  public URI getUri() { return this.uri; }
-  public long getConnectionTimeout() { return this.connectionTimeout; }
-  public int getSocketTimeout() { return this.socketTimeout; }
-  public String getContentEncoding() { return this.contentEncoding; }
-  public boolean getAllowContentEncoding() { return this.allowContentEncoding; }
-  public boolean getFollowRedirects() { return this.followRedirects; }
-
-  public void makeRequest()
-          throws IOException
-  {
-    if ( method != null )
-      throw new IllegalStateException( "Request already made.");
-
-    this.method = getHttpResponse( uri );
-  }
-
-  public int getResponseStatusCode()
-  {
-    if ( method == null )
-      throw new IllegalStateException( "Request has not been made." );
-    return this.method.getStatusCode();
-  }
-
-  public String getResponseStatusText()
-  {
-    if ( method == null )
-      throw new IllegalStateException( "Request has not been made." );
-    return this.method.getStatusText();
-  }
-
-  public Map<String,String> getResponseHeaders()
-  {
-    if ( method == null )
-      throw new IllegalStateException( "Request has not been made." );
-
-    if ( this.respHeaders == null )
-    {
-      this.respHeaders = new HashMap<String,String>();
-      Header[] headers = this.method.getResponseHeaders();
-      for ( Header h : headers )
-        this.respHeaders.put( h.getName(), h.getValue() );
-    }
-
-    return respHeaders;
-  }
-
-  public String getResponseHeaderValue( String name )
-  {
-    if ( method == null )
-      throw new IllegalStateException( "Request has not been made." );
-
-    Header responseHeader = this.method.getResponseHeader( name );
-    return responseHeader == null ? null : responseHeader.getValue();
-  }
-
-  public InputStream getResponseBodyAsInputStream()
-          throws IOException
-  {
-    if ( method == null )
-      throw new IllegalStateException( "Request has not been made." );
-
-    InputStream is = method.getResponseAsStream();
-    Header contentEncodingHeader = method.getResponseHeader( "Content-Encoding" );
-    if ( contentEncodingHeader != null )
-    {
-      String contentEncoding = contentEncodingHeader.getValue();
-      if ( contentEncoding != null )
-      {
-        if ( contentEncoding.equalsIgnoreCase( "gzip" ) )
-          return new GZIPInputStream( is );
-        else if ( contentEncoding.equalsIgnoreCase( "deflate" ) )
-          return new InflaterInputStream( is );
-      }
-    }
-    return is;
-  }
-
-  private HTTPMethod getHttpResponse( URI uri )
-          throws IOException, HTTPException
-  {
-    HTTPMethod method = HTTPMethod.Get(uri.toString() );
-    method.getSession().setConnectionTimeout( this.connectionTimeout );
-    method.getSession().setSoTimeout( this.socketTimeout );
-    method.setFollowRedirects( this.followRedirects );
-    method.setRequestHeader( "Accept-Encoding", this.contentEncoding );
-
-   method.execute();
-    int statusCode = method.getStatusCode();
-    if ( statusCode == 200 || statusCode == 201 )
-    {
-      return method;
-    }
-
-    return null; // ToDo throw exception with some informative inforamtion.
-  }
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+package thredds.util;
+
+import ucar.nc2.util.net.*;
+import org.apache.http.Header;
+
+import java.io.*;
+import java.net.URI;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.InflaterInputStream;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * _more_
+ *
+ * @author edavis
+ * @since 4.0
+ */
+public class HttpUriResolver
+{
+  private org.slf4j.Logger logger =
+          org.slf4j.LoggerFactory.getLogger( HttpUriResolver.class );
+
+  private URI uri;
+  private int connectionTimeout;
+  private int socketTimeout;
+  private String contentEncoding = "gzip,deflate";
+  private boolean allowContentEncoding;
+  private boolean followRedirects;
+
+  private HTTPMethod method = null;
+  private Map<String,String> respHeaders;
+
+  HttpUriResolver( URI uri, int connectionTimeout, int socketTimeout,
+                          boolean allowContentEncoding,
+                          boolean followRedirects )
+  {
+    if ( ! uri.getScheme().equalsIgnoreCase( "http" ) )
+      throw new IllegalArgumentException( "Given a Non-HTTP URI [" + uri.toString() + "].");
+
+    this.uri = uri;
+    this.connectionTimeout = connectionTimeout;
+    this.socketTimeout = socketTimeout;
+    this.allowContentEncoding = allowContentEncoding;
+    this.followRedirects = followRedirects;
+  }
+
+    public void close()
+    {
+        if(method != null) method.close();
+    }
+  public URI getUri() { return this.uri; }
+  public long getConnectionTimeout() { return this.connectionTimeout; }
+  public int getSocketTimeout() { return this.socketTimeout; }
+  public String getContentEncoding() { return this.contentEncoding; }
+  public boolean getAllowContentEncoding() { return this.allowContentEncoding; }
+  public boolean getFollowRedirects() { return this.followRedirects; }
+
+  public void makeRequest()
+          throws IOException
+  {
+    if ( method != null )
+      throw new IllegalStateException( "Request already made.");
+
+    this.method = getHttpResponse( uri );
+  }
+
+  public int getResponseStatusCode()
+  {
+    if ( method == null )
+      throw new IllegalStateException( "Request has not been made." );
+    return this.method.getStatusCode();
+  }
+
+  public String getResponseStatusText()
+  {
+    if ( method == null )
+      throw new IllegalStateException( "Request has not been made." );
+    return this.method.getStatusText();
+  }
+
+  public Map<String,String> getResponseHeaders()
+  {
+    if ( method == null )
+      throw new IllegalStateException( "Request has not been made." );
+
+    if ( this.respHeaders == null )
+    {
+      this.respHeaders = new HashMap<String,String>();
+      Header[] headers = this.method.getResponseHeaders();
+      for ( Header h : headers )
+        this.respHeaders.put( h.getName(), h.getValue() );
+    }
+
+    return respHeaders;
+  }
+
+  public String getResponseHeaderValue( String name )
+  {
+    if ( method == null )
+      throw new IllegalStateException( "Request has not been made." );
+
+    Header responseHeader = this.method.getResponseHeader( name );
+    return responseHeader == null ? null : responseHeader.getValue();
+  }
+
+  public InputStream getResponseBodyAsInputStream()
+          throws IOException
+  {
+    if ( method == null )
+      throw new IllegalStateException( "Request has not been made." );
+
+    InputStream is = method.getResponseAsStream();
+    Header contentEncodingHeader = method.getResponseHeader( "Content-Encoding" );
+    if ( contentEncodingHeader != null )
+    {
+      String contentEncoding = contentEncodingHeader.getValue();
+      if ( contentEncoding != null )
+      {
+        if ( contentEncoding.equalsIgnoreCase( "gzip" ) )
+          return new GZIPInputStream( is );
+        else if ( contentEncoding.equalsIgnoreCase( "deflate" ) )
+          return new InflaterInputStream( is );
+      }
+    }
+    return is;
+  }
+
+  private HTTPMethod getHttpResponse( URI uri )
+          throws IOException, HTTPException
+  {
+    HTTPMethod method = HTTPFactory.Get(uri.toString());
+    method.getSession().setConnectionTimeout( this.connectionTimeout );
+    method.getSession().setSoTimeout( this.socketTimeout );
+    method.setFollowRedirects( this.followRedirects );
+    method.setRequestHeader( "Accept-Encoding", this.contentEncoding );
+
+   method.execute();
+    int statusCode = method.getStatusCode();
+    if ( statusCode == 200 || statusCode == 201 )
+    {
+      return method;
+    }
+
+    return null; // ToDo throw exception with some informative inforamtion.
+  }
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/dataset/NetcdfDataset.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/dataset/NetcdfDataset.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/dataset/NetcdfDataset.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/dataset/NetcdfDataset.java	2013-09-16 07:19:34.501934905 +0200
@@ -57,8 +57,9 @@
 import java.net.*;
 import java.util.*;
 
-import org.apache.commons.httpclient.Header;
+import org.apache.http.Header;
 import thredds.catalog.ServiceType;
+import ucar.nc2.util.net.HTTPFactory;
 import ucar.unidata.util.StringUtil2;
 import ucar.unidata.util.Urlencoded;
 
@@ -119,7 +120,13 @@
 
 public class NetcdfDataset extends ucar.nc2.NetcdfFile {
 
-  /**
+
+    /**
+     * Define the legal Winoows drive letters
+     */
+    static final String DRIVE_LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    /**
    * Possible enhancements for a NetcdfDataset
    */
   static public enum Enhance {
@@ -647,17 +654,75 @@
       location = location.trim();
       location = StringUtil2.replace(location, '\\', "/");
 
-      // Some URLS have multiple prefixed protocols (e.g. thredds:resolve)
-      // so, we cannot use URI or URL classes to parse.
-      String[] prefixes = location.split("[:]");
+      // Start by breaking off any leading protocols;
+      // there may be more than one.
+      // Watch out for Windows paths starting with a drive letter.
+
+      List<String> allprotocols = new ArrayList<String>(); // all leading protocols upto path or host
+
+      // Note, we cannot use split because of the context sensitivity
+      StringBuilder buf = new StringBuilder(location);
+      for(;;) {
+        int index = buf.indexOf(":");
+        if(index < 0) break; // no more protocols
+        String protocol = buf.substring(0,index);
+        // Check for windows drive letter
+            if(index == 1 //=>|protocol| == 1
+           && DRIVE_LETTERS.indexOf(buf.charAt(0)) >= 0) break;
+        allprotocols.add(protocol);
+        buf.delete(0,index+1); // remove the leading protocol
+        if(buf.indexOf("/") == 0)break; // anything after this is not a protocol
+      }
+
+      String trueurl = location;
+      String leadprotocol = null;
+      if(allprotocols.size() == 0) {
+        // The location has no lead protocols, assume file:
+	    leadprotocol = "file";
+      } else {
+        leadprotocol = allprotocols.get(0);
+      }
+
+      // Priority in deciding
+      // the service type is as follows.
+      // 1. "protocol" tag in fragment
+      // 2. lead protocol
+      // 3. path extension
+      // 4. contact the server (if defined)
+
+      // remove any trailing query or fragment
+      String fragment = null;
+      int pos = trueurl.lastIndexOf('#');
+      if(pos >= 0) {
+        fragment = trueurl.substring(pos+1,trueurl.length());
+        trueurl = trueurl.substring(0,pos);
+      }
+      String query = null;
+      pos = location.lastIndexOf('?');
+      if(pos >= 0) {
+        query = trueurl.substring(pos+1,trueurl.length());
+        trueurl = trueurl.substring(0,pos);
+      }
+
       ServiceType svctype = null;
-      if(prefixes.length > 1) {
-          // "switch" based on the leading protocol
-          String protocol = prefixes[0]; //
-          if(protocol.equals("file"))
-              svctype = disambiguateFile(location);
-           else
-              svctype = disambiguateURL(protocol,location);
+
+      if(fragment != null)
+          svctype = searchFragment(fragment);
+
+      if(svctype == null) // See if lead protocol tells us how to interpret
+        svctype = decodeLeadProtocol(leadprotocol);
+
+      if(svctype == null) // Look at the path file extension
+        svctype = decodePathExtension(trueurl);
+
+      if(svctype == null) {
+        //There are several possibilities at this point; all of which
+        // require further info to disambiguate
+        //  - we have file://<path> or file:<path>; without more help, we cannot
+        //    determine the service type
+        //  - we have a simple url: e.g. http://... ; contact the server
+        if(!leadprotocol.equals("file"))
+          svctype = disambiguateHttp(trueurl);
       }
 
       if(svctype == ServiceType.OPENDAP)
@@ -669,9 +734,13 @@
       else if(svctype == ServiceType.DAP4)
           return acquireDap4(cache, factory, hashKey, location,
                                  buffer_size, cancelTask, spiObject);
-      else if(svctype == ServiceType.NCML)
-          return acquireNcml(cache, factory, hashKey, location, buffer_size, cancelTask, spiObject);
-      else if(svctype == ServiceType.THREDDS) {
+      else if(svctype == ServiceType.NCML) {
+          // If lead protocol was null and then pretend it was a file
+          // Note that technically, this should be 'file://'
+          String url = (allprotocols.size() == 0 ? "file:"+trueurl : trueurl);
+          return acquireNcml(cache, factory, hashKey, url,
+                             buffer_size, cancelTask, spiObject);
+      } else if(svctype == ServiceType.THREDDS) {
           Formatter log = new Formatter();
           ThreddsDataFactory tdf = new ThreddsDataFactory();
           NetcdfFile ncfile = tdf.openDataset(location, false, cancelTask, log); // LOOK acquire ??
@@ -679,15 +748,8 @@
               throw new IOException(log.toString());
           return ncfile;
       } else if(svctype != null)
-	throw new IOException("Unknown service type: "+svctype.toString());
+        throw new IOException("Unknown service type: "+svctype.toString());
 
-      // Apparently not a url, see if it looks like an ncml request
-      if(location.endsWith(".xml") || location.endsWith(".ncml")) {
-          // Pretend it was a file: url
-          // Note that technically, this should be 'file://'
-          return acquireNcml(cache, factory, hashKey, "file:"+location,
-                             buffer_size, cancelTask, spiObject);
-      }
       // Next to last resort: look in the cache
       if(cache != null) {
           if(factory == null)
@@ -699,30 +761,14 @@
       return NetcdfFile.open(location, buffer_size, cancelTask, spiObject);
     }
 
-  /*
-   * Attempt to map a file: url to a service type
-   * (see thredds.catalog.ServiceType).
-   *
-   * @param location The file: url to disambiguate
-   * @return ServiceType indicating how to handle the url
-   */
-    @Urlencoded
+    /**
+     * Check path extension; assumes no query or fragment
+     * @param path the path to examine for extension
+     * @return ServiceType inferred from the extension or null
+     */
     static ServiceType
-    disambiguateFile(String location)
+    decodePathExtension(String path)
     {
-        // This should parse as a URL
-        URL urx = null;
-        boolean parses = true;
-        try {urx = new URL(location);} catch (MalformedURLException e) {parses = false;}
-        String path = null;
-        if(parses) {
-            path = urx.getPath();
-            if(path == null || path.length()==0) parses = false;
-        }
-        if(!parses)
-            return null;
-
-        assert urx.getProtocol().equals("file");
         // Look at the path extensions
         if(path.endsWith(".dds")
            || path.endsWith(".das")
@@ -735,12 +781,11 @@
         if(path.endsWith(".xml")
            || path.endsWith(".ncml"))
             return ServiceType.NCML;
-        // See if the fragment gives a clue
-        return searchFragment(location);
+        return null;
     }
 
   /*
-   * Attempt to map a (non-file:) url to a service type
+   * Attempt to map a lead url protocol url to a service type
    * (see thredds.catalog.ServiceType).
    * Possible service types should include at least the following.
    * <ol>
@@ -748,16 +793,13 @@
    * <li> DAP4 (DAP4 protocol)
    * <li> CdmRemote (remote ncstream)
    * </ol>
-   * The mapping from url -> ServiceType is many to one, where for example,
-   * the url protocol of dap4 and file might both map to ServiceType.DAP4.
    *
    * @param protocol The leading protocol
-   * @param location the url to disambiguate
-   * @return ServiceType indicating how to handle the url
+   * @return ServiceType indicating how to handle the url, or null.
    */
     @Urlencoded
     static ServiceType
-    disambiguateURL(String protocol, String location)
+    decodeLeadProtocol(String protocol)
         throws IOException
     {
         if(protocol.equals("dods"))
@@ -768,78 +810,9 @@
             return ServiceType.CdmRemote;
         else if(protocol.equals(ThreddsDataFactory.PROTOCOL)) //thredds
             return ServiceType.THREDDS;
-        else if(protocol.equals("http") || protocol.equals("https"))
-            return disambiguateHttp(location); // Actually contact the server
-	    return searchFragment(location);
-    }
-
-    /**
-     * Given a fragment, look for
-     * markers indicated which protocol to use
-     * @param location the url whose fragment is to be examined
-     * @return The discovered ServiceType, or null
-     */
-    static ServiceType
-    searchFragment(String location)
-    {
-        int pos = location.lastIndexOf('#');
-        if(pos < 0) return null;
-        String fragment = location.substring(pos+1,location.length());
-        Map<String,String> map = parseFragment(fragment);
-        String protocol = map.get("protocol");
-        if(protocol != null) {
-            if(protocol.equalsIgnoreCase("dap")
-               || protocol.equalsIgnoreCase("dods"))
-            return ServiceType.OPENDAP;
-            if(protocol.equalsIgnoreCase("dap4"))
-            return ServiceType.DAP4;
-            if(protocol.equalsIgnoreCase("cdmremote"))
-            return ServiceType.CdmRemote;
-            if(protocol.equalsIgnoreCase("thredds"))
-            return ServiceType.THREDDS;
-            if(protocol.equalsIgnoreCase("ncmdl"))
-            return ServiceType.NCML;
-        }
         return null;
     }
 
-    /**
-     * Given the fragment part of a url, see if it
-     * parses as name=value pairs separated by '&'
-     * (same as query part).
-     * @param fragment the fragment part of a url
-     * @return a map of the name value pairs (possibly empty),
-     *         or null if the fragment does not parse.
-     */
-
-    static Map<String,String>
-    parseFragment(String fragment)
-    {
-	Map<String,String> map = new HashMap<String,String>();
-	if(fragment != null && fragment.length() >= 0) {
-	    if(fragment.charAt(0) == '#')
-		fragment = fragment.substring(1);
-	    String[] pairs = fragment.split("[ \t]*[&][ \t]*");
-	    for(String pair: pairs) {
-		String[] pieces = fragment.split("[ \t]*[=][ \t]*");		
-		switch (pieces.length) {
-		case 1:
-		    map.put(EscapeStrings.unescapeURL(pieces[0]).toLowerCase(),
-			    "true");
-		    break;
-		case 2:
-		    map.put(EscapeStrings.unescapeURL(pieces[0]).toLowerCase(),
-			    EscapeStrings.unescapeURL(pieces[1]).toLowerCase());
-		    break;
-		default:
-		    return null; // does not parse
-		}
-	    }
-	}
-	return map;
-    }
-
-
   /**
    * If the URL alone is not sufficient to disambiguate the location,
    * then this method will attempt to do a specific kind of request on
@@ -848,6 +821,7 @@
    * and uses it value (e.g. "ncstream" or "dods", etc)
    * in order to disambiguate.
    * @param location the url to disambiguate
+   * @param location the original url string
    * @return ServiceType indicating how to handle the url
    */
     @Urlencoded
@@ -858,11 +832,6 @@
       // aggregation cache files are of form
       // http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2.dailyavgs/pressure/air.1981.nc#320092027
 
-        // remove any fragment
-        int pos = location.lastIndexOf("#");
-        if(pos >= 0)
-            location = location.substring(0,pos);
-
         ServiceType result = checkIfDods(location); // dods
         if(result != null)
             return result;
@@ -872,7 +841,7 @@
 
         HTTPMethod method = null;
         try {
-            method = HTTPMethod.Head(location);
+            method = HTTPFactory.Head(location);
             int statusCode = method.execute();
             if(statusCode >= 300) {
                 if(statusCode == 401)
@@ -895,22 +864,19 @@
   // not sure what other opendap servers do, so fall back on check for dds
   static private ServiceType checkIfDods(String location) throws IOException {
     HTTPMethod method = null;
-    // Strip off any trailing constraints
-    if (location.indexOf('?') >= 0) {
-      location = location.substring(0, location.indexOf('?'));
-    }
+    int len = location.length();
     // Strip off any trailing .dds, .das, or .dods
     if (location.endsWith(".dds"))
-      location = location.substring(0, location.length() - ".dds".length());
+      location = location.substring(0,  len - ".dds".length());
     if (location.endsWith(".das"))
-      location = location.substring(0, location.length() - ".das".length());
+      location = location.substring(0, len - ".das".length());
     if (location.endsWith(".dods"))
-      location = location.substring(0, location.length() - ".dods".length());
+      location = location.substring(0, len - ".dods".length());
     // Opendap assumes that the caller has properly escaped the url
     try {
       // For some reason, the head method is not using credentials
       // method = session.newMethodHead(location + ".dds");
-      method = HTTPMethod.Get(location + ".dds");
+      method = HTTPFactory.Get(location + ".dds");
 
       int status = method.execute();
       if (status == 200) {
@@ -937,10 +903,6 @@
   // check for dmr
   static private ServiceType checkIfDap4(String location) throws IOException {
     HTTPMethod method = null;
-    // Strip off any trailing constraints
-    if (location.indexOf('?') >= 0) {
-      location = location.substring(0, location.indexOf('?'));
-    }
     // Strip off any trailing DAP4 prefix
     if (location.endsWith(".dap"))
       location = location.substring(0, location.length() - ".dap".length());
@@ -949,7 +911,7 @@
     else if (location.endsWith(".dsr"))
       location = location.substring(0, location.length() - ".dsr".length());
     try {
-      method = HTTPMethod.Get(location + ".dmr");
+      method = HTTPFactory.Get(location + ".dmr");
 
       int status = method.execute();
       if (status == 200) {
@@ -971,6 +933,73 @@
     }
   }
 
+    /**
+     * Given a location look for
+     * markers indicated which protocol to use
+     * @param fragment the fragment is to be examined
+     * @return The discovered ServiceType, or null
+     */
+    static ServiceType
+    searchFragment(String fragment)
+    {
+        if(fragment.length() == 0)
+            return null;
+        Map<String,String> map = parseFragment(fragment);
+        String protocol = map.get("protocol");
+        if(protocol != null) {
+            if(protocol.equalsIgnoreCase("dap")
+               || protocol.equalsIgnoreCase("dods"))
+            return ServiceType.OPENDAP;
+            if(protocol.equalsIgnoreCase("dap4"))
+            return ServiceType.DAP4;
+            if(protocol.equalsIgnoreCase("cdmremote"))
+            return ServiceType.CdmRemote;
+            if(protocol.equalsIgnoreCase("thredds"))
+            return ServiceType.THREDDS;
+            if(protocol.equalsIgnoreCase("ncmdl"))
+            return ServiceType.NCML;
+        }
+        return null;
+    }
+
+    /**
+     * Given the fragment part of a url, see if it
+     * parses as name=value pairs separated by '&'
+     * (same as query part).
+     * @param fragment the fragment part of a url
+     * @return a map of the name value pairs (possibly empty),
+     *         or null if the fragment does not parse.
+     */
+
+    static Map<String,String>
+    parseFragment(String fragment)
+    {
+        Map<String,String> map = new HashMap<String,String>();
+        if(fragment != null && fragment.length() >= 0) {
+            if(fragment.charAt(0) == '#')
+                fragment = fragment.substring(1);
+            String[] pairs = fragment.split("[ \t]*[&][ \t]*");
+            for(String pair: pairs) {
+                String[] pieces = fragment.split("[ \t]*[=][ \t]*");
+                switch (pieces.length) {
+                case 1:
+                    map.put(EscapeStrings.unescapeURL(pieces[0]).toLowerCase(),
+                            "true");
+                    break;
+                case 2:
+                    map.put(EscapeStrings.unescapeURL(pieces[0]).toLowerCase(),
+                            EscapeStrings.unescapeURL(pieces[1]).toLowerCase());
+                    break;
+                default:
+                    return null; // does not parse
+                }
+            }
+        }
+        return map;
+    }
+
+
+  //////////////////////////////////////////////////
 
   private static boolean isexternalclient = false;
 
@@ -1290,9 +1319,8 @@
   /* @Override
   public Object sendIospMessage(Object message) {
     if (orgFile != null)
-      return orgFile.sendIospMessage(message);
-    else
-      return false;
+      orgFile.sendIospMessage(message);
+    return false;
   } */
 
   /*
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/stream/CdmRemote.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/stream/CdmRemote.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/stream/CdmRemote.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/stream/CdmRemote.java	2013-09-16 07:21:21.097338895 +0200
@@ -1,339 +1,337 @@
-/*
- * Copyright 2009-2012 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-package ucar.nc2.stream;
-
-import ucar.nc2.util.net.HTTPException;
-import ucar.nc2.util.net.HTTPMethod;
-import ucar.nc2.util.net.HTTPSession;
-import org.apache.commons.httpclient.Header;
-
-import ucar.ma2.*;
-import ucar.nc2.Structure;
-import ucar.nc2.Variable;
-import ucar.nc2.util.IO;
-
-import java.io.*;
-import java.net.URLEncoder;
-import java.util.Formatter;
-
-/**
- * A remote CDM dataset (extends NetcdfFile), using cdmremote protocol to communicate.
- * Similar to Opendap in that it is a remote access protocol.
- * Supports full CDM / netcdf-4 data model.
- *
- * @author caron
- * @since Feb 7, 2009
- */
-public class CdmRemote extends ucar.nc2.NetcdfFile {
-  static public final String PROTOCOL = "cdmremote";
-  static public final String SCHEME = PROTOCOL+":";
-
-  static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CdmRemote.class);
-  static private boolean showRequest = false;
-
-  static public void setDebugFlags(ucar.nc2.util.DebugFlags debugFlag) {
-    showRequest = debugFlag.isSet("CdmRemote/showRequest");
-  }
-
-  /**
-   * Create the canonical form of the URL.
-   * If the urlName starts with "http:", change it to start with "cdmremote:", otherwise
-   * leave it alone.
-   *
-   * @param urlName the url string
-   * @return canonical form
-   */
-  public static String canonicalURL(String urlName) {
-    if (urlName.startsWith("http:"))
-      return SCHEME + urlName.substring(5);
-    return urlName;
-  }
-
-  /* IGNORE
-  static synchronized void initHttpClient() {
-    if (httpClient != null) return;
-    try {
-      httpClient = new HTTPSession();
-    } catch (HTTPException he) {
-      httpClient = null;
-    }
-  }
-  */
-
-  //////////////////////////////////////////////////////
-
-  private HTTPSession httpClient;
-
-  private final String remoteURI;
-
-  public CdmRemote(String _remoteURI) throws IOException {
-    long start = System.currentTimeMillis();
-
-    // get http URL
-    String temp = _remoteURI;
-    try {
-      if (temp.startsWith(SCHEME))
-        temp = temp.substring(SCHEME.length());
-      if (!temp.startsWith("http:"))
-        temp = "http:" + temp;
-    } catch (Exception e) {
-    }
-    remoteURI = temp;
-
-    httpClient = new HTTPSession(remoteURI);
-
-    // get the header
-    HTTPMethod method = null;
-    try {
-      String url = remoteURI + "?req=header";
-      method = HTTPMethod.Get(httpClient,url);
-      method.setFollowRedirects(true);
-      if (showRequest) System.out.printf("CdmRemote request %s %n", url);
-      int statusCode = method.execute();
-
-      if (statusCode == 404)
-        throw new FileNotFoundException(method.getURL() + " " + method.getStatusLine());
-
-      if (statusCode >= 300)
-        throw new IOException(method.getURL() + " " + method.getStatusLine());
-
-      InputStream is = method.getResponseAsStream();
-      NcStreamReader reader = new NcStreamReader();
-      reader.readStream(is, this);
-      this.location = SCHEME + remoteURI;
-
-    } finally {
-      if (method != null) method.close();
-    }
-    long took = System.currentTimeMillis() - start;
-    if (showRequest) System.out.printf(" took %d msecs %n", took);
-  }
-
-  @Override
-  protected Array readData(ucar.nc2.Variable v, Section section) throws IOException, InvalidRangeException {
-    //if (unlocked)
-    //  throw new IllegalStateException("File is unlocked - cannot use");
-
-    if (v.getDataType() == DataType.SEQUENCE) {
-      Structure s = (Structure) v;
-      StructureDataIterator siter = getStructureIterator(s, -1);
-      return new ArraySequence(s.makeStructureMembers(), siter, -1);
-    }
-
-    StringBuilder sbuff = new StringBuilder(remoteURI);
-    sbuff.append("?var=");
-    Formatter f = new Formatter();
-    f.format("%s", v.getFullNameEscaped()); // full name
-    if (section != null && v.getDataType() != DataType.SEQUENCE) {
-      f.format("(%s)", section.toString());
-    }
-    sbuff.append( URLEncoder.encode(f.toString(), "UTF-8")); // % escape entire thing varname and section
-
-    if (showRequest)
-      System.out.println(" CdmRemote data request for variable: " + v.getFullName() + " section= " + section + " url=" + sbuff);
-
-    HTTPMethod method = null;
-    try {
-      method = HTTPMethod.Get(httpClient,sbuff.toString());
-      int statusCode = method.execute();
-
-      if (statusCode == 404)
-        throw new FileNotFoundException(method.getPath() + " " + method.getStatusLine());
-
-      if (statusCode >= 300)
-        throw new IOException(method.getPath() + " " + method.getStatusLine());
-
-      Header h = method.getResponseHeader("Content-Length");
-      if (h != null) {
-        String s = h.getValue();
-        int readLen = Integer.parseInt(s);
-        if (showRequest)
-          System.out.printf(" content-length = %d%n", readLen);
-        if (v.getDataType() != DataType.SEQUENCE) {
-          int wantSize = (int) (v.getElementSize() * (section == null ? v.getSize() : section.computeSize()));
-          if (readLen != wantSize)
-            throw new IOException("content-length= " + readLen + " not equal expected Size= " + wantSize); // LOOK
-        }
-      }
-
-      InputStream is = method.getResponseAsStream();
-      NcStreamReader reader = new NcStreamReader();
-      NcStreamReader.DataResult result = reader.readData(is, this);
-
-      assert v.getFullNameEscaped().equals(result.varNameFullEsc);
-      result.data.setUnsigned(v.isUnsigned());
-      return result.data;
-
-    } finally {
-      if (method != null) method.close();
-    }
-  }
-
-  protected StructureDataIterator getStructureIterator(Structure s, int bufferSize) throws java.io.IOException {
-    try {
-      InputStream is = sendQuery(remoteURI, s.getFullNameEscaped());
-      NcStreamReader reader = new NcStreamReader();
-      return reader.getStructureIterator(is, this);
-
-    } catch (Throwable e) {
-      e.printStackTrace();
-      throw new IllegalStateException(e);
-    }
-  }
-
-  public static InputStream sendQuery(String remoteURI, String query) throws IOException {
-    long start = System.currentTimeMillis();
-
-    HTTPSession session = null;
-    HTTPMethod method = null;
-    InputStream stream = null;
-    int statusCode = 0;
-
-    StringBuilder sbuff = new StringBuilder(remoteURI);
-    sbuff.append("?");
-    sbuff.append(query);
-
-    if (showRequest)
-      System.out.printf(" CdmRemote sendQuery= %s", sbuff);
-
-    try {
-
-      try {
-        session = new HTTPSession(sbuff.toString());
-        method = HTTPMethod.Get(session);
-        statusCode = method.execute();
-      } catch (HTTPException he) {
-        throw new IOException(he);
-      }
-
-      if (statusCode == 404)
-        throw new FileNotFoundException(method.getPath() + " " + method.getStatusLine());
-
-      if (statusCode >= 300)
-        throw new IOException(method.getPath() + " " + method.getStatusLine());
-
-      stream = method.getResponseBodyAsStream();
-      if (showRequest) System.out.printf(" took %d msecs %n", System.currentTimeMillis() - start);
-      return stream;
-
-    } catch (IOException ioe) {
-      if (session != null) session.close();
-      throw ioe;
-    }
-  }
-
-  @Override
-  public String getFileTypeId() {
-    return "ncstreamRemote";
-  }
-
-  @Override
-  public String getFileTypeDescription() {
-    return "ncstreamRemote";
-  }
-
-  public void writeToFile(String filename) throws IOException {
-    File file = new File(filename);
-    FileOutputStream fos = new FileOutputStream(file);
-    // WritableByteChannel wbc = fos.getChannel();
-
-    long size = 4;
-    fos.write(NcStream.MAGIC_START);
-
-    // header
-    HTTPMethod method = null;
-    try {
-      // get the header
-      String url = remoteURI + "?req=header";
-      method = HTTPMethod.Get(httpClient,url);
-      if (showRequest) System.out.printf("CdmRemote request %s %n", url);
-      int statusCode = method.execute();
-
-      if (statusCode == 404)
-        throw new FileNotFoundException(method.getURL() + " " + method.getStatusLine());
-
-      if (statusCode >= 300)
-        throw new IOException(method.getURL() + " " + method.getStatusLine());
-
-      InputStream is = method.getResponseBodyAsStream();
-      size += IO.copyB(is, fos, IO.default_socket_buffersize);
-
-    } finally {
-      if (method != null) method.close();
-    }
-
-    for (Variable v : getVariables()) {
-      StringBuilder sbuff = new StringBuilder(remoteURI);
-      sbuff.append("?var=");
-      sbuff.append(URLEncoder.encode(v.getShortName(), "UTF-8"));
-
-      if (showRequest)
-        System.out.println(" CdmRemote data request for variable: " + v.getFullName() + " url=" + sbuff);
-
-      try {
-        method = HTTPMethod.Get(httpClient,sbuff.toString());
-        int statusCode = method.execute();
-
-        if (statusCode == 404)
-          throw new FileNotFoundException(method.getPath() + " " + method.getStatusLine());
-
-        if (statusCode >= 300)
-          throw new IOException(method.getPath() + " " + method.getStatusLine());
-
-        int wantSize = (int) (v.getSize());
-        Header h = method.getResponseHeader("Content-Length");
-        if (h != null) {
-          String s = h.getValue();
-          int readLen = Integer.parseInt(s);
-          if (readLen != wantSize)
-            throw new IOException("content-length= " + readLen + " not equal expected Size= " + wantSize);
-        }
-
-        InputStream is = method.getResponseBodyAsStream();
-        size += IO.copyB(is, fos, IO.default_socket_buffersize);
-
-      } finally {
-        if (method != null) method.close();
-      }
-    }
-
-    fos.flush();
-    fos.close();
-  }
-
-  @Override
-  public synchronized void close() throws java.io.IOException {
-    if (httpClient != null) httpClient.close();
-  }
-
-}
+/*
+ * Copyright 2009-2012 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+package ucar.nc2.stream;
+
+import ucar.nc2.util.net.*;
+import org.apache.http.Header;
+
+import ucar.ma2.*;
+import ucar.nc2.Structure;
+import ucar.nc2.Variable;
+import ucar.nc2.util.IO;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.Formatter;
+
+/**
+ * A remote CDM dataset (extends NetcdfFile), using cdmremote protocol to communicate.
+ * Similar to Opendap in that it is a remote access protocol.
+ * Supports full CDM / netcdf-4 data model.
+ *
+ * @author caron
+ * @since Feb 7, 2009
+ */
+public class CdmRemote extends ucar.nc2.NetcdfFile {
+  static public final String PROTOCOL = "cdmremote";
+  static public final String SCHEME = PROTOCOL+":";
+
+  static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CdmRemote.class);
+  static private boolean showRequest = false;
+
+  static public void setDebugFlags(ucar.nc2.util.DebugFlags debugFlag) {
+    showRequest = debugFlag.isSet("CdmRemote/showRequest");
+  }
+
+  /**
+   * Create the canonical form of the URL.
+   * If the urlName starts with "http:", change it to start with "cdmremote:", otherwise
+   * leave it alone.
+   *
+   * @param urlName the url string
+   * @return canonical form
+   */
+  public static String canonicalURL(String urlName) {
+    if (urlName.startsWith("http:"))
+      return SCHEME + urlName.substring(5);
+    return urlName;
+  }
+
+  /* IGNORE
+  static synchronized void initHttpClient() {
+    if (httpClient != null) return;
+    try {
+      httpClient = HTTPFactory.newSession();
+    } catch (HTTPException he) {
+      httpClient = null;
+    }
+  }
+  */
+
+  //////////////////////////////////////////////////////
+
+  private HTTPSession httpClient;
+
+  private final String remoteURI;
+
+  public CdmRemote(String _remoteURI) throws IOException {
+    long start = System.currentTimeMillis();
+
+    // get http URL
+    String temp = _remoteURI;
+    try {
+      if (temp.startsWith(SCHEME))
+        temp = temp.substring(SCHEME.length());
+      if (!temp.startsWith("http:"))
+        temp = "http:" + temp;
+    } catch (Exception e) {
+    }
+    remoteURI = temp;
+
+    httpClient = HTTPFactory.newSession(remoteURI);
+
+    // get the header
+    HTTPMethod method = null;
+    try {
+      String url = remoteURI + "?req=header";
+      method = HTTPFactory.Get(httpClient, url);
+      method.setFollowRedirects(true);
+      if (showRequest) System.out.printf("CdmRemote request %s %n", url);
+      int statusCode = method.execute();
+
+      if (statusCode == 404)
+        throw new FileNotFoundException(method.getURL() + " " + method.getStatusLine());
+
+      if (statusCode >= 300)
+        throw new IOException(method.getURL() + " " + method.getStatusLine());
+
+      InputStream is = method.getResponseAsStream();
+      NcStreamReader reader = new NcStreamReader();
+      reader.readStream(is, this);
+      this.location = SCHEME + remoteURI;
+
+    } finally {
+      if (method != null) method.close();
+    }
+    long took = System.currentTimeMillis() - start;
+    if (showRequest) System.out.printf(" took %d msecs %n", took);
+  }
+
+  @Override
+  protected Array readData(ucar.nc2.Variable v, Section section) throws IOException, InvalidRangeException {
+    //if (unlocked)
+    //  throw new IllegalStateException("File is unlocked - cannot use");
+
+    if (v.getDataType() == DataType.SEQUENCE) {
+      Structure s = (Structure) v;
+      StructureDataIterator siter = getStructureIterator(s, -1);
+      return new ArraySequence(s.makeStructureMembers(), siter, -1);
+    }
+
+    StringBuilder sbuff = new StringBuilder(remoteURI);
+    sbuff.append("?var=");
+    Formatter f = new Formatter();
+    f.format("%s", v.getFullNameEscaped()); // full name
+    if (section != null && v.getDataType() != DataType.SEQUENCE) {
+      f.format("(%s)", section.toString());
+    }
+    sbuff.append( URLEncoder.encode(f.toString(), "UTF-8")); // % escape entire thing varname and section
+
+    if (showRequest)
+      System.out.println(" CdmRemote data request for variable: " + v.getFullName() + " section= " + section + " url=" + sbuff);
+
+    HTTPMethod method = null;
+    try {
+      method = HTTPFactory.Get(httpClient, sbuff.toString());
+      int statusCode = method.execute();
+
+      if (statusCode == 404)
+        throw new FileNotFoundException(method.getPath() + " " + method.getStatusLine());
+
+      if (statusCode >= 300)
+        throw new IOException(method.getPath() + " " + method.getStatusLine());
+
+      Header h = method.getResponseHeader("Content-Length");
+      if (h != null) {
+        String s = h.getValue();
+        int readLen = Integer.parseInt(s);
+        if (showRequest)
+          System.out.printf(" content-length = %d%n", readLen);
+        if (v.getDataType() != DataType.SEQUENCE) {
+          int wantSize = (int) (v.getElementSize() * (section == null ? v.getSize() : section.computeSize()));
+          if (readLen != wantSize)
+            throw new IOException("content-length= " + readLen + " not equal expected Size= " + wantSize); // LOOK
+        }
+      }
+
+      InputStream is = method.getResponseAsStream();
+      NcStreamReader reader = new NcStreamReader();
+      NcStreamReader.DataResult result = reader.readData(is, this);
+
+      assert v.getFullNameEscaped().equals(result.varNameFullEsc);
+      result.data.setUnsigned(v.isUnsigned());
+      return result.data;
+
+    } finally {
+      if (method != null) method.close();
+    }
+  }
+
+  protected StructureDataIterator getStructureIterator(Structure s, int bufferSize) throws java.io.IOException {
+    try {
+      InputStream is = sendQuery(remoteURI, s.getFullNameEscaped());
+      NcStreamReader reader = new NcStreamReader();
+      return reader.getStructureIterator(is, this);
+
+    } catch (Throwable e) {
+      e.printStackTrace();
+      throw new IllegalStateException(e);
+    }
+  }
+
+  public static InputStream sendQuery(String remoteURI, String query) throws IOException {
+    long start = System.currentTimeMillis();
+
+    HTTPSession session = null;
+    HTTPMethod method = null;
+    InputStream stream = null;
+    int statusCode = 0;
+
+    StringBuilder sbuff = new StringBuilder(remoteURI);
+    sbuff.append("?");
+    sbuff.append(query);
+
+    if (showRequest)
+      System.out.printf(" CdmRemote sendQuery= %s", sbuff);
+
+    try {
+
+      try {
+        session = HTTPFactory.newSession(sbuff.toString());
+        method = HTTPFactory.Get(session);
+        statusCode = method.execute();
+      } catch (HTTPException he) {
+        throw new IOException(he);
+      }
+
+      if (statusCode == 404)
+        throw new FileNotFoundException(method.getPath() + " " + method.getStatusLine());
+
+      if (statusCode >= 300)
+        throw new IOException(method.getPath() + " " + method.getStatusLine());
+
+      stream = method.getResponseBodyAsStream();
+      if (showRequest) System.out.printf(" took %d msecs %n", System.currentTimeMillis() - start);
+      return stream;
+
+    } catch (IOException ioe) {
+      if (session != null) session.close();
+      throw ioe;
+    }
+  }
+
+  @Override
+  public String getFileTypeId() {
+    return "ncstreamRemote";
+  }
+
+  @Override
+  public String getFileTypeDescription() {
+    return "ncstreamRemote";
+  }
+
+  public void writeToFile(String filename) throws IOException {
+    File file = new File(filename);
+    FileOutputStream fos = new FileOutputStream(file);
+    // WritableByteChannel wbc = fos.getChannel();
+
+    long size = 4;
+    fos.write(NcStream.MAGIC_START);
+
+    // header
+    HTTPMethod method = null;
+    try {
+      // get the header
+      String url = remoteURI + "?req=header";
+      method = HTTPFactory.Get(httpClient, url);
+      if (showRequest) System.out.printf("CdmRemote request %s %n", url);
+      int statusCode = method.execute();
+
+      if (statusCode == 404)
+        throw new FileNotFoundException(method.getURL() + " " + method.getStatusLine());
+
+      if (statusCode >= 300)
+        throw new IOException(method.getURL() + " " + method.getStatusLine());
+
+      InputStream is = method.getResponseBodyAsStream();
+      size += IO.copyB(is, fos, IO.default_socket_buffersize);
+
+    } finally {
+      if (method != null) method.close();
+    }
+
+    for (Variable v : getVariables()) {
+      StringBuilder sbuff = new StringBuilder(remoteURI);
+      sbuff.append("?var=");
+      sbuff.append(URLEncoder.encode(v.getShortName(), "UTF-8"));
+
+      if (showRequest)
+        System.out.println(" CdmRemote data request for variable: " + v.getFullName() + " url=" + sbuff);
+
+      try {
+        method = HTTPFactory.Get(httpClient, sbuff.toString());
+        int statusCode = method.execute();
+
+        if (statusCode == 404)
+          throw new FileNotFoundException(method.getPath() + " " + method.getStatusLine());
+
+        if (statusCode >= 300)
+          throw new IOException(method.getPath() + " " + method.getStatusLine());
+
+        int wantSize = (int) (v.getSize());
+        Header h = method.getResponseHeader("Content-Length");
+        if (h != null) {
+          String s = h.getValue();
+          int readLen = Integer.parseInt(s);
+          if (readLen != wantSize)
+            throw new IOException("content-length= " + readLen + " not equal expected Size= " + wantSize);
+        }
+
+        InputStream is = method.getResponseBodyAsStream();
+        size += IO.copyB(is, fos, IO.default_socket_buffersize);
+
+      } finally {
+        if (method != null) method.close();
+      }
+    }
+
+    fos.flush();
+    fos.close();
+  }
+
+  @Override
+  public synchronized void close() throws java.io.IOException {
+    if (httpClient != null) httpClient.close();
+  }
+
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/EasySSLProtocolSocketFactory.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/EasySSLProtocolSocketFactory.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/EasySSLProtocolSocketFactory.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/EasySSLProtocolSocketFactory.java	2013-09-16 06:41:34.650672256 +0200
@@ -1,339 +1,231 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * ====================================================================
- *
- *  Copyright 2002-2004 The Apache Software Foundation
- *
- *  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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package ucar.nc2.util.net;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.*;
-
-import org.apache.commons.httpclient.ConnectTimeoutException;
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.params.HttpConnectionParams;
-import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
-import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
-import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-import javax.net.ssl.*;
-
-/**
- * <p/>
- * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s
- * that accept self-signed certificates.
- * </p>
- * <p/>
- * This socket factory SHOULD NOT be used for productive systems
- * due to security reasons, unless it is a concious decision and
- * you are perfectly aware of security implications of accepting
- * self-signed certificates
- * </p>
- * <p/>
- * <p/>
- * Example of using custom protocol socket factory for a specific host:
- * <pre>
- *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
- * <p/>
- *     HttpClient client = new HttpClient();
- *     client.getHostConfiguration().setHost("localhost", 443, easyhttps);
- *     // use relative url only
- *     GetMethod httpget = new GetMethod("/");
- *     client.executeMethod(httpget);
- *     </pre>
- * </p>
- * <p/>
- * Example of using custom protocol socket factory per default instead of the standard one:
- * <pre>
- *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
- *     Protocol.registerProtocol("https", easyhttps);
- * <p/>
- *     HttpClient client = new HttpClient();
- *     GetMethod httpget = new GetMethod("https://localhost/");
- *     client.executeMethod(httpget);
- *     </pre>
- * </p>
- *
- * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
- *         <p/>
- *         <p/>
- *         DISCLAIMER: HttpClient developers DO NOT actively support this component.
- *         The component is provided as a reference material, which may be inappropriate
- *         for use without additional customization.
- *         </p>
- */
-
-public class EasySSLProtocolSocketFactory implements ProtocolSocketFactory {
-
-//////////////////////////////////////////////////
-
-  private SSLContext sslcontext = null;
-
-  /**
-   * Constructor for EasySSLProtocolSocketFactory.
-   */
-  public EasySSLProtocolSocketFactory() {
-    super();
-  }
-
-
-  /**
-   * @see SecureProtocolSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)
-   */
-  public Socket createSocket(
-          Socket socket,
-          String host,
-          int port,
-          boolean autoClose)
-          throws IOException, UnknownHostException {
-
-    return getSSLContext(null, host, port).getSocketFactory().createSocket(
-            socket,
-            host,
-            port,
-            autoClose);
-  }
-
-  /**
-   * @see SecureProtocolSocketFactory#createSocket(java.lang.String, int)
-   */
-  public Socket createSocket(String host, int port)
-          throws IOException, UnknownHostException {
-    return getSSLContext(null, host, port).getSocketFactory().createSocket(host, port);
-  }
-
-  /**
-   * @see SecureProtocolSocketFactory#createSocket(java.lang.String, int, java.net.InetAddress, int)
-   */
-  public Socket createSocket(
-          String host,
-          int port,
-          InetAddress clientHost,
-          int clientPort)
-          throws IOException, UnknownHostException {
-    return createSocket(
-            host,
-            port,
-            clientHost,
-            clientPort,
-            new HttpConnectionParams());
-  }
-
-  /**
-   * Attempts to get a new socket connection to the given host within the given time limit.
-   * <p/>
-   * To circumvent the limitations of older JREs that do not support connect timeout a
-   * controller thread is executed. The controller thread attempts to create a new socket
-   * within the given limit of time. If socket constructor does not return until the
-   * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
-   * </p>
-   *
-   * @param host         the host name/IP
-   * @param port         the port on the host
-   * @param localAddress the local host name/IP to bind the socket to
-   * @param localPort    the port on the local machine
-   * @param params       {@link HttpConnectionParams Http connection parameters}
-   * @return Socket a new socket
-   * @throws IOException          if an I/O error occurs while creating the socket
-   * @throws UnknownHostException if the IP address of the host cannot be
-   *                              determined
-   */
-  public Socket createSocket(
-          final String host,
-          final int port,
-          final InetAddress localAddress,
-          final int localPort,
-          final HttpConnectionParams params)
-          throws IOException, UnknownHostException, ConnectTimeoutException {
-    if (params == null) {
-      throw new IllegalArgumentException("Parameters may not be null");
-    }
-    int timeout = params.getConnectionTimeout();
-    if (true) {
-      return getSSLContext(params, host, port).getSocketFactory().createSocket(host, port);
-    } else {
-      if (timeout == 0) {
-        return getSSLContext(params, host, port).getSocketFactory().createSocket(host, port);
-      } else {
-        // To be eventually deprecated when migrated to Java 1.4 or above
-        return ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout);
-      }
-    }
-
-  }
-
-  private SSLContext getSSLContext(HttpConnectionParams params, String host, int port) throws HTTPException {
-    if (this.sslcontext == null) {
-      this.sslcontext = createSSLContext(params, host, port);
-    }
-    return this.sslcontext;
-  }
-
-  private SSLContext createSSLContext(HttpConnectionParams params, String host, int port) throws HTTPException {
-    SSLContext sslcontext = null;
-    KeyManager[] keymanagers = null;
-    KeyStore keystore = null;
-    KeyStore truststore = null;
-    TrustManager[] trustmanagers = null;
-
-    String keypassword = null;
-    String keypath = null;
-    String trustpassword = null;
-    String trustpath = null;
-
-    try {
-
-      // Get the HTTPAuthProvider
-      HTTPAuthProvider provider;
-      provider = (HTTPAuthProvider) params.getParameter(CredentialsProvider.PROVIDER);
-      if (provider == null) return stdauthenticate();
-
-      // Abuse the getCredentials() api
-      Credentials creds = null;
-      try {
-          creds = provider.getCredentials(HTTPSSLScheme.Default, null, 0, false);
-          if (creds == null) return stdauthenticate();
-      } catch (CredentialsNotAvailableException e) {
-          return stdauthenticate();
-      }
-
-      HTTPSSLProvider sslprovider = (creds == null ? null : (HTTPSSLProvider) creds);
-      if (sslprovider == null)
-          return stdauthenticate();
-
-      keypath = (String) sslprovider.getKeystore();
-      keypassword = (String) sslprovider.getKeypassword();
-      trustpath = (String) sslprovider.getTruststore();
-      trustpassword = (String) sslprovider.getTrustpassword();
-
-      keystore = buildstore(keypath, keypassword, "key");
-      if (keystore != null) {
-        KeyManagerFactory kmfactory = KeyManagerFactory.getInstance("SunX509");
-        kmfactory.init(keystore, keypassword.toCharArray());
-        keymanagers = kmfactory.getKeyManagers();
-      }
-
-      truststore = buildstore(trustpath, trustpassword, "trust");
-      if (truststore != null) {
-        //TrustManagerFactory trfactory = TrustManagerFactory.getInstance("SunX509");
-        //trfactory.init(truststore, trustpassword.toCharArray());
-        //trustmanagers = trfactory.getTrustManagers();
-        trustmanagers = new TrustManager[]{new EasyX509TrustManager(truststore)};
-      } else {
-        trustmanagers = new TrustManager[]{new EasyX509TrustManager(null)};
-      }
-
-      sslcontext = SSLContext.getInstance("SSL");
-      sslcontext.init(keymanagers, trustmanagers, null);
-
-      return sslcontext;
-
-    } catch (KeyManagementException e) {
-        throw new HTTPException("Key Management exception: " + e.getMessage());
-    } catch (NoSuchAlgorithmException e) {
-        throw new HTTPException("Unsupported algorithm exception: " + e.getMessage());
-    } catch (KeyStoreException e) {
-      throw new HTTPException("Keystore exception: " + e.getMessage());
-    } catch (GeneralSecurityException e) {
-      throw new HTTPException("Key management exception: " + e.getMessage());
-    } catch (IOException e) {
-      throw new HTTPException("I/O error reading keystore/truststore file: " + e.getMessage());
-    }
-  }
-
-  // Do no authentication
-  static private SSLContext
-  stdauthenticate()
-      throws KeyManagementException,NoSuchAlgorithmException, KeyStoreException
-  {
-    TrustManager[] trustmanagers = new TrustManager[]{new EasyX509TrustManager(null)};
-    SSLContext sslcontext = SSLContext.getInstance("SSL");
-    sslcontext.init(null, trustmanagers, null);
-    return sslcontext;
-  }
-
-  static KeyStore
-  buildstore(String path, String password, String prefix) throws HTTPException {
-    KeyStore store = null;
-    try {
-      if (path != null && password != null) {
-        File storefile = new File(path);
-        if (!storefile.canRead())
-          throw new HTTPException("Cannot read specified " + prefix + "store:" + storefile.getAbsolutePath());
-        store = KeyStore.getInstance("JKS");
-        InputStream is = null;
-        try {
-          is = new FileInputStream(storefile);
-          store.load(is, password.toCharArray());
-        } finally {
-          if (is != null) is.close();
-        }
-      }
-    } catch (Exception e) {
-      throw new HTTPException(e);
-    }
-    return store;
-  }
-
-
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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 ucar.nc2.util.net;
+
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.scheme.*;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.io.IOException;
+
+public class EasySSLProtocolSocketFactory implements SchemeLayeredSocketFactory
+{
+
+    private SSLContext sslcontext = null;
+
+    private SSLContext createSSLContext(HttpParams params)
+        throws IOException
+    {
+        if(this.sslcontext == null)
+            try {
+                // Get the Desired kind of authentication
+                this.sslcontext = trustedauthentication(params);
+                if(this.sslcontext == null)
+                    this.sslcontext = stdauthentication();
+            } catch (KeyManagementException e) {
+                throw new HTTPException("Key Management exception: " + e.getMessage());
+            } catch (NoSuchAlgorithmException e) {
+                throw new HTTPException("Unsupported algorithm exception: " + e.getMessage());
+            } catch (KeyStoreException e) {
+                throw new HTTPException("Keystore exception: " + e.getMessage());
+            } catch (GeneralSecurityException e) {
+                throw new HTTPException("Key management exception: " + e.getMessage());
+            } catch (IOException e) {
+                throw new HTTPException("I/O error reading keystore/truststore file: " + e.getMessage());
+            } catch (Exception e) {
+                throw new IOException(e.getMessage(), e);
+            }
+        return this.sslcontext;
+    }
+
+    // Default is to try self-signed certificates
+    private SSLContext
+    stdauthentication()
+        throws Exception
+    {
+        SSLContext context = SSLContext.getInstance("TLS");
+        context.init(null, new TrustManager[]{new EasyX509TrustManager(null)}, null);
+        return context;
+    }
+
+    private SSLContext
+    trustedauthentication(HttpParams params)
+        throws Exception
+    {
+        String keypath = null;
+        String keypassword = null;
+        String trustpath = null;
+        String trustpassword = null;
+        HTTPSSLProvider provider = null;
+        if(params == null) return null;
+        Object o = params.getParameter(HTTPAuthScheme.PROVIDER);
+        if(o == null) return null;
+        if(!(o instanceof HTTPSSLProvider))
+            throw new HTTPException("EasySSLProtocolSocketFactory: provide is not SSL provider");
+        provider = (HTTPSSLProvider)o;
+        keypath = provider.getKeystore();
+        keypassword = provider.getKeypassword();
+        trustpath = provider.getTruststore();
+        trustpassword = provider.getTrustpassword();
+
+        TrustManager[] trustmanagers = null;
+        KeyManager[] keymanagers = null;
+
+        KeyStore keystore = buildstore(keypath, keypassword, "key");
+        if(keystore != null) {
+            KeyManagerFactory kmfactory = KeyManagerFactory.getInstance("SunX509");
+            kmfactory.init(keystore, keypassword.toCharArray());
+            keymanagers = kmfactory.getKeyManagers();
+        }
+        KeyStore truststore = buildstore(trustpath, trustpassword, "trust");
+        if(truststore != null) {
+            //todo: TrustManagerFactory trfactory = TrustManagerFactory.getInstance("SunX509");
+            //trfactory.init(truststore, trustpassword.toCharArray());
+            //trustmanagers = trfactory.getTrustManagers();
+            trustmanagers = new TrustManager[]{new EasyX509TrustManager(truststore)};
+        }
+        if(trustmanagers == null)
+            trustmanagers = new TrustManager[]{new EasyX509TrustManager(null)};
+
+        SSLContext sslcontext = SSLContext.getInstance("TSL");
+        sslcontext.init(keymanagers, trustmanagers, null);
+        return sslcontext;
+    }
+
+    static KeyStore
+    buildstore(String path, String password, String prefix)
+        throws HTTPException
+    {
+        KeyStore store = null;
+        try {
+            if(path != null && password != null) {
+                File storefile = new File(path);
+                if(!storefile.canRead())
+                    throw new HTTPException("Cannot read specified " + prefix + "store:" + storefile.getAbsolutePath());
+                store = KeyStore.getInstance("JKS");
+                InputStream is = null;
+                try {
+                    is = new FileInputStream(storefile);
+                    store.load(is, password.toCharArray());
+                } finally {
+                    if(is != null) is.close();
+                }
+            }
+        } catch (Exception e) {
+            throw new HTTPException(e);
+        }
+        return store;
+    }
+
+    // -------------------------------------------------------------------
+    // javadoc in org.apache.http.conn.scheme.SocketFactory says :
+    // Both Object.equals() and Object.hashCode() must be overridden
+    // for the correct operation of some connection managers
+    // -------------------------------------------------------------------
+
+    public boolean equals(Object obj)
+    {
+        return ((obj != null) && obj.getClass().equals(
+            EasySSLProtocolSocketFactory.class));
+    }
+
+    public int hashCode()
+    {
+        return EasySSLProtocolSocketFactory.class.hashCode();
+    }
+
+    //SchemeLayeredSocketFactory API
+
+    @Override
+    public boolean isSecure(Socket socket)
+        throws IllegalArgumentException
+    {
+        return true;
+    }
+
+    @Override
+    public Socket createLayeredSocket(Socket socket, String s, int i, HttpParams httpParams)
+        throws IOException
+    {
+        return createSSLContext(httpParams).getSocketFactory().createSocket();
+    }
+
+    public Socket createSocket(HttpParams httpParams)
+        throws IOException
+    {
+        return createSSLContext(httpParams).getSocketFactory().createSocket();
+    }
+
+    public Socket connectSocket(Socket sock,
+                                InetSocketAddress remoteAddress,
+                                InetSocketAddress localAddress,
+                                HttpParams params)
+        throws IOException
+    {
+        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
+        int soTimeout = HttpConnectionParams.getSoTimeout(params);
+        SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket(params));
+        if(localAddress != null) {
+            // we need to bind explicitly
+            sslsock.bind(localAddress);
+        }
+        sslsock.connect(remoteAddress, connTimeout);
+        sslsock.setSoTimeout(soTimeout);
+        return sslsock;
+    }
+
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthProvider.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthProvider.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthProvider.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthProvider.java	2013-09-16 07:14:23.852243471 +0200
@@ -33,15 +33,12 @@
 
 package ucar.nc2.util.net;
 
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
+
 import java.io.IOException;
-import java.io.NotSerializableException;
 import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Set;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.auth.*;
 
 /**
  * HTTPAuthProvider contains the necessary information to support a given
@@ -54,138 +51,142 @@
  * store implementing the HttpParams Interface.  The contents of the pair
  * store depends on the particular auth scheme (HTTP Basic, ESG Keystore,
  * etc.)
- *
+ * <p/>
  * HTTPAuthProvider implements the CredentialsProvider interface.
  */
 
 public class HTTPAuthProvider implements Serializable, CredentialsProvider
 {
-static final int MAX_RETRIES = 3;
+    static final int MAX_RETRIES = 3;
 
 //////////////////////////////////////////////////
 // Predefined keys (Used local to the package)
 
-static final String PRINCIPAL = "ucar.nc2.principal";
-static final String URI = "ucar.nc2.url";
-static final String CREDENTIALSPROVIDER = "ucar.nc2.credentialsprovider";
-static final String KEYSTOREPATH = "ucar.nc2.keystore";
-static final String KEYSTOREPASSWORD = "ucar.nc2.keystorepassword";
-static final String TRUSTSTOREPATH = "ucar.nc2.truststore";
-static final String TRUSTSTOREPASSWORD = "ucar.nc2.truststorepassword";
-static final String CREDENTIALS = "ucar.nc2.credentials";
-static final String AUTHSTRING = "ucar.nc2.authstring";
-static String SCHEME = "ucar.nc2.scheme";
-static String PASSWORD = "ucar.nc2.password";
-static String USER = "ucar.nc2.user";
-static public final String WWW_AUTH_RESP = "Authorization";   // from HttpMethodDirector
-static public final String PROXY_AUTH_RESP = "Proxy-Authorization"; // from HttpMethodDirector
+    static final String PRINCIPAL = "ucar.nc2.principal";
+    static final String URI = "ucar.nc2.url";
+    static final String CREDENTIALSPROVIDER = "ucar.nc2.credentialsprovider";
+    static final String KEYSTOREPATH = "ucar.nc2.keystore";
+    static final String KEYSTOREPASSWORD = "ucar.nc2.keystorepassword";
+    static final String TRUSTSTOREPATH = "ucar.nc2.truststore";
+    static final String TRUSTSTOREPASSWORD = "ucar.nc2.truststorepassword";
+    static final String CREDENTIALS = "ucar.nc2.credentials";
+    static final String AUTHSTRING = "ucar.nc2.authstring";
+    static String SCHEME = "ucar.nc2.scheme";
+    static String PASSWORD = "ucar.nc2.password";
+    static String USER = "ucar.nc2.user";
+    static public final String WWW_AUTH_RESP = "Authorization";   // from HttpMethodDirector
+    static public final String PROXY_AUTH_RESP = "Proxy-Authorization"; // from HttpMethodDirector
 
-static private org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(HTTPAuthProvider.class);
+    static private org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(HTTPAuthProvider.class);
 
 //////////////////////////////////////////////////
 // Instance variables
 
-String url = null;
-HTTPMethod method = null;
-int retryCount;
+    String url = null;
+    HTTPMethod method = null;
+    int retryCount;
 
 //////////////////////////////////////////////////
 // Constructor(s)
 
-public HTTPAuthProvider(String url, HTTPMethod method)
-{
-    this.url = url;
-    this.method = method;
-    this.retryCount = MAX_RETRIES;
-}
+    public HTTPAuthProvider(String url, HTTPMethod method)
+    {
+        this.url = url;
+        this.method = method;
+        this.retryCount = MAX_RETRIES;
+    }
 
-//////////////////////////////////////////////////
-// Credentials Provider Interface
+    //////////////////////////////////////////////////
+    // Credentials Provider Interface
 
-public Credentials
-getCredentials(AuthScheme authscheme,
-               String host,
-               int port,
-	       boolean isproxy)
-    throws CredentialsNotAvailableException
-{
-    // There appears to be a bug in HttpMethodDirector such that
-    // as long as bad credentials are provided, it will keep on
-    // calling the credentials provider.  We fix by checking for
-    // retry in same way as HttpMethodDirector.processWWWAuthChallenge.
-    // After MAX_RETRIES, we force retries to stop.
-    AuthState authstate = method.getMethod().getHostAuthState();
-    if(retryCount == 0 && authstate.isAuthAttempted() && authscheme.isComplete()) {
-        return null; // Stop the retry.
-    }
-    retryCount--;
-
-    // Figure out what scheme is being used
-    HTTPAuthScheme scheme;
-    Credentials credentials = null;
-
-    scheme = HTTPAuthScheme.schemeForName(authscheme.getSchemeName());
-
-    if(scheme == null) {
-        LOG.error("HTTPAuthProvider: unsupported scheme: "+authscheme.getSchemeName());
-        //throw new CredentialsNotAvailableException();
-        return null;
-    }
-
-    // search for matching authstore entries
-    HTTPAuthStore.Entry[] matches = HTTPAuthStore.search(new HTTPAuthStore.Entry(scheme,url,null));
-    if(matches.length == 0)  {
-        LOG.debug("HTTPAuthProvider: no match for ("+scheme+","+url+")");
-        //throw new CredentialsNotAvailableException();
-        return null;
-    }
-
-    HTTPAuthStore.Entry entry = matches[0];
-    LOG.debug("HTTPAuthProvider: AuthStore row: "+entry.toString());
-    CredentialsProvider provider = entry.creds;
-
-    if(provider == null) {
-        LOG.debug("HTTPAuthProvider: no credentials provider provided");
-        //throw new CredentialsNotAvailableException();
-        return null;
-    }
-
-    // invoke the (real) credentials provider
-    // Use the incoming parameters
-    credentials = provider.getCredentials(authscheme,host,port,isproxy);
-    if(credentials == null) {
-        LOG.debug("HTTPAuthProvider: cannot obtain credentials");
-        //throw new CredentialsNotAvailableException();
-        return null;
+    public Credentials
+    getCredentials(AuthScope scope)//AuthScheme authscheme,String host,int port,boolean isproxy)
+    {
+        // There appears to be a bug in HttpMethodDirector such that
+        // as long as bad credentials are provided, it will keep on
+        // calling the credentials provider.  We fix by checking for
+        // retry in same way as HttpMethodDirector.processWWWAuthChallenge.
+        // After MAX_RETRIES, we force retries to stop.
+        //todo: AuthState authstate = method.getMethod().getHostAuthState();
+        //if(retryCount == 0 && authstate.isAuthAttempted() && authscheme.isComplete()) {
+        //    return null; // Stop the retry.
+        //}
+        //retryCount--;
+
+        // Figure out what scheme is being used
+        HTTPAuthScheme scheme;
+        Credentials credentials = null;
+
+        scheme = HTTPAuthScheme.schemeForName(scope.getScheme());
+
+        if(scheme == null) {
+            LOG.error("HTTPAuthProvider: unsupported scheme: " + scope.getScheme());
+            //throw new CredentialsNotAvailableException();
+            return null;
+        }
+
+        // search for matching authstore entries
+        HTTPAuthStore.Entry[] matches = HTTPAuthStore.search(new HTTPAuthStore.Entry(scheme, url, null));
+        if(matches.length == 0) {
+            LOG.debug("HTTPAuthProvider: no match for (" + scheme + "," + url + ")");
+            //throw new CredentialsNotAvailableException();
+            return null;
+        }
+
+        HTTPAuthStore.Entry entry = matches[0];
+        LOG.debug("HTTPAuthProvider: AuthStore row: " + entry.toString());
+        CredentialsProvider provider = entry.creds;
+
+        if(provider == null) {
+            LOG.debug("HTTPAuthProvider: no credentials provider provided");
+            //throw new CredentialsNotAvailableException();
+            return null;
+        }
+
+        // invoke the (real) credentials provider
+        // Use the incoming parameters
+        credentials = provider.getCredentials(scope);
+        if(credentials == null) {
+            LOG.debug("HTTPAuthProvider: cannot obtain credentials");
+            //throw new CredentialsNotAvailableException();
+            return null;
+        }
+
+        return credentials;
+    }
+
+    public void setCredentials(AuthScope scope, Credentials creds)
+    {
     }
 
-    return credentials;
-}
+    public void clear()
+    {
+    }
 
 ///////////////////////////////////////////////////
 // toString
 
-public String
-toString()
-{
-    return "HTTPAuthProvider("+url+")";
-}
+    public String
+    toString()
+    {
+        return "HTTPAuthProvider(" + url + ")";
+    }
 
 ///////////////////////////////////////////////////
 // (De-)Serialization support
 
-private void writeObject(java.io.ObjectOutputStream ostream)
+    private void writeObject(java.io.ObjectOutputStream ostream)
         throws IOException
-{
-    ostream.writeObject(url);
-}
+    {
+        ostream.writeObject(url);
+    }
+
+    private void readObject(java.io.ObjectInputStream istream)
+        throws IOException, ClassNotFoundException
+    {
+        url = (String) istream.readObject();
+    }
 
-private void readObject(java.io.ObjectInputStream istream)
-    throws IOException, ClassNotFoundException
-{
-    url = (String)istream.readObject();
-}
 
-    
 }//HTTPAuthProvider
 
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthScheme.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthScheme.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthScheme.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthScheme.java	2013-09-16 07:15:50.182711244 +0200
@@ -1,79 +1,84 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-/**
- * HTTPAuthScheme defines an enum about the currently supported schemes.
- */
-
-public enum HTTPAuthScheme
-{
-    BASIC("BASIC"),
-    DIGEST("DIGEST"),
-    SSL("SSL"),
-    NTLM("NTLM"),
-    ANY("ANY");
-
-    // Define the associated standard name
-    private final String name;
-
-    HTTPAuthScheme(String name)
-    {
-        this.name = name;
-    }
-
-    public String getSchemeName()   { return name; }
- 
-    static public HTTPAuthScheme schemeForName(String name)
-    {
-	if(name != null) {
-  	    for(HTTPAuthScheme s: HTTPAuthScheme.values()) {
-  	        if(name.equalsIgnoreCase(s.name())) return s;
-	    }
-	}
-	return null;
-    }
-
-    static public HTTPAuthScheme fromAuthScope(String scheme)
-    {
-	if(scheme == null) return null;
-	if(scheme.equals(org.apache.commons.httpclient.auth.AuthPolicy.BASIC))
-	    return BASIC;
-	if(scheme.equals(org.apache.commons.httpclient.auth.AuthPolicy.DIGEST))
-	    return DIGEST;
-	if(scheme.equals(org.apache.commons.httpclient.auth.AuthPolicy.NTLM))
-	    return NTLM;
-	return null;
-    }
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.client.params.AuthPolicy;
+
+/**
+ * HTTPAuthScheme defines an enum about the currently supported schemes.
+ */
+
+public enum HTTPAuthScheme
+{
+    BASIC("BASIC"),
+    DIGEST("DIGEST"),
+    SSL("SSL"),
+    NTLM("NTLM"),
+    ANY("ANY");
+
+    // Define parameter names
+    static public final String PROVIDER  = "HTTP.provider";
+
+    // Define the associated standard name
+    private final String name;
+
+    HTTPAuthScheme(String name)
+    {
+        this.name = name;
+    }
+
+    public String getSchemeName()   { return name; }
+ 
+    static public HTTPAuthScheme schemeForName(String name)
+    {
+	if(name != null) {
+  	    for(HTTPAuthScheme s: HTTPAuthScheme.values()) {
+  	        if(name.equalsIgnoreCase(s.name())) return s;
+	    }
+	}
+	return null;
+    }
+
+    static public HTTPAuthScheme fromAuthScope(String scheme)
+    {
+	if(scheme == null) return null;
+	if(scheme.equals(AuthPolicy.BASIC))
+	    return BASIC;
+	if(scheme.equals(AuthPolicy.DIGEST))
+	    return DIGEST;
+	if(scheme.equals(AuthPolicy.NTLM))
+	    return NTLM;
+	return null;
+    }
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthStore.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthStore.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthStore.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPAuthStore.java	2013-09-16 06:54:44.698149816 +0200
@@ -38,7 +38,8 @@
 import java.util.*;
 import java.io.*;
 
-import org.apache.commons.httpclient.auth.*;
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
 
 import javax.crypto.*;
 import javax.crypto.spec.*;
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPBasicProvider.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPBasicProvider.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPBasicProvider.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPBasicProvider.java	2013-09-16 07:10:52.770325065 +0200
@@ -1,85 +1,108 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-
-//////////////////////////////////////////////////
-// Provide a non-interactive CredentialsProvider to hold
-// a username + password that might have been taken from e.g.
-// the user info part of a URL.
-
-public class HTTPBasicProvider implements CredentialsProvider, Credentials, Serializable
-{
-    String username = null;
-    String password = null;
-
-    public HTTPBasicProvider(String username, String password)
-    {
-	this.username = username;
-	this.password = password;
-    }
-
-    // Credentials Provider Interface
-    public Credentials
-    getCredentials(AuthScheme authscheme, String host, int port, boolean isproxy)
-	throws CredentialsNotAvailableException
-    {
-	UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
-	return creds;
-    }
-
-    // Serializable Interface
-    private void writeObject(java.io.ObjectOutputStream oos)
-	throws IOException
-    {
-	oos.writeObject(this.username);
-	oos.writeObject(this.password);
-    }
-
-    private void readObject(java.io.ObjectInputStream ois)
-	throws IOException, ClassNotFoundException
-    {
-	this.username = (String) ois.readObject();
-	this.password = (String) ois.readObject();
-    }
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.Principal;
+
+
+//////////////////////////////////////////////////
+// Provide a non-interactive CredentialsProvider to hold
+// a username + password that might have been taken from e.g.
+// the user info part of a URL.
+
+public class HTTPBasicProvider implements CredentialsProvider, Credentials, Serializable
+{
+    String username = null;
+    String password = null;
+
+    public HTTPBasicProvider(String username, String password)
+    {
+	this.username = username;
+	this.password = password;
+    }
+
+    // Credentials Provider Interface
+    public Credentials
+    getCredentials(AuthScope scope) //AuthScheme authscheme, String host, int port, boolean isproxy)
+    {
+	    UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
+	    return creds;
+    }
+
+    public void
+    setCredentials(AuthScope authscope, Credentials credentials)
+    {
+
+    }
+
+    public void
+    clear()
+    {
+
+    }
+
+    // Credentials Interface
+    public Principal
+    getUserPrincipal()
+    {
+        return null;
+    }
+
+    public String
+    getPassword()
+    {
+        return null;
+    }
+
+
+    // Serializable Interface
+    private void writeObject(java.io.ObjectOutputStream oos)
+	throws IOException
+    {
+	oos.writeObject(this.username);
+	oos.writeObject(this.password);
+    }
+
+    private void readObject(java.io.ObjectInputStream ois)
+	throws IOException, ClassNotFoundException
+    {
+	this.username = (String) ois.readObject();
+	this.password = (String) ois.readObject();
+    }
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HttpClientManager.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HttpClientManager.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HttpClientManager.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HttpClientManager.java	2013-09-16 07:13:05.281368349 +0200
@@ -1,374 +1,372 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpMethodBase;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-import java.io.*;
-import java.util.zip.InflaterInputStream;
-import java.util.zip.GZIPInputStream;
-import java.util.Formatter;
-
-import ucar.nc2.util.IO;
-import ucar.unidata.util.Urlencoded;
-
-/**
- * Convenience routines that wrap HTTPSession.
- *
- * @author caron
- */
-public class HttpClientManager
-{
-    static private boolean debug = false;
-    static private int timeout = 0;
-
-    /**
-     * initialize the HttpClient layer.
-     *
-     * @param provider  CredentialsProvider.
-     * @param userAgent Content of User-Agent header, may be null
-     */
-    static public void init(CredentialsProvider provider, String userAgent)
-    {
-        if(provider != null)
-            HTTPSession.setGlobalCredentialsProvider(provider);
-
-        if(userAgent != null)
-            HTTPSession.setGlobalUserAgent(userAgent + "/NetcdfJava/HttpClient");
-        else
-            HTTPSession.setGlobalUserAgent("NetcdfJava/HttpClient");
-
-    }
-
-    public static void clearState()
-    {
-    }
-
-    /**
-     * Get the content from a url. For large returns, its better to use getResponseAsStream.
-     *
-     * @param urlencoded url as a String
-     * @return contents of url as a String
-     * @throws java.io.IOException on error
-     */
-    @Urlencoded
-    public static String getContentAsString(String urlencoded)
-        throws IOException
-    {
-        return getContentAsString(null,urlencoded);
-    }
-
-    /**
-     * Get the content from a url. For large returns, its better to use getResponseAsStream.
-     *
-     * @param session   use this session, if null, create a new one
-     * @param urlencoded url as a String
-     * @return contents of url as a String
-     * @throws java.io.IOException on error
-     */
-    @Urlencoded @Deprecated
-    public static String getContentAsString(HTTPSession session, String urlencoded) throws IOException
-    {
-        HTTPSession useSession = session;
-        try {
-            if(useSession == null)
-                useSession = new HTTPSession();
-            HTTPMethod m = HTTPMethod.Get(useSession);
-            m.execute(urlencoded);
-            return m.getResponseAsString();
-        } finally {
-            if((session == null) && (useSession != null))
-                useSession.close();
-        }
-    }
-
-    /**
-     * Put content to a url, using HTTP PUT. Handles one level of 302 redirection.
-     *
-     * @param urlencoded url as a String
-     * @param content    PUT this content at the given url.
-     * @return the HTTP status return code
-     * @throws java.io.IOException on error
-     */
-    public static int putContent(String urlencoded, String content) throws IOException
-    {
-        HTTPSession session = null;
-
-        try {
-
-            session = new HTTPSession();
-            HTTPMethod m = HTTPMethod.Put(session);
-
-            m.setRequestContentAsString(content);
-
-            m.execute(urlencoded);
-
-            int resultCode = m.getStatusCode();
-
-            // followRedirect wont work for PUT
-            if(resultCode == 302) {
-                String redirectLocation;
-                Header locationHeader = m.getResponseHeader("location");
-                if(locationHeader != null) {
-                    redirectLocation = locationHeader.getValue();
-                    resultCode = putContent(redirectLocation, content);
-                }
-            }
-
-            return resultCode;
-
-        } finally {
-            if(session != null) session.close();
-        }
-    }
-
-    //////////////////////
-
-    static public String getUrlContentsAsString(String urlencoded, int maxKbytes)
-    {
-        return getUrlContentsAsString(null,urlencoded,maxKbytes);
-    }
-
-    @Deprecated
-    static public String getUrlContentsAsString(HTTPSession session, String urlencoded, int maxKbytes)
-    {
-        HTTPSession useSession = session;
-        try {
-            if(useSession == null)
-                useSession = new HTTPSession();
-
-            HTTPMethod m = HTTPMethod.Get(useSession);
-            m.setFollowRedirects(true);
-            m.setRequestHeader("Accept-Encoding", "gzip,deflate");
-
-            int status = m.execute(urlencoded);
-            if(status != 200) {
-                throw new RuntimeException("failed status = " + status);
-            }
-
-            String charset = m.getResponseCharSet();
-            if(charset == null) charset = "UTF-8";
-
-            // check for deflate and gzip compression
-            Header h = m.getResponseHeader("content-encoding");
-            String encoding = (h == null) ? null : h.getValue();
-
-            if(encoding != null && encoding.equals("deflate")) {
-                byte[] body = m.getResponseAsBytes();
-                InputStream is = new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(body)), 10000);
-                return readContents(is, charset, maxKbytes);
-
-            } else if(encoding != null && encoding.equals("gzip")) {
-                byte[] body = m.getResponseAsBytes();
-                InputStream is = new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(body)), 10000);
-                return readContents(is, charset, maxKbytes);
-
-            } else {
-                byte[] body = m.getResponseAsBytes(maxKbytes * 1000);
-                return new String(body, charset);
-            }
-
-        } catch (Exception e) {
-            if(debug) e.printStackTrace();
-            return null;
-
-        } finally {
-            if((session == null) && (useSession != null))
-                useSession.close();
-        }
-    }
-
-    static private String readContents(InputStream is, String charset, int maxKbytes) throws IOException
-    {
-        ByteArrayOutputStream bout = new ByteArrayOutputStream(1000 * maxKbytes);
-        IO.copy(is, bout, 1000 * maxKbytes);
-        return bout.toString(charset);
-    }
-
-    static public void copyUrlContentsToFile(String urlencoded, File file)
-        throws HTTPException
-    {
-        copyUrlContentsToFile(null,urlencoded,file);
-    }
-
-    @Deprecated
-    static public void copyUrlContentsToFile(HTTPSession session, String urlencoded, File file)
-        throws HTTPException
-    {
-        HTTPSession useSession = session;
-        try {
-            if(useSession == null)
-                useSession = new HTTPSession();
-
-            HTTPMethod m = HTTPMethod.Get(useSession);
-            m.setRequestHeader("Accept-Encoding", "gzip,deflate");
-
-            int status = m.execute(urlencoded);
-
-            if(status != 200) {
-                throw new RuntimeException("failed status = " + status);
-            }
-
-            String charset = m.getResponseCharSet();
-            if(charset == null) charset = "UTF-8";
-
-            // check for deflate and gzip compression
-            Header h = m.getResponseHeader("content-encoding");
-            String encoding = (h == null) ? null : h.getValue();
-
-            if(encoding != null && encoding.equals("deflate")) {
-                InputStream is = new BufferedInputStream(new InflaterInputStream(m.getResponseAsStream()), 10000);
-                IO.writeToFile(is, file.getPath());
-
-            } else if(encoding != null && encoding.equals("gzip")) {
-                InputStream is = new BufferedInputStream(new GZIPInputStream(m.getResponseAsStream()), 10000);
-                IO.writeToFile(is, file.getPath());
-
-            } else {
-                IO.writeToFile(m.getResponseAsStream(), file.getPath());
-            }
-
-        } catch (Exception e) {
-            if(debug) e.printStackTrace();
-
-        } finally {
-            if((session == null) && (useSession != null))
-                useSession.close();
-        }
-    }
-
-    static public long appendUrlContentsToFile(String urlencoded, File file, long start, long end)
-        throws HTTPException
-    {
-        return appendUrlContentsToFile(null,urlencoded,file,start,end);
-    }
-
-    @Deprecated
-    static public long appendUrlContentsToFile(HTTPSession session, String urlencoded, File file, long start, long end)
-        throws HTTPException
-    {
-        HTTPSession useSession = session;
-        long nbytes = 0;
-
-        try {
-            if(useSession == null)
-                useSession = new HTTPSession();
-
-            HTTPMethod m = HTTPMethod.Get(useSession);
-            m.setRequestHeader("Accept-Encoding", "gzip,deflate");
-            m.setRequestHeader("Range", "bytes=" + start + "-" + end);
-
-            int status = m.execute(urlencoded);
-            if((status != 200) && (status != 206)) {
-                throw new RuntimeException("failed status = " + status);
-            }
-
-            String charset = m.getResponseCharSet();
-            if(charset == null) charset = "UTF-8";
-
-            // check for deflate and gzip compression
-            Header h = m.getResponseHeader("content-encoding");
-            String encoding = (h == null) ? null : h.getValue();
-
-            if(encoding != null && encoding.equals("deflate")) {
-                InputStream is = new BufferedInputStream(new InflaterInputStream(m.getResponseAsStream()), 10000);
-                nbytes = IO.appendToFile(is, file.getPath());
-
-            } else if(encoding != null && encoding.equals("gzip")) {
-                InputStream is = new BufferedInputStream(new GZIPInputStream(m.getResponseAsStream()), 10000);
-                nbytes = IO.appendToFile(is, file.getPath());
-
-            } else {
-                nbytes = IO.appendToFile(m.getResponseAsStream(), file.getPath());
-            }
-
-        } catch (Exception e) {
-            if(debug) e.printStackTrace();
-
-        } finally {
-            if((session == null) && (useSession != null))
-                session.close();
-        }
-
-        return nbytes;
-    }
-
-    static public void showHttpRequestInfo(Formatter f, HttpMethodBase m)
-    {
-        f.format("HttpClient request %s %s %n", m.getName(), m.getPath());
-        f.format("   do Authentication=%s%n", m.getDoAuthentication());
-        f.format("   follow Redirects =%s%n", m.getFollowRedirects());
-        f.format("   effectiveVersion =%s%n", m.getEffectiveVersion());
-        f.format("   hostAuthState    =%s%n", m.getHostAuthState());
-
-        HttpMethodParams p = m.getParams();
-        f.format("   cookie policy    =%s%n", p.getCookiePolicy());
-        f.format("   http version     =%s%n", p.getVersion());
-        f.format("   timeout (msecs)  =%d%n", p.getSoTimeout());
-        f.format("   virtual host     =%s%n", p.getVirtualHost());
-
-        f.format("Request Headers = %n");
-        Header[] heads = m.getRequestHeaders();
-        for(int i = 0;i < heads.length;i++)
-            f.format("  %s", heads[i]);
-
-        f.format("%n");
-    }
-
-    static public void showHttpResponseInfo(Formatter f, HttpMethodBase m)
-    {
-        f.format("HttpClient response status = %s%n", m.getStatusLine());
-        f.format("Reponse Headers = %n");
-        Header[] heads = m.getResponseHeaders();
-        for(int i = 0;i < heads.length;i++)
-            f.format("  %s", heads[i]);
-        f.format("%n");
-    }
-
-    /*
-    public static void main(String[] args) throws IOException
-    {
-        HTTPSession.setGlobalUserAgent("TestUserAgent123global");
-        HttpClientManager.getContentAsString(null, "http://motherlode.ucar.edu:9080/thredds/catalog.html");
-
-        HTTPSession sess = new HTTPSession("http://motherlode.ucar.edu:9080/thredds/catalog.html");
-        sess.setUserAgent("TestUserAgent123session");
-        HttpClientManager.getContentAsString(sess, "http://motherlode.ucar.edu:9080/thredds/catalog.html");
-
-    } */
-
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.Header;
+
+import java.io.*;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.http.client.CredentialsProvider;
+import ucar.nc2.util.IO;
+import ucar.unidata.util.Urlencoded;
+
+/**
+ * Convenience routines that wrap HTTPSession.
+ *
+ * @author caron
+ */
+public class HttpClientManager
+{
+    static private boolean debug = false;
+    static private int timeout = 0;
+
+    /**
+     * initialize the HttpClient layer.
+     *
+     * @param provider  CredentialsProvider.
+     * @param userAgent Content of User-Agent header, may be null
+     */
+    static public void init(CredentialsProvider provider, String userAgent)
+    {
+        if(provider != null)
+            HTTPSession.setGlobalCredentialsProvider(provider);
+
+        if(userAgent != null)
+            HTTPSession.setGlobalUserAgent(userAgent + "/NetcdfJava/HttpClient");
+        else
+            HTTPSession.setGlobalUserAgent("NetcdfJava/HttpClient");
+
+    }
+
+    public static void clearState()
+    {
+    }
+
+    /**
+     * Get the content from a url. For large returns, its better to use getResponseAsStream.
+     *
+     * @param urlencoded url as a String
+     * @return contents of url as a String
+     * @throws java.io.IOException on error
+     */
+    @Urlencoded
+    public static String getContentAsString(String urlencoded)
+        throws IOException
+    {
+        return getContentAsString(null,urlencoded);
+    }
+
+    /**
+     * Get the content from a url. For large returns, its better to use getResponseAsStream.
+     *
+     * @param session   use this session, if null, create a new one
+     * @param urlencoded url as a String
+     * @return contents of url as a String
+     * @throws java.io.IOException on error
+     */
+    @Urlencoded @Deprecated
+    public static String getContentAsString(HTTPSession session, String urlencoded) throws IOException
+    {
+        HTTPSession useSession = session;
+        try {
+            if(useSession == null)
+                useSession = HTTPFactory.newSession();
+            HTTPMethod m = HTTPFactory.Get(useSession);
+            m.execute(urlencoded);
+            return m.getResponseAsString();
+        } finally {
+            if((session == null) && (useSession != null))
+                useSession.close();
+        }
+    }
+
+    /**
+     * Put content to a url, using HTTP PUT. Handles one level of 302 redirection.
+     *
+     * @param urlencoded url as a String
+     * @param content    PUT this content at the given url.
+     * @return the HTTP status return code
+     * @throws java.io.IOException on error
+     */
+    public static int putContent(String urlencoded, String content) throws IOException
+    {
+        HTTPSession session = null;
+
+        try {
+
+            session = HTTPFactory.newSession();
+            HTTPMethod m = HTTPFactory.Put(session);
+
+            m.setRequestContentAsString(content);
+
+            m.execute(urlencoded);
+
+            int resultCode = m.getStatusCode();
+
+            // followRedirect wont work for PUT
+            if(resultCode == 302) {
+                String redirectLocation;
+                Header locationHeader = m.getResponseHeader("location");
+                if(locationHeader != null) {
+                    redirectLocation = locationHeader.getValue();
+                    resultCode = putContent(redirectLocation, content);
+                }
+            }
+
+            return resultCode;
+
+        } finally {
+            if(session != null) session.close();
+        }
+    }
+
+    //////////////////////
+
+    static public String getUrlContentsAsString(String urlencoded, int maxKbytes)
+    {
+        return getUrlContentsAsString(null,urlencoded,maxKbytes);
+    }
+
+    @Deprecated
+    static public String getUrlContentsAsString(HTTPSession session, String urlencoded, int maxKbytes)
+    {
+        HTTPSession useSession = session;
+        try {
+            if(useSession == null)
+                useSession = HTTPFactory.newSession();
+
+            HTTPMethod m = HTTPFactory.Get(useSession);
+            m.setFollowRedirects(true);
+            m.setRequestHeader("Accept-Encoding", "gzip,deflate");
+
+            int status = m.execute(urlencoded);
+            if(status != 200) {
+                throw new RuntimeException("failed status = " + status);
+            }
+
+            String charset = m.getResponseCharSet();
+            if(charset == null) charset = "UTF-8";
+
+            // check for deflate and gzip compression
+            Header h = m.getResponseHeader("content-encoding");
+            String encoding = (h == null) ? null : h.getValue();
+
+            if(encoding != null && encoding.equals("deflate")) {
+                byte[] body = m.getResponseAsBytes();
+                InputStream is = new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(body)), 10000);
+                return readContents(is, charset, maxKbytes);
+
+            } else if(encoding != null && encoding.equals("gzip")) {
+                byte[] body = m.getResponseAsBytes();
+                InputStream is = new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(body)), 10000);
+                return readContents(is, charset, maxKbytes);
+
+            } else {
+                byte[] body = m.getResponseAsBytes(maxKbytes * 1000);
+                return new String(body, charset);
+            }
+
+        } catch (Exception e) {
+            if(debug) e.printStackTrace();
+            return null;
+
+        } finally {
+            if((session == null) && (useSession != null))
+                useSession.close();
+        }
+    }
+
+    static private String readContents(InputStream is, String charset, int maxKbytes) throws IOException
+    {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(1000 * maxKbytes);
+        IO.copy(is, bout, 1000 * maxKbytes);
+        return bout.toString(charset);
+    }
+
+    static public void copyUrlContentsToFile(String urlencoded, File file)
+        throws HTTPException
+    {
+        copyUrlContentsToFile(null,urlencoded,file);
+    }
+
+    @Deprecated
+    static public void copyUrlContentsToFile(HTTPSession session, String urlencoded, File file)
+        throws HTTPException
+    {
+        HTTPSession useSession = session;
+        try {
+            if(useSession == null)
+                useSession = HTTPFactory.newSession();
+
+            HTTPMethod m = HTTPFactory.Get(useSession);
+            m.setRequestHeader("Accept-Encoding", "gzip,deflate");
+
+            int status = m.execute(urlencoded);
+
+            if(status != 200) {
+                throw new RuntimeException("failed status = " + status);
+            }
+
+            String charset = m.getResponseCharSet();
+            if(charset == null) charset = "UTF-8";
+
+            // check for deflate and gzip compression
+            Header h = m.getResponseHeader("content-encoding");
+            String encoding = (h == null) ? null : h.getValue();
+
+            if(encoding != null && encoding.equals("deflate")) {
+                InputStream is = new BufferedInputStream(new InflaterInputStream(m.getResponseAsStream()), 10000);
+                IO.writeToFile(is, file.getPath());
+
+            } else if(encoding != null && encoding.equals("gzip")) {
+                InputStream is = new BufferedInputStream(new GZIPInputStream(m.getResponseAsStream()), 10000);
+                IO.writeToFile(is, file.getPath());
+
+            } else {
+                IO.writeToFile(m.getResponseAsStream(), file.getPath());
+            }
+
+        } catch (Exception e) {
+            if(debug) e.printStackTrace();
+
+        } finally {
+            if((session == null) && (useSession != null))
+                useSession.close();
+        }
+    }
+
+    static public long appendUrlContentsToFile(String urlencoded, File file, long start, long end)
+        throws HTTPException
+    {
+        return appendUrlContentsToFile(null,urlencoded,file,start,end);
+    }
+
+    @Deprecated
+    static public long appendUrlContentsToFile(HTTPSession session, String urlencoded, File file, long start, long end)
+        throws HTTPException
+    {
+        HTTPSession useSession = session;
+        long nbytes = 0;
+
+        try {
+            if(useSession == null)
+                useSession = HTTPFactory.newSession();
+
+            HTTPMethod m = HTTPFactory.Get(useSession);
+            m.setRequestHeader("Accept-Encoding", "gzip,deflate");
+            m.setRequestHeader("Range", "bytes=" + start + "-" + end);
+
+            int status = m.execute(urlencoded);
+            if((status != 200) && (status != 206)) {
+                throw new RuntimeException("failed status = " + status);
+            }
+
+            String charset = m.getResponseCharSet();
+            if(charset == null) charset = "UTF-8";
+
+            // check for deflate and gzip compression
+            Header h = m.getResponseHeader("content-encoding");
+            String encoding = (h == null) ? null : h.getValue();
+
+            if(encoding != null && encoding.equals("deflate")) {
+                InputStream is = new BufferedInputStream(new InflaterInputStream(m.getResponseAsStream()), 10000);
+                nbytes = IO.appendToFile(is, file.getPath());
+
+            } else if(encoding != null && encoding.equals("gzip")) {
+                InputStream is = new BufferedInputStream(new GZIPInputStream(m.getResponseAsStream()), 10000);
+                nbytes = IO.appendToFile(is, file.getPath());
+
+            } else {
+                nbytes = IO.appendToFile(m.getResponseAsStream(), file.getPath());
+            }
+
+        } catch (Exception e) {
+            if(debug) e.printStackTrace();
+
+        } finally {
+            if((session == null) && (useSession != null))
+                session.close();
+        }
+
+        return nbytes;
+    }
+
+    /* todo:
+    static public void showHttpRequestInfo(Formatter f, HttpRequestBase m)
+    {
+        f.format("HttpClient request %s %s %n", m.getName(), m.getPath());
+        f.format("   do Authentication=%s%n", m.getDoAuthentication());
+        f.format("   follow Redirects =%s%n", m.getFollowRedirects());
+        f.format("   effectiveVersion =%s%n", m.getEffectiveVersion());
+        f.format("   hostAuthState    =%s%n", m.getHostAuthState());
+
+        HttpMethodParams p = m.getParams();
+        f.format("   cookie policy    =%s%n", p.getCookiePolicy());
+        f.format("   http version     =%s%n", p.getVersion());
+        f.format("   timeout (msecs)  =%d%n", p.getSoTimeout());
+        f.format("   virtual host     =%s%n", p.getVirtualHost());
+
+        f.format("Request Headers = %n");
+        Header[] heads = m.getRequestHeaders();
+        for(int i = 0;i < heads.length;i++)
+            f.format("  %s", heads[i]);
+
+        f.format("%n");
+    }
+
+    static public void showHttpResponseInfo(Formatter f, HttpRequest m)
+    {
+        f.format("HttpClient response status = %s%n", m.getStatusLine());
+        f.format("Reponse Headers = %n");
+        Header[] heads = m.getResponseHeaders();
+        for(int i = 0;i < heads.length;i++)
+            f.format("  %s", heads[i]);
+        f.format("%n");
+    }  */
+
+    /*
+    public static void main(String[] args) throws IOException
+    {
+        HTTPSession.setGlobalUserAgent("TestUserAgent123global");
+        HttpClientManager.getContentAsString(null, "http://motherlode.ucar.edu:9080/thredds/catalog.html");
+
+        HTTPSession sess = HTTPFactory.newSession("http://motherlode.ucar.edu:9080/thredds/catalog.html");
+        sess.setUserAgent("TestUserAgent123session");
+        HttpClientManager.getContentAsString(sess, "http://motherlode.ucar.edu:9080/thredds/catalog.html");
+
+    } */
+
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPCredsProvider.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPCredsProvider.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPCredsProvider.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPCredsProvider.java	2013-09-16 07:05:07.959427605 +0200
@@ -1,96 +1,122 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-
-//////////////////////////////////////////////////
-// Provide a non-interactive CredentialsProvider to hold
-// an arbitrary credentials object provided by the user.
-
-public class HTTPCredsProvider implements CredentialsProvider, Credentials, Serializable
-{
-    Credentials creds = null;
-
-    public HTTPCredsProvider(Credentials creds)
-    {
-	this.creds = creds;
-    }
-
-    // Credentials Provider Interface
-    public Credentials
-    getCredentials(AuthScheme authscheme, String host, int port, boolean isproxy)
-	throws CredentialsNotAvailableException
-    {
-	return creds;
-    }
-
-    // Serializable Interface
-    private void writeObject(java.io.ObjectOutputStream oos)
-	throws IOException
-    {
-        boolean isser = (this.creds instanceof Serializable);
-        oos.writeObject(isser);
-        if(isser)
-            oos.writeObject(this.creds);
-        else {
-            oos.writeObject(this.creds.getClass());
-        }
-    }
-
-    private void readObject(java.io.ObjectInputStream ois)
-	throws IOException, ClassNotFoundException
-    {
-        // serializing the credentials is a bit tricky
-        // since it might not support the serializable interface.
-        boolean isser = (Boolean)ois.readObject();
-        Object o = ois.readObject();
-        if(isser)
-            this.creds = (Credentials)o;
-        else {
-            try {
-                this.creds = (Credentials)((Class)o).newInstance();
-            } catch (Exception e) {
-                throw new ClassNotFoundException("HTTPCredsProvider: Cannot create Credentials instance",e);
-            }
-        }
-    }
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.Principal;
+
+
+/**
+Provide a non-interactive CredentialsProvider to hold
+an arbitrary credentials object provided by the user.
+This is used in the case when the credentials (not the provider)
+are fixed. (see e.g. HTTPSession.setGlobalCredentials).
+*/
+
+public class HTTPCredsProvider implements CredentialsProvider, Credentials, Serializable
+{
+    Credentials creds = null;
+
+    public HTTPCredsProvider(Credentials creds)
+    {
+        this.creds = creds;
+    }
+
+    // Credentials Provider Interface
+    public Credentials
+    getCredentials(AuthScope scope) //AuthScheme authscheme, String host, int port, boolean isproxy)
+    {
+        return creds;
+    }
+
+    public void
+    setCredentials(AuthScope authscope, Credentials credentials)
+    {
+
+    }
+
+    public void
+    clear()
+    {
+
+    }
+
+    // Credentials Interface
+    public Principal
+    getUserPrincipal()
+    {
+        return null;
+    }
+
+    public String
+    getPassword()
+    {
+        return null;
+    }
+
+    // Serializable Interface
+    private void writeObject(java.io.ObjectOutputStream oos)
+        throws IOException
+    {
+        boolean isser = (this.creds instanceof Serializable);
+        oos.writeObject(isser);
+        if(isser)
+            oos.writeObject(this.creds);
+        else {
+            oos.writeObject(this.creds.getClass());
+        }
+    }
+
+    private void readObject(java.io.ObjectInputStream ois)
+        throws IOException, ClassNotFoundException
+    {
+        // serializing the credentials is a bit tricky
+        // since it might not support the serializable interface.
+        boolean isser = (Boolean) ois.readObject();
+        Object o = ois.readObject();
+        if(isser)
+            this.creds = (Credentials) o;
+        else {
+            try {
+                this.creds = (Credentials) ((Class) o).newInstance();
+            } catch (Exception e) {
+                throw new ClassNotFoundException("HTTPCredsProvider: Cannot create Credentials instance", e);
+            }
+        }
+    }
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPFactory.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPFactory.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPFactory.java	1970-01-01 01:00:00.000000000 +0100
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPFactory.java	2013-09-16 07:24:06.604650208 +0200
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.*;
+
+import net.jcip.annotations.NotThreadSafe;
+import org.apache.http.*;
+import org.apache.http.client.methods.*;
+import org.apache.http.client.params.AllClientPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import ucar.nc2.util.EscapeStrings;
+
+/**
+ * HTTPFactory creates method instance.
+ * This code was originally in HttpMethod.
+ */
+
+public class HTTPFactory
+{
+
+    //////////////////////////////////////////////////////////////////////////
+    // Static factory methods for creating HTTPSession instances
+
+    static public HTTPSession newSession() throws HTTPException
+    {
+        return new HTTPSession();
+    }
+
+    static public HTTPSession newSession(String legalurl) throws HTTPException
+    {
+        return new HTTPSession(legalurl);
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+    // Static factory methods for creating HTTPMethod instances
+
+    static public HTTPMethod Get(HTTPSession session) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Get, session, null);
+    }
+
+    static public HTTPMethod Head(HTTPSession session) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Head, session, null);
+    }
+
+    static public HTTPMethod Put(HTTPSession session) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Put, session, null);
+    }
+
+    static public HTTPMethod Post(HTTPSession session) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Post, session, null);
+    }
+
+    static public HTTPMethod Options(HTTPSession session) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Options, session, null);
+    }
+
+    static public HTTPMethod Get(HTTPSession session, String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Get, session, legalurl);
+    }
+
+    static public HTTPMethod Head(HTTPSession session, String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Head, session, legalurl);
+    }
+
+    static public HTTPMethod Put(HTTPSession session, String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Put, session, legalurl);
+    }
+
+    static public HTTPMethod Post(HTTPSession session, String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Post, session, legalurl);
+    }
+
+    static public HTTPMethod Options(HTTPSession session, String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Options, session, legalurl);
+    }
+
+    static public HTTPMethod Get(String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Get, legalurl);
+    }
+
+    static public HTTPMethod Head(String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Head, legalurl);
+    }
+
+    static public HTTPMethod Put(String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Put, legalurl);
+    }
+
+    static public HTTPMethod Post(String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Post, legalurl);
+    }
+
+    static public HTTPMethod Options(String legalurl) throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Options, legalurl);
+    }
+
+    static public HTTPMethod Get() throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Get);
+    }
+
+    static public HTTPMethod Head() throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Head);
+    }
+
+    static public HTTPMethod Put() throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Put);
+    }
+
+    static public HTTPMethod Post() throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Post);
+    }
+
+    static public HTTPMethod Options() throws HTTPException
+    {
+        return new HTTPMethod(HTTPSession.Methods.Options);
+    }
+
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPMethod.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPMethod.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPMethod.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPMethod.java	2013-09-16 06:44:59.065924414 +0200
@@ -37,22 +37,25 @@
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.nio.charset.Charset;
 import java.util.*;
 
-import com.sun.org.apache.xerces.internal.util.*;
 import net.jcip.annotations.NotThreadSafe;
-import org.apache.commons.httpclient.*;
-import org.apache.commons.httpclient.URI;
-import org.apache.commons.httpclient.methods.*;
-import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
-import org.apache.commons.httpclient.methods.multipart.Part;
-import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.apache.commons.httpclient.auth.*;
-
-import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.http.*;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.*;
+import org.apache.http.client.params.AllClientPNames;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicHttpResponse;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
 import ucar.nc2.util.EscapeStrings;
 
+import javax.print.URIException;
+
 
 /**
  * HTTPMethod is the encapsulation of specific
@@ -60,9 +63,9 @@
  * The general processing sequence is as follows.
  * <ol>
  * <li> Create an HTTPMethod object using one of the
- * factory methods (e.g. HTTPMethod.Get()).
+ * methods of HTTPFactory (e.g. HTTPFactory.Get()).
  * <p/>
- * <li> Set parameters and headers.
+ * <li> Set parameters and headers of the returned HTTPMethod instance.
  * <p/>
  * <li> Invoke the execute() method to actually make
  * the request.
@@ -128,7 +131,7 @@
  * To support this use case, HTTPMethod supports what amounts
  * to a one-shot use. The steps are as follows:
  * <ol>
- * <li> HTTPMethod method = HTTPMethod.Get(<url string>); note
+ * <li> HTTPMethod method = HTTPFactory.Get(<url string>); note
  * that this implicitly creates a session internal to the
  * method instance.
  * <p/>
@@ -161,149 +164,6 @@
 public class HTTPMethod
 {
     //////////////////////////////////////////////////////////////////////////
-    // Static factory methods
-
-    static public HTTPMethod Get(HTTPSession session) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Get, session, null);
-    }
-
-    static public HTTPMethod Head(HTTPSession session) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Head, session, null);
-    }
-
-    static public HTTPMethod Put(HTTPSession session) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Put, session, null);
-    }
-
-    static public HTTPMethod Post(HTTPSession session) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Post, session, null);
-    }
-
-    static public HTTPMethod Options(HTTPSession session) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Options, session, null);
-    }
-
-    static public HTTPMethod Get(HTTPSession session, String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Get, session, legalurl);
-    }
-
-    static public HTTPMethod Head(HTTPSession session, String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Head, session, legalurl);
-    }
-
-    static public HTTPMethod Put(HTTPSession session, String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Put, session, legalurl);
-    }
-
-    static public HTTPMethod Post(HTTPSession session, String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Post, session, legalurl);
-    }
-
-    static public HTTPMethod Options(HTTPSession session, String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Options, session, legalurl);
-    }
-
-    static public HTTPMethod Get(String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Get, legalurl);
-    }
-
-    static public HTTPMethod Head(String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Head, legalurl);
-    }
-
-    static public HTTPMethod Put(String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Put, legalurl);
-    }
-
-    static public HTTPMethod Post(String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Post, legalurl);
-    }
-
-    static public HTTPMethod Options(String legalurl) throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Options, legalurl);
-    }
-
-    static public HTTPMethod Get() throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Get);
-    }
-
-    static public HTTPMethod Head() throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Head);
-    }
-
-    static public HTTPMethod Put() throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Put);
-    }
-
-    static public HTTPMethod Post() throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Post);
-    }
-
-    static public HTTPMethod Options() throws HTTPException
-    {
-        return new HTTPMethod(HTTPSession.Methods.Options);
-    }
-
-    //////////////////////////////////////////////////////////////////////////
-    // Constants
-
-    //////////////////////////////////////////////////
-    // Type declarations
-
-    // Define a Retry Handler that supports specifiable retries
-    // and is optionally verbose.
-    static public class RetryHandler
-        extends org.apache.commons.httpclient.DefaultHttpMethodRetryHandler
-    {
-        static final int DFALTRETRIES = 5;
-        static int retries = DFALTRETRIES;
-        static boolean verbose = false;
-
-        public RetryHandler()
-        {
-            super(retries, false);
-        }
-
-        public boolean retryMethod(final org.apache.commons.httpclient.HttpMethod method,
-                                   final IOException exception,
-                                   int executionCount)
-        {
-            if(verbose) {
-                HTTPSession.log.debug(String.format("Retry: count=%d exception=%s\n", executionCount, exception.toString()));
-            }
-            return super.retryMethod(method, exception, executionCount);
-        }
-		
-	static public int getRetries() {return RetryHandler.retries;}
-	static public void setRetries(int retries)
-        {
-	    if(retries > 0)
-		RetryHandler.retries = retries;
-	}
-	static public boolean getVerbose() {return RetryHandler.verbose;}
-	static public void setVerbose(boolean tf) {RetryHandler.verbose = tf;}
-    }
-
-    //////////////////////////////////////////////////////////////////////////
     // Static variables
 
     static HashMap<String, Object> globalparams = new HashMap<String, Object>();
@@ -317,25 +177,23 @@
         globalparams.put(name, value);
     }
 
-    static public int getRetryCount() {return RetryHandler.getRetries();}
-    static public void setRetryCount(int count)
-	{RetryHandler.setRetries(count);}
-
     //////////////////////////////////////////////////
     // Instance fields
 
     HTTPSession session = null;
     boolean localsession = false;
-    HttpMethodBase method = null; // Current method
     String legalurl = null;
     List<Header> headers = new ArrayList<Header>();
     HashMap<String, Object> params = new HashMap<String, Object>();
-    HttpState context = null;
-    RequestEntity content = null;
+    HttpContext context = null;
+    HttpEntity content = null;
     HTTPSession.Methods methodclass = null;
-    Part[] multiparts = null;
     HTTPMethodStream methodstream = null; // wrapper for strm
     boolean closed = false;
+    HttpRequestBase method = null;
+    HttpResponse response = null;
+    //todo: List<org.apache.http.entity.mime.FormBodyPart> multiparts = null;
+
 
 
     //////////////////////////////////////////////////
@@ -357,7 +215,7 @@
         throws HTTPException
     {
         if(session == null) {
-            session = new HTTPSession();
+            session = HTTPFactory.newSession();
             localsession = true;
         }
         this.session = session;
@@ -373,37 +231,37 @@
         this.methodclass = m;
     }
 
-    HttpMethodBase
+    HttpRequestBase
     create()
     {
-        HttpMethodBase method = null;
+        HttpRequestBase method = null;
         // Unfortunately, the apache httpclient 3 code has a restrictive
         // notion of a legal url, so we need to encode it before use
         String urlencoded = EscapeStrings.escapeURL(this.legalurl);
 
         switch (this.methodclass) {
         case Put:
-            method = new PutMethod(urlencoded);
+            method = new HttpPut(urlencoded);
             break;
         case Post:
-            method = new PostMethod(urlencoded);
+            method = new HttpPost(urlencoded);
             break;
         case Get:
-            method = new GetMethod(urlencoded);
+            method = new HttpGet(urlencoded);
             break;
         case Head:
-            method = new HeadMethod(urlencoded);
+            method = new HttpHead(urlencoded);
             break;
         case Options:
-            method = new OptionsMethod(urlencoded);
+            method = new HttpOptions(urlencoded) ;
             break;
         default:
             break;
         }
         // Force some actions
         if(method != null) {
-            method.setFollowRedirects(true);
-            method.setDoAuthentication(true);
+            method.getParams().setParameter(AllClientPNames.HANDLE_REDIRECTS,true);
+            method.getParams().setParameter(AllClientPNames.HANDLE_AUTHENTICATION, true);
         }
         return method;
     }
@@ -413,14 +271,16 @@
         switch (this.methodclass) {
         case Put:
             if(this.content != null)
-                ((PutMethod) method).setRequestEntity(this.content);
+                ((HttpPut)method).setEntity(this.content);
             break;
         case Post:
-            if(multiparts != null && multiparts.length > 0) {
-                MultipartRequestEntity mre = new MultipartRequestEntity(multiparts, method.getParams());
-                ((PostMethod) method).setRequestEntity(mre);
-            } else if(this.content != null)
-                ((PostMethod) method).setRequestEntity(this.content);
+            //todo: if(multiparts != null && multiparts.length > 0) {
+            //    MultipartEntity mre = new MultipartEntity();
+            //    for()
+            //    ((PostMethod) method).setRequestEntity(mre);
+            //} else
+            if(this.content != null)
+                ((HttpPost) method).setEntity(this.content);
             break;
         case Head:
         case Get:
@@ -429,7 +289,7 @@
             break;
         }
         this.content = null; // do not reuse
-        this.multiparts = null;
+        //todo: this.multiparts = null;
     }
 
     public int execute(String url) throws HTTPException
@@ -448,51 +308,46 @@
         if(!localsession && !sessionCompatible(this.legalurl))
             throw new HTTPException("HTTPMethod: session incompatible url: " + this.legalurl);
 
-        if(this.method != null)
-            this.method.releaseConnection();
-        this.method = create();
+        if(method != null)
+            method.releaseConnection();
+        method = create();
 
         try {
             if(headers.size() > 0) {
                 for(Header h : headers) {
-                    method.addRequestHeader(h);
+                    method.addHeader(h);
                 }
             }
             if(globalparams != null) {
-                HttpMethodParams hmp = method.getParams();
+                HttpParams hmp = method.getParams();
                 for(String key : globalparams.keySet()) {
                     hmp.setParameter(key, globalparams.get(key));
                 }
             }
             if(params != null) {
-                HttpMethodParams hmp = method.getParams();
+                HttpParams hmp = method.getParams();
                 for(String key : params.keySet()) {
                     hmp.setParameter(key, params.get(key));
                 }
             }
 
-            // Change the retry handler
-            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new RetryHandler());
+            //todo: Change the retry handler
+            //httpclient.setHttpRequestRetryHandler(myRetryHandler);
+            //method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new RetryHandler());
 
             setcontent();
 
             setAuthentication(session, this);
 
-            // WARNING; DANGER WILL ROBINSION
-            // httpclient3 only allows one registered https protocol, so
-            // we built our own protocol registry to also take port into account
-            // (see HTTPSession.registerProtocol())
-
-            // get the protocol and port
-            URL hack = new URL(this.legalurl);
-            Protocol handler = session.getProtocol(hack.getProtocol(),
-                hack.getPort());
-
-            HostConfiguration hc = session.sessionClient.getHostConfiguration();
-            hc = new HostConfiguration(hc);
-            hc.setHost(hack.getHost(), hack.getPort(), handler);
-            session.sessionClient.executeMethod(hc, method);
-            int code = getStatusCode();
+            //todo: get the protocol and port
+            //URL hack = new URL(this.legalurl);
+            //Protocol handler = session.getProtocol(hack.getProtocol(),
+            //    hack.getPort());
+            //HostConfiguration hc = session.sessionClient.getHostConfiguration();
+            //hc = new HostConfiguration(hc);
+            //hc.setHost(hack.getHost(), hack.getPort(), handler);
+            response = session.sessionClient.execute(method);
+            int code = response.getStatusLine().getStatusCode();
             return code;
         } catch (Exception ie) {
             throw new HTTPException(ie);
@@ -532,46 +387,42 @@
     //////////////////////////////////////////////////
     // Accessors
 
-    public void setContext(HttpState cxt)
+    public void setContext(HttpContext cxt)
     {
         session.setContext(cxt);
     }
 
-    public HttpState getContext()
+    public HttpContext getContext()
     {
         return session.getContext();
     }
 
     public int getStatusCode()
     {
-        return method == null ? 0 : method.getStatusCode();
+        return response == null ? 0 : response.getStatusLine().getStatusCode();
     }
 
     public String getStatusLine()
     {
-        return method == null ? null : method.getStatusLine().toString();
+        return response == null ? null : response.getStatusLine().toString();
     }
 
     public String getRequestLine()
     {
         //fix: return (method == null ? null : method.getRequestLine().toString());
-        return "getrequestline not implemented";
+        throw new UnsupportedOperationException("getrequestline not implemented");
     }
 
     public String getPath()
     {
-        try {
-            return (method == null ? null : method.getURI().toString());
-        } catch (URIException e) {
-            return null;
-        }
+        return (method == null ? null : method.getURI().toString());
     }
 
     public boolean canHoldContent()
     {
         if(method == null)
             return false;
-        return !(method instanceof HeadMethod);
+        return !(method instanceof HttpHead);
     }
 
     public InputStream getResponseBodyAsStream()
@@ -588,8 +439,8 @@
         } else { // first time
             HTTPMethodStream stream = null;
             try {
-                if(method == null) return null;
-                stream = new HTTPMethodStream(method.getResponseBodyAsStream(), this);
+                if(response == null) return null;
+                stream = new HTTPMethodStream(response.getEntity().getContent(), this);
             } catch (Exception e) {
                 stream = null;
             }
@@ -598,37 +449,40 @@
         return this.methodstream;
     }
 
+    public byte[] getResponseAsBytes(int maxbytes)
+    {
+        byte[] contents = getResponseAsBytes();
+        if(contents.length > maxbytes) {
+            byte[] result = new byte[maxbytes];
+            System.arraycopy(contents,0,result,0,maxbytes);
+            contents = result;
+        }
+        return contents;
+    }
+
     public byte[] getResponseAsBytes()
     {
         if(closed)
             throw new IllegalStateException("HTTPMethod: method is closed") ;
         byte[] content = null;
+        if(response != null)
         try {
-            content = method.getResponseBody();
+            content = EntityUtils.toByteArray(response.getEntity());
         } catch (Exception e) {/*ignore*/}
         return content;
     }
 
-    public byte[] getResponseAsBytes(int maxsize)
-    {
-        byte[] content = getResponseAsBytes();
-        if(content != null && content.length > maxsize) {
-            byte[] limited = new byte[maxsize];
-            System.arraycopy(content, 0, limited, 0, maxsize);
-            content = limited;
-        }
-        return content;
-    }
-
     public String getResponseAsString(String charset)
     {
         if(closed)
             throw new IllegalStateException("HTTPMethod: method is closed") ;
-        /*charset argument currently unused ?*/
         String content = null;
+        if(response != null)
         try {
-            content = method.getResponseBodyAsString();
+            Charset cset = Charset.forName(charset);
+            content = EntityUtils.toString(response.getEntity(),cset);
         } catch (Exception e) {/*ignore*/}
+        close();//getting the response will disallow later stream
         return content;
     }
 
@@ -650,7 +504,7 @@
 
     public void setRequestHeader(String name, String value) throws HTTPException
     {
-        setRequestHeader(new Header(name, value));
+        setRequestHeader(new BasicHeader(name, value));
     }
 
     public void setRequestHeader(Header h) throws HTTPException
@@ -667,7 +521,7 @@
         if(this.method == null)
             return null;
         try {
-            return (this.method.getRequestHeader(name));
+            return (this.method.getFirstHeader(name));
         } catch (Exception e) {
             return null;
         }
@@ -678,7 +532,7 @@
         if(this.method == null)
             return null;
         try {
-            Header[] hs = this.method.getRequestHeaders();
+            Header[] hs = this.method.getAllHeaders();
             return hs;
         } catch (Exception e) {
             return null;
@@ -688,22 +542,7 @@
     public Header getResponseHeader(String name)
     {
         try {
-            return this.method.getResponseHeader(name);
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    public Header getResponseHeaderdmh(String name)
-    {
-        try {
-
-            Header[] headers = getResponseHeaders();
-            for(Header h : headers) {
-                if(h.getName().equals(name))
-                    return h;
-            }
-            return null;
+            return this.response.getFirstHeader(name);
         } catch (Exception e) {
             return null;
         }
@@ -712,17 +551,7 @@
     public Header[] getResponseHeaders()
     {
         try {
-            Header[] hs = this.method.getResponseHeaders();
-            return hs;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    public Header[] getResponseFooters()
-    {
-        try {
-            Header[] hs = this.method.getResponseFooters();
+            Header[] hs = this.response.getAllHeaders();
             return hs;
         } catch (Exception e) {
             return null;
@@ -738,39 +567,40 @@
     {
         if(this.method == null)
             return null;
-        return this.method.getParams().getParameter(key);
+        return method.getParams().getParameter(key);
     }
 
-    public HttpMethodParams getMethodParameters()
+    public HttpParams getMethodParameters()
     {
-        if(this.method == null)
+        if(method == null)
             return null;
-        return this.method.getParams();
+        return method.getParams();
     }
 
     public Object getResponseParameter(String name)
     {
-        if(this.method == null)
+        if(method == null)
             return null;
-        return this.method.getParams().getParameter(name);
+        return method.getParams().getParameter(name);
     }
 
 
     public void setRequestContentAsString(String content) throws HTTPException
     {
         try {
-            this.content = new StringRequestEntity(content, "application/text", "UTF-8");
+            this.content = new StringEntity(content, "application/text", "UTF-8");
         } catch (UnsupportedEncodingException ue) {
         }
     }
 
-    public void setMultipartRequest(Part[] parts) throws HTTPException
-    {
-        multiparts = new Part[parts.length];
-        for(int i = 0;i < parts.length;i++) {
-            multiparts[i] = parts[i];
-        }
-    }
+    //todo:
+    // public void setMultipartRequest(Part[] parts) throws HTTPException
+    //{
+    //    multiparts = new Part[parts.length];
+    //    for(int i = 0;i < parts.length;i++) {
+    //        multiparts[i] = parts[i];
+    //    }
+    //}
 
     public String getCharSet()
     {
@@ -779,59 +609,45 @@
 
     public String getName()
     {
-        return this.method == null ? null : this.method.getName();
+        return method == null ? null : method.getMethod();
     }
 
     public String getURL()
     {
-        return this.method == null ? null : this.method.getPath().toString();
+        return method == null ? null : method.getURI().toString();
     }
 
-    public String getEffectiveVersion()
+    public String getProtocolVersion()
     {
         String ver = null;
-        if(this.method != null) {
-            ver = this.method.getEffectiveVersion().toString();
+        if(method != null) {
+            ver = method.getProtocolVersion().toString();
         }
         return ver;
     }
 
-
-    public String getProtocolVersion()
-    {
-        return getEffectiveVersion();
-    }
-
     public String getSoTimeout()
     {
-        return this.method == null ? null : "" + this.method.getParams().getSoTimeout();
+        return method == null ? null : "" + method.getParams().getParameter(AllClientPNames.SO_TIMEOUT);
     }
 
-    public String getVirtualHost()
-    {
-        return this.method == null ? null : this.method.getParams().getVirtualHost();
-    }
-
-/*public HeaderIterator headerIterator() {
-    return new BasicHeaderIterator(getResponseHeaders(), null);
-}*/
-
     public String getStatusText()
     {
         return getStatusLine();
     }
 
-    public static Enumeration getAllowedMethods()
+    public static Set<String> getAllowedMethods()
     {
-        Enumeration e = new OptionsMethod().getAllowedMethods();
-        return e;
+        HttpResponse rs = new BasicHttpResponse(new ProtocolVersion("http",1,1),0,"");
+        Set<String> set = new HttpOptions().getAllowedMethods(rs);
+        return set;
     }
 
     // Convenience methods to minimize changes elsewhere
 
     public void setFollowRedirects(boolean tf)
     {
-        return; //ignore ; always done
+        //ignore ; always done
     }
 
     public String getResponseCharSet()
@@ -852,15 +668,15 @@
         return this.localsession;
     }
 
-    public HttpMethodBase
+    public HttpRequest
     getMethod()
     {
-        return this.method;
+        return method;
     }
 
     public boolean hasStreamOpen()
     {
-        return this.methodstream != null;
+        return methodstream != null;
     }
 
     public boolean isClosed()
@@ -892,7 +708,7 @@
      * We do not know, necessarily,
      * which scheme(s) will be
      * encountered, so most testing
-     * occurs in HTTPAuthCreds.
+     * occurs in HTTPAuthProvider
      */
 
     static synchronized private void
@@ -903,13 +719,12 @@
 
         // Provide a credentials (provider) to enact the process
         CredentialsProvider cp = new HTTPAuthProvider(url, method);
-
         // Since we not know where this will get called, do everywhere
-        session.sessionClient.getParams().setParameter(CredentialsProvider.PROVIDER, cp);
-
-        // Pass down info to the socket factory
-        HttpConnectionManagerParams hcp = session.sessionClient.getHttpConnectionManager().getParams();
-        hcp.setParameter(CredentialsProvider.PROVIDER, cp);
+        if(session != null && session.sessionClient != null) {
+            session.sessionClient.setCredentialsProvider(cp);
+        }
+        //HttpParams hcp = session.sessionClient.getConnectionManager().getParams();
+        //hcp.setParameter(CredentialsProvider.PROVIDER, cp);
 
     }
 
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPSession.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPSession.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPSession.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPSession.java	2013-09-16 06:46:44.531379394 +0200
@@ -34,13 +34,24 @@
 package ucar.nc2.util.net;
 
 import net.jcip.annotations.NotThreadSafe;
-import org.apache.commons.httpclient.*;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-import org.apache.commons.httpclient.params.*;
-import org.apache.commons.httpclient.protocol.Protocol;
-
-import java.net.MalformedURLException;
-import java.net.URL;
+import org.apache.http.*;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.params.AllClientPNames;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.AbstractHttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.PoolingClientConnectionManager;
+import org.apache.http.params.*;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+
+import javax.net.ssl.SSLException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.*;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
@@ -57,23 +68,23 @@
  * A Session does, however, encapsulate an instance of an Apache HttpClient.
  * <p/>
  * It is possible to specify a url when invoking, for example,
- * HTTPMethod.Get.  This is because the url argument to the
+ * HTTPFactory.Get.  This is because the url argument to the
  * HTTPSession constructor actually serves two purposes.  First, if
  * the method is created without specifying a url, then the session
  * url is used to specify the data to be retrieved by the method
  * invocation.  Second, if the method is created and specifies a
- * url, for example, HTTPMethod m = HTTPMethod.Get(session,url2);
+ * url, for example, HTTPMethod m = HTTPFactory.Get(session,url2);
  * this second url is used to specify the data to be retrieved by
  * the method invocation.  This might (and does) occur if, for
  * example, the url given to HTTPSession represented some general
  * url such as http://motherlode.ucar.edu/path/file.nc and the url
- * given to HTTPMethod.Get was for something more specific such as
+ * given to HTTPFactory.Get was for something more specific such as
  * http://motherlode.ucar.edu/path/file.nc.dds.
  * <p/>
  * The important point is that in this second method, the url must
  * be "compatible" with the session url.  The term "compatible"
  * basically means that the HTTPSession url, as a string, must be a
- * prefix of the url given to HTTPMethod.Get. This maintains the
+ * prefix of the url given to HTTPFactory.Get. This maintains the
  * semantics of the Session but allows flexibility in accessing data
  * from the server.
  * <p/>
@@ -101,17 +112,17 @@
     static public int SC_UNAUTHORIZED = HttpStatus.SC_UNAUTHORIZED;
     static public int SC_OK = HttpStatus.SC_OK;
     static public String CONNECTION_TIMEOUT = HttpConnectionParams.CONNECTION_TIMEOUT;
-    static public String SO_TIMEOUT = HttpMethodParams.SO_TIMEOUT;
+    static public String SO_TIMEOUT = AllClientPNames.SO_TIMEOUT;
 
-    static public String ALLOW_CIRCULAR_REDIRECTS = HttpClientParams.ALLOW_CIRCULAR_REDIRECTS;
-    static public String MAX_REDIRECTS = HttpClientParams.MAX_REDIRECTS;
-    static public String USER_AGENT = HttpMethodParams.USER_AGENT;
-    static public String PROTOCOL_VERSION = HttpMethodParams.PROTOCOL_VERSION;
-    static public String VIRTUAL_HOST = HttpMethodParams.VIRTUAL_HOST;
-    static public String USE_EXPECT_CONTINUE = HttpMethodParams.USE_EXPECT_CONTINUE;
-    static public String STRICT_TRANSFER_ENCODING = HttpMethodParams.STRICT_TRANSFER_ENCODING;
-    static public String HTTP_ELEMENT_CHARSET = HttpMethodParams.HTTP_ELEMENT_CHARSET;
-    static public String HTTP_CONTENT_CHARSET = HttpMethodParams.HTTP_CONTENT_CHARSET;
+    static public String ALLOW_CIRCULAR_REDIRECTS = AllClientPNames.ALLOW_CIRCULAR_REDIRECTS;
+    static public String MAX_REDIRECTS = AllClientPNames.MAX_REDIRECTS;
+    static public String USER_AGENT = AllClientPNames.USER_AGENT;
+    static public String PROTOCOL_VERSION = AllClientPNames.PROTOCOL_VERSION;
+    static public String VIRTUAL_HOST = AllClientPNames.VIRTUAL_HOST;
+    static public String USE_EXPECT_CONTINUE = AllClientPNames.USE_EXPECT_CONTINUE;
+    static public String STRICT_TRANSFER_ENCODING = AllClientPNames.STRICT_TRANSFER_ENCODING;
+    static public String HTTP_ELEMENT_CHARSET = AllClientPNames.HTTP_ELEMENT_CHARSET;
+    static public String HTTP_CONTENT_CHARSET = AllClientPNames.HTTP_CONTENT_CHARSET;
 
     /*fix:*/
     static public String HTTP_CONNECTION = "<undefined>";
@@ -131,8 +142,8 @@
 
     static class Proxy
     {
-        String host = null;
-        int port = -1;
+        public String host = null;
+        public int port = -1;
     }
 
     static enum Methods
@@ -151,18 +162,62 @@
         }
     }
 
-    // We need more powerful protocol registry.
-    static class ProtocolEntry
-    {
-        public String protocol = null;
-        public int port = 0;
-        public Protocol handler;
+    // Define a Retry Handler that supports specifiable retries
+    // and is optionally verbose.
+    static public class RetryHandler
+        implements org.apache.http.client.HttpRequestRetryHandler
+    {
+        static final int DFALTRETRIES = 5;
+        static int retries = DFALTRETRIES;
+        static boolean verbose = false;
+
+        public RetryHandler()
+        {
+        }
+
+	public boolean
+	retryRequest(IOException exception,
+                     int executionCount,
+                     HttpContext context)
+        {
+            if(verbose) {
+                HTTPSession.log.debug(String.format("Retry: count=%d exception=%s\n", executionCount, exception.toString()));
+            }
+            if(executionCount >= retries)
+                return false;
+            if((exception instanceof InterruptedIOException) // Timeout
+                || (exception instanceof UnknownHostException)
+                || (exception instanceof ConnectException) // connection refused
+                || (exception instanceof SSLException)) // ssl handshake problem
+                return false;
+            HttpRequest request
+                = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
+            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
+            if(idempotent) // Retry if the request is considered idempotent
+                return true;
+
+            return false;
+        }
 
-        public ProtocolEntry(String protocol, int port, Protocol handler)
+        static public synchronized int getRetries()
         {
-            this.protocol = protocol;
-            this.port = port;
-            this.handler = handler;
+            return RetryHandler.retries;
+        }
+
+        static public synchronized void setRetries(int retries)
+        {
+            if(retries > 0)
+                RetryHandler.retries = retries;
+        }
+
+        static public synchronized boolean getVerbose()
+        {
+            return RetryHandler.verbose;
+        }
+
+        static public synchronized void setVerbose(boolean tf)
+        {
+            RetryHandler.verbose = tf;
         }
     }
 
@@ -172,9 +227,7 @@
     static public org.slf4j.Logger log
         = org.slf4j.LoggerFactory.getLogger(HTTPSession.class);
 
-    static MultiThreadedHttpConnectionManager connmgr;
-
-    //fix: protected static SchemeRegistry schemes;
+    static PoolingClientConnectionManager connmgr;
 
     static String globalAgent = "/NetcdfJava/HttpClient3";
     static int threadcount = DFALTTHREADCOUNT;
@@ -182,23 +235,18 @@
     static int globalSoTimeout = 0;
     static int globalConnectionTimeout = 0;
     static Proxy globalproxy = null;
-    static List<ProtocolEntry> registry;
+    static int localSoTimeout = 0;
+    static int localConnectionTimeout = 0;
 
     static {
-        connmgr = new MultiThreadedHttpConnectionManager();
+        connmgr = new PoolingClientConnectionManager();
+        connmgr.getSchemeRegistry().register(
+            new Scheme("https", 8443,
+                new EasySSLProtocolSocketFactory()));
+        connmgr.getSchemeRegistry().register(
+            new Scheme("https", 443,
+                new EasySSLProtocolSocketFactory()));
         setGlobalThreadCount(DFALTTHREADCOUNT);
-        registry = new ArrayList<ProtocolEntry>();
-        // Fill in the registry for our various https ports
-        // allow self-signed certificates
-        registerProtocol("https", 0,
-            new Protocol("https",
-                new EasySSLProtocolSocketFactory(),
-                443)); // default
-        registerProtocol("https", 8443,
-            new Protocol("https",
-                new EasySSLProtocolSocketFactory(),
-                8443)); // std tomcat https entry
-
         setGlobalConnectionTimeout(DFALTTIMEOUT);
         setGlobalSoTimeout(DFALTTIMEOUT);
         getGlobalProxyD(); // get info from -D if possible
@@ -220,8 +268,8 @@
 
     static public void setGlobalThreadCount(int nthreads)
     {
-        connmgr.getParams().setMaxTotalConnections(nthreads);
-        connmgr.getParams().setDefaultMaxConnectionsPerHost(nthreads);
+        connmgr.setMaxTotal(nthreads);
+        connmgr.setDefaultMaxPerRoute(nthreads);
     }
 
     // Alias
@@ -232,86 +280,22 @@
 
     static public int getGlobalThreadCount()
     {
-        return connmgr.getParams().getMaxTotalConnections();
+        return connmgr.getMaxTotal();
     }
 
 
-    static public Cookie[] getGlobalCookies()
+    static public List<Cookie> getGlobalCookies()
     {
-        HttpClient client = new HttpClient(connmgr);
-        Cookie[] cookies = client.getState().getCookies();
+        AbstractHttpClient client = new DefaultHttpClient(connmgr);
+        List<Cookie> cookies = client.getCookieStore().getCookies();
         return cookies;
     }
 
-    // Replace org.apache.commons.httpclient.protocol.Protocol.register()
-    // This is done because the handler must depend on both the protocol
-    // (e.g https) as well as the port. One hopes this is fixed
-    // in apache httpclient v4.
-
-    static synchronized public void
-    registerProtocol(String protocol, int port, Protocol handler)
-        throws IllegalArgumentException
-    {
-        if(protocol == null)
-            throw new IllegalArgumentException();
-        if(port < 0) port = 0;
-        // port == 0 is wildcard, so use standard Protocol registry
-        if(port == 0) {// look to the standard protocol registry
-            if(handler == null)
-                Protocol.unregisterProtocol(protocol);
-            else
-                Protocol.registerProtocol(protocol, handler);
-        } else {
-            for(int i = 0;i < registry.size();i++) {
-                ProtocolEntry entry = registry.get(i);
-                if(!entry.protocol.equals(protocol)) continue;
-                if(entry.port != port) continue;
-                if(handler == null)
-                    registry.remove(i); //delete
-                else
-                    entry.handler = handler; // replace
-                return;
-            }
-            registry.add(new ProtocolEntry(protocol, port, handler));
-        }
-    }
-
-    static synchronized public Protocol
-    getProtocol(String protocol, int port)
-        throws IllegalArgumentException, IllegalStateException
-    {
-        ProtocolEntry entry = null;
-        if(protocol == null)
-            throw new IllegalArgumentException();
-        if(port < 0) port = 0;
-        // port == 0 is wildcard
-        if(port == 0) {
-            return Protocol.getProtocol(protocol); // may throw exception
-        }
-        for(int i = 0;i < registry.size();i++) {
-            entry = registry.get(i);
-            if(!entry.protocol.equals(protocol)) continue;
-            if(entry.port != port) continue;
-            return entry.handler;
-        }
-        // Retry with port 0
-        Protocol p = Protocol.getProtocol(protocol); // may throw exception
-        if(p == null)
-            throw new IllegalStateException(); // no such protocol X port
-        return p;
-    }
-
     // Timeouts
 
-    static public void setConnectionManagerTimeout(int timeout)
-    {
-        setGlobalConnectionTimeout(timeout);
-    }
-
     static public void setGlobalConnectionTimeout(int timeout)
     {
-        connmgr.getParams().setConnectionTimeout(timeout);
-
+        if(timeout >= 0) globalConnectionTimeout = timeout;
     }
 
     static public void setGlobalSoTimeout(int timeout)
@@ -400,6 +384,19 @@
         defineCredentialsProvider(scheme, HTTPAuthStore.ANY_URL, provider);
     }
 
+    static public int
+    getRetryCount()
+    {
+        return RetryHandler.getRetries();
+    }
+
+    static public void
+    setRetryCount(int count)
+    {
+        RetryHandler.setRetries(count);
+    }
+
+
     // Static Utilitiy functions
 
     static String
@@ -473,8 +470,8 @@
     static public String
     getUrlAsString(String url) throws HTTPException
     {
-        HTTPSession session = new HTTPSession(url);
-        HTTPMethod m = HTTPMethod.Get(session);
+        HTTPSession session = HTTPFactory.newSession(url);
+        HTTPMethod m = HTTPFactory.Get(session);
         int status = m.execute();
         String content = null;
         if(status == 200) {
@@ -487,8 +484,8 @@
     static public int
     putUrlAsString(String content, String url) throws HTTPException
     {
-        HTTPSession session = new HTTPSession(url);
-        HTTPMethod m = HTTPMethod.Put(session);
+        HTTPSession session = HTTPFactory.newSession(url);
+        HTTPMethod m = HTTPFactory.Put(session);
         m.setRequestContentAsString(content);
         int status = m.execute();
         m.close();
@@ -584,9 +581,9 @@
     //////////////////////////////////////////////////
     // Instance variables
 
-    HttpClient sessionClient = null;
+    AbstractHttpClient sessionClient = null;
     List<ucar.nc2.util.net.HTTPMethod> methodList = new Vector<HTTPMethod>();
-    HttpState context = null;
+    HttpContext context = null;
     String identifier = "Session";
     String useragent = null;
     String legalurl = null;
@@ -612,21 +609,21 @@
     {
         this.legalurl = legalurl;
         try {
-            sessionClient = new HttpClient(connmgr);
-            HttpClientParams clientparams = sessionClient.getParams();
+            sessionClient = new DefaultHttpClient(connmgr);
+            HttpParams clientparams = sessionClient.getParams();
 
             // Allow (circular) redirects
             clientparams.setParameter(ALLOW_CIRCULAR_REDIRECTS, true);
             clientparams.setParameter(MAX_REDIRECTS, 25);
 
             if(globalSoTimeout > 0)
-                setSoTimeout(globalSoTimeout);
+                clientparams.setParameter(AllClientPNames.SO_TIMEOUT, globalSoTimeout);
 
             if(globalConnectionTimeout > 0)
-                setConnectionTimeout(globalConnectionTimeout);
+                clientparams.setParameter(AllClientPNames.CONN_MANAGER_TIMEOUT, (long) globalConnectionTimeout);
 
             if(globalAgent != null)
-                setUserAgent(globalAgent); // May get overridden by setUserAgent
+                clientparams.setParameter(AllClientPNames.USER_AGENT, globalAgent);
 
             setAuthenticationPreemptive(globalauthpreemptive);
 
@@ -653,23 +650,21 @@
 
     public void setAuthenticationPreemptive(boolean tf)
     {
-        if(sessionClient != null)
-            sessionClient.getParams().setAuthenticationPreemptive(tf);
+        //fix if(sessionClient != null)
+        //sessionClient.getParams().setAuthenticationPreemptive(tf);
     }
 
     public void setSoTimeout(int timeout)
     {
-        sessionClient.getParams().setSoTimeout(timeout);
+        if(timeout >= 0) localSoTimeout = timeout;
     }
 
     public void setConnectionTimeout(int timeout)
     {
-        sessionClient.setConnectionTimeout(timeout);
+        if(timeout >= 0) localConnectionTimeout = timeout;
     }
 
 
-    //fix: public void setStateX(HttpState cxt) {sessionState = cxt;}
-
     /**
      * Close the session. This implies closing
      * any open methods.
@@ -677,25 +672,26 @@
 
     synchronized public void close()
     {
-	if(closed)
-	    return; // multiple calls ok
-	while(methodList.size() > 0) {
-           HTTPMethod m = methodList.get(0);
-           m.close(); // forcibly close; will invoke removemethod().
-       }
-       closed = true;
+        if(closed)
+            return; // multiple calls ok
+        while(methodList.size() > 0) {
+            HTTPMethod m = methodList.get(0);
+            m.close(); // forcibly close; will invoke removemethod().
+        }
+        closed = true;
     }
 
     public String getCookiePolicy()
     {
-        return sessionClient == null ? null : sessionClient.getParams().getCookiePolicy();
+        return sessionClient == null ? null
+            : (String) sessionClient.getParams().getParameter(AllClientPNames.COOKIE_POLICY);
     }
 
-    public Cookie[] getCookies()
+    public List<Cookie> getCookies()
     {
         if(sessionClient == null)
             return null;
-        Cookie[] cookies = sessionClient.getState().getCookies();
+        List<Cookie> cookies = sessionClient.getCookieStore().getCookies();
         return cookies;
     }
 
@@ -712,16 +708,16 @@
 
     public void setMaxRedirects(int n)
     {
-        HttpClientParams clientparams = sessionClient.getParams();
+        HttpParams clientparams = sessionClient.getParams();
         clientparams.setParameter(MAX_REDIRECTS, n);
     }
 
-    public void setContext(HttpState cxt)
+    public void setContext(HttpContext cxt)
     {
         context = cxt;
     }
 
-    public HttpState getContext()
+    public HttpContext getContext()
     {
         return context;
     }
@@ -729,8 +725,8 @@
 
     public void clearState()
     {
-        sessionClient.getState().clearCookies();
-        sessionClient.getState().clearCredentials();
+        sessionClient.getCredentialsProvider().clear();
+        sessionClient.getCookieStore().clear();
     }
 
 
@@ -742,8 +738,10 @@
     setProxy(Proxy proxy)
     {
         if(sessionClient == null) return;
-        if(proxy != null && proxy.host != null)
-            sessionClient.getHostConfiguration().setProxy(proxy.host, proxy.port);
+        if(proxy != null && proxy.host != null) {
+            HttpHost httpproxy = new HttpHost(proxy.host, proxy.port);
+            sessionClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, httpproxy);
+        }
     }
 
     void
@@ -840,7 +838,7 @@
             sessionList.clear();
             // Rebuild the connection manager
             connmgr.shutdown();
-            connmgr = new MultiThreadedHttpConnectionManager();
+            connmgr = new PoolingClientConnectionManager();
             setGlobalThreadCount(DFALTTHREADCOUNT);
         }
     }
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLProvider.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLProvider.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLProvider.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLProvider.java	2013-09-16 07:06:34.183900791 +0200
@@ -1,116 +1,136 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-/**
- * Provide an HTTP SSL CredentialsProvider
- * The getCredentials method is used in a
- * non-standard way
- */
-
-public class HTTPSSLProvider implements CredentialsProvider, Credentials, Serializable
-{
-    String keystore = null;
-    String keypass = null;
-    String truststore = null;
-    String trustpass = null;
-
-    public HTTPSSLProvider()
-    {
-        this(null,"",null,"");
-    }
-
-    public HTTPSSLProvider(String keystore,String keypass,
-                           String truststore,String trustpass)
-    {
-	this.keystore = keystore;
-	this.keypass = keypass;
-	this.truststore = truststore;
-	this.trustpass = trustpass;
-    }     
-
-    public HTTPSSLProvider(String keystore, String keypass)
-    {
-	this(keystore,keypass,null,null);
-    }     
-
-    // Provide accessors
-    public String getKeystore() {return keystore;}
-    public String getKeypassword() {return keypass;}
-    public String getTruststore() {return truststore;}
-    public String getTrustpassword() {return trustpass;}
-
-    // Credentials Provider Interface is abused
-
-    public Credentials
-    getCredentials(AuthScheme authscheme,
-                   String host,
-                   int port,
-	           boolean isproxy)
-        throws CredentialsNotAvailableException
-    {
-	return (Credentials) this;
-    }
-
-
-    // Serializable Interface
-    private void writeObject(java.io.ObjectOutputStream oos)
-        throws IOException
-    {
-        oos.writeObject(this.keystore);
-        oos.writeObject(this.keypass);
-        oos.writeObject(this.truststore);
-        oos.writeObject(this.trustpass);
-    }
-
-    private void readObject(java.io.ObjectInputStream ois)
-            throws IOException, ClassNotFoundException
-    {
-        this.keystore = (String)ois.readObject();
-        this.keypass = (String)ois.readObject();
-        this.truststore = (String)ois.readObject();
-        this.trustpass = (String)ois.readObject();
-    }
-
-
-
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.Principal;
+
+/**
+ * Provide an HTTP SSL CredentialsProvider
+ * The getCredentials method is used in a
+ * non-standard way
+ */
+
+public class HTTPSSLProvider implements CredentialsProvider, Credentials, Serializable
+{
+    String keystore = null;
+    String keypass = null;
+    String truststore = null;
+    String trustpass = null;
+
+    public HTTPSSLProvider()
+    {
+        this(null,"",null,"");
+    }
+
+    public HTTPSSLProvider(String keystore,String keypass,
+                           String truststore,String trustpass)
+    {
+	this.keystore = keystore;
+	this.keypass = keypass;
+	this.truststore = truststore;
+	this.trustpass = trustpass;
+    }     
+
+    public HTTPSSLProvider(String keystore, String keypass)
+    {
+	this(keystore,keypass,null,null);
+    }     
+
+    // Provide accessors
+    public String getKeystore() {return keystore;}
+    public String getKeypassword() {return keypass;}
+    public String getTruststore() {return truststore;}
+    public String getTrustpassword() {return trustpass;}
+
+    // Credentials Provider Interface is abused
+
+    public Credentials
+    getCredentials(AuthScope scope) //AuthScheme authscheme,String host,int port,boolean isproxy)
+    {
+	    return (Credentials) this;
+    }
+
+    public void
+    setCredentials(AuthScope scope, Credentials creds)
+    {
+
+    }
+
+    public void
+    clear()
+    {
+
+    }
+
+    // Credentials Interface
+    public Principal
+    getUserPrincipal()
+    {
+        return null;
+    }
+
+    public String
+    getPassword()
+    {
+       return null;
+    }
+
+
+    // Serializable Interface
+    private void writeObject(java.io.ObjectOutputStream oos)
+        throws IOException
+    {
+        oos.writeObject(this.keystore);
+        oos.writeObject(this.keypass);
+        oos.writeObject(this.truststore);
+        oos.writeObject(this.trustpass);
+    }
+
+    private void readObject(java.io.ObjectInputStream ois)
+            throws IOException, ClassNotFoundException
+    {
+        this.keystore = (String)ois.readObject();
+        this.keypass = (String)ois.readObject();
+        this.truststore = (String)ois.readObject();
+        this.trustpass = (String)ois.readObject();
+    }
+
+
+
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLScheme.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLScheme.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLScheme.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/net/HTTPSSLScheme.java	2013-09-16 07:09:21.105137441 +0200
@@ -1,112 +1,94 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.AuthScope;
-import org.apache.commons.httpclient.auth.AuthenticationException;
-import org.apache.commons.httpclient.auth.MalformedChallengeException;
-
-public class HTTPSSLScheme implements AuthScheme
-{
-
-static public final HTTPSSLScheme Default  = new HTTPSSLScheme();
-
-public
-HTTPSSLScheme()
-{
-}
-
-public String
-getSchemeName()
-{
-    return "SSL";
-}
-
-
-public void
-processChallenge(String url)
-    throws MalformedChallengeException
-{
-}
-    
-public String
-getParameter(String key)
-{
-    return null;
-}
-    
-public String
-getRealm()
-{
-    return AuthScope.ANY_REALM;
-}
-    
-@Deprecated
-public String
-getID()
-{
-    return null;
-}
-    
-public boolean
-isConnectionBased()
-{
-    return false;
-}
-    
-public boolean
-isComplete()
-{
-    return true;
-}
-    
-@Deprecated
-public String
-authenticate(Credentials credentials, String url, String url1)
-    throws AuthenticationException
-{
-    return null;
-}
-    
-public String
-authenticate(Credentials credentials, HttpMethod httpMethod)
-    throws AuthenticationException
-{
-    return null;
-}
-
-}
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.apache.http.auth.*;
+
+public class HTTPSSLScheme implements AuthScheme
+{
+
+static public final HTTPSSLScheme Default  = new HTTPSSLScheme();
+
+public
+HTTPSSLScheme()
+{
+}
+
+public String
+getSchemeName()
+{
+    return "SSL";
+}
+
+public void
+processChallenge(Header header)
+    throws MalformedChallengeException
+{
+}
+    
+public String
+getParameter(String key)
+{
+    return null;
+}
+    
+public String
+getRealm()
+{
+    return AuthScope.ANY_REALM;
+}
+    
+public boolean
+isConnectionBased()
+{
+    return false;
+}
+    
+public boolean
+isComplete()
+{
+    return true;
+}
+
+@Deprecated
+public Header
+authenticate(Credentials credentials, HttpRequest request)
+    throws AuthenticationException
+{
+    return null;
+}
+
+}
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/URLnaming.java thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/URLnaming.java
--- thredds-4.3.18/cdm/src/main/java/ucar/nc2/util/URLnaming.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/nc2/util/URLnaming.java	2013-09-16 06:52:51.175110116 +0200
@@ -1,361 +1,359 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-package ucar.nc2.util;
-
-import ucar.nc2.util.EscapeStrings;
-import org.apache.commons.httpclient.URIException;
-import org.apache.commons.httpclient.util.URIUtil;
-
-import java.io.UnsupportedEncodingException;
-import java.net.*;
-import java.io.File;
-
-/**
- * Networking utilities.
- *
- * @author caron
- */
-public class URLnaming {
-
-  @Deprecated
-  public static String escapeQuery(String urlString) {
-    urlString = urlString.trim();
-    String[] split = urlString.split("[?]");
-    return (split[0] == null ? "" : split[0])
-            + (split[1] == null ? "" : '?' + EscapeStrings.escapeURLQuery(split[1]));
-  }
-
-  @Deprecated
-  private static String escapeQueryNew(String urlString) {
-    urlString = urlString.trim();
-    URI uri = null;
-    try {
-      uri = new URI(urlString);
-      return uri.toASCIIString();
-    } catch (URISyntaxException e) {
-      e.printStackTrace();
-      return "";
-    }
-  }
-
-  @Deprecated
-  private static String escapeQueryURIUtil(String urlString) {
-    urlString = urlString.trim();
-    int posQ = urlString.indexOf("?");
-    if ((posQ > 0) && (posQ < urlString.length() - 2)) {
-      String query = urlString.substring(posQ + 1);
-      if (query.indexOf("%") < 0) { // assume that its not already encoded...
-        String path = urlString.substring(0, posQ);
-        try {
-          urlString = path + "?" + URIUtil.encodeQuery(query);
-        } catch (URIException e) {
-          e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-        }
-      }
-    }
-    return urlString;
-  }
-
-  @Deprecated
-  private static String escapeQueryEncoder(String urlString) {
-    urlString = urlString.trim();
-    int posQ = urlString.indexOf("?");
-    if ((posQ > 0) && (posQ < urlString.length() - 2)) {
-      String query = urlString.substring(posQ + 1);
-      if (!query.contains("%")) { // skip if already encoded
-        String path = urlString.substring(0, posQ);
-        try {
-          urlString = path + "?" + URLEncoder.encode(query, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-          e.printStackTrace();
-        }
-      }
-    }
-    return urlString;
-  }
-
-  @Deprecated
-  private static String unescapeQueryDODS(String urlString) {
-    urlString = urlString.trim();
-    int posQ = urlString.indexOf("?");
-    if ((posQ >= 0) && (posQ < urlString.length() - 2)) {
-      String path = urlString.substring(0, posQ);
-      String query = urlString.substring(posQ + 1);
-      return path + "?" + EscapeStrings.unescapeURLQuery(query);
-    }
-    return urlString;
-  }
-
-
-  @Deprecated
-  private static String unescapeQueryDecoder(String urlString) {
-
-    urlString = urlString.trim();
-    int posQ = urlString.indexOf("?");
-    if ((posQ >= 0) && (posQ < urlString.length() - 2)) {
-      String path = urlString.substring(0, posQ);
-      String query = urlString.substring(posQ + 1);
-      try {
-        return path + "?" + URLDecoder.decode(query, "UTF-8");
-      } catch (UnsupportedEncodingException e) {
-        e.printStackTrace();
-      }
-    }
-    return urlString;
-  }
-
-
-  /// try to figure out if we need to add file: to the location when writing
-  static public String canonicalizeWrite(String location) {
-    try {
-      URI refURI = URI.create(location);
-      if (refURI.isAbsolute())
-        return location;
-    } catch (Exception e) {
-      //return "file:" + location;
-    }
-    return "file:" + location;
-  }
-
-  /**
-   * This augments URI.resolve(), by also dealing with file: URIs.
-   * If baseURi is not a file: scheme, then URI.resolve is called.
-   * Otherwise the last "/" is found in the base, and the ref is appended to it.
-   * <p> For file: baseURLS: only reletive URLS not starting with / are supported. This is
-   * apparently different from the behavior of URI.resolve(), so may be trouble,
-   * but it allows NcML absolute location to be specified without the file: prefix.
-   * <p/>
-   * Example : <pre>
-   * base:     file://my/guide/collections/designfaq.ncml
-   * ref:      sub/my.nc
-   * resolved: file://my/guide/collections/sub/my.nc
-   * </pre>
-   *
-   * @param baseUri     base URI as a Strng
-   * @param relativeUri reletive URI, as a String
-   * @return the resolved URI as a String
-   */
-  public static String resolve(String baseUri, String relativeUri) {
-    if ((baseUri == null) || (relativeUri == null))
-      return relativeUri;
-
-    if (relativeUri.startsWith("file:"))
-      return relativeUri;
-
-    // deal with a base file URL
-    if (baseUri.startsWith("file:")) {
-
-      // the case where the reletiveURL is absolute.
-      // unfortunately, we may get an Exception
-      try {
-        URI uriRelative = URI.create(relativeUri);
-        if (uriRelative.isAbsolute())
-          return relativeUri;
-      } catch (Exception e) {
-        // empty
-      }
-
-      if ((relativeUri.length() > 0) && (relativeUri.charAt(0) == '#'))
-        return baseUri + relativeUri;
-
-      if ((relativeUri.length() > 0) && (relativeUri.charAt(0) == '/'))
-        return relativeUri;
-
-      int pos = baseUri.lastIndexOf('/');
-      if (pos > 0) {
-        return baseUri.substring(0, pos + 1) + relativeUri;
-      }
-    }
-
-    // non-file URLs
-
-    //relativeUri = canonicalizeRead(relativeUri);
-    try {
-      URI reletiveURI = URI.create(relativeUri);
-      if (reletiveURI.isAbsolute())
-        return relativeUri;
-
-      //otherwise let the URI class resolve it
-      URI baseURI = URI.create(baseUri);
-      URI resolvedURI = baseURI.resolve(reletiveURI);
-      return resolvedURI.toASCIIString();
-
-    } catch (IllegalArgumentException e) {
-      return  relativeUri;
-    }
-  }
-
-  /// try to figure out if we need to add file: to the location when reading
-  static public String canonicalizeRead(String location) {
-    try {
-      URI refURI = URI.create(location);
-      if (refURI.isAbsolute())
-        return location;
-    } catch (Exception e) {
-      return "file:" + location;
-    }
-    return location;
-  }
-
-
-  public static String resolveFile(String baseDir, String filepath) {
-    if (baseDir == null) return filepath;
-    if (filepath == null) return filepath;
-    File file = new File(filepath);
-    if (file.isAbsolute()) return filepath;
-
-    if (baseDir.startsWith("file:"))
-      baseDir = baseDir.substring(5);
-
-    File base = new File(baseDir);
-    if (!base.isDirectory())
-      base = base.getParentFile();
-    if (base == null) return filepath;
-    return base.getAbsolutePath() + "/" + filepath;
-  }
-
-  ///////////////////////////////////////////////////////////////////
-
-  /* private static void initProtocolHandler() {
-    // test setting the http protocol handler
-    try {
-      new java.net.URL(null, "http://motherlode.ucar.edu:8080/", new sun.net.www.protocol.http.Handler());
-    } catch (java.net.MalformedURLException e) {
-      e.printStackTrace();
-    }
-
-  } */
-
-  private static void test(String uriS) {
-    System.out.println(uriS);
-    //uriS = URLEncoder.encode(uriS, "UTF-8");
-    //System.out.println(uriS);
-
-    URI uri = URI.create(uriS);
-    System.out.println(" scheme=" + uri.getScheme());
-    System.out.println(" getSchemeSpecificPart=" + uri.getSchemeSpecificPart());
-    System.out.println(" getAuthority=" + uri.getAuthority());
-    System.out.println(" getPath=" + uri.getPath());
-    System.out.println(" getQuery=" + uri.getQuery());
-    System.out.println();
-  }
-
-  public static void main1(String args[]) {
-    testResolve("file:/test/me/", "blank in dir", "file:/test/me/blank in dir");
-  }
-
-  public static void main2(String args[]) {
-    test("file:test/dir");
-    test("file:/test/dir");
-    test("file://test/dir");
-    test("file:///test/dir");
-
-    test("file:C:/Program Files (x86)/Apache Software Foundation/Tomcat 5.0/content/thredds/cache");
-    test("file:C:\\Program Files (x86)\\Apache Software Foundation\\Tomcat 5.0\\content\\thredds\\cache");
-    test("http://localhost:8080/thredds/catalog.html?hi=lo");
-  }
-
-  private static void testResolve(String base, String rel, String result) {
-    System.out.println("\nbase= " + base);
-    System.out.println("rel= " + rel);
-    System.out.println("resolve= " + resolve(base, rel));
-    if (result != null)
-      assert resolve(base, rel).equals(result);
-  }
-
-  public static void main3(String args[]) {
-    testResolve("http://test/me/", "wanna", "http://test/me/wanna");
-    testResolve("http://test/me/", "/wanna", "http://test/wanna");
-    testResolve("file:/test/me/", "wanna", "file:/test/me/wanna");
-    testResolve("file:/test/me/", "/wanna", "/wanna");  // LOOK doesnt work for URI.resolve() directly.
-
-    testResolve("file://test/me/", "http:/wanna", "http:/wanna");
-    testResolve("file://test/me/", "file:/wanna", "file:/wanna");
-    testResolve("file://test/me/", "C:/wanna", "C:/wanna");
-    testResolve("http://test/me/", "file:wanna", "file:wanna");
-  }
-
-
-  public static void main4(String args[]) {
-    try {
-      URL url = new URL("file:src/test/data/ncml/nc/");
-      URI uri = new URI("file:src/test/data/ncml/nc/");
-      File f = new File(uri);
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-  }
-
-  public static void main5(String args[]) throws URISyntaxException {
-    String uriString = "http://motherlode.ucar.edu:8081/dts/test.53.dods?types[0:1:9]";
-    URI uri = new URI(uriString);
-  }
-
-  private static void checkEsc(String s) {
-    System.out.printf("org =            %s%n", s);
-    System.out.printf("escapeQuery    = %s%n", escapeQuery(s));
-    System.out.printf("escapeQueryNew = %s%n", escapeQueryNew(s));
-    System.out.printf("escQueryURIUtil= %s%n", escapeQueryURIUtil(s));
-    System.out.printf("escQueryEncoder= %s%n", escapeQueryEncoder(s));
-    System.out.printf("unescQueryDODS = %s%n", unescapeQueryDODS(escapeQuery(s)));
-    System.out.printf("%n");
-  }
-
-  private static void checkUnEsc(String esc) {
-    System.out.printf("esc =             %s%n", esc);
-    System.out.printf("unescQueryDODS  = %s%n", unescapeQueryDODS(esc));
-    System.out.printf("unescapeDecoder = %s%n", unescapeQueryDecoder(esc));
-    System.out.printf("escapeQuery     = %s%n", escapeQuery(unescapeQueryDODS(esc)));
-    System.out.printf("%n");
-  }
-
-  private static void decode(String esc) {
-    System.out.printf("esc =               %s%n", esc);
-    System.out.printf("URLDecoder.decode = %s%n", URLDecoder.decode(esc));
-    System.out.printf("%n");
-  }
-
-
-
-  public static void main(String args[]) throws URISyntaxException {
-    if (args.length > 0) {
-      checkUnEsc(args[0]);
-    } else {
-      String s = "/thredds/dodsC/grib/NCEP/NAM/CONUS_12km/best.dods?Relative_humidity_pressure%5b0:1:0%5d%5b0:1:24%5d%5b0:10:420%5d%5b0:10:610%5d";
-      decode(s);
-    }
-
-  }
-
-
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+package ucar.nc2.util;
+
+
+import javax.print.URIException;
+import java.io.UnsupportedEncodingException;
+import java.net.*;
+import java.io.File;
+
+/**
+ * Networking utilities.
+ *
+ * @author caron
+ */
+public class URLnaming {
+
+  @Deprecated
+  public static String escapeQuery(String urlString) {
+    urlString = urlString.trim();
+    String[] split = urlString.split("[?]");
+    return (split[0] == null ? "" : split[0])
+            + (split[1] == null ? "" : '?' + EscapeStrings.escapeURLQuery(split[1]));
+  }
+
+  @Deprecated
+  private static String escapeQueryNew(String urlString) {
+    urlString = urlString.trim();
+    URI uri = null;
+    try {
+      uri = new URI(urlString);
+      return uri.toASCIIString();
+    } catch (URISyntaxException e) {
+      e.printStackTrace();
+      return "";
+    }
+  }
+
+  @Deprecated
+  private static String escapeQueryURIUtil(String urlString) {
+    urlString = urlString.trim();
+    int posQ = urlString.indexOf("?");
+    if ((posQ > 0) && (posQ < urlString.length() - 2)) {
+      String query = urlString.substring(posQ + 1);
+      if (query.indexOf("%") < 0) { // assume that its not already encoded...
+        String path = urlString.substring(0, posQ);
+        try {
+          urlString = path + "?" + URLEncoder.encode(query,"UTF-8");
+        } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        }
+      }
+    }
+    return urlString;
+  }
+
+  @Deprecated
+  private static String escapeQueryEncoder(String urlString) {
+    urlString = urlString.trim();
+    int posQ = urlString.indexOf("?");
+    if ((posQ > 0) && (posQ < urlString.length() - 2)) {
+      String query = urlString.substring(posQ + 1);
+      if (!query.contains("%")) { // skip if already encoded
+        String path = urlString.substring(0, posQ);
+        try {
+          urlString = path + "?" + URLEncoder.encode(query, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+    return urlString;
+  }
+
+  @Deprecated
+  private static String unescapeQueryDODS(String urlString) {
+    urlString = urlString.trim();
+    int posQ = urlString.indexOf("?");
+    if ((posQ >= 0) && (posQ < urlString.length() - 2)) {
+      String path = urlString.substring(0, posQ);
+      String query = urlString.substring(posQ + 1);
+      return path + "?" + EscapeStrings.unescapeURLQuery(query);
+    }
+    return urlString;
+  }
+
+
+  @Deprecated
+  private static String unescapeQueryDecoder(String urlString) {
+
+    urlString = urlString.trim();
+    int posQ = urlString.indexOf("?");
+    if ((posQ >= 0) && (posQ < urlString.length() - 2)) {
+      String path = urlString.substring(0, posQ);
+      String query = urlString.substring(posQ + 1);
+      try {
+        return path + "?" + URLDecoder.decode(query, "UTF-8");
+      } catch (UnsupportedEncodingException e) {
+        e.printStackTrace();
+      }
+    }
+    return urlString;
+  }
+
+
+  /// try to figure out if we need to add file: to the location when writing
+  static public String canonicalizeWrite(String location) {
+    try {
+      URI refURI = URI.create(location);
+      if (refURI.isAbsolute())
+        return location;
+    } catch (Exception e) {
+      //return "file:" + location;
+    }
+    return "file:" + location;
+  }
+
+  /**
+   * This augments URI.resolve(), by also dealing with file: URIs.
+   * If baseURi is not a file: scheme, then URI.resolve is called.
+   * Otherwise the last "/" is found in the base, and the ref is appended to it.
+   * <p> For file: baseURLS: only reletive URLS not starting with / are supported. This is
+   * apparently different from the behavior of URI.resolve(), so may be trouble,
+   * but it allows NcML absolute location to be specified without the file: prefix.
+   * <p/>
+   * Example : <pre>
+   * base:     file://my/guide/collections/designfaq.ncml
+   * ref:      sub/my.nc
+   * resolved: file://my/guide/collections/sub/my.nc
+   * </pre>
+   *
+   * @param baseUri     base URI as a Strng
+   * @param relativeUri reletive URI, as a String
+   * @return the resolved URI as a String
+   */
+  public static String resolve(String baseUri, String relativeUri) {
+    if ((baseUri == null) || (relativeUri == null))
+      return relativeUri;
+
+    if (relativeUri.startsWith("file:"))
+      return relativeUri;
+
+    // deal with a base file URL
+    if (baseUri.startsWith("file:")) {
+
+      // the case where the reletiveURL is absolute.
+      // unfortunately, we may get an Exception
+      try {
+        URI uriRelative = URI.create(relativeUri);
+        if (uriRelative.isAbsolute())
+          return relativeUri;
+      } catch (Exception e) {
+        // empty
+      }
+
+      if ((relativeUri.length() > 0) && (relativeUri.charAt(0) == '#'))
+        return baseUri + relativeUri;
+
+      if ((relativeUri.length() > 0) && (relativeUri.charAt(0) == '/'))
+        return relativeUri;
+
+      int pos = baseUri.lastIndexOf('/');
+      if (pos > 0) {
+        return baseUri.substring(0, pos + 1) + relativeUri;
+      }
+    }
+
+    // non-file URLs
+
+    //relativeUri = canonicalizeRead(relativeUri);
+    try {
+      URI reletiveURI = URI.create(relativeUri);
+      if (reletiveURI.isAbsolute())
+        return relativeUri;
+
+      //otherwise let the URI class resolve it
+      URI baseURI = URI.create(baseUri);
+      URI resolvedURI = baseURI.resolve(reletiveURI);
+      return resolvedURI.toASCIIString();
+
+    } catch (IllegalArgumentException e) {
+      return  relativeUri;
+    }
+  }
+
+  /// try to figure out if we need to add file: to the location when reading
+  static public String canonicalizeRead(String location) {
+    try {
+      URI refURI = URI.create(location);
+      if (refURI.isAbsolute())
+        return location;
+    } catch (Exception e) {
+      return "file:" + location;
+    }
+    return location;
+  }
+
+
+  public static String resolveFile(String baseDir, String filepath) {
+    if (baseDir == null) return filepath;
+    if (filepath == null) return filepath;
+    File file = new File(filepath);
+    if (file.isAbsolute()) return filepath;
+
+    if (baseDir.startsWith("file:"))
+      baseDir = baseDir.substring(5);
+
+    File base = new File(baseDir);
+    if (!base.isDirectory())
+      base = base.getParentFile();
+    if (base == null) return filepath;
+    return base.getAbsolutePath() + "/" + filepath;
+  }
+
+  ///////////////////////////////////////////////////////////////////
+
+  /* private static void initProtocolHandler() {
+    // test setting the http protocol handler
+    try {
+      new java.net.URL(null, "http://motherlode.ucar.edu:8080/", new sun.net.www.protocol.http.Handler());
+    } catch (java.net.MalformedURLException e) {
+      e.printStackTrace();
+    }
+
+  } */
+
+  private static void test(String uriS) {
+    System.out.println(uriS);
+    //uriS = URLEncoder.encode(uriS, "UTF-8");
+    //System.out.println(uriS);
+
+    URI uri = URI.create(uriS);
+    System.out.println(" scheme=" + uri.getScheme());
+    System.out.println(" getSchemeSpecificPart=" + uri.getSchemeSpecificPart());
+    System.out.println(" getAuthority=" + uri.getAuthority());
+    System.out.println(" getPath=" + uri.getPath());
+    System.out.println(" getQuery=" + uri.getQuery());
+    System.out.println();
+  }
+
+  public static void main1(String args[]) {
+    testResolve("file:/test/me/", "blank in dir", "file:/test/me/blank in dir");
+  }
+
+  public static void main2(String args[]) {
+    test("file:test/dir");
+    test("file:/test/dir");
+    test("file://test/dir");
+    test("file:///test/dir");
+
+    test("file:C:/Program Files (x86)/Apache Software Foundation/Tomcat 5.0/content/thredds/cache");
+    test("file:C:\\Program Files (x86)\\Apache Software Foundation\\Tomcat 5.0\\content\\thredds\\cache");
+    test("http://localhost:8080/thredds/catalog.html?hi=lo");
+  }
+
+  private static void testResolve(String base, String rel, String result) {
+    System.out.println("\nbase= " + base);
+    System.out.println("rel= " + rel);
+    System.out.println("resolve= " + resolve(base, rel));
+    if (result != null)
+      assert resolve(base, rel).equals(result);
+  }
+
+  public static void main3(String args[]) {
+    testResolve("http://test/me/", "wanna", "http://test/me/wanna");
+    testResolve("http://test/me/", "/wanna", "http://test/wanna");
+    testResolve("file:/test/me/", "wanna", "file:/test/me/wanna");
+    testResolve("file:/test/me/", "/wanna", "/wanna");  // LOOK doesnt work for URI.resolve() directly.
+
+    testResolve("file://test/me/", "http:/wanna", "http:/wanna");
+    testResolve("file://test/me/", "file:/wanna", "file:/wanna");
+    testResolve("file://test/me/", "C:/wanna", "C:/wanna");
+    testResolve("http://test/me/", "file:wanna", "file:wanna");
+  }
+
+
+  public static void main4(String args[]) {
+    try {
+      URL url = new URL("file:src/test/data/ncml/nc/");
+      URI uri = new URI("file:src/test/data/ncml/nc/");
+      File f = new File(uri);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  public static void main5(String args[]) throws URISyntaxException {
+    String uriString = "http://motherlode.ucar.edu:8081/dts/test.53.dods?types[0:1:9]";
+    URI uri = new URI(uriString);
+  }
+
+  private static void checkEsc(String s) {
+    System.out.printf("org =            %s%n", s);
+    System.out.printf("escapeQuery    = %s%n", escapeQuery(s));
+    System.out.printf("escapeQueryNew = %s%n", escapeQueryNew(s));
+    System.out.printf("escQueryURIUtil= %s%n", escapeQueryURIUtil(s));
+    System.out.printf("escQueryEncoder= %s%n", escapeQueryEncoder(s));
+    System.out.printf("unescQueryDODS = %s%n", unescapeQueryDODS(escapeQuery(s)));
+    System.out.printf("%n");
+  }
+
+  private static void checkUnEsc(String esc) {
+    System.out.printf("esc =             %s%n", esc);
+    System.out.printf("unescQueryDODS  = %s%n", unescapeQueryDODS(esc));
+    System.out.printf("unescapeDecoder = %s%n", unescapeQueryDecoder(esc));
+    System.out.printf("escapeQuery     = %s%n", escapeQuery(unescapeQueryDODS(esc)));
+    System.out.printf("%n");
+  }
+
+  private static void decode(String esc) {
+    System.out.printf("esc =               %s%n", esc);
+    System.out.printf("URLDecoder.decode = %s%n", URLDecoder.decode(esc));
+    System.out.printf("%n");
+  }
+
+
+
+  public static void main(String args[]) throws URISyntaxException {
+    if (args.length > 0) {
+      checkUnEsc(args[0]);
+    } else {
+      String s = "/thredds/dodsC/grib/NCEP/NAM/CONUS_12km/best.dods?Relative_humidity_pressure%5b0:1:0%5d%5b0:1:24%5d%5b0:10:420%5d%5b0:10:610%5d";
+      decode(s);
+    }
+
+  }
+
+
 }
\ Manca newline alla fine del file
diff -Nru thredds-4.3.18/cdm/src/main/java/ucar/unidata/io/http/HTTPRandomAccessFile.java thredds-4.3.18-gil/cdm/src/main/java/ucar/unidata/io/http/HTTPRandomAccessFile.java
--- thredds-4.3.18/cdm/src/main/java/ucar/unidata/io/http/HTTPRandomAccessFile.java	2013-09-16 02:10:48.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/main/java/ucar/unidata/io/http/HTTPRandomAccessFile.java	2013-09-16 07:30:57.722067952 +0200
@@ -33,9 +33,8 @@
 
 package ucar.unidata.io.http;
 
-import ucar.nc2.util.net.HTTPMethod;
-import ucar.nc2.util.net.HTTPSession;
-import org.apache.commons.httpclient.Header;
+import ucar.nc2.util.net.*;
+import org.apache.http.Header;
 import ucar.unidata.util.Urlencoded;
 
 import java.io.FileNotFoundException;
@@ -77,13 +76,13 @@
     if (debugLeaks)
       allFiles.add(location);
 
-    session = new HTTPSession(url);
+    session = HTTPFactory.newSession(url);
 
     boolean needtest = true;
 
     HTTPMethod method = null;
     try {
-      method = HTTPMethod.Head(session);
+      method = HTTPFactory.Head(session);
 
       doConnect(method);
 
@@ -137,7 +136,7 @@
   private boolean rangeOk(String url) {
     HTTPMethod method = null;
     try {
-      method = HTTPMethod.Get(session,url);
+      method = HTTPFactory.Get(session,url);
       method.setRequestHeader("Range", "bytes=" + 0 + "-" + 1);
       doConnect(method);
 
@@ -204,7 +203,7 @@
 
     HTTPMethod method = null;
     try {
-      method = HTTPMethod.Get(session);
+      method = HTTPFactory.Get(session);
       method.setFollowRedirects(true);
       method.setRequestHeader("Range", "bytes=" + pos + "-" + end);
       doConnect(method);
diff -Nru thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/NoTestAuth2.java thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/NoTestAuth2.java
--- thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/NoTestAuth2.java	2013-09-16 02:10:49.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/NoTestAuth2.java	2013-09-16 07:36:04.853944841 +0200
@@ -1,107 +1,101 @@
-/*
- * Copyright (c) 1998 - 2011. University Corporation for Atmospheric Research/Unidata
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-package ucar.nc2.util.net;
-
-import junit.framework.TestCase;
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.Credentials;
-
-import org.junit.Test;
-import ucar.nc2.util.net.HTTPException;
-import ucar.nc2.util.net.HTTPMethod;
-import ucar.nc2.util.net.HTTPSession;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-
-public class NoTestAuth2 extends TestCase
-{
-  static class Data
-  {
-      String url;
-      CredentialsProvider provider;
-      public Data(String u,CredentialsProvider p) {this.url=u; this.provider=p;}
-  }
-    static private Data[] cases = new Data[] {
-      new Data("http://thredds-test.ucar.edu:8080/thredds/dodsC/restrict/testdata/testData.nc.html",
-               new CredentialsProvider() {
-                   public Credentials getCredentials(AuthScheme sch, String h, int p, boolean pr)
-                           throws CredentialsNotAvailableException {
-                     UsernamePasswordCredentials creds
-                       = new UsernamePasswordCredentials("tiggeUser","tigge");
-                     System.out.printf("getCredentials called: creds=|%s| host=%s port=%d isproxy=%b authscheme=%s%n",
-                                  creds.toString(),h,p,pr,sch);
-                     return creds;
-                   }
-               }),
-      new Data("https://thredds-test.ucar.edu:8443/dts/b31.dds",null),
-    };
-
-
-  public void testAuth2() throws Exception
-  {
-    boolean pass = true;
-    for(Data data: cases) {
-        HTTPSession session = new HTTPSession(data.url);
-        if(data.provider != null)
-            session.setCredentialsProvider(data.provider);
-        session.setUserAgent("tdmRunner");
-        HTTPSession.setGlobalUserAgent("TDM v4.3");
-        HTTPMethod m = null;
-        try {
-          System.out.printf("url %s%n", data.url);
-          m = HTTPMethod.Get(session);
-          int status = m.execute();
-          String s = m.getResponseAsString();
-          System.out.printf("Trigger response = %d == %s%n", status, s);
-          if(status != 200  && status != 404)
-              pass = false;
-        } catch (HTTPException e) {
-          System.err.println("Fail: "+data.url);
-          ByteArrayOutputStream bos = new ByteArrayOutputStream(10000);
-          e.printStackTrace(new PrintStream(bos));
-          e.printStackTrace();
-          pass = false;
-        } finally {
-          if (session != null) session.close();
-        }
-    }
-    if(pass)
-      assertTrue("testAuth2", true);
-    else
-      assertTrue("testAuth2", false);
-  }
-
-}
+/*
+ * Copyright (c) 1998 - 2011. University Corporation for Atmospheric Research/Unidata
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+package ucar.nc2.util.net;
+
+import junit.framework.TestCase;
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+public class NoTestAuth2 extends TestCase
+{
+  static class Data
+  {
+      String url;
+      CredentialsProvider provider;
+      public Data(String u,CredentialsProvider p) {this.url=u; this.provider=p;}
+  }
+    static private Data[] cases = new Data[] {
+      new Data("http://thredds-test.ucar.edu:8080/thredds/dodsC/restrict/testdata/testData.nc.html",
+               new CredentialsProvider() {
+                   public Credentials getCredentials(AuthScope scope) //AuthScheme sch, String h, int p, boolean pr)
+                   {
+                     UsernamePasswordCredentials creds
+                       = new UsernamePasswordCredentials("tiggeUser","tigge");
+                     System.out.printf("getCredentials called: creds=|%s| host=%s port=%d%n",
+                                  creds.toString(),scope.getHost(),scope.getPort());
+                     return creds;
+                   }
+                   public void setCredentials(AuthScope scope, Credentials creds) {}
+                   public void clear() {}
+               }),
+      new Data("https://thredds-test.ucar.edu:8443/dts/b31.dds",null),
+    };
+
+
+  public void testAuth2() throws Exception
+  {
+    boolean pass = true;
+    for(Data data: cases) {
+        HTTPSession session = HTTPFactory.newSession(data.url);
+        if(data.provider != null)
+            session.setCredentialsProvider(data.provider);
+        session.setUserAgent("tdmRunner");
+        HTTPSession.setGlobalUserAgent("TDM v4.3");
+        HTTPMethod m = null;
+        try {
+          System.out.printf("url %s%n", data.url);
+          m = HTTPFactory.Get(session);
+          int status = m.execute();
+          String s = m.getResponseAsString();
+          System.out.printf("Trigger response = %d == %s%n", status, s);
+          if(status != 200  && status != 404)
+              pass = false;
+        } catch (HTTPException e) {
+          System.err.println("Fail: "+data.url);
+          ByteArrayOutputStream bos = new ByteArrayOutputStream(10000);
+          e.printStackTrace(new PrintStream(bos));
+          e.printStackTrace();
+          pass = false;
+        } finally {
+          if (session != null) session.close();
+        }
+    }
+    if(pass)
+      assertTrue("testAuth2", true);
+    else
+      assertTrue("testAuth2", false);
+  }
+
+}
diff -Nru thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestAuth.java thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestAuth.java
--- thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestAuth.java	2013-09-16 02:10:49.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestAuth.java	2013-09-16 07:37:28.160571635 +0200
@@ -1,452 +1,455 @@
-/*
- * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
- *
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.protocol.Protocol;
-import org.junit.Test;
-import ucar.nc2.TestLocal;
-import ucar.nc2.util.UnitTestCommon;
-
-import java.io.*;
-import java.util.List;
-import java.io.Serializable;
-
-public class TestAuth extends UnitTestCommon
-{
-    // Add a temporary control for remote versus localhost
-    static boolean remote = false;
-
-    // TODO: add proxy and digest tests
-
-    // Assuming we have thredds root, then the needed keystores
-    // are located in this directory
-    static final String KEYDIR = "/cdm/src/test/resources";
-
-    static final String CLIENTKEY = "clientkey.jks";
-    static final String CLIENTPWD = "changeit";
-
-    // Mnemonics for xfail
-    static final boolean MUSTFAIL = true;
-    static final boolean MUSTPASS = false;
-
-    static {
-        // Register the 8843 protocol to test client side keys
-        HTTPSession.registerProtocol("https", 8843,
-                new Protocol("https",
-                        new EasySSLProtocolSocketFactory(),
-                        8843));
-	HTTPSession.TESTING = true;
-    }
-
-    //////////////////////////////////////////////////
-    // Provide a non-interactive CredentialsProvider to hold
-    // the user+pwd; used in several places
-    static class BasicProvider implements CredentialsProvider, Serializable
-    {
-        String username = null;
-        String password = null;
-
-        public BasicProvider(String username, String password)
-        {
-            this.username = username;
-            this.password = password;
-        }
-
-        // Credentials Provider Interface
-        public Credentials
-        getCredentials(AuthScheme authscheme, String host, int port, boolean isproxy)
-                throws CredentialsNotAvailableException
-        {
-            UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
-            System.out.printf("getCredentials called: creds=|%s| host=%s port=%d isproxy=%b authscheme=%s%n",
-                    creds.toString(), host, port, isproxy, authscheme);
-            return creds;
-        }
-
-        // Serializable Interface
-        private void writeObject(java.io.ObjectOutputStream oos)
-                throws IOException
-        {
-            oos.writeObject(this.username);
-            oos.writeObject(this.password);
-        }
-
-        private void readObject(java.io.ObjectInputStream ois)
-                throws IOException, ClassNotFoundException
-        {
-            this.username = (String) ois.readObject();
-            this.password = (String) ois.readObject();
-        }
-    }
-
-    //////////////////////////////////////////////////
-    //////////////////////////////////////////////////
-
-    // Define the test sets
-
-    int passcount = 0;
-    int xfailcount = 0;
-    int failcount = 0;
-    boolean verbose = true;
-    boolean pass = false;
-
-    String datadir = null;
-    String threddsroot = null;
-
-    public TestAuth(String name, String testdir)
-    {
-        super(name);
-        setTitle("DAP Authorization tests");
-    }
-
-    public TestAuth(String name)
-    {
-        this(name, null);
-    }
-
-    public TestAuth()
-        {
-            this("TestAuth", null);
-        }
-    @Test
-    public void
-    testSSH() throws Exception
-    {
-        String[] sshurls = {
-                "https://thredds-test.ucar.edu:8444/dts/b31.dds"
-        };
-
-        System.out.println("*** Testing: Simple Https");
-        for (String url : sshurls) {
-            System.out.println("*** URL: " + url);
-            HTTPSession session = new HTTPSession(url);
-            HTTPMethod method = HTTPMethod.Get(session);
-            int status = method.execute();
-            System.out.printf("\tstatus code = %d\n", status);
-            pass = (status == 200);
-            assertTrue("testSSH", pass);
-        }
-    }
-
-    //////////////////////////////////////////////////
-
-    static class AuthDataBasic
-    {
-        String url;
-        String user = null;
-        String password = null;
-        boolean xfail = false; // failure expected
-
-        public AuthDataBasic(String url, String usr, String pwd, boolean xfail)
-        {
-            this.url = url;
-            this.user = usr;
-            this.password = pwd;
-            this.xfail = xfail;
-        }
-    }
-
-    static AuthDataBasic[] basictests = {
-                new AuthDataBasic("http://motherlode.ucar.edu:8081/thredds/dodsC/restrict/testData.nc.html",
-                        "tiggeUser", "tigge", MUSTPASS),
-                new AuthDataBasic("http://motherlode.ucar.edu:8081/thredds/dodsC/restrict/testData.nc.html",
-                        "", "", MUSTFAIL)
-        };
-
-
-    @Test
-    public void
-    testBasic() throws Exception
-    {
-        System.out.println("*** Testing: Http Basic Password Authorization");
-
-        for (AuthDataBasic data : basictests) {
-            CredentialsProvider provider = new BasicProvider(data.user, data.password);
-            System.out.println("*** URL: " + data.url);
-            // Test local credentials provider
-            HTTPSession session = new HTTPSession(data.url);
-            session.setCredentialsProvider(provider);
-            HTTPMethod method = HTTPMethod.Get(session);
-            int status = method.execute();
-            System.out.printf("\tlocal provider: status code = %d\n", status);
-            System.out.flush();
-            pass = (status == 200 || status == 404); // non-existence is ok
-            String msg;
-            if (data.xfail) {
-                msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
-                pass = !pass;
-            } else {
-                msg = pass ? "Local test passed" : "Local test failed";
-            }
-            System.out.println("\t" + msg);
-            if (pass) {
-                // Test global credentials provider
-                HTTPSession.setGlobalCredentialsProvider(provider);
-                session = new HTTPSession(data.url);
-                method = HTTPMethod.Get(session);
-                status = method.execute();
-                System.out.printf("\tglobal provider test: status code = %d\n", status);
-                System.out.flush();
-                pass = (status == 200 || status == 404); // non-existence is ok
-                if (data.xfail) {
-                    msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
-                    pass = !pass;
-                } else {
-                    msg = pass ? "Local test passed" : "Local test failed";
-                }
-                System.out.println("\t" + msg);
-            }
-            if (pass)
-                assertTrue("testBasic", true);
-            else
-                assertTrue("testBasic", false);
-        }
-    }
-
-    @Test
-    public void
-    testBasic2() throws Exception
-    {
-        System.out.println("*** Testing: Http Basic Password Authorization Using direct credentials");
-
-        for (AuthDataBasic data : basictests) {
-            Credentials cred = new UsernamePasswordCredentials(data.user, data.password);
-            System.out.println("*** URL: " + data.url);
-            // Test local credentials provider
-            HTTPSession session = new HTTPSession(data.url);
-            session.setCredentials(HTTPAuthScheme.BASIC,cred);
-            HTTPMethod method = HTTPMethod.Get(session);
-            int status = method.execute();
-            System.out.printf("\tlocal provider: status code = %d\n", status);
-            System.out.flush();
-            pass = (status == 200 || status == 404); // non-existence is ok
-            String msg;
-            if (data.xfail) {
-                msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
-                pass = !pass;
-            } else {
-                msg = pass ? "Local test passed" : "Local test failed";
-            }
-            System.out.println("\t" + msg);
-            if (pass) {
-                // Test global credentials provider
-                HTTPSession.setGlobalCredentials(HTTPAuthScheme.BASIC,cred);
-                session = new HTTPSession(data.url);
-                method = HTTPMethod.Get(session);
-                status = method.execute();
-                System.out.printf("\tglobal provider test: status code = %d\n", status);
-                System.out.flush();
-                pass = (status == 200 || status == 404); // non-existence is ok
-                if (data.xfail) {
-                    msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
-                    pass = !pass;
-                } else {
-                    msg = pass ? "Local test passed" : "Local test failed";
-                }
-                System.out.println("\t" + msg);
-            }
-            if (pass)
-                assertTrue("testBasic", true);
-            else
-                assertTrue("testBasic", false);
-        }
-    }
-
-    // This test is turned off until such time as thredds-test is properly set up
-    @Test
-    public void
-    testKeystore() throws Exception
-    {
-        if (false) {
-            System.out.println("*** Testing: Client-side Key based Authorization");
-
-            String server;
-            String path;
-            if (remote) {
-                server = "thredds-test.ucar.edu:8843";
-                path = "/dts/b31.dds";
-            } else {
-                server = "localhost:8843";
-                path = "/thredds/dodsC/testStandardTdsScan/1day.nc.dds";
-            }
-
-            String url = "https://" + server + path;
-            System.out.println("*** URL: " + url);
-
-            // See if the client keystore exists
-            String keystore = threddsRoot + KEYDIR + "/" + CLIENTKEY;
-            File tmp = new File(keystore);
-            if (!tmp.exists() || !tmp.canRead())
-                throw new Exception("Cannot read client key store: " + keystore);
-
-            CredentialsProvider provider = new HTTPSSLProvider(keystore, CLIENTPWD);
-            HTTPSession.setGlobalCredentialsProvider(HTTPAuthScheme.SSL, provider);
-
-            HTTPSession session = new HTTPSession(url);
-
-            //session.setCredentialsProvider(provider);
-
-            HTTPMethod method = HTTPMethod.Get(session);
-
-            int status = method.execute();
-            System.out.printf("Execute: status code = %d\n", status);
-            pass = (status == 200);
-            if (pass)
-                assertTrue("testKeystore", true);
-            else
-                assertTrue("testKeystore", false);
-        }
-    }
-
-    @Test
-    public void
-    testSerialize() throws Exception
-    {
-        System.out.println("*** Testing: HTTPAuthStore (de-)serialization");
-
-        boolean ok = true;
-        CredentialsProvider creds1 = new BasicProvider("p1", "pwd");
-        CredentialsProvider creds2 = new HTTPSSLProvider("keystore", "keystorepwd");
-        CredentialsProvider creds3 = new BasicProvider("p3", "pwd3");
-
-        // Add some entries to HTTPAuthStore
-        HTTPAuthStore.clear();
-        HTTPAuthStore.insert(new HTTPAuthStore.Entry(
-                HTTPAuthScheme.BASIC,
-                "http://ceda.ac.uk/dap/neodc/casix/seawifs_plankton/data/monthly/PSC_monthly_1998.nc.dds",
-                creds1)
-        );
-        HTTPAuthStore.insert(new HTTPAuthStore.Entry(
-                HTTPAuthScheme.SSL,
-                "http://ceda.ac.uk",
-                creds2)
-        );
-        HTTPAuthStore.insert(new HTTPAuthStore.Entry(
-                HTTPAuthScheme.BASIC,
-                "http://ceda.ac.uk",
-                creds3)
-        );
-
-        // Remove any old file
-        File target1 = new File(TestLocal.temporaryDataDir + "serial1");
-        target1.delete();
-
-        // serialize out
-        OutputStream ostream = new FileOutputStream(target1);
-        HTTPAuthStore.serialize(ostream, "password1");
-        // Read in
-        InputStream istream = new FileInputStream(target1);
-        List<HTTPAuthStore.Entry> entries = HTTPAuthStore.getDeserializedEntries(istream, "password1");
-
-        // compare
-        List<HTTPAuthStore.Entry> rows = HTTPAuthStore.getAllRows();
-        for (HTTPAuthStore.Entry row : rows) {
-            HTTPAuthStore.Entry match = null;
-            for (HTTPAuthStore.Entry e : entries) {
-                block:
-                {
-                    if (!HTTPAuthStore.Entry.identical(row, e)) break block;
-                    if (match == null)
-                        match = e;
-                    else {
-                        System.out.println("ambigous match");
-                        ok = false;
-                    }
-                }
-            }
-            if (match == null) {
-                System.out.println("no match for: " + row.toString());
-                ok = false;
-            }
-        }
-        assertTrue("test(De-)Serialize", ok);
-    }
-
-
-    // This test actually is does nothing because I have no way to test it
-    // since it requires a firwall proxy that requires username+pwd
-    @Test
-    public void
-    testFirewall() throws Exception
-    {
-	String user = null;
-	String pwd  = null;
-	String host = null;
-	int    port = -1;
-	String url  = null;
-
-        System.out.println("*** Testing: Http Firewall Proxy (with authentication)");
-	if(false) {
-            CredentialsProvider provider = new BasicProvider(user,pwd);
-            System.out.println("*** URL: " + url);
-            // Test local credentials provider
-            HTTPSession session = new HTTPSession(url);
-            session.setProxy(host,port);
-            session.setCredentialsProvider(provider);
-            HTTPMethod method = HTTPMethod.Get(session);
-            int status = method.execute();
-            System.out.printf("\tlocal provider: status code = %d\n", status);
-            System.out.flush();
-            pass = (status == 200 || status == 404); // non-existence is ok
-            String msg = pass ? "Local test passed" : "Local test failed";
-            System.out.println("\t" + msg);
-            if (pass) {
-                // Test global credentials provider
-                HTTPSession.setGlobalCredentialsProvider(provider);
-                HTTPSession.setGlobalProxy(host,port);
-                session = new HTTPSession(url);
-                method = HTTPMethod.Get(session);
-                status = method.execute();
-                System.out.printf("\tglobal provider test: status code = %d\n", status);
-                System.out.flush();
-                pass = (status == 200 || status == 404); // non-existence is ok
-                msg = pass ? "Local test passed" : "Local test failed";
-                System.out.println("\t" + msg);
-            }
-            if (pass)
-                assertTrue("testProxy", true);
-            else
-                assertTrue("testProxy", false);
-        }
-	assertTrue("testProxy",true);
-    }
-
-
-}
-
+/*
+ * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
+ *
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
+import org.junit.Test;
+import ucar.nc2.TestLocal;
+import ucar.nc2.util.UnitTestCommon;
+
+import java.io.*;
+import java.util.List;
+
+public class TestAuth extends UnitTestCommon
+{
+    // Add a temporary control for remote versus localhost
+    static boolean remote = false;
+
+    // TODO: add proxy and digest tests
+
+    // Assuming we have thredds root, then the needed keystores
+    // are located in this directory
+    static final String KEYDIR = "/cdm/src/test/resources";
+
+    static final String CLIENTKEY = "clientkey.jks";
+    static final String CLIENTPWD = "changeit";
+
+    // Mnemonics for xfail
+    static final boolean MUSTFAIL = true;
+    static final boolean MUSTPASS = false;
+
+    static {
+        //todo: Register the 8843 protocol to test client side keys
+        // HTTPSession.registerProtocol("https", 8843,
+        //       new Protocol("https",
+        //               new EasySSLProtocolSocketFactory(),
+        //               8843));
+        HTTPSession.TESTING = true;
+    }
+
+    //////////////////////////////////////////////////
+    // Provide a non-interactive CredentialsProvider to hold
+    // the user+pwd; used in several places
+    static class BasicProvider implements CredentialsProvider, Serializable
+    {
+        String username = null;
+        String password = null;
+
+        public BasicProvider(String username, String password)
+        {
+            this.username = username;
+            this.password = password;
+        }
+
+        // Credentials Provider Interface
+        public Credentials
+        getCredentials(AuthScope scope) //AuthScheme authscheme, String host, int port, boolean isproxy)
+        {
+            UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
+            System.out.printf("getCredentials called: creds=|%s| host=%s port=%d%n",
+                creds.toString(), scope.getHost(), scope.getPort());
+            return creds;
+        }
+
+        public void setCredentials(AuthScope scope, Credentials creds)
+        {
+        }
+
+        public void clear()
+        {
+        }
+
+        // Serializable Interface
+        private void writeObject(java.io.ObjectOutputStream oos)
+            throws IOException
+        {
+            oos.writeObject(this.username);
+            oos.writeObject(this.password);
+        }
+
+        private void readObject(java.io.ObjectInputStream ois)
+            throws IOException, ClassNotFoundException
+        {
+            this.username = (String) ois.readObject();
+            this.password = (String) ois.readObject();
+        }
+    }
+
+    //////////////////////////////////////////////////
+    //////////////////////////////////////////////////
+
+    // Define the test sets
+
+    int passcount = 0;
+    int xfailcount = 0;
+    int failcount = 0;
+    boolean verbose = true;
+    boolean pass = false;
+
+    String datadir = null;
+    String threddsroot = null;
+
+    public TestAuth(String name, String testdir)
+    {
+        super(name);
+        setTitle("DAP Authorization tests");
+    }
+
+    public TestAuth(String name)
+    {
+        this(name, null);
+    }
+
+    public TestAuth()
+    {
+        this("TestAuth", null);
+    }
+
+    @Test
+    public void
+    testSSH() throws Exception
+    {
+        String[] sshurls = {
+            "https://thredds-test.ucar.edu:8444/dts/b31.dds"
+        };
+
+        System.out.println("*** Testing: Simple Https");
+        for(String url : sshurls) {
+            System.out.println("*** URL: " + url);
+            HTTPSession session = HTTPFactory.newSession(url);
+            HTTPMethod method = HTTPFactory.Get(session);
+            int status = method.execute();
+            System.out.printf("\tstatus code = %d\n", status);
+            pass = (status == 200);
+            assertTrue("testSSH", pass);
+        }
+    }
+
+    //////////////////////////////////////////////////
+
+    static class AuthDataBasic
+    {
+        String url;
+        String user = null;
+        String password = null;
+        boolean xfail = false; // failure expected
+
+        public AuthDataBasic(String url, String usr, String pwd, boolean xfail)
+        {
+            this.url = url;
+            this.user = usr;
+            this.password = pwd;
+            this.xfail = xfail;
+        }
+    }
+
+    static AuthDataBasic[] basictests = {
+        new AuthDataBasic("http://motherlode.ucar.edu:8081/thredds/dodsC/restrict/testData.nc.html",
+            "tiggeUser", "tigge", MUSTPASS),
+        new AuthDataBasic("http://motherlode.ucar.edu:8081/thredds/dodsC/restrict/testData.nc.html",
+            "", "", MUSTFAIL)
+    };
+
+
+    @Test
+    public void
+    testBasic() throws Exception
+    {
+        System.out.println("*** Testing: Http Basic Password Authorization");
+
+        for(AuthDataBasic data : basictests) {
+            CredentialsProvider provider = new BasicProvider(data.user, data.password);
+            System.out.println("*** URL: " + data.url);
+            // Test local credentials provider
+            HTTPSession session = HTTPFactory.newSession(data.url);
+            session.setCredentialsProvider(provider);
+            HTTPMethod method = HTTPFactory.Get(session);
+            int status = method.execute();
+            System.out.printf("\tlocal provider: status code = %d\n", status);
+            System.out.flush();
+            pass = (status == 200 || status == 404); // non-existence is ok
+            String msg;
+            if(data.xfail) {
+                msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
+                pass = !pass;
+            } else {
+                msg = pass ? "Local test passed" : "Local test failed";
+            }
+            System.out.println("\t" + msg);
+            if(pass) {
+                // Test global credentials provider
+                HTTPSession.setGlobalCredentialsProvider(provider);
+                session = HTTPFactory.newSession(data.url);
+                method = HTTPFactory.Get(session);
+                status = method.execute();
+                System.out.printf("\tglobal provider test: status code = %d\n", status);
+                System.out.flush();
+                pass = (status == 200 || status == 404); // non-existence is ok
+                if(data.xfail) {
+                    msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
+                    pass = !pass;
+                } else {
+                    msg = pass ? "Local test passed" : "Local test failed";
+                }
+                System.out.println("\t" + msg);
+            }
+            if(pass)
+                assertTrue("testBasic", true);
+            else
+                assertTrue("testBasic", false);
+        }
+    }
+
+    @Test
+    public void
+    testBasic2() throws Exception
+    {
+        System.out.println("*** Testing: Http Basic Password Authorization Using direct credentials");
+
+        for(AuthDataBasic data : basictests) {
+            Credentials cred = new UsernamePasswordCredentials(data.user, data.password);
+            System.out.println("*** URL: " + data.url);
+            // Test local credentials provider
+            HTTPSession session = HTTPFactory.newSession(data.url);
+            session.setCredentials(HTTPAuthScheme.BASIC, cred);
+            HTTPMethod method = HTTPFactory.Get(session);
+            int status = method.execute();
+            System.out.printf("\tlocal provider: status code = %d\n", status);
+            System.out.flush();
+            pass = (status == 200 || status == 404); // non-existence is ok
+            String msg;
+            if(data.xfail) {
+                msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
+                pass = !pass;
+            } else {
+                msg = pass ? "Local test passed" : "Local test failed";
+            }
+            System.out.println("\t" + msg);
+            if(pass) {
+                // Test global credentials provider
+                HTTPSession.setGlobalCredentials(HTTPAuthScheme.BASIC, cred);
+                session = HTTPFactory.newSession(data.url);
+                method = HTTPFactory.Get(session);
+                status = method.execute();
+                System.out.printf("\tglobal provider test: status code = %d\n", status);
+                System.out.flush();
+                pass = (status == 200 || status == 404); // non-existence is ok
+                if(data.xfail) {
+                    msg = pass ? "Local test failed to fail (xfail)" : "Local test passed (xfail)";
+                    pass = !pass;
+                } else {
+                    msg = pass ? "Local test passed" : "Local test failed";
+                }
+                System.out.println("\t" + msg);
+            }
+            if(pass)
+                assertTrue("testBasic", true);
+            else
+                assertTrue("testBasic", false);
+        }
+    }
+
+    // This test is turned off until such time as thredds-test is properly set up
+    @Test
+    public void
+    testKeystore() throws Exception
+    {
+        if(false) {
+            System.out.println("*** Testing: Client-side Key based Authorization");
+
+            String server;
+            String path;
+            if(remote) {
+                server = "thredds-test.ucar.edu:8843";
+                path = "/dts/b31.dds";
+            } else {
+                server = "localhost:8843";
+                path = "/thredds/dodsC/testStandardTdsScan/1day.nc.dds";
+            }
+
+            String url = "https://" + server + path;
+            System.out.println("*** URL: " + url);
+
+            // See if the client keystore exists
+            String keystore = threddsRoot + KEYDIR + "/" + CLIENTKEY;
+            File tmp = new File(keystore);
+            if(!tmp.exists() || !tmp.canRead())
+                throw new Exception("Cannot read client key store: " + keystore);
+
+            CredentialsProvider provider = new HTTPSSLProvider(keystore, CLIENTPWD);
+            HTTPSession.setGlobalCredentialsProvider(HTTPAuthScheme.SSL, provider);
+
+            HTTPSession session = HTTPFactory.newSession(url);
+
+            //session.setCredentialsProvider(provider);
+
+            HTTPMethod method = HTTPFactory.Get(session);
+
+            int status = method.execute();
+            System.out.printf("Execute: status code = %d\n", status);
+            pass = (status == 200);
+            if(pass)
+                assertTrue("testKeystore", true);
+            else
+                assertTrue("testKeystore", false);
+        }
+    }
+
+    @Test
+    public void
+    testSerialize() throws Exception
+    {
+        System.out.println("*** Testing: HTTPAuthStore (de-)serialization");
+
+        boolean ok = true;
+        CredentialsProvider creds1 = new BasicProvider("p1", "pwd");
+        CredentialsProvider creds2 = new HTTPSSLProvider("keystore", "keystorepwd");
+        CredentialsProvider creds3 = new BasicProvider("p3", "pwd3");
+
+        // Add some entries to HTTPAuthStore
+        HTTPAuthStore.clear();
+        HTTPAuthStore.insert(new HTTPAuthStore.Entry(
+            HTTPAuthScheme.BASIC,
+            "http://ceda.ac.uk/dap/neodc/casix/seawifs_plankton/data/monthly/PSC_monthly_1998.nc.dds",
+            creds1)
+        );
+        HTTPAuthStore.insert(new HTTPAuthStore.Entry(
+            HTTPAuthScheme.SSL,
+            "http://ceda.ac.uk",
+            creds2)
+        );
+        HTTPAuthStore.insert(new HTTPAuthStore.Entry(
+            HTTPAuthScheme.BASIC,
+            "http://ceda.ac.uk",
+            creds3)
+        );
+
+        // Remove any old file
+        File target1 = new File(TestLocal.temporaryDataDir + "serial1");
+        target1.delete();
+
+        // serialize out
+        OutputStream ostream = new FileOutputStream(target1);
+        HTTPAuthStore.serialize(ostream, "password1");
+        // Read in
+        InputStream istream = new FileInputStream(target1);
+        List<HTTPAuthStore.Entry> entries = HTTPAuthStore.getDeserializedEntries(istream, "password1");
+
+        // compare
+        List<HTTPAuthStore.Entry> rows = HTTPAuthStore.getAllRows();
+        for(HTTPAuthStore.Entry row : rows) {
+            HTTPAuthStore.Entry match = null;
+            for(HTTPAuthStore.Entry e : entries) {
+                block:
+                {
+                    if(!HTTPAuthStore.Entry.identical(row, e)) break block;
+                    if(match == null)
+                        match = e;
+                    else {
+                        System.out.println("ambigous match");
+                        ok = false;
+                    }
+                }
+            }
+            if(match == null) {
+                System.out.println("no match for: " + row.toString());
+                ok = false;
+            }
+        }
+        assertTrue("test(De-)Serialize", ok);
+    }
+
+
+    // This test actually is does nothing because I have no way to test it
+    // since it requires a firwall proxy that requires username+pwd
+    @Test
+    public void
+    testFirewall() throws Exception
+    {
+        String user = null;
+        String pwd = null;
+        String host = null;
+        int port = -1;
+        String url = null;
+
+        System.out.println("*** Testing: Http Firewall Proxy (with authentication)");
+        if(false) {
+            CredentialsProvider provider = new BasicProvider(user, pwd);
+            System.out.println("*** URL: " + url);
+            // Test local credentials provider
+            HTTPSession session = HTTPFactory.newSession(url);
+            session.setProxy(host, port);
+            session.setCredentialsProvider(provider);
+            HTTPMethod method = HTTPFactory.Get(session);
+            int status = method.execute();
+            System.out.printf("\tlocal provider: status code = %d\n", status);
+            System.out.flush();
+            pass = (status == 200 || status == 404); // non-existence is ok
+            String msg = pass ? "Local test passed" : "Local test failed";
+            System.out.println("\t" + msg);
+            if(pass) {
+                // Test global credentials provider
+                HTTPSession.setGlobalCredentialsProvider(provider);
+                HTTPSession.setGlobalProxy(host, port);
+                session = HTTPFactory.newSession(url);
+                method = HTTPFactory.Get(session);
+                status = method.execute();
+                System.out.printf("\tglobal provider test: status code = %d\n", status);
+                System.out.flush();
+                pass = (status == 200 || status == 404); // non-existence is ok
+                msg = pass ? "Local test passed" : "Local test failed";
+                System.out.println("\t" + msg);
+            }
+            if(pass)
+                assertTrue("testProxy", true);
+            else
+                assertTrue("testProxy", false);
+        }
+        assertTrue("testProxy", true);
+    }
+
+
+}
+
diff -Nru thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestHTTPMethod.java thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestHTTPMethod.java
--- thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestHTTPMethod.java	2013-09-16 02:10:49.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestHTTPMethod.java	2013-09-16 07:41:12.550792277 +0200
@@ -86,8 +86,8 @@
         System.out.println("*** URL: " + url);
 
         System.out.println("*** Testing: HTTPMethod.getResponseBodyAsStream");
-        session = new HTTPSession(url);
-        method = HTTPMethod.Get(session);
+        session = HTTPFactory.newSession(url);
+        method = HTTPFactory.Get(session);
         method.execute();
         InputStream stream = method.getResponseBodyAsStream();
         // Read the whole thing
@@ -116,8 +116,8 @@
         System.out.println("*** URL: " + url);
 
         System.out.println("*** Testing: HTTPMethod.getResponseBodyAsStream partial read");
-        session = new HTTPSession(url);
-        method = HTTPMethod.Get(session);
+        session = HTTPFactory.newSession(url);
+        method = HTTPFactory.Get(session);
         method.execute();
         InputStream stream = method.getResponseBodyAsStream();
         byte[] buffer = new byte[EXPECTED];
diff -Nru thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestHTTPSession.java thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestHTTPSession.java
--- thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestHTTPSession.java	2013-09-16 02:10:49.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestHTTPSession.java	2013-09-16 07:38:53.471093249 +0200
@@ -1,87 +1,87 @@
-/*
- * Copyright (c) 1998 - 2012. University Corporation for Atmospheric Research/Unidata
- * Portions of this software were developed by the Unidata Program at the
- * University Corporation for Atmospheric Research.
- *
- * Access and use of this software shall impose the following obligations
- * and understandings on the user. The user is granted the right, without
- * any fee or cost, to use, copy, modify, alter, enhance and distribute
- * this software, and any derivative works thereof, and its supporting
- * documentation for any purpose whatsoever, provided that this entire
- * notice appears in all copies of the software, derivative works and
- * supporting documentation.  Further, UCAR requests that the user credit
- * UCAR/Unidata in any publications that result from the use of this
- * software or in any product that includes this software. The names UCAR
- * and/or Unidata, however, may not be used in any advertising or publicity
- * to endorse or promote any products or commercial entity unless specific
- * written permission is obtained from UCAR/Unidata. The user also
- * understands that UCAR/Unidata is not obligated to provide the user with
- * any support, consulting, training or assistance of any kind with regard
- * to the use, operation and performance of this software nor to provide
- * the user with any updates, revisions, new versions or "bug fixes."
- *
- * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-package ucar.nc2.util.net;
-
-import org.junit.Test;
-import ucar.nc2.util.UnitTestCommon;
-
-import static junit.framework.Assert.assertTrue;
-
-public class TestHTTPSession extends UnitTestCommon
-{
-  //////////////////////////////////////////////////
-
-  // Define the test sets
-
-  int passcount = 0;
-  int xfailcount = 0;
-  int failcount = 0;
-  boolean verbose = true;
-  boolean pass = false;
-
-  String datadir = null;
-  String threddsroot = null;
-
-  public TestHTTPSession()
-  {
-    super();
-    setTitle("HTTP Session tests");
-    HTTPSession.TESTING = true;
-  }
-
-  @Test
-  public void
-  testAgent() throws Exception {
-    String globalagent = "TestUserAgent123global";
-    String sessionagent = "TestUserAgent123session";
-    String url =
-            "http://thredds-test.ucar.edu:8081/dts/test.01.dds";
-
-    System.out.println("*** Testing: User Agent");
-    System.out.println("*** URL: " + url);
-    System.out.println("Test: HTTPSession.setGlobalUserAgent(" + globalagent + ")");
-    HTTPSession.setGlobalUserAgent(globalagent);
-    HTTPSession session = new HTTPSession(url);
-    HTTPMethod method = HTTPMethod.Get(session);
-    method.execute();
-    System.out.println("Validate by examining localserver log output");
-
-    System.out.println("Test: HTTPSession.setUserAgent(" + sessionagent + ")");
-    session.setUserAgent(sessionagent);
-    method = HTTPMethod.Get(session);
-    method.execute();
-    System.out.println("Validate by examining localserver log output");
-
-    assertTrue("TestHTTPSession.testAgent", true);
-  }
-}
+/*
+ * Copyright (c) 1998 - 2012. University Corporation for Atmospheric Research/Unidata
+ * Portions of this software were developed by the Unidata Program at the
+ * University Corporation for Atmospheric Research.
+ *
+ * Access and use of this software shall impose the following obligations
+ * and understandings on the user. The user is granted the right, without
+ * any fee or cost, to use, copy, modify, alter, enhance and distribute
+ * this software, and any derivative works thereof, and its supporting
+ * documentation for any purpose whatsoever, provided that this entire
+ * notice appears in all copies of the software, derivative works and
+ * supporting documentation.  Further, UCAR requests that the user credit
+ * UCAR/Unidata in any publications that result from the use of this
+ * software or in any product that includes this software. The names UCAR
+ * and/or Unidata, however, may not be used in any advertising or publicity
+ * to endorse or promote any products or commercial entity unless specific
+ * written permission is obtained from UCAR/Unidata. The user also
+ * understands that UCAR/Unidata is not obligated to provide the user with
+ * any support, consulting, training or assistance of any kind with regard
+ * to the use, operation and performance of this software nor to provide
+ * the user with any updates, revisions, new versions or "bug fixes."
+ *
+ * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package ucar.nc2.util.net;
+
+import org.junit.Test;
+import ucar.nc2.util.UnitTestCommon;
+
+import static junit.framework.Assert.assertTrue;
+
+public class TestHTTPSession extends UnitTestCommon
+{
+  //////////////////////////////////////////////////
+
+  // Define the test sets
+
+  int passcount = 0;
+  int xfailcount = 0;
+  int failcount = 0;
+  boolean verbose = true;
+  boolean pass = false;
+
+  String datadir = null;
+  String threddsroot = null;
+
+  public TestHTTPSession()
+  {
+    super();
+    setTitle("HTTP Session tests");
+    HTTPSession.TESTING = true;
+  }
+
+  @Test
+  public void
+  testAgent() throws Exception {
+    String globalagent = "TestUserAgent123global";
+    String sessionagent = "TestUserAgent123session";
+    String url =
+            "http://thredds-test.ucar.edu:8081/dts/test.01.dds";
+
+    System.out.println("*** Testing: User Agent");
+    System.out.println("*** URL: " + url);
+    System.out.println("Test: HTTPSession.setGlobalUserAgent(" + globalagent + ")");
+    HTTPSession.setGlobalUserAgent(globalagent);
+    HTTPSession session = HTTPFactory.newSession(url);
+    HTTPMethod method = HTTPFactory.Get(session);
+    method.execute();
+    System.out.println("Validate by examining localserver log output");
+
+    System.out.println("Test: HTTPSession.setUserAgent(" + sessionagent + ")");
+    session.setUserAgent(sessionagent);
+    method = HTTPFactory.Get(session);
+    method.execute();
+    System.out.println("Validate by examining localserver log output");
+
+    assertTrue("TestHTTPSession.testAgent", true);
+  }
+}
diff -Nru thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestState.java thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestState.java
--- thredds-4.3.18/cdm/src/test/java/ucar/nc2/util/net/TestState.java	2013-09-16 02:10:49.000000000 +0200
+++ thredds-4.3.18-gil/cdm/src/test/java/ucar/nc2/util/net/TestState.java	2013-09-16 07:42:37.343341121 +0200
@@ -81,11 +81,11 @@
         throws Exception
     {
 
-        HTTPSession session = new HTTPSession(SESSIONURL);
+        HTTPSession session = HTTPFactory.newSession(SESSIONURL);
         assertFalse(session.isClosed());
 
         // Check state transitions for open and execute
-        HTTPMethod method = HTTPMethod.Get(session, TESTSOURCE1);
+        HTTPMethod method = HTTPFactory.Get(session, TESTSOURCE1);
         assertFalse(method.isClosed());
         int methodcount = session.getMethodcount();
         assertTrue(methodcount == 1);
@@ -101,7 +101,7 @@
         assertTrue(methodcount == 0);
 
         // Check that method close forcibly closes streams
-        method = HTTPMethod.Get(session, TESTSOURCE1);
+        method = HTTPFactory.Get(session, TESTSOURCE1);
         methodcount = session.getMethodcount();
         assertTrue(methodcount == 1);
         method.execute();
@@ -113,7 +113,7 @@
 
         // Check that session close closes methods and streams
         // and transitively until stream close
-        method = HTTPMethod.Get(session);
+        method = HTTPFactory.Get(session);
         methodcount = session.getMethodcount();
         assertTrue(methodcount == 1);
         method.execute();
@@ -126,37 +126,25 @@
         assertTrue(session.isClosed());
 
         // Test Local session
-        method = HTTPMethod.Get();
+        method = HTTPFactory.Get();
         assertTrue(method.isSessionLocal());
         session = method.getSession();
         methodcount = session.getMethodcount();
         assertTrue(methodcount == 1);
         method.execute(TESTSOURCE1);
-        String body = method.getResponseAsString();
-        stream = (HTTPMethodStream) method.getResponseBodyAsStream();
-        byte[] bbody = readbinaryfile(stream);
-        method.close();
-        assertTrue(stream.isClosed());
-        assertFalse(method.hasStreamOpen());
+        String body = method.getResponseAsString();// will close stream
+        try {
+            stream = (HTTPMethodStream) method.getResponseBodyAsStream();
+            readbinaryfile(stream);
+            System.err.println("Stream not closed.");
+            assertFalse(stream.isClosed());
+        } catch (Exception e) {
+            assertFalse(method.hasStreamOpen());
+        }
         assertTrue(method.isClosed());
         methodcount = session.getMethodcount();
         assertTrue(methodcount == 0);
         assertTrue(session.isClosed());
-
-        // Finally, do a content comparison
-        String s = new String(bbody,UTF8);
-        if(verbose) {
-            System.err.println("Body as String:\n"+body);
-            System.err.println("Body as Bytes:\n"+s);
-        }
-
-        String compare = compare("TestState",body,s);
-        if(compare != null) {
-            System.out.println(compare);
-            pass = false;
-        } else
-            pass = true;
-        assertTrue(pass);
     }
 
     static public byte[]
diff -Nru thredds-4.3.18/pom.xml thredds-4.3.18-gil/pom.xml
--- thredds-4.3.18/pom.xml	2013-09-16 07:46:40.701502787 +0200
+++ thredds-4.3.18-gil/pom.xml	2013-09-16 07:53:21.421366395 +0200
@@ -410,9 +410,31 @@
 
       <!-- client -->
       <dependency>
-        <groupId>commons-httpclient</groupId>
-        <artifactId>commons-httpclient</artifactId>
-        <version>${commons-httpclient.version}</version>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>${org.apache.httpcomponents.httpclient.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>  <!-- replace with jcl-over-slf4j -->
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpcore</artifactId>
+        <version>${org.apache.httpcomponents.httpcore.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>  <!-- replace with jcl-over-slf4j -->
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpmime</artifactId>
+        <version>${org.apache.httpcomponents.httpmime.version}</version>
         <exclusions>
           <exclusion>
             <groupId>commons-logging</groupId>  <!-- replace with jcl-over-slf4j -->
@@ -884,7 +906,9 @@
     <com.sleepycat.version>4.0.92</com.sleepycat.version>
     <commons-dbcp.version>1.4</commons-dbcp.version>
     <commons-fileupload.version>1.2.2</commons-fileupload.version>
-    <commons-httpclient.version>3.1</commons-httpclient.version>
+    <org.apache.httpcomponents.httpcore.version>4.2.4</org.apache.httpcomponents.httpcore.version>
+    <org.apache.httpcomponents.httpclient.version>4.2.5</org.apache.httpcomponents.httpclient.version>
+    <org.apache.httpcomponents.httpmime.version>4.2.5</org.apache.httpcomponents.httpmime.version>
     <commons-io.version>2.4</commons-io.version>
     <derby.version>10.9.1.0</derby.version>
     <javax.activation.version>1.1.1</javax.activation.version>