/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package flex.messaging.io.amf.client;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import flex.messaging.MessageException;
import flex.messaging.io.amf.ActionContext;
import flex.messaging.io.amf.ActionMessage;
import flex.messaging.io.amf.AmfTrace;
import flex.messaging.io.amf.MessageBody;
import flex.messaging.io.amf.MessageHeader;
import flex.messaging.io.ClassAliasRegistry;
import flex.messaging.io.MessageDeserializer;
import flex.messaging.io.MessageIOConstants;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.AmfMessageSerializer;
import flex.messaging.io.amf.AmfMessageDeserializer;
import flex.messaging.io.amf.client.exceptions.ClientStatusException;
import flex.messaging.io.amf.client.exceptions.ServerStatusException;

/**
 * A Java alternative to the native flash.net.NetConnection class for
 * sending AMF formatted requests over HTTP or HTTPS.
 * AMFConnection in Actionscript. AMF connection automatically handles cookies
 * by looking for cookie headers and setting the cookies in subsequent request.
 *
 * AMF connection class is not thread safe.
 */
public class AMFConnection
{
    //--------------------------------------------------------------------------
    //
    // Public Static Variables
    //
    //--------------------------------------------------------------------------

    public static final String COOKIE = "Cookie";
    public static final String COOKIE2 = "Cookie2";
    public static final String COOKIE_SEPERATOR = ";";
    public static final String COOKIE_NAMEVALUE_SEPERATOR = "=";
    public static final String SET_COOKIE = "Set-Cookie";
    public static final String SET_COOKIE2 = "Set-Cookie2";

    //--------------------------------------------------------------------------
    //
    // Private Static Variables
    //
    //--------------------------------------------------------------------------

    private static int DEFAULT_OBJECT_ENCODING = MessageIOConstants.AMF3;
    private static String HTTP_HEADER_NAME_CONTENT_TYPE = "Content-Type";

    //--------------------------------------------------------------------------
    //
    // Public Static Methods
    //
    //--------------------------------------------------------------------------

    /**
     * Registers a custom alias for a class name bidirectionally.
     *
     * @param alias The alias for the class name.
     * @param className The concrete class name.
     */
    public static void registerAlias(String alias, String className)
    {
        ClassAliasRegistry registry = ClassAliasRegistry.getRegistry();
        registry.registerAlias(alias, className);
        registry.registerAlias(className, alias);
    }

    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Creates a default AMF connection instance.
     */
    public AMFConnection()
    {
    }

    //--------------------------------------------------------------------------
    //
    // Private Variables
    //
    //--------------------------------------------------------------------------

    private ActionContext actionContext;
    private boolean connected;
    private boolean instantiateTypes = true;
    private Proxy proxy;
    private int objectEncoding;
    private boolean objectEncodingSet = false;
    private SerializationContext serializationContext;
    private String url;
    private URL urlObject;

    //--------------------------------------------------------------------------
    //
    // Protected Variables
    //
    //--------------------------------------------------------------------------

    /**
     * List of AMF message headers.
     */
    protected List<MessageHeader> amfHeaders;

    /**
     * An AMF connection may have an AMF header processor where AMF headers
     * can be passed to as they are encountered in AMF response messages.
     */
    protected AMFHeaderProcessor amfHeaderProcessor;

    /**
     * Used internally by AMF serialization code to log debug info.
     */
    protected AmfTrace amfTrace;

    /**
     * A map of cookie names and values that are used to keep track of cookies.
     */
    protected Map<String, String> cookies;

    /**
     * Map of Http request header names and values.
     */
    protected Map<String,String> httpRequestHeaders;

    /**
     * Sequentially incremented counter used to generate a unique responseURI
     * to match response messages to responders.
     */
    protected int responseCounter;

    /**
     * The URL connection used to make AMF formatted HTTP and HTTPS requests for
     * this connection.
     */
    protected HttpURLConnection urlConnection;

    /**
     * A buffered input stream that wraps the input stream of the underlying
     * url connection. This is returned in server and client exceptions as part
     * of the HTTP response info.
     */
    protected BufferedInputStream urlConnectionInputStream;

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  amfHeaderProcessor
    //----------------------------------

