brett       2004/07/01 05:55:49

  Modified:    src/java/org/apache/maven/util Tag: MAVEN-1_0-BRANCH
                        HttpUtils.java
               src/java/org/apache/maven/verifier Tag: MAVEN-1_0-BRANCH
                        DependencyVerifier.java
               xdocs    Tag: MAVEN-1_0-BRANCH changes.xml
  Log:
  fixes to httpclient code
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.28.4.11 +156 -96   maven/src/java/org/apache/maven/util/HttpUtils.java
  
  Index: HttpUtils.java
  ===================================================================
  RCS file: /home/cvs/maven/src/java/org/apache/maven/util/HttpUtils.java,v
  retrieving revision 1.28.4.10
  retrieving revision 1.28.4.11
  diff -u -r1.28.4.10 -r1.28.4.11
  --- HttpUtils.java    27 Jun 2004 07:57:48 -0000      1.28.4.10
  +++ HttpUtils.java    1 Jul 2004 12:55:46 -0000       1.28.4.11
  @@ -31,7 +31,9 @@
   import java.net.URLConnection;
   import java.text.SimpleDateFormat;
   import java.util.Date;
  +import java.util.TimeZone;
   
  +import org.apache.commons.lang.StringUtils;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import org.apache.commons.httpclient.Credentials;
  @@ -61,6 +63,11 @@
   {
       private static final Log LOG = LogFactory.getLog(HttpUtils.class);
   
  +    private static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT");
  +
  +    /** @todo make it a property. */
  +    private static final int REDIRECT_LIMIT = 5;
  +
       /**
        * Use a proxy to bypass the firewall with or without authentication
        *
  @@ -262,6 +269,8 @@
                                   String loginDomain )
           throws IOException
       {
  +        LOG.debug( "Getting URL: " + url );
  +
           //set the timestamp to the file date.
           long timestamp = -1;
           if ( useTimestamp && destinationFile.exists() )
  @@ -360,90 +369,22 @@
                   client.getState().setCredentials(null, null, creds);
               }
   
  -            int statusCode = -1;
  -            InputStream is = null;
  -            GetMethod get = new GetMethod(source.getPath());
  -            try {
  -                if ( timestamp >= 0 )
  -                {
  -                    SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd-MMM-yy 
HH:mm:ss zzz");
  -                    get.addRequestHeader(new Header("If-Modified-Since", 
fmt.format(new Date(timestamp))));
  -                }
  -
  -                // We will retry up to 3 times.
  -                for (int i = 0; i < 3; i++)
  -                {
  -                    try 
  -                    {
  -                        statusCode = client.executeMethod(get);
  -                        if (statusCode != -1) {
  -                            break;
  -                        }
  -                    }
  -                    catch (HttpRecoverableException e)
  -                    {
  -                        if (i < 2) {
  -                            throw e;
  -                        }
  -                        LOG.warn( "A recoverable exception occurred." + 
e.getMessage());
  -                    }
  -                    catch (IOException e)
  -                    {
  -                        throw e;
  -                    }
  -                    if (i < 2) {
  -                        LOG.warn("retrying " + (i + 1) + " of 3");
  -                    }
  +            for (int i = 0; i < REDIRECT_LIMIT; i++ )
  +            {
  +                String redirect = retrieveArtifact(client, source, destinationFile, 
timestamp, silent);
  +                if (redirect == null) {
  +                    break;
                   }
  -    
  -                boolean use = statusCode < 300 && statusCode != 
HttpURLConnection.HTTP_NOT_MODIFIED;
  -    
  -                // Must read content regardless
  -                is = get.getResponseBodyAsStream();
  -                if (is == null) {
  -                    if (!silent) LOG.info("Not modified");
  -                    return;
  +                if (i >= REDIRECT_LIMIT - 1) {
  +                    throw new IOException("Redirection limit of " + REDIRECT_LIMIT 
+ " exceeded");
                   }
   
  -                int projected = 0;
  -                Header header = get.getResponseHeader("Content-Length");
  -                if (header != null) {
  -                    projected = Integer.valueOf(header.getValue()).intValue()/1024;
  -                }
  +                redirect = StringUtils.replace( redirect, ":/", "://" );
  +                redirect = StringUtils.replace( redirect, "//", "/" );
   
  -                long remoteTimestamp = 0;
  -                header = get.getResponseHeader("Last-Modified");
  -                if (header != null) {
  -                    try {
  -                        remoteTimestamp = 
DateParser.parseDate(header.getValue()).getTime();
  -                    }
  -                    catch (DateParseException e) {
  -                        LOG.warn("Unable to parse last modified header", e );
  -                    }
  -                }
  -                else {
  -                    if (!silent) LOG.warn("warning: last-modified not specified");
  -                }
  -                process( use, is, destinationFile, projected, timestamp, 
remoteTimestamp, silent );
  -            }
  -            finally {
  -                if (is != null) try { is.close(); } catch (Exception e) { 
LOG.error("error closing stream", e); }
  -                get.releaseConnection();
  -            }
  -
  -            if ( statusCode == HttpURLConnection.HTTP_NOT_FOUND)
  -            {
  -                throw new FileNotFoundException(url.toString());
  -            }
  -            // test for 401 result (HTTP only)
  -            if ( statusCode == HttpURLConnection.HTTP_UNAUTHORIZED )
  -            {
  -                throw new IOException( "Not authorized." );
  -            }
  -            // test for 407 result (HTTP only)
  -            if ( statusCode == HttpURLConnection.HTTP_PROXY_AUTH )
  -            {
  -                throw new IOException( "Not authorized by proxy." );
  +                source = new URL( redirect );
  +                hc.setHost(source.getHost(), source.getPort(), 
source.getProtocol());
  +                client.setHostConfiguration(hc);
               }
           }
           else
  @@ -474,7 +415,7 @@
   
                   if ( connection.getLastModified() <= timestamp && 
connection.getLastModified() != 0 )
                   {
  -                    if (!silent) LOG.info("Not modified");
  +                    if (!silent) LOG.debug("Not modified");
                       return;
                   }
   
  @@ -489,6 +430,121 @@
           }
       }
   
  +    private static String retrieveArtifact(HttpClient client, URL source, File 
destinationFile, long timestamp, boolean silent) throws FileNotFoundException, 
IOException, HttpRecoverableException {
  +        int statusCode = -1;
  +        String redirectUrl = null;
  +        InputStream is = null;
  +        GetMethod get = new GetMethod(source.getPath());
  +        // Handle these ourselves until httpclient deals with cross host redirects
  +        get.setFollowRedirects(false);
  +        try {
  +            if ( timestamp >= 0 )
  +            {
  +                SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd-MMM-yy 
HH:mm:ss zzz");
  +                fmt.setTimeZone(GMT_TIME_ZONE);
  +                Header hdr = new Header("If-Modified-Since", fmt.format(new 
Date(timestamp)));
  +                LOG.debug("sending ==> " + hdr + "(" + timestamp + ")");
  +                get.addRequestHeader(hdr);
  +            }
  +
  +            // We will retry up to 3 times.
  +            for (int i = 0; i < 3; i++)
  +            {
  +                try 
  +                {
  +                    statusCode = client.executeMethod(get);
  +                    if (statusCode != -1) {
  +                        LOG.debug("Received status code: " + statusCode);
  +                        break;
  +                    }
  +                }
  +                catch (HttpRecoverableException e)
  +                {
  +                    if (i >= 2) {
  +                        throw e;
  +                    }
  +                    LOG.warn( "A recoverable exception occurred." + e.getMessage());
  +                }
  +                catch (IOException e)
  +                {
  +                    throw e;
  +                }
  +                LOG.warn("retrying (" + (i + 1) + ")");
  +            }
  +    
  +            boolean use = statusCode < 300;
  +
  +            if (statusCode == HttpURLConnection.HTTP_NOT_MODIFIED) {
  +                if (!silent) LOG.debug("Not modified");
  +            }
  +            else if (statusCode >= 300 && statusCode < 400) {
  +                Header header = get.getResponseHeader("Location");
  +                if (header != null) {
  +                    redirectUrl = header.getValue();
  +                    LOG.debug("Location: " + redirectUrl);
  +                }
  +                else {
  +                    LOG.warn("Location header not specified");
  +                }
  +            }
  +
  +            // Must read content regardless
  +            is = get.getResponseBodyAsStream();
  +            if (is == null) {
  +                return redirectUrl;
  +            }
  +
  +            int projected = 0;
  +            Header header = get.getResponseHeader("Content-Length");
  +            if (header != null) {
  +                try {
  +                    projected = Integer.valueOf(header.getValue()).intValue();
  +                }
  +                catch (NumberFormatException e) {
  +                    LOG.warn( "error parsing content length header '" + 
header.getValue() + "' " + e );
  +                }
  +            }
  +
  +            long remoteTimestamp = 0;
  +            if ( use ) {
  +                header = get.getResponseHeader("Last-Modified");
  +                if (header != null) {
  +                    try {
  +                        remoteTimestamp = 
DateParser.parseDate(header.getValue()).getTime();
  +                    }
  +                    catch (DateParseException e) {
  +                        LOG.warn("Unable to parse last modified header", e );
  +                    }
  +                    LOG.debug("last-modified = " + header.getValue() + " (" + 
remoteTimestamp + ")");
  +                }
  +                else {
  +                    if (!silent) LOG.warn("warning: last-modified not specified");
  +                }
  +            }
  +            process( use, is, destinationFile, projected, timestamp, 
remoteTimestamp, silent );
  +        }
  +        finally {
  +            if (is != null) try { is.close(); } catch (Exception e) { 
LOG.error("error closing stream", e); }
  +            get.releaseConnection();
  +        }
  +
  +        if ( statusCode == HttpURLConnection.HTTP_NOT_FOUND)
  +        {
  +            throw new FileNotFoundException(source.toString());
  +        }
  +        // test for 401 result (HTTP only)
  +        if ( statusCode == HttpURLConnection.HTTP_UNAUTHORIZED )
  +        {
  +            throw new IOException( "Not authorized." );
  +        }
  +        // test for 407 result (HTTP only)
  +        if ( statusCode == HttpURLConnection.HTTP_PROXY_AUTH )
  +        {
  +            throw new IOException( "Not authorized by proxy." );
  +        }
  +        return redirectUrl;
  +    }
  +
       private static void process( boolean use, InputStream is, File destinationFile, 
long projected, long timestamp, long remoteTimestamp, boolean silent ) 
           throws IOException {
           byte[] buffer = new byte[100 * 1024];
  @@ -509,27 +565,30 @@
                       }
                   }
               }
  +        }
  +        finally {
  +            if (os != null) try { os.close(); } catch (Exception e) { 
LOG.error("error closing stream", e); }
  +        }
   
  -            if ( use ) {
  -                if ( !silent ) {
  -                    System.out.println( (total/1024) + "K downloaded");
  -                }
  +        if ( use ) {
  +            if ( !silent ) {
  +                System.out.println( (total/1024) + "K downloaded");
  +            }
  +
  +            LOG.debug("Local timestamp: " + timestamp);
  +            LOG.debug("Remote timestamp: " + remoteTimestamp);
     
  -                // if (and only if) the use file time option is set, then the
  -                // saved file now has its timestamp set to that of the downloaded
  -                // file
  -                if ( timestamp >= 0 )
  +            // if (and only if) the use file time option is set, then the
  +            // saved file now has its timestamp set to that of the downloaded
  +            // file
  +            if ( timestamp >= 0 )
  +            {
  +                if ( remoteTimestamp != 0 )
                   {
  -                    if ( remoteTimestamp != 0 )
  -                    {
  -                        touchFile( destinationFile, remoteTimestamp );
  -                    }
  +                    touchFile( destinationFile, remoteTimestamp );
                   }
               }
           }
  -        finally {
  -            if (os != null) try { os.close(); } catch (Exception e) { 
LOG.error("error closing stream", e); }
  -        }
       }
   
       /**
  @@ -590,6 +649,7 @@
               modifiedTime = timemillis;
           }
   
  +        LOG.debug("touching " + file + " with " + modifiedTime);
           file.setLastModified( modifiedTime );
           return true;
       }
  
  
  
  No                   revision
  No                   revision
  1.34.4.8  +17 -6     maven/src/java/org/apache/maven/verifier/DependencyVerifier.java
  
  Index: DependencyVerifier.java
  ===================================================================
  RCS file: 
/home/cvs/maven/src/java/org/apache/maven/verifier/DependencyVerifier.java,v
  retrieving revision 1.34.4.7
  retrieving revision 1.34.4.8
  diff -u -r1.34.4.7 -r1.34.4.8
  --- DependencyVerifier.java   27 Jun 2004 07:57:48 -0000      1.34.4.7
  +++ DependencyVerifier.java   1 Jul 2004 12:55:46 -0000       1.34.4.8
  @@ -141,7 +141,7 @@
               {
                   failedDependencies.add( artifact );
               }
  -            else
  +            else if ( artifact.isSnapshot() )
               {
                   // The artifact exists but we need to take into account the user
                   // being online and whether the artifact is a snapshot. If the user
  @@ -151,11 +151,11 @@
                   // take their chances with a strong warning that they could possibly
                   // be using an out-of-date artifact. We don't want to cripple users
                   // when working offline.
  -                if ( online && artifact.isSnapshot() )
  +                if ( online )
                   {
                       failedDependencies.add( artifact );
                   }
  -                else if ( !online && artifact.isSnapshot() )
  +                else
                   {
                       log.warn( getMessage( "offline.snapshot.warning", 
artifact.getName() ) );
                   }
  @@ -235,6 +235,7 @@
        */
       private void getDependencies()
       {
  +        log.debug("Getting failed dependencies: " + failedDependencies);
           for ( Iterator i = failedDependencies.iterator(); i.hasNext();)
           {
               Artifact artifact = (Artifact) i.next();
  @@ -263,7 +264,7 @@
                   {
                       // The snapshot jar locally exists and not in remote repository
                       // FIXME: localize this message
  -                    log.debug("Artifact " + artifact.getUrlPath()
  +                    log.info("Artifact " + artifact.getUrlPath()
                           + " doesn't exists in remote repository, but it exists 
locally");
                       i.remove();
                   }
  @@ -285,11 +286,16 @@
       private boolean getRemoteArtifact( Artifact artifact )
       {
           boolean artifactFound = false;
  +        boolean errorsFound = false;
   
           for ( Iterator i = 
getProject().getContext().getMavenRepoRemote().iterator(); i.hasNext();)
           {
               String remoteRepo = (String) i.next();
   
  +            if (remoteRepo.endsWith("/")) {
  +                remoteRepo = remoteRepo.substring(0, remoteRepo.length() - 1);
  +            }
  +
               // The username and password parameters are not being
               // used here. Those are the "" parameters you see below.
               String url = remoteRepo + "/" + artifact.getUrlPath();
  @@ -311,7 +317,6 @@
               // of the checksum file was successful.
               try
               {
  -                log.debug( "Getting URL: " + url );
                   String loginHost = (String) getProject().getContext().getVariable( 
MavenConstants.PROXY_LOGINHOST );
                   String loginDomain = (String) 
getProject().getContext().getVariable( MavenConstants.PROXY_LOGINDOMAIN );
                   HttpUtils.getFile( url,
  @@ -329,6 +334,11 @@
                   // Artifact was found, continue checking additional remote repos 
(if any)
                   // in case there is a newer version (i.e. snapshots) in another repo
                   artifactFound = true;
  +
  +                if ( !artifact.isSnapshot() )
  +                {
  +                    break;
  +                }
               }
               catch (FileNotFoundException e)
               {
  @@ -361,6 +371,7 @@
                   // FIXME: localize this message
                   log.warn("Error retrieving artifact from [" + url + "]: " + e);
                   log.debug("Error details", e);
  +                errorsFound = true;
               }
           }
   
  
  
  
  No                   revision
  No                   revision
  1.14.4.27 +7 -0      maven/xdocs/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/maven/xdocs/changes.xml,v
  retrieving revision 1.14.4.26
  retrieving revision 1.14.4.27
  diff -u -r1.14.4.26 -r1.14.4.27
  --- changes.xml       28 Jun 2004 12:22:07 -0000      1.14.4.26
  +++ changes.xml       1 Jul 2004 12:55:49 -0000       1.14.4.27
  @@ -24,6 +24,13 @@
       <author email="[EMAIL PROTECTED]">Vincent Massol</author>
     </properties>
     <body>
  +    <release version="1.0-final-SNAPSHOT" date="in CVS">
  +      <action dev="brett" type="fix" issue="MAVEN-1343">Bugfixes for new httpclient 
based downloading (incorrect timestamps)</action>
  +      <action dev="brett" type="fix" issue="MAVEN-1353">Handle cross site 
redirects</action>
  +      <action dev="brett" type="fix" issue="MAVEN-1290">Correct absolute paths with 
no drive designator on windows</action>
  +      <action dev="brett" type="fix" issue="MAVEN-1341">Amend bootstrap to create 
directories that might not exist</action>
  +      <action dev="brett" type="fix" issue="MAVEN-1344">If artifact is not a 
snapshot, don't continue checking for newer downloads once one is successful</action>
  +    </release>
       <release version="1.0-rc4" date="2004-06-28">
         <action dev="brett" type="update">Set maven.plugin.user.dir to 
${maven.home.local}/plugins by default, move maven.plugin.unpacked.dir to 
${maven.home.local}/cache.</action>
         <action dev="brett" type="update">Read local plugin jars from 
maven.plugin.user.dir instead of maven.plugin.unpacked.dir.</action>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to