/*
 * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.rmi.transport.proxy;

import java.io.*;
import java.net.*;

import sun.rmi.runtime.Log;

/**
 * The HttpSendSocket class extends the java.net.Socket class
 * by enclosing the data output stream in, then extracting the input
 * stream from, an HTTP protocol transmission.
 *
 * NOTES:
 *
 * Since the length of the output request must be known before the
 * HTTP header can be completed, all of the output is buffered by
 * an HttpOutputStream object until either an attempt is made to
 * read from this socket, or the socket is explicitly closed.
 *
 * On the first read attempt to read from this socket, the buffered
 * output is sent to the destination as the body of an HTTP POST
 * request.  All reads will then acquire data from the body of
 * the response.  A subsequent attempt to write to this socket will
 * throw an IOException.
 */
class HttpSendSocket extends Socket implements RMISocketInfo {

    /** the host to connect to */
    protected String host;

    /** the port to connect to */
    protected int port;

    /** the URL to forward through */
    protected URL url;

    /** the object managing this connection through the URL */
    protected URLConnection conn = null;

    /** internal input stream for this socket */
    protected InputStream in = null;

    /** internal output stream for this socket */
    protected OutputStream out = null;

    /** the notifying input stream returned to users */
    protected HttpSendInputStream inNotifier;

    /** the notifying output stream returned to users */
    protected HttpSendOutputStream outNotifier;

    /**
     * Line separator string.  This is the value of the line.separator
     * property at the moment that the socket was created.
     */
    private String lineSeparator =
        java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("line.separator"));

    /**
     * Create a stream socket and connect it to the specified port on
     * the specified host.
     * @param host the host
     * @param port the port
     */
    public HttpSendSocket(String host, int port, URL url) throws IOException
    {
        super((SocketImpl)null);        // no underlying SocketImpl for this object

        if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
            RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
                "host = " + host + ", port = " + port + ", url = " + url);
        }

        this.host = host;
        this.port = port;
        this.url = url;

        inNotifier = new HttpSendInputStream(null, this);
        outNotifier = new HttpSendOutputStream(writeNotify(), this);
    }

    /**
     * Create a stream socket and connect it to the specified port on
     * the specified host.
     * @param host the host
     * @param port the port
     */
    public HttpSendSocket(String host, int port) throws IOException
    {
        this(host, port, new URL("http", host, port, "/"));
    }

    /**
     * Create a stream socket and connect it to the specified address on
     * the specified port.
     * @param address the address
     * @param port the port
     */
    public HttpSendSocket(InetAddress address, int port) throws IOException
    {
        this(address.getHostName(), port);
    }

    /**
     * Indicate that this socket is not reusable.
     */
    public boolean isReusable()
    {
        return false;
    }

    /**
     * Create a new socket connection to host (or proxy), and prepare to
     * send HTTP transmission.
     */
    public synchronized OutputStream writeNotify() throws IOException
    {
        if (conn != null) {
            throw new IOException("attempt to write on HttpSendSocket after " +
                                  "request has been sent");
        }

        conn = url.openConnection();
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestProperty("Content-type", "application/octet-stream");

        inNotifier.deactivate();
        in = null;

        return out = conn.getOutputStream();
    }

    /**
     * Send HTTP output transmission and prepare to receive response.
     */
    public synchronized InputStream readNotify() throws IOException
    {
        RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
            "sending request and activating input stream");

        outNotifier.deactivate();
        out.close();
        out = null;

        try {
            in = conn.getInputStream();
        } catch (IOException e) {
            RMIMasterSocketFactory.proxyLog.log(Log.BRIEF,
                "failed to get input stream, exception: ", e);

            throw new IOException("HTTP request failed");
        }

        /*
         * If an HTTP error response is returned, sometimes an IOException
         * is thrown, which is handled above, and other times it isn't, and
         * the error response body will be available for reading.
         * As a safety net to catch any such unexpected HTTP behavior, we
         * verify that the content type of the response is what the
         * HttpOutputStream generates: "application/octet-stream".
         * (Servers' error responses will generally be "text/html".)
         * Any error response body is printed to the log.
         */
        String contentType = conn.getContentType();
        if (contentType == null ||
            !conn.getContentType().equals("application/octet-stream"))
        {
            if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.BRIEF)) {
                String message;
                if (contentType == null) {
                    message = "missing content type in response" +
                        lineSeparator;
                } else {
                    message = "invalid content type in response: " +
                        contentType + lineSeparator;
                }

                message += "HttpSendSocket.readNotify: response body: ";
                try {
                    DataInputStream din = new DataInputStream(in);
                    String line;
                    while ((line = din.readLine()) != null)
                        message += line + lineSeparator;
                } catch (IOException e) {
                }
                RMIMasterSocketFactory.proxyLog.log(Log.BRIEF, message);
            }

            throw new IOException("HTTP request failed");
        }

        return in;
    }

    /**
     * Get the address to which the socket is connected.
     */
    public InetAddress getInetAddress()
    {
        try {
            return InetAddress.getByName(host);
        } catch (UnknownHostException e) {
            return null;        // null if couldn't resolve destination host
        }
    }

    /**
     * Get the local address to which the socket is bound.
     */
    public InetAddress getLocalAddress()
    {
        try {
            return InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            return null;        // null if couldn't determine local host
        }
    }

    /**
     * Get the remote port to which the socket is connected.
     */
    public int getPort()
    {
        return port;
    }

    /**
     * Get the local port to which the socket is connected.
     */
    public int getLocalPort()
    {
        return -1;      // request not applicable to this socket type
    }

    /**
     * Get an InputStream for this socket.
     */
    public InputStream getInputStream() throws IOException
    {
        return inNotifier;
    }

    /**
     * Get an OutputStream for this socket.
     */
    public OutputStream getOutputStream() throws IOException
    {
        return outNotifier;
    }

    /**
     * Enable/disable TCP_NODELAY.
     * This operation has no effect for an HttpSendSocket.
     */
    public void setTcpNoDelay(boolean on) throws SocketException
    {
    }

    /**
     * Retrieve whether TCP_NODELAY is enabled.
     */
    public boolean getTcpNoDelay() throws SocketException
    {
        return false;   // imply option is disabled
    }

    /**
     * Enable/disable SO_LINGER with the specified linger time.
     * This operation has no effect for an HttpSendSocket.
     */
    public void setSoLinger(boolean on, int val) throws SocketException
    {
    }

    /**
     * Retrive setting for SO_LINGER.
     */
    public int getSoLinger() throws SocketException
    {
        return -1;      // imply option is disabled
    }

    /**
     * Enable/disable SO_TIMEOUT with the specified timeout
     * This operation has no effect for an HttpSendSocket.
     */
    public synchronized void setSoTimeout(int timeout) throws SocketException
    {
    }

    /**
     * Retrive setting for SO_TIMEOUT.
     */
    public synchronized int getSoTimeout() throws SocketException
    {
        return 0;       // imply option is disabled
    }

    /**
     * Close the socket.
     */
    public synchronized void close() throws IOException
    {
        if (out != null) // push out transmission if not done
            out.close();
    }

    /**
     * Return string representation of this pseudo-socket.
     */
    public String toString()
    {
        return "HttpSendSocket[host=" + host +
               ",port=" + port +
               ",url=" + url + "]";
    }
}