    /**
     * Returns the AMF header processor associated with the AMF connection. AMF
     * header processor is same as NetConnection's client property.
     * See flash.net.NetConnection#client.
     *
     * @return The AMF header processor associated with the AMF connection.
     */
    public AMFHeaderProcessor getAMFHeaderProcessor()
    {
        return amfHeaderProcessor;
    }

    /**
     * Sets the AMF header processor associated with the AMF connection.
     *
     * @param amfHeaderProcessor The AMF header processor to set.
     */
    public void setAMFHeaderProcessor(AMFHeaderProcessor amfHeaderProcessor)
    {
        this.amfHeaderProcessor = amfHeaderProcessor;
    }

    //----------------------------------
    //  amfTrace
    //----------------------------------

    /**
     * Returns the <tt>AmfTrace</tt> associated with the AMF connection.
     *
     * @return The <tt>AmfTrace</tt> associated with the AMF connection.
     */
    public AmfTrace getAmfTrace()
    {
        return amfTrace;
    }

    /**
     * Sets the <tt>AmfTrace</tt> associated with the AMF connection.
     *
     * @param amfTrace The <tt>AmfTrace</tt> associated with the AMF connection.
     */
    public void setAmfTrace(AmfTrace amfTrace)
    {
        this.amfTrace = amfTrace;
    }

    //----------------------------------
    //  defaultObjectEncoding
    //----------------------------------

    /**
     * The default object encoding for all AMFConnection instances. This
     * controls which version of AMF is used during serialization. The default
     * is AMF 3. See flash.net.ObjectEncoding#DEFAULT
     *
     * @return The default object encoding of the AMF connection.
     */
    public static int getDefaultObjectEncoding()
    {
        return DEFAULT_OBJECT_ENCODING;
    }

    /**
     * Sets the default object encoding of the AMF connection.
     *
     * @param value The value to set the default object encoding to.
     */
    public static void setDefaultObjectEncoding(int value)
    {
        DEFAULT_OBJECT_ENCODING = value;
    }

    //----------------------------------
    //  instantiateTypes
    //----------------------------------

    /**
     * Returns instantiateTypes property. InstantiateTypes property determines
     * whether type information will be used to instantiate a new instance.
     * If set to false, types will be deserialized as flex.messaging.io.ASObject
     * instances with type information retained but not used to create an instance.
     * Note that types in the flex.* package (and any subpackage) will always be
     * instantiated. The default is true.
     *
     * @return The instantitateTypes property.
     */
    public boolean isInstantiateTypes()
    {
        return instantiateTypes;
    }

    /**
     * Sets the instantiateTypes property.
     *
     * @param instantiateTypes The value to set the instantiateTypes property to.
     */
    public void setInstantiateTypes(boolean instantiateTypes)
    {
        this.instantiateTypes = instantiateTypes;
    }

    //----------------------------------
    //  objectEncoding
    //----------------------------------

    /**
     * The object encoding for this AMFConnection sets which AMF version to
     * use during serialization. If set, this version overrides the
     * defaultObjectEncoding.
     *
     * @return The object encoding for the AMF connection.
     */
    public int getObjectEncoding()
    {
        if (!objectEncodingSet)
            return getDefaultObjectEncoding();
        return objectEncoding;
    }

    /**
     * Sets the object encoding for the AMF connection.
     *
     * @param objectEncoding The value to set the object encoding to.
     */
    public void setObjectEncoding(int objectEncoding)
    {
        this.objectEncoding = objectEncoding;
        objectEncodingSet = true;
    }

    //----------------------------------
    //  proxy
    //----------------------------------

    /**
     * Returns the <tt>Proxy</tt> this AMF connection is using;
     * <code>null</code> by default.
     *
     * @return The <tt>Proxy</tt> this AMF connection is using.
     */
    public Proxy getProxy()
    {
        return proxy;
    }

    /**
     * Sets the <tt>Proxy</tt> that this AMF connection will use.
     * Set to <code>null</code> to clear out any existing proxy setting that
     * should no longer be used.
     *
     * @param proxy The <tt>Proxy</tt> this AMF connection will use.
     */
    public void setProxy(Proxy proxy)
    {
        this.proxy = proxy;
    }

