/* HTTPConnection.java --
   Copyright (C) 2004, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.net.protocol.http;

import gnu.classpath.SystemProperties;

import gnu.java.lang.CPStringBuilder;
import gnu.java.net.EmptyX509TrustManager;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

/**
 * A connection to an HTTP server.
 *
 * @author Chris Burdess (dog@gnu.org)
 */
public class HTTPConnection
{

  /**
   * The default HTTP port.
   */
  public static final int HTTP_PORT = 80;

  /**
   * The default HTTPS port.
   */
  public static final int HTTPS_PORT = 443;

  private static final String userAgent = SystemProperties.getProperty("http.agent");

  /**
   * The host name of the server to connect to.
   */
  protected final String hostname;

  /**
   * The port to connect to.
   */
  protected final int port;

  /**
   * Whether the connection should use transport level security (HTTPS).
   */
  protected final boolean secure;

  /**
   * The connection timeout for connecting the underlying socket.
   */
  protected final int connectionTimeout;

  /**
   * The read timeout for reads on the underlying socket.
   */
  protected final int timeout;

  /**
   * The host name of the proxy to connect to.
   */
  protected String proxyHostname;

  /**
   * The port on the proxy to connect to.
   */
  protected int proxyPort;

  /**
   * The major version of HTTP supported by this client.
   */
  protected int majorVersion;

  /**
   * The minor version of HTTP supported by this client.
   */
  protected int minorVersion;

  private final List<HandshakeCompletedListener> handshakeCompletedListeners;

  /**
   * The socket this connection communicates on.
   */
  protected Socket socket;

  /**
   * The SSL socket factory to use.
   */
  private SSLSocketFactory sslSocketFactory;

  /**
   * The socket input stream.
   */
  protected InputStream in;

  /**
   * The socket output stream.
   */
  protected OutputStream out;

  /**
   * Nonce values seen by this connection.
   */
  private Map<String, Integer> nonceCounts;

  /**
   * The cookie manager for this connection.
   */
  protected CookieManager cookieManager;


  /**
   * The pool that this connection is a member of (if any).
   */
  private Pool pool;

  /**
   * Creates a new HTTP connection.
   * @param hostname the name of the host to connect to
   */
  public HTTPConnection(String hostname)
  {
    this(hostname, HTTP_PORT, false, 0, 0);
  }

  /**
   * Creates a new HTTP or HTTPS connection.
   * @param hostname the name of the host to connect to
   * @param secure whether to use a secure connection
   */
  public HTTPConnection(String hostname, boolean secure)
  {
    this(hostname, secure ? HTTPS_PORT : HTTP_PORT, secure, 0, 0);
  }

  /**
   * Creates a new HTTP or HTTPS connection on the specified port.
   * @param hostname the name of the host to connect to
   * @param secure whether to use a secure connection
   * @param connectionTimeout the connection timeout
   * @param timeout the socket read timeout
   */
  public HTTPConnection(String hostname, boolean secure,
                        int connectionTimeout, int timeout)
  {
    this(hostname, secure ? HTTPS_PORT : HTTP_PORT, secure,
         connectionTimeout, timeout);
  }

  /**
   * Creates a new HTTP connection on the specified port.
   * @param hostname the name of the host to connect to
   * @param port the port on the host to connect to
   */
  public HTTPConnection(String hostname, int port)
  {
    this(hostname, port, false, 0, 0);
  }

  /**
   * Creates a new HTTP or HTTPS connection on the specified port.
   * @param hostname the name of the host to connect to
   * @param port the port on the host to connect to
   * @param secure whether to use a secure connection
   */
  public HTTPConnection(String hostname, int port, boolean secure)
  {
    this(hostname, port, secure, 0, 0);
  }

