ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject cvs commit: jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http Base64Encode.java ContentGuesser.java HttpAuthenticationStrategy.java HttpBasicAuth.java HttpDigestAuth.java HttpGet.java HttpHead.java HttpPost.java HttpRequestParameter.java HttpTask.java NullOutputStream.java SetProxy.java
Date Tue, 27 Nov 2001 22:43:44 GMT
stevel      01/11/27 14:43:44

  Added:       proposal/sandbox/httptasks/docs/manual/OptionalTasks
                        httptasks.html
               proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http
                        Base64Encode.java ContentGuesser.java
                        HttpAuthenticationStrategy.java HttpBasicAuth.java
                        HttpDigestAuth.java HttpGet.java HttpHead.java
                        HttpPost.java HttpRequestParameter.java
                        HttpTask.java NullOutputStream.java SetProxy.java
  Log:
  Stuck the http task set (get, head, post, setproxy) into the sandbox. All need to move to httpclient for a better user experience, except maybe setproxy which is ready to roll as is.
  
  Revision  Changes    Path
  1.1                  jakarta-ant/proposal/sandbox/httptasks/docs/manual/OptionalTasks/httptasks.html
  
  Index: httptasks.html
  ===================================================================
  <html>
  <head>
  <title>Http Tasks</title>
  </head>
  <body>
  <h2>Http Tasks</h2>
  
  Tasks do to make the basic HTTP requests: get, post, head, put, with authentication.
  There is also a task to configure the proxy settings of the http tasks.
  <p>
  These tasks significantly extend the basic <a
  href="../CoreTasks/get.html">get task</a>, but are split off into the optional section
  so that
  <ol>
  <li> The core ant file doesn't get so big
  <li> this implementation can move to using an optional jar (HttpClient) to work around
  limitations of the HTTP support built in to the Java platform.   
  </ol>
  
  <h3>Core Functionality and Parameters</h3>
  
  <p>Common functionality to the core tasks tasks is </p>
  
  <ol>
  
  <li>Ability to name the remote url which the target of the request.</li>
  
  <li>Ability to name a local file as the local store of any returned
  content.</li>
  
  <li>Ability to name a property as the local store of any returned
  content.</li>
  
  <li>Ability to name a property to be set to &quot;true&quot; when a
  request succeeds.</li>
  
  <li>The option to list a number of parameters, each with a name and a
  value. Some methods (HttpGet, HttpHead) attach these parameters to the
  stated url to generate the url to actually fetch. Others (HttpPost) send
  the parameters up in the standard representation of form data.</li>
  
  <li>The option to state the authentication policy and then the username
  and password. Currently only basic authentication is used, which is
  utterly insecure except over an https link</li>
  
  <li>A 'verbose' option which provides extra information and progess
  information during a download.</li>
  
  <li>Timestamp control, using the <i>usetimestamp</i> flag. When set the
  timestamp of downloaded content is set to match that of the remote file
  (Java 1.2 or later only), and the local timestamp of the destination
  file (if it exists) used to set the if-modified-since header in the
  request, which will trigger optional download only. </li>
  
  </ol>
  
  <h3>Parameters</h3>
  
  <p> The <i>url</i> parameter specifies the URL to access. The optional
  <i>dest</i> parameter specifies a destination to which the retrieved
  page will be written. The optional <i>destinationproperty </i>parameter
  specifies a name of a property to save the content to, instead of a
  property. If neither <i>dest</i> nor <i>destinationproperty</i>
  specified, the contents of the specified URL are discarded (this is
  useful when accessing the URL for the purpose of causing some action on
  the remote server).</p>
  
  <p> When the <i>verbose</i> option is enabled, the task displays a '.' for every 
    64 KB retrieved. If the <i>blocksize</i> parameter is adjusted then files are 
    uploaded or downloaded in a different size block from this, and progress markers 
    appear appropriately. </p>
  
  The <i>usetimestamp</i> option enables you to control downloads so that
  the remote file is only fetched if newer than the local copy. If there
  is no local copy, the download always takes place. When a file is
  downloaded, the timestamp of the downloaded file is set to the remote
  timestamp, if the JVM is Java1.2 or later. NB: This timestamp facility
  only works on downloads using the HTTP protocol.
  
  <p>The <i>authtype</i>, <i>username</i>, and <i>password</i> options enable support 
    for password protected pages. Currently only 'Basic' authentication is used, 
    which is notoriously insecure except over an encrypted https channel.</p>
  <table border="1" cellpadding="2" cellspacing="0">
    <tr> 
      <td valign="top"><b>Attribute</b></td>
      <td valign="top"><b>Description</b></td>
      <td align="center" valign="top"><b>Required</b></td>
    </tr>
    <tr> 
      <td valign="top">authtype</td>
      <td valign="top">the HTTP authentication protocol to use, <i>none</i> or <i>basic</i>.</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">blocksize</td>
      <td valign="top">size (in kilobytes) of the data block used for upload and 
        download. Default: 64.<br>
        Keep this to a multiple of the hard disk sector size for file IO performance.</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top"><b>dest</b></td>
      <td valign="top">the file where to store the retrieved file.</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">destinationProperty</td>
      <td valign="top">the name of a property to fill with the returned content. 
        Ignored if <i>dest</i> is set</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">failonerror</td>
      <td valign="top">stop the build if the request failed. default: true</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">password</td>
      <td valign="top">the password for authentication.</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">successProperty</td>
      <td valign="top">the name of a property to set to &quot;true&quot; if the 
        request succeeds.<br>
        Set <i>failonerror</i> to false for this to be of use.</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top"><b>url</b></td>
      <td valign="top">the URL from which to retrieve a file.</td>
      <td align="center" valign="top">Yes</td>
    </tr>
    <tr> 
      <td valign="top">usecaches</td>
      <td valign="top">boolean to enable 'caching' of content during the fetch process. 
        default:false</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr>
      <td valign="top">useresponsecode</td>
      <td valign="top">boolean to enable success/failure to be determined by result 
        of the received response code. HTTP only. default=true.</td>
      <td align="center" valign="top">&nbsp;</td>
    </tr>
    <tr> 
      <td valign="top">username</td>
      <td valign="top">the user name for authentication.</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">usetimestamp</td>
      <td valign="top">boolean flag to conditionally download a file based on the 
        timestamp of the local copy. HTTP only</td>
      <td align="center" valign="top">No</td>
    </tr>
    <tr> 
      <td valign="top">verbose</td>
      <td valign="top"> boolean flag to control progress information display.</td>
      <td align="center" valign="top">No</td>
    </tr>
  </table>
  <p> The <i>successProperty</i> names a property which will be set to "true" if 
    the request was deemed successful. For any non-http protocol, success is defined 
    as the request completing. For http and https, success is defined as the request 
    completing, and the response code from the serving being one of the 'success' 
    values -any number between 200 and 299 inclusive. The usual HTTP_OK (200) is 
    therefore a success, as is HTTP_ACCEPTED (202). But failures such as BAD_REQUEST 
    (400) and the ubiquitous HTTP_NOT_FOUND (404) are most definately errors. So 
    an attempt to access a missing url may result 'failure',even though some content 
    was download (such as, perhaps, the 'file not found' text). If this is not what 
    you desire, then set <i>useresponsecode</i>=&quot;false&quot; for the system 
    to interpret any data back as a success. 
  <h3>Parameters specified as nested elements</h3>
  
  <p><b>param</b></p>
  
  <p>Specifies an HTTP request parameter to send as part of the request.
  For <i>get</i> and <i>head</i> request methods the parameters are
  encoded as part of the URL. For <i>post</i> request methods, the
  parameters are sent as the POST request data.</p>
  
  <table cellspacing="0" cellpadding="2" border="1">
    <tbody>
    <tr>
      <td valign="top"><b>Attribute</b></td>
      <td valign="top"><b>Description</b></td>
      <td valign="top" align="middle"><b>Required</b></td>
    </tr>
    <tr>
      <td valign="top">name</td>
      <td valign="top">the name of the request property to set.</td>
      <td valign="top" align="middle">Yes</td>
    </tr>
    <tr>
      <td valign="top">value</td>
      <td valign="top">the value of the request property. You may alternatively
        specify the value as text between the beginning and ending param tags.</td>
      <td valign="center" align="middle">Yes</td>
    </tr>
    </tbody>
  </table>
  
  <p><b>header</b></p>
  
  <p>Specifies an arbitrary HTTP request header that will be sent with the
  request.</p>
  
  <table cellspacing="0" cellpadding="2" border="1">
    <tr>
      <td valign="top"><b>Attribute</b></td>
      <td valign="top"><b>Description</b></td>
      <td valign="top" align="middle"><b>Required</b></td>
    </tr>
    <tr>
      <td valign="top">name</td>
      <td valign="top">the name of the HTTP request header</td>
      <td valign="top" align="middle">Yes</td>
    </tr>
    <tr>
      <td valign="top">value</td>
      <td valign="top">the value of the HTTP request header. You may alternatively
        specify the value as text between the beginning and ending header tags.</td>
      <td valign="center" align="middle">Yes</td>
    </tr>
  </table>
  <h3>Quirky Limitations of java.net classes</h3>
  Multiple HTTP headers can with the same name can <b>not</b> be set, even 
  though the protocol permits it. Java1.1 and Java 1.2 <i>may</i> permit multiple 
  cookies to be set, but this behaviour is explicitly not supported on Java1.3,
  as someone went and change the code to stop this (Java bug ID #4242254). 
  You need to set multiple cookies in one go and hope the far end can handle it
  <p>
  Bug ID #4160499 covers another issue, to wit: some versions of Java throw
  exceptions when an error code is greater than 400 and the dest file isn't
  one of a few simple file types, but Java 1.2 and 1.3 do not. So there
  is no way to get the error text when a jsp page throws some exception.
  <p>
  Also, although this isnt going to be filed until we have a short
  test case, but if you recieve a short response with less content than 
  the content-length header promises, the library seems to silently 
  reduce the content length header to match, which seems the wrong action.     
  
    
    
  <h2><a name="httpget">HttpGet</a></h2>
  <h3>Description</h3>
  
  <p>Accesses a URL to retrieve a file or to cause some action on the server.</p>
  
  <p> This task should be preferred above the <a href="#cvs">CVS task</a> when doing 
    automated builds. CVS is significantly slower than loading a compressed archive 
    with http/ftp. This task will also retrieve content using other supported protocols, 
    such as ftp: and file: 
  <p>All the attributes of httptask may be used. Note that a quirk of the implementation 
    of the http client in java makes it impossible to reliably fetch the response 
    details from any unsuccessful request against a URL which doesn't end in '.htm,.html 
    or .txt'. This means that if the task is used to compile jsp pages by issuing 
    request against them, the text details of any errors will not be picked up. 
  <h3>Examples</h3>
  
  <pre>  &lt;httpget url=&quot;http://jakarta.apache.org/&quot; dest=&quot;help/index.html&quot;/&gt;</pre>
  <p>Fetches the index page of http://jakarta.apache.org/, and stores it in the 
    file <code>help/index.html</code>. </p>
  
  <pre>    &lt;httpget src=&quot;http://jakarta.apache.org/builds/tomcat/nightly/ant.zip&quot;
          dest=&quot;optional.jar&quot;
          verbose=&quot;true&quot;
          usetimestamp=&quot;true&quot;
  	&gt;
          &lt;header name=&quot;Cookie&quot; value=&quot;someid=43ff2b&quot;/&gt;
      &lt;/httpget&gt;</pre>
  <p> Retrieves the nightly ant build from the tomcat distribution, if the local 
    copy is missing or out of date. Uses the verbose option for progress information. 
    A cookie is supplied for the server's benefit.</p>
  <pre>    &lt;httpget url="https://www.pizzaservices.com/prices.jsp"
           dest="pizza-prices.xml&quot;&gt;
         &lt;param name=&quot;zipcode&quot;&gt;57340&lt;/param&gt;
         &lt;param name=&quot;pizza&quot;&gt;pepperoni&lt;/param&gt;
      &lt;/httpget&gt;</pre>
  <p>Builds a URL by adding parameters (&quot;?zipcode=57340&amp;pizza=pepperoni&quot;) 
    to the base URL and then fetches the contents (fictional example)</p>
  <h2><a name="httphead">HttpHead</a> </h2>
  <p>The http HEAD request is similar to the normal GET request , except it, by 
    definition, returns no content, just a success code and http headers. Accordingly, 
    the destination properties of the base class -<i>dest</i> and -, <i>destinationpropertyname</i>) 
    are not supported -any attempt to use them will result in a build failure. Note 
    also that the http and https protocols are the only protocols supported. </p>
  <p>
  HttpHead is useful for triggering server side actions, but note that many servers
  interpret a HEAD very differently from a GET. An HttpGet request with the
  return data discarded is often a more reliable approach.
  </p>
  
  <p> Where head can be useful is in testing for the availability and reachability 
    of servers, such as in the following test for apache being reachable, which 
    sets a variable on success:- 
  <pre>
      &lt;httphead url="http://www.apache.org/"
      	 failonerror="false"
      	 successproperty="reachable.apache"
      	 /&gt;
  </pre>
  
  <p>Note that sometimes a missing file on a mis-configured server still generates 
    a successful '200' response to a GET request -and returns a 'missing' file page, 
    but a HEAD request will reliably pick up the 'missing file' error. </p>
  <h2><a name="httppost">HttpPost</a></h2>
  
  <p>This implements the POST request. Supplied parameter data is turned into form 
    data and sent as the body of the request, rather than appended to the URL. If 
    a file to upload is specified instead, using <i>uploadFile</i>, the parameter 
    values are ignored. Instead the content type of the file is sent in the header 
    -based on the <i>contentType</i> attribute or what the java runtime thinks the 
    content type is based on the file extension. The file is uploaded. </p>
  
  <p>Like HttpGet, this command can return a content which can downloaded to a file,
    to a property, or just ignored.</p>
  
  <p>This task adds two new attributes to the base set. </p>
  <table cellspacing="0" cellpadding="2" border="1">
    <tr>
      <td valign="top" width="78"><b>Attribute</b></td>
      <td valign="top" width="559"><b>Description</b></td>
      <td valign="top" align="middle" width="62"><b>Required</b></td>
    </tr>
    <tr>
      <td valign="top" width="78">uploadFile</td>
      <td valign="top" width="559">a file to upload. when specified, all parameters
        are ignored.</td>
      <td valign="top" align="middle" width="62">
        <div align="center">no</div>
      </td>
    </tr>
    <tr>
      <td valign="top" width="78">contentType </td>
      <td valign="top" width="559">the type of the content (text/html, text/xml,
        application/binary, etc). Only of relevance when a file is being uploaded,
        and still optional in that case. </td>
      <td valign="center" align="middle" width="62">
        <div align="center">no</div>
      </td>
    </tr>
  </table>
  <h3></h3>
  <pre>
     &lt;httppost url=&quot;http://www.example.com/servlet/docserver&quot;
             authtype=&quot;basic&quot; username=&quot;joe&quot; password=&quot;silly&quot;&gt;
         &lt;param name=&quot;action&quot; value=&quot;getdoc&quot;/&gt;
         &lt;param name=&quot;ISBN&quot;&gt;038550120X&lt;/param&gt;
         &lt;param name=&quot;pages&quot;&gt;19-20&lt;/param&gt;
         &lt;header name=&quot;Accept-Language&quot; value=&quot;en-us&quot;/&gt;
     &lt;/httppost&gt;</pre>
  <p>Accesses a server at www.foo.com, passing a request to some servlet asking it
  to retrieve several pages from a stored book. An HTTP header specifying
  acceptable languages for the returned contents is also sent. Basic
  authentication is used with a user name of &quot;joe&quot; and a password of
  &quot;silly&quot;.</p>
  <p>
  <pre>    &lt;httppost url="https://www.pizzaservices.com"
           uploadFile="pizza-order.xml"
           contentType="text/xml"&gt;
  </pre>
  <p>Sends a pre-prepared order for a pizza to a pizza vendor accepting orders using 
    xml-rpc requests. (NB: fictional example) </p>
  <h2><a name="SetProxy"></a>SetProxy</h2>
  <p>This task configures the proxy settings for all http tasks which follow it 
    in the build. That includes the original Get task, but not the telnet and FTP 
    tasks. The proxy settings remain in place until changed or the build finishes, 
    and will also hold for other ant build files invoked and even non-forked java 
    invocations, and even URL resolutions of XML parsers running in the same JVM
    </p>
  <table cellspacing="0" cellpadding="2" border="1">
    <tr> 
      <td valign="top" width="78"><b>Attribute</b></td>
      <td valign="top" width="559"><b>Description</b></td>
      <td valign="top" align="middle" width="62"><b>Required</b></td>
    </tr>
    <tr> 
      <td valign="top" width="78">proxyHost</td>
      <td valign="top" width="559">hostname of a web/ftp proxy server</td>
      <td valign="top" align="middle" width="62"> 
        <div align="center">no</div>
      </td>
    </tr>
    <tr> 
      <td valign="top" width="78">proxyPort </td>
      <td valign="top" width="559">integer; the port of the proxy server</td>
      <td valign="center" align="middle" width="62"> 
        <div align="center">no</div>
      </td>
    </tr>
    <tr> 
      <td valign="top" width="78">socksProxyHost</td>
      <td valign="top" width="559">hostname of a SOCKS4 proxy server</td>
      <td valign="center" align="middle" width="62"> 
        <div align="center">no</div>
      </td>
    </tr>
    <tr> 
      <td valign="top" width="78">socksProxyPort</td>
      <td valign="top" width="559">integer; port number of a SOCKS4 server (default=1080)</td>
      <td valign="center" align="middle" width="62"> 
        <div align="center">no</div>
      </td>
    </tr>
  </table>
  <h3></h3>
  <p>Turn off all proxies</p>
  <pre>    &lt;setproxy proxyhost=&quot;&quot; socksProxyHost=&quot;&quot; /&gt;</pre>
  <p>Set web proxy to 'web-proxy:80'; do not make any changes to existing socks 
    settings (if any)</p>
  <pre>    &lt;setproxy proxyHost=&quot;web-proxy&quot; proxyPort=&quot;80&quot;/&gt;</pre>
  <p>Turn on socks</p>
  <pre>    &lt;setproxy socksProxyHost=&quot;socks-server&quot; socksProxyPort=&quot;1080&quot;/&gt;</pre>
  <p>Do nothing</p>
  <pre>    &lt;setproxy/&gt;</pre>
  <hr>
  <p align="center">Copyright &copy; 2000,2001 Apache Software Foundation. All rights
  Reserved.</p>
  
  </body>
  </html>
  
  
  
  
  
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/Base64Encode.java
  
  Index: Base64Encode.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  /**
   * This code handles Base64 encoding for basic authentication
   * and the like
   *
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created 02 April 2001
   */
  class Base64Encode {
  
      /**
       * the encode alphabet
       */
      private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
  
  
      /**
       * Encode a block of binary data as base64 as specified in RFC1521.
       *
       * @param data the binary data to encode.
       * @return An array of characters that represent the data encoded
       *      as Base64
       */
      public char[] encodeBase64(byte[] data) {
          char[] out = new char[((data.length + 2) / 3) * 4];
  
          //
          // 3 bytes encode to 4 chars.  Output is always an even
          // multiple of 4 characters.
          //
          for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
              boolean quad = false;
              boolean triple = false;
              //convert to unsigned byte
              int val = (0xFF & (int) data[i]);
              val <<= 8;
              if ((i + 1) < data.length) {
                  val |= (0xFF & (int) data[i + 1]);
                  triple = true;
              }
              val <<= 8;
              if ((i + 2) < data.length) {
                  val |= (0xFF & (int) data[i + 2]);
                  quad = true;
              }
              out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
              val >>= 6;
              out[index + 2] = alphabet[(triple ? (val & 0x3F) : 64)];
              val >>= 6;
              out[index + 1] = alphabet[val & 0x3F];
              val >>= 6;
              out[index + 0] = alphabet[val & 0x3F];
          }
          return out;
      }
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/ContentGuesser.java
  
  Index: ContentGuesser.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.IOException;
  import java.net.*;
  
  /**
   * this is a class to work around the fact a function I want (guessContentTypeFromName)
   * is protected.
   *
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  class ContentGuesser extends URLConnection {
  
      /**
       * stub Constructor for the ContentGuesser object
       *
       * @param url Description of Parameter
       */
      ContentGuesser(URL url) {
          super(url);
      }
  
  
      /**
       * this stub is needed for the build
       *
       * @exception IOException Description of Exception
       */
      public void connect()
          throws IOException {
      }
  
  
      /**
       * make a protected method public.
       * This guesses file type from extension. It's ok for very
       * well known types...
       * @param filename file to guess type of
       * @return what the system guessed
       */
      public static String guessContentType(String filename) {
          return guessContentTypeFromName(filename);
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpAuthenticationStrategy.java
  
  Index: HttpAuthenticationStrategy.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import org.apache.tools.ant.BuildException;
  import java.net.URLConnection;
  
  /**
   * this interface is for use by classes which authenticate connections.
   *
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created 20 March 2001
   */
  
  public interface HttpAuthenticationStrategy {
  
  
      /**
       * Sets the AuthenticationHeader attribute of the HttpAuthStrategy
       * object
       *
       * @param requestConnection The current request
       * @param responseConnection any previous request, which can contain a
       *          challenge for the next round. Will often be null
       * @param user the current user name
       * @param password the current password
       */
      public void setAuthenticationHeader(URLConnection requestConnection,
              URLConnection responseConnection,
              String user, String password)
              throws BuildException ;
  
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpBasicAuth.java
  
  Index: HttpBasicAuth.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.apache.tools.ant.*;
  import org.apache.tools.ant.taskdefs.Get;
  
  
  /**
   * this class implements basic auth, the one that shouldn't be used
   * except over an encrypted link or trusted network.
   *
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created 20 March 2001
   */
  
  public class HttpBasicAuth implements HttpAuthenticationStrategy {
  
  
      /**
       * Sets the AuthenticationHeader attribute of the HttpAuthStrategy
       * object
       *
       * @param requestConnection The current request
       * @param responseConnection any previous request, which can contain a
       *          challenge for the next round. Will often be null
       * @param user the current user name
       * @param password the current password
       */
      public void setAuthenticationHeader(URLConnection requestConnection,
              URLConnection responseConnection,
              String username, String password)
              throws BuildException {
  
          if (username != null) {
              password = username == null ? "" : password;
              String encodeStr = username + ":" + password;
              char[] encodedPass;
              String encodedPassStr;
              
              Base64Encode encoder = new Base64Encode();
              encodedPass = encoder.encodeBase64(encodeStr.getBytes());
              encodedPassStr= new String(encodedPass);
              /* this uses the get task
              Get.Base64Converter converter= new Get.Base64Converter();
              encodedPassStr = converter.encode(encodeStr);
              */
              String authStr = "BASIC " +encodedPassStr;
              requestConnection.setRequestProperty("Authorization", authStr);
              }
          }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpDigestAuth.java
  
  Index: HttpDigestAuth.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.apache.tools.ant.*;
  
  
  /**
   * this class implements basic auth, the one that shouldn't be used
   * except over an encrypted link or trusted network.
   *
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created 20 March 2001
   */
  
  public class HttpDigestAuth implements HttpAuthenticationStrategy {
  
  
      /**
       * Sets the AuthenticationHeader attribute of the HttpAuthStrategy
       * object
       *
       * @param requestConnection The current request
       * @param responseConnection any previous request, which can contain a
       *          challenge for the next round. Will often be null
       * @param user the current user name
       * @param password the current password
       */
      public void setAuthenticationHeader(URLConnection requestConnection,
              URLConnection responseConnection,
              String username, String password)
              throws BuildException {
  
          if (username != null) {
              password = username == null ? "" : password;
              String encodeStr = username + ":" + password;
              Base64Encode encoder = new Base64Encode();
              char[] encodedPass = encoder.encodeBase64(encodeStr.getBytes());
              String authStr = "BASIC " + new String(encodedPass);
              requestConnection.setRequestProperty("Authorization", authStr);
              }
          }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpGet.java
  
  Index: HttpGet.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.apache.tools.ant.*;
  
  /**
   * This class implements boring old HTTP1.0 get. It represents
   * a refactoring of Get to HttpTask and then into a specific
   * subclass. because almost everything is done by the parent,
   * this class is almost completely empty
   * @since ant1.5
   * @author costin@dnt.ro
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  
  public class HttpGet extends HttpTask {
  
       /**
       * override of test
       * @return true always
       */
  
      protected boolean areParamsAddedToUrl() {
          return true;
      }
  
       /**
       * this must be overridden by implementations
       * to set the request method to GET, POST, whatever
       * @return GET, obviously
       */
       public String getRequestMethod() {
           return "GET";
       }
  }
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpHead.java
  
  Index: HttpHead.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.apache.tools.ant.*;
  
  /**
   * Head is a get with a different method and the notion of
   * destination file missing. Why would anyone want to make a HEAD
   * request? a) side effects on the server and b) polling for stuff
   * @since ant1.5
   * @author costin@dnt.ro
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  
  public class HttpHead extends HttpTask {
  
       /**
       * this must be overridden by implementations
       * to set the request method to GET, POST, whatever
       * @return HEAD always
       */
       public String getRequestMethod() {
           return "HEAD";
       }
  
       /**
       * override of test
       * @return true always
       */
  
      protected boolean areParamsAddedToUrl() {
          return true;
      }
  
      /**
       * add a check for all the destination settings being
       * null; nothing else makes sense for a HEAD.
       *
       * @return true if everything is fine. false if we have encountered
       *      problems but arent allowed to fail on an error,
       * @exception BuildException only throw this when the failonerror
       *      flag is true
       */
  
      protected void verifyArguments()
          throws BuildException {
          BuildException trouble = null;
          if(getDest() != null || getDestinationProperty() !=null) {
              throw new BuildException("destination properties must not be defined for a HEAD request");
          }
          super.verifyArguments();
      }
  
  }
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpPost.java
  
  Index: HttpPost.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.apache.tools.ant.*;
  
  /**
   * this class does post of form content or raw files. you can have one
   * or the other -as soon as a file is specified all the other properties
   * are dropped on the floor.
   * a file post will have content type determined from the extension, you can
   * override it
   * @since ant1.5
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  
  public class HttpPost extends HttpTask {
  
      /**
       * file to upload. Null is ok
       */
  
      protected File postFile=null;
  
      /**
       * set the file to post
       */
      public void setUploadFile(File postFile) {
          this.postFile=postFile;
      }
  
       /**
        * query the post file
        * @return the file or null for 'not defined'
        */
      public File getUploadFile() {
          return postFile;
      }
  
      /**
       * content type. ignored when the file is null,
       * and even then we guess it if aint specified
       */
  
       private String contentType;
  
       /**
        * set the content type. Recommended if a file is being uploaded
        */
       public void setContentType(String contentType) {
           this.contentType=contentType;
       }
  
       /**
        * query the content type
        * @return the content type or null for 'not defined'
        */
       public String getContentType() {
           return contentType;
       }
  
       /**
       * override of test
       * @return false always
       */
  
      protected boolean areParamsAddedToUrl() {
          return false;
      }
  
      /**
       * this override of the base connect pumps
       * up the parameter vector as form data
       *
        * @param connection where to connect to
       * @exception BuildException build trouble
       * @exception IOException IO trouble
       */
      protected URLConnection doConnect(URLConnection connection)
          throws BuildException, IOException {
  
          if(postFile==null) {
              return doConnectFormPost(connection);
          }
          else {
              return doConnectFilePost(connection);
          }
      }
  
      /**
       * feed up the parameter vector as form data
       *
        * @param connection where to connect to
       * @exception BuildException build trouble
       * @exception IOException IO trouble
       */
      protected URLConnection doConnectFormPost(URLConnection connection)
          throws BuildException, IOException {
  
          log("Posting data as a form",Project.MSG_VERBOSE);
          // Create the output payload
          ByteArrayOutputStream byteStream = new ByteArrayOutputStream(256);
          PrintWriter out = new PrintWriter(byteStream);
          writePostData(out);
          out.flush();
          out.close();
          byte[] data=byteStream.toByteArray();
          //send it
          
          return doConnectWithUpload(connection,
                  "application/x-www-form-urlencoded",
                  byteStream.size(),
                  new ByteArrayInputStream(data));
      }
  
      /**
       * feed up the data file
       *
        * @param connection where to connect to
       * @exception BuildException build trouble
       * @exception IOException IO trouble
       */
      protected URLConnection doConnectFilePost(URLConnection connection)
          throws BuildException, IOException {
          int size=(int)postFile.length();
          log("Posting file "+postFile,Project.MSG_VERBOSE);
          InputStream instream=new FileInputStream(postFile);
          String type=contentType;
          if(type==null) {
              type=ContentGuesser.guessContentType(postFile.getName());
          }
          return doConnectWithUpload(connection,
                  type,
                  size,
                  instream);
      }
  
  
      /**
       * write out post data in form mode
       *
       * @param out Description of Parameter
       */
      protected void writePostData(PrintWriter out) {
          HttpRequestParameter param;
          Vector params=getRequestParameters();
          for (int i = 0; i < params.size(); i++) {
              if (i > 0) {
                  out.print('&');
              }
              param = (HttpRequestParameter) params.get(i);
              out.print(param.toString());
              log("parameter : "+param.toString(),Project.MSG_DEBUG);
          }
      }
  
       /**
       * this must be overridden by implementations
       * to set the request method to GET, POST, whatever
       * @return the method string
       */
       public String getRequestMethod() {
           return "POST";
       }
  
  
  }
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpRequestParameter.java
  
  Index: HttpRequestParameter.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  import java.net.URLEncoder;
  
  /**
   * This class is used to store name-value pairs for request parameters
   * and headers
   *
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  
  public class HttpRequestParameter {
  
      /**
       * request name
       */
      private String name;
      
      /**
       * request value
       */
      private String value;
  
  
      /**
       * Sets the Name attribute of the request parameter
       *
       * @param name The new Name value
       */
      public void setName(String name) {
          this.name = name;
      }
  
  
      /**
       * Sets the Value attribute of the request parameter
       *
       * @param value The new Value value
       */
      public void setValue(String value) {
          this.value = value;
      }
  
  
      /**
       * Gets the Name attribute of the request parameter
       *
       * @return The Name value
       */
      public String getName() {
          return name;
      }
  
  
      /**
       * Gets the Value attribute of the request parameter
       *
       * @return The Value
       */
      public String getValue() {
          return value;
      }
  
  
      /**
       * Adds a feature to the Text attribute of the request parameter
       *
       * @param text The feature to be added to the Text attribute
       */
      public void addText(String text) {
          this.value = text;
      }
  
  
      /**
       * simple stringifier returning name and value encoded for use in HTTP requests
       *
       * @return a string for informational purposes
       */
      public String toString() {
          return  URLEncoder.encode(getName())+
              '='+URLEncoder.encode(getValue());
      }
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/HttpTask.java
  
  Index: HttpTask.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.apache.tools.ant.*;
  import org.apache.tools.ant.types.EnumeratedAttribute;
  
  /**
   * This class is a foundational class for all the tasks which implement
   * http methods. To implement a subclass you *must* provide
   * an implementation of getRequestMethod(). Consider also
   * stating the parameter policy (areParamsAddedToUrl()) and
   * then, if needed, overriding doConnect, and the onConnected(),
   * OnDownloadFinished() methods.
   * @since ant1.5
   * @author costin@dnt.ro
   * @author matth@pobox.com Matt Humphrey
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  public abstract class HttpTask extends Task {
  
      /**
       * flag to control action on execution trouble
       */
      protected boolean failOnError=true;
  
      /**
       * this sets the size of the buffer and the hash for download
       */
  
      protected int blockSize = 64;
  
      /**
       * property to set on success
       */
  
      protected String successProperty;
  
      /**
       * source URL. required
       */
      private String source;
  
      /**
       * destination for download
       */
      private File dest;
      /**
       * verbose flag gives extra information
       */
      private boolean verbose = false;
  
      /**
       * timestamp based download flag. off by default
       */
      private boolean useTimestamp = false;
  
      /**
       * authorization mechanism in use.
       */
      private int authType = AUTH_NONE;
  
      /**
       * username for authentication
       */
      private String username;
  
      /**
       * password for authentication
       */
      private String password;
  
      /**
       * parameters to send on a request
       */
      private Vector params = new Vector();
  
      /**
       * headers to send on a request
       */
      private Vector headers = new Vector();
  
      /**
       * cache policy
       */
      private boolean usecaches = false;
  
      /**
       * the name of a destination property
       */
  
      private String destinationPropname = null;
  
      /***
       * a flag to control whether or not response codes
       * are acted on
       */
      private boolean useResponseCode=true;
  
      /**
       * No authentication specified
       */
      public final static int AUTH_NONE = 0;
  
      /**
       * basic 'cleartext' authentication
       */
      public final static int AUTH_BASIC = 1;
  
      /**
       * digest auth. not actually supported but present for completeness
       */
      public final static int AUTH_DIGEST = 2;
  
  
      /**
       * turn caching on or off. only relevant for protocols and methods
       * which are cacheable (HEAD, GET) on http
       *
       * @param usecaches The new UseCaches value
       */
      public void setUseCaches(boolean usecaches) {
          this.usecaches = usecaches;
      }
  
      /**
       * turn caching on or off. only relevant for protocols and methods
       * which are cacheable (HEAD, GET) on http
       *
       * @param usecaches The new UseCaches value
       */
      public void setUseResponseCode(boolean useResponseCodes ) {
          this.useResponseCode  = useResponseCode ;
      }
  
  
      /**
       * Set the URL.
       *
       * @param u URL for the file.
       */
      public void setURL(String u) {
          this.source = u;
      }
  
  
      /**
       * the local destination for any response. this can be null for 'dont
       * download'
       *
       * @param dest Path to file.
       */
      public void setDest(File dest) {
          this.dest = dest;
      }
  
  /**
       * the local destination for any response. this can be null for 'dont
       * download'
       *
       * @param dest Path to file.
       */
      public void setDestinationProperty(String name) {
          this.destinationPropname = name;
      }
  
  
      /**
       * Be verbose, if set to " <CODE>true</CODE> ".
       *
       * @param verbose The new Verbose value
       */
      public void setVerbose(boolean verbose) {
          this.verbose = verbose;
      }
  
  
      /**
       * set fail on error flag
       *
       * @param b The new FailOnError value
       */
      public void setFailOnError(boolean b) {
          failOnError = b;
      }
  
  
      /**
       * Use timestamps, if set to " <CODE>true</CODE> ". <p>
       *
       * In this situation, the if-modified-since header is set so that
       * the file is only fetched if it is newer than the local file (or
       * there is no local file) This flag is only valid on HTTP connections,
       * it is ignored in other cases. When the flag is set, the local copy
       * of the downloaded file will also have its timestamp set to the
       * remote file time. <br>
       * Note that remote files of date 1/1/1970 (GMT) are treated as 'no
       * timestamp', and web servers often serve files with a timestamp
       * in the future by replacing their timestamp with that of the current
       * time. Also, inter-computer clock differences can cause no end of
       * grief.
       *
       * @param usetimestamp The new UseTimestamp value
       */
      public void setUseTimestamp(boolean usetimestamp) {
          if (project.getJavaVersion() != Project.JAVA_1_1) {
              this.useTimestamp = usetimestamp;
          }
          else {
              log("usetimestamp is not supported on java 1.1", Project.MSG_WARN);
          }
      }
  
  
      /**
       * Sets the Authtype attribute of the HttpTask object REVISIT/REFACTOR
       *
       * @param type The new Authtype value
       */
      public void setAuthtype(AuthMethodType type) {
          this.authType=type.mapValueToNumber();
      }
  
  
      /**
       * Sets the Username used for authentication. setting the username
       * implicitly turns authentication on.
       *
       * @param username The new Username value
       */
      public void setUsername(String username) {
          this.username = username;
          if (authType == AUTH_NONE) {
              authType = AUTH_BASIC;
          }
      }
  
  
      /**
       * Sets the Password attribute of the HttpTask object
       *
       * @param password The new Password value
       */
      public void setPassword(String password) {
          this.password = password;
      }
  
  
      /**
       * set a variable to be set in the event of success
       *
       * @param successProperty The new SuccessProperty value
       */
      public void setSuccessProperty(String successProperty) {
          this.successProperty = successProperty;
      }
  
      /**
       * get block size (kb)
       */
  
       public int getBlockSize() {
           return blockSize;
       }
  
       /**
        * set the new block size for download
        * @param the new value (in kilobytes)
        */
       public void setBlockSize(int blocksize) {
           this.blockSize=blockSize;
       }
  
  
      /**
       * query cache policy
       *
       * @return The UseCaches value
       */
      public boolean getUseCaches() {
          return usecaches;
      }
  
  
      /**
       * query fail on error flag
       *
       * @return The FailFailOnError value
       */
      public boolean getFailOnError() {
          return failOnError;
      }
  
  
      /**
       * get the username
       *
       * @return current username or null for 'none'
       */
      public String getUsername() {
          return username;
      }
  
  
      /**
       * get the password
       *
       * @return current password or null for 'none'
       */
      public String getPassword() {
          return password;
      }
  
  
      /**
       * @return The RemoteURL value
       */
      public String getURL() {
          return source;
      }
  
  
      /**
       * access parameters
       *
       * @return The RequestParameters value
       */
      public Vector getRequestParameters() {
          return params;
      }
  
  
      /**
       * accessor of success property name
       *
       * @return The SuccessProperty value
       */
      public String getSuccessProperty() {
          return successProperty;
      }
  
      /**
       * accessor of destination property name
       *
       * @return The destination value
       */
      public String getDestinationProperty() {
          return destinationPropname;
      }
  
      /**
       * accessor of destination
       *
       * @return Thedestination
       */
      public File getDest() {
          return dest;
      }
  
  
      /**
       * if the user wanted a success property, this is it. of course, it
       * is only relevant if failonerror=false
       *
       * @return Description of the Returned Value
       */
  
      public void noteSuccess() {
          if (successProperty != null && successProperty.length() > 0) {
              getProject().setProperty(successProperty, "true");
          }
      }
  
  
      /**
       * Does the work.
       * @todo extract content length header and use it to verify
       * completeness of download
       * @exception BuildException Thrown in unrecoverable error.
       */
      public void execute()
          throws BuildException {
  
          //check arguments, will bail out if there
          //was trouble 
          verifyArguments();
          
          //set up the URL connection
          URL url = buildURL();
  
          try {
  
              //now create a connection
              URLConnection connection = url.openConnection();
  
              //set caching option to whatever
              connection.setUseCaches(getUseCaches());
  
              //set the timestamp option if flag is set and
              //the local file actually exists.
              long localTimestamp = getTimestamp();
              if (localTimestamp != 0) {
                  if (verbose) {
                      Date t = new Date(localTimestamp);
                      log("local file date : " + t.toString());
                  }
                  connection.setIfModifiedSince(localTimestamp);
              }
  
              // Set auth header, if specified
              //NB: verifyArguments will already have checked that you can't
              //have a null username with a non-null strategy.
              HttpAuthenticationStrategy authStrategy=getAuthStrategy();
              if (authStrategy != null) {
                  authStrategy.setAuthenticationHeader(connection,null,username,password);
              }
  
              // Set explicitly specified request headers
              HttpRequestParameter header;
              for (int i = 0; i < headers.size(); i++) {
                  header = (HttpRequestParameter) headers.get(i);
                  connection.setRequestProperty(header.getName(), header.getValue());
              }
  
              //cast to an http connection if we can,
              //then set the request method pulled from the subclass
              String method=getRequestMethod();
              HttpURLConnection httpConnection = null;
              if (connection instanceof HttpURLConnection) {
                  httpConnection = (HttpURLConnection) connection;
                  httpConnection.setRequestMethod(method);
              }
              log("making "+method+" to "+url);
  
              //call self or subclass for the connect.
              //the connection object may change identity at this point.
              connection=doConnect(connection);
  
              //then provide a bit of overridable post processing for the fun of it
              if (!onConnected(connection)) {
                  return;
              }
  
              //repeat the cast.
              if (connection instanceof HttpURLConnection) {
                  httpConnection = (HttpURLConnection) connection;
              }
              if(httpConnection != null) {
                  // check for a 304 result (HTTP only) when we set the timestamp
                  // earlier on (A fractional performance tweak)
                  if (localTimestamp != 0) {
                      if (getResponseCode(httpConnection) == HttpURLConnection.HTTP_NOT_MODIFIED) {
                          //not modified so no file download. just return instead
                          //and trace out something so the user doesn't think that the
                          //download happened when it didn't
                          log("Local file is up to date - so nothing was downloaded");
                          noteSuccess();
                          return;
                      }
                  }
  
              }
              
  
              //get the input stream
              InputStream is = getInputStream(connection);
  
              //bail out if the input stream isn't valid at this point
              //again, though we should have got to this point earlier.
              
              if (is == null) {
                  log("Can't get " + url, Project.MSG_ERR);
                  if (getFailOnError()) {
                      return;
                  }
                  throw new BuildException("Can't reach URL");
              }
  
              //pick a file or null stream for saving content
              OutputStream out = null;
              if (dest != null) {
                  log("Saving output to "+dest,Project.MSG_DEBUG);
                  out = new FileOutputStream(dest);
              }
              else {
                  if(destinationPropname!=null) {
                      //save contents to a property
                      log("Saving output to property "+destinationPropname,
                          Project.MSG_DEBUG);
                      out=new ByteArrayOutputStream(blockSize * 1024);
                  }
                  else {
                      //discard everything
                      out = new NullOutputStream();
                  }
              }
  
              //get content length
              //do it this way instead of calling getContentLength() because
              //that way is sporadically unreliable (length is downgraded to 
              //size of small packets)
              int contentLength=connection.getHeaderFieldInt("Content-Length",-1);
              int bytesRead=0;
              
              //now start download.
              byte[] buffer = new byte[blockSize * 1024];
              int length;
  
              while ((length = is.read(buffer)) >= 0 && 
                  (contentLength==-1 || bytesRead<contentLength)) {
                  bytesRead+=length;
                  out.write(buffer, 0, length);
                  if (verbose) {
                      showProgressChar('.');
                  }
              }
  
              //finished successfully - clean up.
              if (verbose) {
                  showProgressChar('\n');
              }
  
  
              //if it we were saving to a byte array, then
              //set the destination property with its contents
              if(out instanceof ByteArrayOutputStream) {
                  getProject().setProperty(destinationPropname,
                          out.toString());
              }
              
              //everything is downloaded; close files
              out.flush();
              out.close();
              is.close();
              is=null;
              out=null;
              
  
              //another overridable notification method
              if (!onDownloadFinished(connection)) {
                  return;
              }
  
              //REFACTOR: move this down to HttpHead? What if a post wants
              //to set a date?
              //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 (useTimestamp) {
                  long remoteTimestamp = connection.getLastModified();
                  if (verbose) {
                      Date t = new Date(remoteTimestamp);
                      log("last modified = " + t.toString()
                               + ((remoteTimestamp == 0) ? " - using current time instead" : ""));
                  }
                  if (remoteTimestamp != 0) {
                      touchFile(dest, remoteTimestamp);
                  }
              }
  
              
              String failureString=null;
              if(contentLength>-1 && bytesRead!=contentLength) {
                  failureString="Incomplete download -Expected "+contentLength
                                  +"received "+bytesRead+" bytes";
              }
              else {
  
                  //finally clean anything up.
                  //http requests have their response code checked, and only
                  //those in the success range are deemed successful.
                  if (httpConnection != null && useResponseCode) {
                      int statusCode=httpConnection.getResponseCode();
                      if(statusCode <200 || statusCode >299) {
                           failureString="Server error code "+statusCode+" received";
                      }
                  }
              }
                  
              //check for an error message
              if(failureString==null) {
                  noteSuccess();
              }
              else {
                  if(failOnError)
                      throw new BuildException(failureString);
                  else
                      log(failureString,Project.MSG_ERR);
              }
              
          }
          catch (IOException ioe) {
              log("Error performing "+getRequestMethod() +" on " + url +
                  " : "+ioe.toString(), Project.MSG_ERR);
              if (failOnError) {
                  throw new BuildException(ioe);
              }
          }
      }
  
      /**
       * show a progress character
       * @todo this doesn't work in shell wrappers
       */
  
      protected void showProgressChar(char c) {
          System.out.write(c);
      }
  
  
      /**
       * Adds a form / request parameter.
       *
       * @param param The feature to be added to the HttpRequestParameter
       *      attribute
       */
      public void addParam(HttpRequestParameter param) {
          params.add(param);
      }
  
  
      /**
       * Adds an HTTP request header.
       *
       * @param header The feature to be added to the Header attribute
       */
      public void addHeader(HttpRequestParameter header) {
          headers.add(header);
      }
  
  
      /**
       * this must be overridden by implementations to set the request method
       * to GET, POST, whatever NB: this method only gets called for an
       * http request
       *
       * @return the method string
       */
      protected abstract String getRequestMethod();
  
  
      /**
       * determine the timestamp to use if the flag is set and the local
       * file actually exists.
       *
       * @return 0 for 'no timestamp', a number otherwhise
       */
  
      protected long getTimestamp() {
          long timestamp = 0;
          if (useTimestamp && dest != null && dest.exists()) {
              timestamp = dest.lastModified();
          }
          else {
              timestamp = 0;
          }
          return timestamp;
      }
  
  
      /**
       * ask for authentication details. An empty string means 'no auth'
       *
       * @return an RFC2617 auth string
       */
  
      protected String getAuthenticationString() {
          // Set authorization eader, if specified
          if (authType == AUTH_BASIC && username != null) {
              password = password == null ? "" : password;
              String encodeStr = username + ":" + password;
              Base64Encode encoder = new Base64Encode();
              char[] encodedPass = encoder.encodeBase64(encodeStr.getBytes());
              String authStr = "BASIC " + new String(encodedPass);
              return authStr;
          }
          else {
              return null;
          }
      }
  
  
      /**
       * this overridable method verifies that all the params are valid
       * the base implementation checks for remote url validity and if the
       * destination is not null, write access to what mustnt be a directory.
       * sublcasses can call the base class as well as check their own data
       *
       * @return true if everything is fine. false if we have encountered
       *      problems but arent allowed to fail on an error,
       * @exception BuildException only throw this when the failonerror
       *      flag is true
       */
  
      protected void verifyArguments()
          throws BuildException {
          BuildException trouble = null;
          //check remote params -but only create an exception, not throw it
          if (getURL() == null) {
              throw new BuildException("target URL missing");
          }
          //check destination parameters  -but only create an exception, not throw it
          if (dest != null && dest.exists()) {
              if (dest.isDirectory()) {
                  throw new BuildException("The specified destination is a directory");
              }
              else if (!dest.canWrite()) {
                  throw new BuildException("Can't write to " + dest.getAbsolutePath());
              }
          }
          //check auth policy
          if(authType!=AUTH_NONE && username==null) {
             throw new BuildException("no username defined to use with authorisation");
          }
       }
  
  
      /**
       * set the timestamp of a named file to a specified time. prints a
       * warning on java1.1
       *
       * @param file Description of Parameter
       * @param timemillis Description of Parameter
       * @exception BuildException Thrown in unrecoverable error. Likely
       *      this comes from file access failures.
       */
      protected void touchFile(File file, long timemillis)
          throws BuildException {
          getProject().setFileLastModified(file, timemillis);
      }
  
  
      /**
       * build a URL from the source url, maybe with parameters attached
       *
       * @return Description of the Returned Value
       * @exception BuildException Description of Exception
       */
      protected URL buildURL()
          throws BuildException {
          String urlbase = getURL();
          try {
              if (areParamsAddedToUrl()) {
                  urlbase = parameterizeURL();
              }
              return new URL(urlbase);
          }
          catch (MalformedURLException e) {
              throw new BuildException("Invalid URL");
          }
      }
  
  
      /**
       * take a url and add parameters to it. if there are no parameters
       * the base url string is returned
       *
       * @return a string to be used for URL creation
       * @exception BuildException Description of Exception
       */
      protected String parameterizeURL()
          throws BuildException {
          //return immediately if there are no parameters
          if (params.size() == 0) {
              return getURL();
          }
  
          StringBuffer buf = new StringBuffer(getURL());
          //this devious little line code recognises a parameter string already
          //in the source url, and if so doesnt add a new one
          buf.append(source.indexOf('?') == -1 ? '?' : '&');
          HttpRequestParameter param;
  
          //run through the parameter list, encode the name/value pairs and
          //append them to the list
          for (int i = 0; i < params.size(); i++) {
              if (i > 0) {
                  buf.append('&');
              }
              param = (HttpRequestParameter) params.get(i);
              buf.append(param.toString());
          }
          return buf.toString();
      }
  
  
      /**
       * query for the request wanting parameters on the url default is
       * true, subclasses may want to change
       *
       * @return true if a url should have params attached.
       */
  
      protected boolean areParamsAddedToUrl() {
          return true;
      }
  
      /**
       * get the auth policy
       * a null return value means 'no policy chosen'
       * @return current authorisation strategy or null
       */
  
       protected HttpAuthenticationStrategy getAuthStrategy() {
          HttpAuthenticationStrategy strategy=null;
          switch(authType) {
              case AUTH_BASIC:
                  strategy=new HttpBasicAuth();
                  break;
  
              case AUTH_DIGEST:
                  //TODO
                  break;
  
              case AUTH_NONE:
              default:
                  break;
          }
          return strategy;
  
       }
  
      /**
       * this method opens the connection. It can recognise a 401 error code
       * and in digest auth will then open a new connection with the
       * supplied nonce encoded. That is why it can return a new
       * connection object.
       * @todo handle digest auth
       * @param connection where to connect to
       * @exception BuildException build trouble
       * @exception IOException IO trouble
       * @return a new connection. This may be different than the old one
       */
  
      protected URLConnection makeConnectionWithAuthHandling(URLConnection connection)
          throws BuildException, IOException {
          log("Connecting to "+connection.toString(),Project.MSG_DEBUG);    
          connection.connect();
          URLConnection returnConnection=connection;
          log("connected",Project.MSG_DEBUG);
          if (connection instanceof HttpURLConnection) {
              HttpURLConnection httpConnection = (HttpURLConnection) connection;
              if(getResponseCode(httpConnection)==HttpURLConnection.HTTP_UNAUTHORIZED
                          && authType==AUTH_DIGEST) {
                  //TODO auth failure. in digest mode we can make a new auth
                  //duplicating all the settings then reconnect
                  //and return it
                  log("Digest authentication needed but not yet supported",Project.MSG_DEBUG);
              }
          }
  
          return returnConnection;
      }
  
  
      /** 
       * by making a query for a value from the connection, we force the
       * client code to actually do the http request and go into input mode.
       * so next we can check for trouble. 
       */
      void probeConnection (HttpURLConnection connection) {
          String probe=connection.getHeaderFieldKey(0);
      }
      
  
      /**
       * get a response from a connection request.
       * This code fixes a problem found in HttpURLConnection, that
       * any attempt to get the response code would trigger a FileNotFound
       * @see <a href="http://developer.java.sun.com/developer/bugParade/bugs/4160499.html">
       * BugParade details </a>
       * "If the requested file does not exist, and ends in .html, .htm, .txt or /, you
       *  will get the error stream with no exception thrown. If the file does not end
       *  like any of these you can catch the exception and immediately request it again
       *  to get the error stream. The response code can be obtained with
       *  getResponseCode()."
       * which means, to really get the response code you need to ask twice.
       * @param connection the current http link
       * @return whatever we get back
       * @throws IOException if anything other than file not found gets thrown,
       * and even a FileNotFound exception if that gets thrown too many times.
       */
      protected int getResponseCode(HttpURLConnection connection)
      throws IOException  {
          //force the creation of the input stream
          //(which is what HttpURLConnection.getResponseCode() does internally
          //that way the bug handler code is only needed once.
  
          //probeConnection(connection);
          IOException swallowed=null;
          boolean caught=false;
          int response=0;
          for (int attempts = 0; attempts < 5; attempts++) {
              try {
                  response = connection.getResponseCode();
                  caught=true;
                  break;
              }
              catch (FileNotFoundException ex) {
                  log("Swallowed FileNotFoundException in getResponseCode",
                      Project.MSG_VERBOSE);
                  log(ex.toString(),Project.MSG_DEBUG);
                  swallowed=ex;
              }
          }
          if(!caught && swallowed!=null) {
              throw swallowed;
          }
          return response;
      }
  
      /**
       * get an input stream from a connection
       * This code tries to fix a problem found in HttpURLConnection, that
       * any attempt to get the response code would trigger a FileNotFound
       * BugParade ID 4160499 :
       * <blockquote>
       * "If the requested file does not exist, and ends in .html, .htm, .txt or /, you
       *  will get the error stream with no exception thrown. If the file does not end
       *  like any of these you can catch the exception and immediately request it again
       *  to get the error stream. The response code can be obtained with
       *  getResponseCode()."
       * <blockquote>
       * which means, to really get the response code you need to ask twice. More to the point
       * this handling is not consistent across JVMs: on java 1.3 you can ask as often as you like
       * but you are not going to get the input stream on a JSP page when it has some 500 class error.
       * @param connection the current link
       * @return the input stream.
       * @throws IOException if anything other than file not found gets thrown,
       * and even a FileNotFound exception if that gets thrown too many times.
       */
  
     protected InputStream getInputStream(URLConnection connection)
      throws IOException  {
          IOException swallowed=null;
          InputStream instream=null;
          for (int attempts = 0; attempts < 5; attempts++) {
              try {
                  instream = connection.getInputStream();
                  break;
              }
              catch (FileNotFoundException ex) {
                  log("Swallowed IO exception in getInputStream",
                      Project.MSG_VERBOSE);
                  log(ex.toString(),Project.MSG_DEBUG);
                  swallowed=ex;
              }
          }
          if(instream==null && swallowed!=null) {
              throw swallowed;
          }
          return instream;
      }
  
  
  
      /**
       * this method is inteded for overriding. it is called when connecting
       * to a URL, and the base implementation just calls connect() on the
       * parameter. any subclass that wants to pump its own datastream up
       * (like post) must override this
       *
       * @param connection where to connect to
       * @exception BuildException build trouble
       * @exception IOException IO trouble
       */
  
      protected URLConnection doConnect(URLConnection connection)
          throws BuildException, IOException {
          return makeConnectionWithAuthHandling(connection);
      }
  
  
      /**
       * this is a method for upload centric post-like requests
       *
       * @param connection who we talk to
       * @param contentType Description of Parameter
       * @param contentLength Description of Parameter
       * @param content Description of Parameter
       * @exception IOException something went wrong with the IO
       */
      protected URLConnection doConnectWithUpload(URLConnection connection,
              String contentType, int contentLength,
              InputStream content)
          throws IOException {
  
          log("uploading " + contentLength + " bytes of type " + contentType,
                  Project.MSG_VERBOSE);
          //tell the connection we are in output mode
          connection.setDoOutput(true);
  
  
          // Set content length and type headers
          connection.setRequestProperty("Content-Length", String.valueOf(contentLength));
          connection.setRequestProperty("Content-Type", contentType);
          //todo: add auth handling
          //connection=makeConnectionWithAuthHandling(connection);
          connection.connect();
          OutputStream toServer = connection.getOutputStream();
  
          //create a buffer which is the smaller of
          //the content length and the block size (in KB)
          int buffersize=blockSize*1024;
          if(contentLength<buffersize)
              buffersize=contentLength;
          byte[] buffer = new byte[buffersize];
          int remaining = contentLength;
  
          while (remaining > 0) {
              int read = content.read(buffer);
              log("block of "+read,Project.MSG_DEBUG);
              toServer.write(buffer, 0, read);
              remaining -= read;
              if (verbose) {
                  showProgressChar('^');
              }
          }
          if (verbose) {
              showProgressChar('\n');
          }
          log("upload completed",Project.MSG_DEBUG);
          return connection;
      }
  
      /**
       * internal event handler called after a connect can throw an exception
       * or return false for an immediate exit from the process
       *
       * @param connection the now open connection
       * @return true if the execution is to continue
       * @exception BuildException Description of Exception
       */
      protected boolean onConnected(URLConnection connection)
          throws BuildException {
          return true;
      }
  
  
      /**
       * internal event handler called after the download is complete the
       * code can still bail out at this point, and the connection may contain
       * headers of interest. can throw an exception or return false for
       * an immediate exit from the process
       *
       * @param connection the now open connection
       * @return true if the execution is to continue
       * @exception BuildException Description of Exception
       */
      protected boolean onDownloadFinished(URLConnection connection)
          throws BuildException {
          return true;
      }
  
  
      /**
       * Enumerated attribute for "authType" with the value "basic" (note,
       * eventually we can add "digest" authentication)
       *
       * @author matt_h@pobox.com;
       * @created March 17, 2001
       */
      public static class AuthMethodType extends EnumeratedAttribute {
          /**
           * Gets the possible values of authorisation supported
           *
           * @return The Values value
           */
          public String[] getValues() {
              return new String[]{"none", "basic","digest"};
          }
  
          /**
           * lookup from value to a numeric value. defaults to 0, basic-auth
           * @param choice string selection
           * @return selected value
          */
          public int  mapValueToNumber() {
              String choice=getValue();
              int value=0;
              String[] values=getValues();
              for(int i=0;i<values.length;i++) {
                  if(values[i].equalsIgnoreCase(choice))
                      value=i;
              }
              return value;
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/NullOutputStream.java
  
  Index: NullOutputStream.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  import java.io.OutputStream;
  import java.io.IOException;
  
  /**
   * simple output stream which discards all write requests this should
   * really be part of java.io, as it is sporadically invaluable
   *
   * @author slo
   * @created March 17, 2001
   */
  public class NullOutputStream extends OutputStream {
  
      /**
       * discard all incoming bytes
       *
       * @param b byte to write
       * @exception IOException never throwable in this subclass
       */
      public void write(int b)
          throws IOException {
      }
  
  
      /**
       * discard all incoming bytes
       *
       * @param b  byte array
       * @exception IOException never throwable in this subclass
       */
      public void write(byte[] b)
          throws IOException {
      }
  
  
      /**
       * discard all incoming bytes
       *
       * @param b  byte array
       * @param off starting offset
       * @param len length to write
       * @exception IOException never throwable in this subclass
       */
      public void write(byte[] b,
              int off,
              int len)
          throws IOException {
      }
  
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/httptasks/src/main/org/apache/tools/ant/taskdefs/optional/http/SetProxy.java
  
  Index: SetProxy.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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 org.apache.tools.ant.taskdefs.optional.http;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import java.lang.reflect.*;
  import org.apache.tools.ant.*;
  
  /**
   * proxy definition task. This allows all web tasks in the build file
   * executed after this task to access the web through a proxy server
   *
   * @author steve_l@iseran.com Steve Loughran
   * @created March 17, 2001
   */
  
  public class SetProxy extends Task {
  
      /**
       * proxy details
       */
      protected String proxyHost = null;
  
      /**
       * name of proxy port
       */
      protected int proxyPort = 80;
  
      /**
       * socks host.
       */
      private String socksProxyHost = null;
      /**
       * socks proxy port. 1080 is the default
       */
      private int socksProxyPort = 1080;
  
  
  
      /**
       * set a proxy host. the port should be defined too
       *
       * @param hostname the new proxy hostname
       */
      public void setProxyHost(String hostname) {
          proxyHost = hostname;
      }
  
  
      /**
       * set the proxy port number.
       *
       * @param port port number of the proxy
       */
      public void setProxyPort(int port) {
          proxyPort = port;
      }
  
  
      /**
       * accessor to proxy hostname
       *
       * @return the hostname or null
       */
  
      public String getProxyHost() {
          return proxyHost;
      }
  
  
      /**
       * accessor to proxy hostname
       *
       * @return the port number
       */
  
      public int getProxyPort() {
          return proxyPort;
      }
  
  
      /**
       * Set the SocksProxyHost attribute
       *
       * @param host The new SocksProxyHost value
       */
      public void setSocksProxyHost(String host) {
          this.socksProxyHost = host;
      }
  
  
      /**
       * Set the SocksProxyPort attribute
       *
       * @param port The new SocksProxyPort value
       */
      public void setSocksProxyPort(int port) {
          this.socksProxyPort = port;
      }
  
  
  
      /**
       * if the proxy port and host settings are not null, then the settings
       * get applied these settings last beyond the life of the object and
       * apply to all network connections
       *
       * @return true if the settings were applied
       */
  
      public void applyWebProxySettings() {
          boolean settingsChanged=false;
          Properties prop = System.getProperties();
          if (getProxyHost() != null) {
              log("Setting proxy to " + getProxyHost() + ":" + getProxyPort(),
                      Project.MSG_VERBOSE);
              prop.put("http.proxyHost", getProxyHost());
              prop.put("http.proxyPort", String.valueOf(getProxyPort()));
              prop.put("https.proxyHost", getProxyHost());
              prop.put("https.proxyPort", String.valueOf(getProxyPort()));
              prop.put("ftp.proxyHost", getProxyHost());
              prop.put("ftp.proxyPort", String.valueOf(getProxyPort()));
              settingsChanged=true;
          }
  
          //socks
          if (socksProxyHost != null) {
              log("Setting proxy to " + getProxyHost() + ":" + getProxyPort(),
                      Project.MSG_VERBOSE);
              prop.put("socksProxyHost", socksProxyHost);
              prop.put("socksProxyPort", Integer.toString(socksProxyPort));
              settingsChanged=true;
          }
  
          //for Java1.1 we need to tell the system that the settings are new
          if(settingsChanged && project.getJavaVersion() == Project.JAVA_1_1) {
              prop.put("http.proxySet", "true");
              sun.net.www.http.HttpClient.resetProperties();
          }
          legacyResetProxySettingsCall();
      }
  
  
      /**
       * make a call to sun.net.www.http.HttpClient.resetProperties();
       * this is only needed for java 1.1; reflection is used to stop the compiler
       * whining, and in case cleanroom JVMs dont have the class.
       * @return Description of the Returned Value
       * @returns
       */
  
      protected boolean legacyResetProxySettingsCall() {
          try {
              Class c = Class.forName("sun.net.www.http.HttpClient");
              Method reset = c.getMethod("resetProperties", null);
              reset.invoke(null, null);
              return true;
          }
          catch (ClassNotFoundException cnfe) {
              return false;
          }
          catch (NoSuchMethodException e) {
              return false;
          }
          catch (IllegalAccessException e) {
              return false;
          }
          catch (InvocationTargetException e) {
              return false;
          }
  
      }
  
  
      /**
       * Does the work.
       *
       * @exception BuildException Thrown in unrecoverable error.
       */
      public void execute()
          throws BuildException {
          applyWebProxySettings();
      }
  
  }
  
  
  
  

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message