    //----------------------------------
    //  url
    //----------------------------------

    /**
     * Returns the HTTP or HTTPS url for the AMF connection.
     *
     * @return The HTTP or HTTPs url for the AMF connection.
     */
    public String getUrl()
    {
        return url;
    }

    //--------------------------------------------------------------------------
    //
    // Public Methods
    //
    //--------------------------------------------------------------------------

    /**
     * Adds an AMF packet-level header which is sent with every request for
     * the life of this AMF connection.
     *
     * @param name The name of the header.
     * @param mustUnderstand Whether the header must be processed or not.
     * @param data The value of the header.
     */
    public void addAmfHeader(String name, boolean mustUnderstand, Object data)
    {
        if (amfHeaders == null)
            amfHeaders = new ArrayList<MessageHeader>();

        MessageHeader header = new MessageHeader(name, mustUnderstand, data);
        amfHeaders.add(header);
    }

    /**
     * Add an AMF packet-level header with mustUnderstand=false, which is sent
     * with every request for the life of this AMF connection.
     *
     * @param name The name of the header.
     * @param data The value of the header.
     */
    public void addAmfHeader(String name, Object data)
    {
        addAmfHeader(name, false, data);
    }

    /**
     * Removes any AMF headers found with the name given.
     *
     * @param name The name of the header(s) to remove.
     *
     * @return true if a header existed with the given name.
     */
    public boolean removeAmfHeader(String name)
    {
        boolean exists = false;
        if (amfHeaders != null)
        {
            for (Iterator<MessageHeader> iterator = amfHeaders.iterator(); iterator.hasNext();)
            {
                MessageHeader header = iterator.next();
                if (name.equals(header.getName()))
                {
                    iterator.remove();
                    exists = true;
                }
            }
        }
        return exists;
    }

    /**
     * Removes all AMF headers.
     */
    public void removeAllAmfHeaders()
    {
        if (amfHeaders != null)
            amfHeaders = null;
    }

    /**
     * Adds a Http request header to the underlying connection.
     *
     * @param name The name of the Http header.
     * @param value The value of the Http header.
     */
    public void addHttpRequestHeader(String name, String value)
    {
        if (httpRequestHeaders == null)
            httpRequestHeaders = new HashMap<String,String>();

        httpRequestHeaders.put(name, value);
    }

    /**
     * Removes the Http header found with the name given.
     *
     * @param name The name of the Http header.
     *
     * @return true if a header existed with the given name.
     */
    public boolean removeHttpRequestHeader(String name)
    {
        boolean exists = false;
        if (httpRequestHeaders != null)
        {
            Object previousValue = httpRequestHeaders.remove(name);
            exists = (previousValue != null);
        }
        return exists;
    }

    /**
     * Removes all Http request headers.
     */
    public void removeAllHttpRequestHeaders()
    {
        if (httpRequestHeaders != null)
            httpRequestHeaders = null;
    }

    /**
     * Makes an AMF request to the server. A connection must have been made
     * prior to making a call.
     *
     * @param command The method to call on the server.
     * @param arguments Arguments for the method.
     *
     * @return The result of the call.
     *
     * @throws ClientStatusException If there is a client side exception.
     * @throws ServerStatusException If there is a server side exception.
     */
    public Object call(String command, Object ... arguments) throws ClientStatusException , ServerStatusException
    {
        if (!connected)
        {
            String message = "AMF connection is not connected";
            ClientStatusException cse = new ClientStatusException(message, ClientStatusException.AMF_CALL_FAILED_CODE);
            throw cse;
        }

        String responseURI = getResponseURI();

        // TODO: Support customizable batching of messages.
        ActionMessage requestMessage = new ActionMessage(getObjectEncoding());

        if (amfHeaders != null)
        {
            for (MessageHeader header : amfHeaders)
                requestMessage.addHeader(header);
        }

        MessageBody amfMessage = new MessageBody(command, responseURI, arguments);
        requestMessage.addBody(amfMessage);

        // Setup for AMF message serializer
        actionContext.setRequestMessage(requestMessage);
        ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
        AmfMessageSerializer amfMessageSerializer = new AmfMessageSerializer();
        amfMessageSerializer.initialize(serializationContext, outBuffer, amfTrace);

        try
        {
            amfMessageSerializer.writeMessage(requestMessage);
            Object result = send(outBuffer);
            return result;
        }
        catch (Exception e)
        {
            if (e instanceof ClientStatusException)
                throw (ClientStatusException)e;
            if (e instanceof ServerStatusException)
                throw (ServerStatusException)e;
            // Otherwise, wrap into a ClientStatusException.
            throw new ClientStatusException(e, ClientStatusException.AMF_CALL_FAILED_CODE, generateHttpResponseInfo());
        }
        finally
        {
            try
            {
                outBuffer.close();
            }
            catch (IOException ignore){}
        }
    }