  /**
   * Creates a new HTTP or HTTPS connection on the specified port.
   * @param hostname the name of the host to connect to
   * @param port the port on the host to connect to
   * @param secure whether to use a secure connection
   * @param connectionTimeout the connection timeout
   * @param timeout the socket read timeout
   *
   * @throws IllegalArgumentException if either connectionTimeout or
   * timeout less than zero.
   */
  public HTTPConnection(String hostname, int port, boolean secure,
                        int connectionTimeout, int timeout)
  {
    if (connectionTimeout < 0 || timeout < 0)
      throw new IllegalArgumentException();

    this.hostname = hostname;
    this.port = port;
    this.secure = secure;
    this.connectionTimeout = connectionTimeout;
    this.timeout = timeout;
    majorVersion = minorVersion = 1;
    handshakeCompletedListeners
      = new ArrayList<HandshakeCompletedListener>(2);
  }

  /**
   * Returns the name of the host to connect to.
   */
  public String getHostName()
  {
    return hostname;
  }

  /**
   * Returns the port on the host to connect to.
   */
  public int getPort()
  {
    return port;
  }

  /**
   * Indicates whether to use a secure connection or not.
   */
  public boolean isSecure()
  {
    return secure;
  }

  /**
   * Returns the HTTP version string supported by this connection.
   * @see #majorVersion
   * @see #minorVersion
   */
  public String getVersion()
  {
    return "HTTP/" + majorVersion + '.' + minorVersion;
  }

  /**
   * Sets the HTTP version supported by this connection.
   * @param majorVersion the major version
   * @param minorVersion the minor version
   */
  public void setVersion(int majorVersion, int minorVersion)
  {
    if (majorVersion != 1)
      {
        throw new IllegalArgumentException("major version not supported: " +
                                           majorVersion);
      }
    if (minorVersion < 0 || minorVersion > 1)
      {
        throw new IllegalArgumentException("minor version not supported: " +
                                           minorVersion);
      }
    this.majorVersion = majorVersion;
    this.minorVersion = minorVersion;
  }

  /**
   * Directs this connection to use the specified proxy.
   * @param hostname the proxy host name
   * @param port the port on the proxy to connect to
   */
  public void setProxy(String hostname, int port)
  {
    proxyHostname = hostname;
    proxyPort = port;
  }

  /**
   * Indicates whether this connection is using an HTTP proxy.
   */
  public boolean isUsingProxy()
  {
    return (proxyHostname != null && proxyPort > 0);
  }

  /**
   * Sets the cookie manager to use for this connection.
   * @param cookieManager the cookie manager
   */
  public void setCookieManager(CookieManager cookieManager)
  {
    this.cookieManager = cookieManager;
  }

  /**
   * Returns the cookie manager in use for this connection.
   */
  public CookieManager getCookieManager()
  {
    return cookieManager;
  }

  /**
   * Manages a pool of HTTPConections.  The pool will have a maximum
   * size determined by the value of the maxConn parameter passed to
   * the {@link #get} method.  This value inevitably comes from the
   * http.maxConnections system property.  If the
   * classpath.net.http.keepAliveTTL system property is set, that will
   * be the maximum time (in seconds) that an idle connection will be
   * maintained.
   */
  static class Pool
  {
    /**
     * Singleton instance of the pool.
     */
    static Pool instance = new Pool();

    /**
     * The pool
     */
    final LinkedList<HTTPConnection> connectionPool
      = new LinkedList<HTTPConnection>();

    /**
     * Maximum size of the pool.
     */
    int maxConnections;

    /**
     * If greater than zero, the maximum time a connection will remain
     * int the pool.
     */
    int connectionTTL;

