/* HTTPURLConnection.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 java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ProtocolException;
import java.net.URL;
import java.security.cert.Certificate;
import java.util.Collections;
import java.util.Date;
import java.util.Map;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocketFactory;

/**
 * A URLConnection that uses the HTTPConnection class.
 *
 * @author Chris Burdess (dog@gnu.org)
 */
public class HTTPURLConnection
 extends HttpsURLConnection
  implements HandshakeCompletedListener
{
  /*
   * The underlying connection.
   */
  private HTTPConnection connection;

  // These are package private for use in anonymous inner classes.
  String proxyHostname;
  int proxyPort;
  String agent;
  boolean keepAlive;

  private Request request;
  private Headers requestHeaders;
  private ByteArrayOutputStream requestSink;
  private boolean requestMethodSetExplicitly;

  private Response response;
  private InputStream responseSink;
  private InputStream errorSink;

  private HandshakeCompletedEvent handshakeEvent;

  /**
   * Constructor.
   * @param url the URL
   */
  public HTTPURLConnection(URL url)
    throws IOException
  {
    super(url);
    requestHeaders = new Headers();
    proxyHostname = SystemProperties.getProperty("http.proxyHost");
    if (proxyHostname != null && proxyHostname.length() > 0)
      {
        String port = SystemProperties.getProperty("http.proxyPort");
        if (port != null && port.length() > 0)
          {
            proxyPort = Integer.parseInt(port);
          }
        else
          {
            proxyHostname = null;
            proxyPort = -1;
          }
      }
    agent = SystemProperties.getProperty("http.agent");
    String ka = SystemProperties.getProperty("http.keepAlive");
    keepAlive = !(ka != null && "false".equals(ka));
  }

  public void connect()
    throws IOException
  {
    if (connected)
      {
        return;
      }
    String protocol = url.getProtocol();
    boolean secure = "https".equals(protocol);
    String host = url.getHost();
    int port = url.getPort();
    if (port < 0)
      {
        port = secure ? HTTPConnection.HTTPS_PORT :
          HTTPConnection.HTTP_PORT;
      }
    String file = url.getFile();
    String username = url.getUserInfo();
    String password = null;
    if (username != null)
      {
        int ci = username.indexOf(':');
        if (ci != -1)
          {
            password = username.substring(ci + 1);
            username = username.substring(0, ci);
          }
      }
    final Credentials creds = (username == null) ? null :
      new Credentials (username, password);
    
    if ("POST".equals(method))
      {
        String contentType = requestHeaders.getValue("Content-Type");
        if (null == contentType)
          requestHeaders.addValue("Content-Type",
                                  "application/x-www-form-urlencoded");
      }

    boolean retry;
    do
      {
        retry = false;
        if (connection == null)
          {
            connection = getConnection(host, port, secure);
            if (secure)
              {
                SSLSocketFactory factory = getSSLSocketFactory();
                HostnameVerifier verifier = getHostnameVerifier();
                if (factory != null)
                  {
                    connection.setSSLSocketFactory(factory);
                  }
                connection.addHandshakeCompletedListener(this);
                // TODO verifier
              }
          }
        if (proxyHostname != null)
          {
            if (proxyPort < 0)
              {
                proxyPort = secure ? HTTPConnection.HTTPS_PORT :
                  HTTPConnection.HTTP_PORT;
              }
            connection.setProxy(proxyHostname, proxyPort);
          }
        try
          {
            request = connection.newRequest(method, file);
            if (!keepAlive)
              {
                request.setHeader("Connection", "close");
              }
            if (agent != null)
              {
                request.setHeader("User-Agent", agent);
              }
            request.getHeaders().putAll(requestHeaders);
            if (requestSink != null)
              {
                byte[] content = requestSink.toByteArray();
                RequestBodyWriter writer = new ByteArrayRequestBodyWriter(content);
                request.setRequestBodyWriter(writer);
              }
            if (creds != null)
              {
                request.setAuthenticator(new Authenticator() {
                    public Credentials getCredentials(String realm, int attempts)
                    {
                      return (attempts < 2) ? creds : null;
                    }
                  });
              }
            response = request.dispatch();
          }
        catch (IOException ioe)
          {
            if (connection.useCount > 0)
              {
                // Connection re-use failed: Try a new connection.
                try
                  {
                    connection.close();
                  }
                catch (IOException _)
                  {
                    // Ignore.
                  }
                connection = null;
                retry = true;
                continue;
              }
            else
              {
                // First time the connection was used: Hard failure.
                throw ioe;
              }
          }
        
        if (response.isRedirect() && getInstanceFollowRedirects())
          {
	    // Read the response body, if there is one.  If the
	    // redirect points us back at the same server, we will use
	    // the cached connection, so we must make sure there is no
	    // pending data in it.
            InputStream body = response.getBody();
	    if (body != null)
	      {
		byte[] ignore = new byte[1024];
		while (true)
		  {
		    int n = body.read(ignore, 0, ignore.length);
		    if (n == -1)
		      break;
		  }
	      }

            // Follow redirect
            String location = response.getHeader("Location");
	    if (location != null)
	      {
		String connectionUri = connection.getURI();
		int start = connectionUri.length();
		if (location.startsWith(connectionUri) &&
		    location.charAt(start) == '/')
		  {
		    file = location.substring(start);
		    retry = true;
		  }
		else if (location.startsWith("http:"))
		  {
		    connection.close();
		    connection = null;
		    secure = false;
		    start = 7;
		    int end = location.indexOf('/', start);
                    if (end == -1)
                      end = location.length();
		    host = location.substring(start, end);
		    int ci = host.lastIndexOf(':');
		    if (ci != -1)
		      {
			port = Integer.parseInt(host.substring (ci + 1));
			host = host.substring(0, ci);
		      }
		    else
		      {
			port = HTTPConnection.HTTP_PORT;
		      }
		    file = location.substring(end);
		    retry = true;
		  }
		else if (location.startsWith("https:"))
		  {
		    connection.close();
		    connection = null;
		    secure = true;
		    start = 8;
		    int end = location.indexOf('/', start);
                    if (end == -1)
                      end = location.length();
		    host = location.substring(start, end);
		    int ci = host.lastIndexOf(':');
		    if (ci != -1)
		      {
			port = Integer.parseInt(host.substring (ci + 1));
			host = host.substring(0, ci);
		      }
		    else
		      {
			port = HTTPConnection.HTTPS_PORT;
		      }
		    file = location.substring(end);
		    retry = true;
		  }
		else if (location.length() > 0)
		  {
		    // Malformed absolute URI, treat as file part of URI
		    if (location.charAt(0) == '/')
		      {
			// Absolute path
			file = location;
		      }
		    else
		      {
			// Relative path
			int lsi = file.lastIndexOf('/');
			file = (lsi == -1) ? "/" : file.substring(0, lsi + 1);
		    file += location;
		      }
		    retry = true;
		  }
	      }
          }
        else
          {
            responseSink = response.getBody();
            
            if (response.isError())
	      errorSink = responseSink;
          }
      }
    while (retry);
    connected = true;
  }  

  /**
   * Returns a connection, from the pool if necessary.
   */
  HTTPConnection getConnection(String host, int port, boolean secure)
    throws IOException
  {
    HTTPConnection connection;
    if (keepAlive)
      {
        connection = HTTPConnection.Pool.instance.get(host, port, secure, getConnectTimeout(), 0);
      }
    else
      {
        connection = new HTTPConnection(host, port, secure, 0, getConnectTimeout());
      }
    return connection;
  }

  public void disconnect()
  {
    if (connection != null)
      {
        try
          {
            connection.close();
          }
        catch (IOException e)
          {
          }
      }
  }

  public boolean usingProxy()
  {
    return (proxyHostname != null);
  }

  /**
   * Overrides the corresponding method in HttpURLConnection to permit
   * arbitrary methods, as long as they're valid ASCII alphabetic
   * characters. This is to permit WebDAV and other HTTP extensions to
   * function.
   * @param method the method
   */
  public void setRequestMethod(String method)
    throws ProtocolException
  {
    if (connected)
      {
        throw new ProtocolException("Already connected");
      }
    // Validate
    method = method.toUpperCase();
    int len = method.length();
    if (len == 0)
      {
        throw new ProtocolException("Empty method name");
      }
    for (int i = 0; i < len; i++)
      {
        char c = method.charAt(i);
        if (c < 0x41 || c > 0x5a)
          {
            throw new ProtocolException("Illegal character '" + c +
                                        "' at index " + i);
          }
      }
    // OK
    this.method = method;
    requestMethodSetExplicitly = true;
  }

  public String getRequestProperty(String key)
  {    
    return requestHeaders.getValue(key);
  }

  public Map getRequestProperties()
  {
    if (connected)
      throw new IllegalStateException("Already connected");
    
    Map m = requestHeaders.getAsMap();
    return Collections.unmodifiableMap(m);
  }

  public void setRequestProperty(String key, String value)
  {
    super.setRequestProperty(key, value);
    
    requestHeaders.put(key, value);
  }

  public void addRequestProperty(String key, String value)
  {
    super.addRequestProperty(key, value);
    requestHeaders.addValue(key, value);
  }

  public OutputStream getOutputStream()
    throws IOException
  {
    if (connected)
      {
        throw new ProtocolException("Already connected");
      }
    if (!doOutput)
      {
        throw new ProtocolException("doOutput is false");
      }
    else if (!requestMethodSetExplicitly)
      {
        /*
         * Silently change the method to POST if no method was set
         * explicitly. This is due to broken applications depending on this
         * behaviour (Apache XMLRPC for one).
         */
        method = "POST";
      }
    if (requestSink == null)
      {
        requestSink = new ByteArrayOutputStream();
      }
    return requestSink;
  }
  
  // -- Response --
  
  public InputStream getInputStream()
    throws IOException
  {
    if (!connected)
      {
        connect();
      }
    if (!doInput)
      {
        throw new ProtocolException("doInput is false");
      }
    
    if (response.isError())
      {
        int code = response.getCode();
        if (code == 404 || code == 410)
          throw new FileNotFoundException(url.toString());
      
        throw new IOException("Server returned HTTP response code " + code
                              + " for URL " + url.toString());
      }
    
    return responseSink;
  }

  public InputStream getErrorStream()
  {
    return errorSink;
  }

  public Map getHeaderFields()
  {
    if (!connected)
      {
        try
          {
            connect();
          }
        catch (IOException e)
          {
            return null;
          }
      }
    Map m = response.getHeaders().getAsMap();
    m.put(null, Collections.singletonList(getStatusLine(response)));
    return Collections.unmodifiableMap(m);
  }

  String getStatusLine(Response response)
  {
    return "HTTP/" + response.getMajorVersion() +
      "." + response.getMinorVersion() +
      " " + response.getCode() +
      " " + response.getMessage();
  }
  
  public String getHeaderField(int index)
  {
    if (!connected)
      {
        try
          {
            connect();
          }
        catch (IOException e)
          {
            return null;
          }
      }
    if (index == 0)
      {
        return getStatusLine(response);
      }
    return response.getHeaders().getHeaderValue(index - 1);
  }

  public String getHeaderFieldKey(int index)
  {
    if (!connected)
      {
        try
          {
            connect();
          }
        catch (IOException e)
          {
            return null;
          }
      }
    // index of zero is the status line.
    return response.getHeaders().getHeaderName(index - 1);
  }

  public String getHeaderField(String name)
  {
    if (!connected)
      {
        try
          {
            connect();
          }
        catch (IOException e)
          {
            return null;
          }
      }
    return response.getHeader(name);
  }

  public long getHeaderFieldDate(String name, long def)
  {
    if (!connected)
      {
        try
          {
            connect();
          }
        catch (IOException e)
          {
            return def;
          }
      }
    Date date = response.getDateHeader(name);
    return (date == null) ? def : date.getTime();
  }

  public String getContentType()
  {
    return getHeaderField("Content-Type");
  }

  public int getResponseCode()
    throws IOException
  {
    if (!connected)
      {
        connect();
      }
    return response.getCode();
  }

  public String getResponseMessage()
    throws IOException
  {
    if (!connected)
      {
        connect();
      }
    return response.getMessage();
  }

  // -- HTTPS specific --

  public String getCipherSuite()
  {
    if (!connected)
      {
        throw new IllegalStateException("not connected");
      }
    return handshakeEvent.getCipherSuite();
  }
  
  public Certificate[] getLocalCertificates()
  {
    if (!connected)
      {
        throw new IllegalStateException("not connected");
      }
    return handshakeEvent.getLocalCertificates();
  }

  public Certificate[] getServerCertificates()
    throws SSLPeerUnverifiedException
  {
    if (!connected)
      {
        throw new IllegalStateException("not connected");
      }
    return handshakeEvent.getPeerCertificates();
  }

  // HandshakeCompletedListener

  public void handshakeCompleted(HandshakeCompletedEvent event)
  {
    handshakeEvent = event;
  }

  /**
   * Set the connection timeout speed, in milliseconds, or zero if the timeout
   * is to be considered infinite.
   *
   * Overloaded.
   *
   */
  public void setConnectTimeout(int timeout)
    throws IllegalArgumentException
  {
    super.setConnectTimeout( timeout );
    if( connection == null )
      return;
    try 
      {
	connection.getSocket().setSoTimeout( timeout );
      } 
    catch(IOException se)
      {
	// Ignore socket exceptions.
      }
  }
}