    /**
     * Closes the underlying URL connection, sets the url to null, and clears
     * the cookies.
     */
    public void close()
    {
        // Clear the cookies.
        if (cookies != null)
            cookies.clear();

        // Clear the URL connection and URL.
        if (urlConnection != null)
        {
            urlConnection.disconnect();
            urlConnection = null;
        }
        url = null;
        urlObject = null;

        serializationContext = null;
        connected = false;
    }

    /**
     * Connects to the URL provided. Any previous connections are closed.
     *
     * @param connectUrl The url to connect to.
     *
     * @throws ClientStatusException If there is a client side exception.
     */
    public void connect(String connectUrl) throws ClientStatusException
    {
        if (connected)
            close();

        url = connectUrl;

        // Try to encode the url in case it has spaces etc.
        String encodedUrl = null;
        try
        {
            URL raw = new URL(url);
            URI uri = new URI(raw.getProtocol(), raw.getUserInfo(), raw.getHost(), raw.getPort(), raw.getPath(), raw.getQuery(), null);
            encodedUrl = uri.toString();
        }
        catch (Exception e)
        {
            // NOWARN
        }

        try
        {
            urlObject = new URL(encodedUrl != null? encodedUrl : url);

            serializationContext = new SerializationContext();
            serializationContext.createASObjectForMissingType = true;
            // Make sure collections are written out as Arrays (vs. ArrayCollection),
            // in case the server does not recognize ArrayCollections.
            serializationContext.legacyCollection = true;
            // When legacyMap is true, Java Maps are serialized as ECMA arrays
            // instead of anonymous Object.
            serializationContext.legacyMap = true;
            internalConnect();
        }
        catch (IOException e)
        {
            ClientStatusException exception = new ClientStatusException(e, ClientStatusException.AMF_CONNECT_FAILED_CODE);
            throw exception;
        }
    }

    //--------------------------------------------------------------------------
    //
    // Protected Methods
    //
    //--------------------------------------------------------------------------

    /**
     * Generates the HTTP response info for the server status exception.
     *
     * @return The HTTP response info for the server status exception.
     */
    protected HttpResponseInfo generateHttpResponseInfo()
    {
        HttpResponseInfo httpResponseInfo = null;
        try
        {
            if (urlConnection != null)
            {
                int responseCode = urlConnection.getResponseCode();
                String responseMessage = urlConnection.getResponseMessage();
                httpResponseInfo = new HttpResponseInfo(responseCode, responseMessage, urlConnectionInputStream);
            }
        }
        catch (IOException ignore)
        {
        }
        return httpResponseInfo;
    }

    /**
     * Generates and returns the response URI.
     *
     * @return The response URI.
     */
    protected String getResponseURI()
    {
        String responseURI = "/" + responseCounter;
        responseCounter++;
        return responseURI;
    }

    /**
     * An internal method that sets up the underlying URL connection.
     *
     * @throws IOException If an exception is encountered during URL connection setup.
     */
    protected void internalConnect() throws IOException
    {
        if (proxy == null)
            urlConnection = (HttpURLConnection)urlObject.openConnection();
        else
            urlConnection = (HttpURLConnection)urlObject.openConnection(proxy);

        urlConnection.setDoOutput(true);
        setHttpRequestHeaders();
        serializationContext.instantiateTypes = instantiateTypes;
        actionContext = new ActionContext();
        connected = true;
    }