    /**
     * A thread that removes connections older than connectionTTL.
     */
    class Reaper
      implements Runnable
    {
      public void run()
      {
        synchronized (Pool.this)
          {
            try
              {
                do
                  {
                    while (connectionPool.size() > 0)
                      {
                        long currentTime = System.currentTimeMillis();

                        HTTPConnection c =
                          (HTTPConnection)connectionPool.getFirst();

                        long waitTime = c.timeLastUsed
                          + connectionTTL - currentTime;

                        if (waitTime <= 0)
                          removeOldest();
                        else
                          try
                            {
                              Pool.this.wait(waitTime);
                            }
                          catch (InterruptedException _)
                            {
                              // Ignore the interrupt.
                            }
                      }
                    // After the pool is empty, wait TTL to see if it
                    // is used again.  This is because in the
                    // situation where a single thread is making HTTP
                    // requests to the same server it can remove the
                    // connection from the pool before the Reaper has
                    // a chance to start.  This would cause the Reaper
                    // to exit if it were not for this extra delay.
                    // The result would be starting a Reaper thread
                    // for each HTTP request.  With the delay we get
                    // at most one Reaper created each TTL.
                    try
                      {
                        Pool.this.wait(connectionTTL);
                      }
                    catch (InterruptedException _)
                      {
                        // Ignore the interrupt.
                      }
                  }
                while (connectionPool.size() > 0);
              }
            finally
              {
                reaper = null;
              }
          }
      }
    }

    Reaper reaper;

    /**
     * Private constructor to ensure singleton.
     */
    private Pool()
    {
    }

    /**
     * Tests for a matching connection.
     *
     * @param c connection to match.
     * @param h the host name.
     * @param p the port.
     * @param sec true if using https.
     *
     * @return true if c matches h, p, and sec.
     */
    private static boolean matches(HTTPConnection c,
                                   String h, int p, boolean sec)
    {
      return h.equals(c.hostname) && (p == c.port) && (sec == c.secure);
    }

    /**
     * Get a pooled HTTPConnection.  If there is an existing idle
     * connection to the requested server it is returned.  Otherwise a
     * new connection is created.
     *
     * @param host the name of the host to connect to
     * @param port the port on the host to connect to
     * @param secure whether to use a secure connection
     *
     * @return the HTTPConnection.
     */
    synchronized HTTPConnection get(String host,
                                    int port,
                                    boolean secure,
                                    int connectionTimeout, int timeout)
    {
      String ttl =
        SystemProperties.getProperty("classpath.net.http.keepAliveTTL");
      connectionTTL = 10000;
      if (ttl != null && ttl.length() > 0)
        try
          {
            int v = 1000 * Integer.parseInt(ttl);
            if (v >= 0)
              connectionTTL = v;
          }
        catch (NumberFormatException _)
          {
            // Ignore.
          }

      String mc = SystemProperties.getProperty("http.maxConnections");
      maxConnections = 5;
      if (mc != null && mc.length() > 0)
        try
          {
            int v = Integer.parseInt(mc);
            if (v > 0)
              maxConnections = v;
          }
        catch (NumberFormatException _)
          {
            // Ignore.
          }

      HTTPConnection c = null;

      ListIterator it = connectionPool.listIterator(0);
      while (it.hasNext())
        {
          HTTPConnection cc = (HTTPConnection)it.next();
          if (matches(cc, host, port, secure))
            {
              c = cc;
              it.remove();
              // Update the timeout.
              if (c.socket != null)
                try
                  {
                    c.socket.setSoTimeout(timeout);
                  }
                catch (SocketException _)
                  {
                    // Ignore.
                  }
              break;
            }
        }
      if (c == null)
        {
          c = new HTTPConnection(host, port, secure,
                                 connectionTimeout, timeout);
          c.setPool(this);
        }
      return c;
    }

    /**
     * Put an idle HTTPConnection back into the pool.  If this causes
     * the pool to be come too large, the oldest connection is removed
     * and closed.
     *
     */
    synchronized void put(HTTPConnection c)
    {
      c.timeLastUsed = System.currentTimeMillis();
      connectionPool.addLast(c);

      // maxConnections must always be >= 1
      while (connectionPool.size() >= maxConnections)
        removeOldest();

      if (connectionTTL > 0 && null == reaper) {
        // If there is a connectionTTL, then the reaper has removed
        // any stale connections, so we don't have to check for stale
        // now.  We do have to start a reaper though, as there is not
        // one running now.
        reaper = new Reaper();
        Thread t = new Thread(reaper, "HTTPConnection.Reaper");
        t.setDaemon(true);
        t.start();
      }
    }