    /**
     * Processes the HTTP response headers and body.
     */
    protected Object processHttpResponse(InputStream inputStream) throws ClassNotFoundException, IOException, ClientStatusException, ServerStatusException
    {
        processHttpResponseHeaders();
        return processHttpResponseBody(inputStream);
    }

    /**
     * Processes the HTTP response body.
     */
    protected Object processHttpResponseBody(InputStream inputStream)
            throws ClassNotFoundException, IOException, ClientStatusException,
            ServerStatusException
    {
        if (urlConnectionInputStream != null)
            urlConnectionInputStream.close();
        urlConnectionInputStream = new BufferedInputStream(inputStream);
        // Mark the first 2 bytes so that the stream can be reset in case it
        // contains non-AMF data.
        urlConnectionInputStream.mark(2);
        ActionMessage message = new ActionMessage();
        actionContext.setRequestMessage(message);
        MessageDeserializer deserializer = new AmfMessageDeserializer();
        deserializer.initialize(serializationContext, urlConnectionInputStream, amfTrace);
        try
        {
            deserializer.readMessage(message, actionContext);
        }
        catch (MessageException me)
        {
            // Means the stream contained non-AMF data, reset the stream and throw.
            if (AmfMessageDeserializer.CODE_VERSION_MISMATCH.equals(me.getCode()))
            {
                urlConnectionInputStream.reset();
                String errorMessage = "Unsupported AMF version";
                throw new ClientStatusException(errorMessage, ClientStatusException.AMF_CALL_FAILED_CODE, generateHttpResponseInfo());
            }
            throw me;
        }
        return processAmfPacket(message);
    }

    /**
     * Processes the HTTP response headers.
     */
    protected void processHttpResponseHeaders()
    {
        Map<String, List<String>> headers = urlConnection.getHeaderFields();
        for (Map.Entry<String, List<String>> element : headers.entrySet())
        {
            String headerName = element.getKey();
            List<String> headerValues = element.getValue();
            for (String headerValue : headerValues)
            {
                if (SET_COOKIE.equals(headerName) || COOKIE.equals(headerName)
                        || SET_COOKIE2.equals(headerName) || COOKIE2.equals(headerName))
                    processSetCookieHeader(headerValue);
            }
        }
    }

    /**
     * Processes the AMF packet.
     */
    protected Object processAmfPacket(ActionMessage packet) throws ServerStatusException
    {
        processAmfHeaders(packet.getHeaders());
        return processAmfBody(packet.getBodies());
    }

    /**
     * Processes the AMF headers by dispatching them to an AMF header processor,
     * if one exists.
     */
    protected void processAmfHeaders(ArrayList<MessageHeader> headers)
    {
        // No need to process headers if there's no AMF header processor.
        if (amfHeaderProcessor == null)
            return;

        for (MessageHeader header : headers)
            amfHeaderProcessor.processHeader(header);
    }

    /**
     * Processes the AMF body. Note that this method won't work if batching of
     * AMF messages is supported at some point but for now we are guaranteed to
     * have a single message.
     */
    protected Object processAmfBody(ArrayList<MessageBody> messages) throws ServerStatusException
    {
        for (MessageBody message : messages)
        {
            String targetURI = message.getTargetURI();

            if (targetURI.endsWith(MessageIOConstants.RESULT_METHOD))
            {
                return message.getData();
            }
            else if (targetURI.endsWith(MessageIOConstants.STATUS_METHOD))
            {
                String exMessage = "Server error";
                HttpResponseInfo responseInfo = generateHttpResponseInfo();
                ServerStatusException exception = new ServerStatusException(exMessage, message.getData(), responseInfo);
                throw exception;
            }
        }
        return null; // Should not happen.
    }

    /**
     * Writes the output buffer and processes the HTTP response.
     */
    protected Object send(ByteArrayOutputStream outBuffer) throws ClassNotFoundException, IOException, ClientStatusException, ServerStatusException
    {
        // Every Http request needs a new HttpURLConnection, hence the internalConnect.
        internalConnect();

        outBuffer.writeTo(urlConnection.getOutputStream());
        outBuffer.flush();
        outBuffer.close();

        // Process the response
        return processHttpResponse(urlConnection.getInputStream());
    }

    /**
     * Processes the incoming set-cookie headers.
     *
     * @param headerValue The value of the set-cookie header.
     */
    protected void processSetCookieHeader(String headerValue)
    {
        String cookie = headerValue;
        if (cookie.indexOf(COOKIE_SEPERATOR) > 0)
            cookie = headerValue.substring(0, cookie.indexOf(COOKIE_SEPERATOR));
        String name = cookie.substring(0, cookie.indexOf(COOKIE_NAMEVALUE_SEPERATOR));
        String value = cookie.substring(cookie.indexOf(COOKIE_NAMEVALUE_SEPERATOR) + 1, cookie.length());
        if (cookies == null)
            cookies = new HashMap<String, String>();
        cookies.put(name, value);
    }

    /**
     * Sets the Http request headers, including the cookie headers.
     */
    protected void setHttpRequestHeaders()
    {
        setHttpRequestCookieHeader();
        if (httpRequestHeaders != null)
        {
            for (Map.Entry<String, String> element : httpRequestHeaders.entrySet())
            {
                String key = element.getKey();
                String value = element.getValue();
                urlConnection.setRequestProperty(key, value);
            }
        }
        // Always set valid Content-Type header (overrides any user-defined Content-Type).
        urlConnection.setRequestProperty(HTTP_HEADER_NAME_CONTENT_TYPE, flex.messaging.io.MessageIOConstants.AMF_CONTENT_TYPE);
    }

    /**
     * Sets the Http request cookie headers.
     */
    protected void setHttpRequestCookieHeader()
    {
        if (cookies == null)
            return;

        // Set the cookies, if any.
        StringBuffer cookieHeaderValue = null;
        for (Map.Entry<String, String> element : cookies.entrySet())
        {
            String name = element.getKey();
            String value = element.getValue();
            if (cookieHeaderValue == null) // First cookie
                cookieHeaderValue = new StringBuffer(name + COOKIE_NAMEVALUE_SEPERATOR + value);
            else
                cookieHeaderValue.append(COOKIE_SEPERATOR + " " + name + COOKIE_NAMEVALUE_SEPERATOR + value);
        }
        if (cookieHeaderValue != null)
            urlConnection.setRequestProperty(COOKIE, cookieHeaderValue.toString());
    }

    //--------------------------------------------------------------------------
    //
    // Inner Classes
    //
    //--------------------------------------------------------------------------

    /**
     * An inner class to represent the HTTP response associated with the exception.
     */
    public static class HttpResponseInfo
    {
        private int responseCode;
        private String responseMessage;
        private InputStream responseInputStream;

        /**
         * Creates an HTTP response info with the HTTP code, message, and the
         * input stream.
         *
         * @param responseCode The HTTP response code.
         * @param responseMessage the HTTP message.
         * @param responseInputStream The underlying input stream.
         */
        public HttpResponseInfo(int responseCode, String responseMessage, InputStream responseInputStream)
        {
            this.responseCode = responseCode;
            this.responseMessage = responseMessage;
            this.responseInputStream = responseInputStream;
        }

        /**
         * Returns the HTTP response code.
         *
         * @return The HTTP response code.
         */
        public int getResponseCode()
        {
            return responseCode;
        }

        /**
         * Returns the HTTP response message.
         *
         * @return The HTTP response message.
         */
        public String getResponseMessage()
        {
            return responseMessage;
        }

        /**
         * Returns the underlying response input stream.
         *
         * @return The underlying response input stream.
         */
        public InputStream getResponseInputStream()
        {
            return responseInputStream;
        }

        /**
         * Returns a String representation of the HTTP response info.
         *
         * @return A String representation of the HTTP response info.
         */
        @Override
        public String toString()
        {
            return "HttpResponseInfo " + "\n\tcode: " + responseCode
                + "\n\tmessage: " + responseMessage;
        }
    }
}