    /**
     * Remove the oldest connection from the pool and close it.
     */
    void removeOldest()
    {
      HTTPConnection cx = (HTTPConnection)connectionPool.removeFirst();
      try
        {
          cx.closeConnection();
        }
      catch (IOException ioe)
        {
          // Ignore it.  We are just cleaning up.
        }
    }
  }

  /**
   * The number of times this HTTPConnection has be used via keep-alive.
   */
  int useCount;

  /**
   * If this HTTPConnection is in the pool, the time it was put there.
   */
  long timeLastUsed;

  /**
   * Set the connection pool that this HTTPConnection is a member of.
   * If left unset or set to null, it will not be a member of any pool
   * and will not be a candidate for reuse.
   *
   * @param p the pool.
   */
  void setPool(Pool p)
  {
    pool = p;
  }

  /**
   * Signal that this HTTPConnection is no longer needed and can be
   * returned to the connection pool.
   *
   */
  void release()
  {
    if (pool != null)
      {
        useCount++;
        pool.put(this);

      }
    else
      {
        // If there is no pool, just close.
        try
          {
            closeConnection();
          }
        catch (IOException ioe)
          {
            // Ignore it.  We are just cleaning up.
          }
      }
  }

  /**
   * Creates a new request using this connection.
   * @param method the HTTP method to invoke
   * @param path the URI-escaped RFC2396 <code>abs_path</code> with
   * optional query part
   */
  public Request newRequest(String method, String path)
  {
    if (method == null || method.length() == 0)
      {
        throw new IllegalArgumentException("method must have non-zero length");
      }
    if (path == null || path.length() == 0)
      {
        path = "/";
      }
    Request ret = new Request(this, method, path);
    if ((secure && port != HTTPS_PORT) ||
        (!secure && port != HTTP_PORT))
      {
        ret.setHeader("Host", hostname + ":" + port);
      }
    else
      {
        ret.setHeader("Host", hostname);
      }
    ret.setHeader("User-Agent", userAgent);
    ret.setHeader("Connection", "keep-alive");
    ret.setHeader("Accept-Encoding",
                  "chunked;q=1.0, gzip;q=0.9, deflate;q=0.8, " +
                  "identity;q=0.6, *;q=0");
    if (cookieManager != null)
      {
        Cookie[] cookies = cookieManager.getCookies(hostname, secure, path);
        if (cookies != null && cookies.length > 0)
          {
            CPStringBuilder buf = new CPStringBuilder();
            buf.append("$Version=1");
            for (int i = 0; i < cookies.length; i++)
              {
                buf.append(',');
                buf.append(' ');
                buf.append(cookies[i].toString());
              }
            ret.setHeader("Cookie", buf.toString());
          }
      }
    return ret;
  }

  /**
   * Closes this connection.
   */
  public void close()
    throws IOException
  {
    closeConnection();
  }

  /**
   * Retrieves the socket associated with this connection.
   * This creates the socket if necessary.
   */
  protected synchronized Socket getSocket()
    throws IOException
  {
    if (socket == null)
      {
        String connectHostname = hostname;
        int connectPort = port;
        if (isUsingProxy())
          {
            connectHostname = proxyHostname;
            connectPort = proxyPort;
          }
        socket = new Socket();
        InetSocketAddress address =
          new InetSocketAddress(connectHostname, connectPort);
        if (connectionTimeout > 0)
          {
            socket.connect(address, connectionTimeout);
          }
        else
          {
            socket.connect(address);
          }
        if (timeout > 0)
          {
            socket.setSoTimeout(timeout);
          }
        if (secure)
          {
            try
              {
                SSLSocketFactory factory = getSSLSocketFactory();
                SSLSocket ss =
                  (SSLSocket) factory.createSocket(socket, connectHostname,
                                                   connectPort, true);
                String[] protocols = { "TLSv1", "SSLv3" };
                ss.setEnabledProtocols(protocols);
                ss.setUseClientMode(true);
                synchronized (handshakeCompletedListeners)
                  {
                    if (!handshakeCompletedListeners.isEmpty())
                      {
                        for (Iterator i =
                             handshakeCompletedListeners.iterator();
                             i.hasNext(); )
                          {
                            HandshakeCompletedListener l =
                              (HandshakeCompletedListener) i.next();
                            ss.addHandshakeCompletedListener(l);
                          }
                      }
                  }
                ss.startHandshake();
                socket = ss;
              }
            catch (GeneralSecurityException e)
              {
                throw new IOException(e.getMessage());
              }
          }
        in = socket.getInputStream();
        in = new BufferedInputStream(in);
        out = socket.getOutputStream();
        out = new BufferedOutputStream(out);
      }
    return socket;
  }

  SSLSocketFactory getSSLSocketFactory()
    throws GeneralSecurityException
  {
    if (sslSocketFactory == null)
      {
        TrustManager tm = new EmptyX509TrustManager();
        SSLContext context = SSLContext.getInstance("SSL");
        TrustManager[] trust = new TrustManager[] { tm };
        context.init(null, trust, null);
        sslSocketFactory = context.getSocketFactory();
      }
    return sslSocketFactory;
  }

  void setSSLSocketFactory(SSLSocketFactory factory)
  {
    sslSocketFactory = factory;
  }

  protected synchronized InputStream getInputStream()
    throws IOException
  {
    if (socket == null)
      {
        getSocket();
      }
    return in;
  }

  protected synchronized OutputStream getOutputStream()
    throws IOException
  {
    if (socket == null)
      {
        getSocket();
      }
    return out;
  }

  /**
   * Closes the underlying socket, if any.
   */
  protected synchronized void closeConnection()
    throws IOException
  {
    if (socket != null)
      {
        try
          {
            socket.close();
          }
        finally
          {
            socket = null;
          }
      }
  }

  /**
   * Returns a URI representing the connection.
   * This does not include any request path component.
   */
  protected String getURI()
  {
    CPStringBuilder buf = new CPStringBuilder();
    buf.append(secure ? "https://" : "http://");
    buf.append(hostname);
    if (secure)
      {
        if (port != HTTPConnection.HTTPS_PORT)
          {
            buf.append(':');
            buf.append(port);
          }
      }
    else
      {
        if (port != HTTPConnection.HTTP_PORT)
          {
            buf.append(':');
            buf.append(port);
          }
      }
    return buf.toString();
  }

  /**
   * Get the number of times the specified nonce has been seen by this
   * connection.
   */
  int getNonceCount(String nonce)
  {
    if (nonceCounts == null)
      {
        return 0;
      }
    return nonceCounts.get(nonce).intValue();
  }

  /**
   * Increment the number of times the specified nonce has been seen.
   */
  void incrementNonce(String nonce)
  {
    int current = getNonceCount(nonce);
    if (nonceCounts == null)
      {
        nonceCounts = new HashMap<String, Integer>();
      }
    nonceCounts.put(nonce, new Integer(current + 1));
  }

  // -- Events --

  void addHandshakeCompletedListener(HandshakeCompletedListener l)
  {
    synchronized (handshakeCompletedListeners)
      {
        handshakeCompletedListeners.add(l);
      }
  }
  void removeHandshakeCompletedListener(HandshakeCompletedListener l)
  {
    synchronized (handshakeCompletedListeners)
      {
        handshakeCompletedListeners.remove(l);
      }
  }

}
