harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ghar...@apache.org
Subject svn commit: r407625 [13/16] - in /incubator/harmony/enhanced/classlib/trunk/modules/rmi3: ./ doc/ make/ src/ src/common/ src/common/javasrc/ src/common/javasrc/java/ src/common/javasrc/java/rmi/ src/common/javasrc/java/rmi/activation/ src/common/javasr...
Date Thu, 18 May 2006 20:01:30 GMT
Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectInputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectInputStream.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectInputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectInputStream.java Thu May 18 13:01:22 2006
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport;
+
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.IOException;
+import java.rmi.server.RMIClassLoader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.harmony.rmi.common.GetBooleanPropAction;
+import org.apache.harmony.rmi.common.RMIProperties;
+
+
+/**
+ * The RMIObjectInputStream is a subclass of ObjectInputStream performing
+ * deserialization for RMI calls.
+ *
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class RMIObjectInputStream extends ObjectInputStream {
+
+    // Annotations for serialized objects.
+    private ObjectInputStream locStream;
+
+    // ClassLoader which will be used for classes resolving
+    private ClassLoader defaultLoader = null;
+
+    // True if this stream was created for handling a RemoteCall
+    private boolean isRCallStream = false;
+
+    // True if we need DGC ack call.
+    private boolean needDGCAck = false;
+
+    /*
+     * If true we'll not load classes from places other then local classpath and
+     * location set by java.rmi.server.codebase property.
+     */
+    private static boolean useCodebaseOnly =
+            ((Boolean) AccessController.doPrivileged(new GetBooleanPropAction(
+                    RMIProperties.USECODEBASEONLY_PROP))).booleanValue();
+
+    /**
+     * Constructs a RMIObjectInputStream that reads from the specified
+     * InputStream. This stream will be a non-RemoteCall stream (i.e.
+     * isRemoteCallStream() method will return false).
+     *
+     * @param in underlying InputStream
+     *
+     * @throws IOException if an I/O error occured during stream initialization
+     */
+    public RMIObjectInputStream(InputStream in) throws IOException {
+        this (in, false);
+    }
+
+    /**
+     * Constructs a RMIObjectInputStream that reads from the specified
+     * InputStream.
+     *
+     * @param in underlying InputStream
+     * @param isRCallStream true if this stream was created for handling
+     *        a RemoteCall and false otherwise
+     *
+     * @throws IOException if an I/O error occured during stream initialization
+     */
+    public RMIObjectInputStream(InputStream in, boolean isRCallStream)
+            throws IOException {
+        super(in);
+        this.isRCallStream = isRCallStream;
+        locStream = this;
+        AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                enableResolveObject(true);
+                return null;
+            }});
+    }
+
+    /**
+     * Resolves annotated class. To resolves class method calls
+     * Class.forName(classname, false, classloader) where classloader is
+     * the first non-null class loader up in the execution stack or null
+     * if no non-null class loaders were found in the stack.
+     *
+     * @param streamCl annotated class
+     *
+     * @throws IOException if an I/O exception occured
+     * @throws ClassNotFoundException if class of a serialized object
+     *         could not be found
+     */
+    protected Class resolveClass(ObjectStreamClass streamCl)
+            throws IOException, ClassNotFoundException {
+        String annot = (locStream == null) ? null
+                : (String) locStream.readObject();
+
+        if (useCodebaseOnly) {
+            annot = null;
+        }
+        Class cl = RMIClassLoader.loadClass(annot, streamCl.getName(),
+                defaultLoader);
+        return cl;
+    }
+
+    /**
+     * Resolves annotated proxy class.
+     *
+     * @param interf array of interfaces which proxy class should implement
+     *
+     * @throws IOException if an I/O exception occured
+     * @throws ClassNotFoundException if class of a serialized object
+     *         could not be found
+     */
+    protected Class resolveProxyClass(String[] interf)
+            throws IOException, ClassNotFoundException {
+        String annot = (locStream == null) ? null
+                : (String) locStream.readObject();
+
+        if (useCodebaseOnly) {
+            annot = null;
+        }
+        Class cl = RMIClassLoader.loadProxyClass(annot, interf, defaultLoader);
+        return cl;
+    }
+
+    /**
+     * Sets annotation's stream to the value specified.
+     * Subclasses should call this method if they want to read annotations from
+     * the stream other then one for objects themselves.
+     *
+     * @param in stream for annotations
+     */
+    protected void setLocStream(ObjectInputStream in) {
+        locStream = in;
+    }
+
+    /**
+     * Reads object (possibly primitive value) from the stream.
+     *
+     * @param cl expected class to be read from the stream
+     * @param loader ClassLoader for classes resolving (ClassLoader which
+     *        will be specified in the calls to RMIClassLoader.)
+     *
+     * @return object read from the stream
+     *
+     * @throws IOException if an I/O error occured during deserialization
+     * @throws ClassNotFoundException if class of a serialized object
+     *         could not be found
+     */
+    public synchronized Object readRMIObject(Class cl, ClassLoader loader)
+            throws IOException, ClassNotFoundException {
+        defaultLoader = loader;
+
+        try {
+            if (cl.isPrimitive()) {
+                if (cl == Boolean.TYPE) {
+                    return new Boolean(readBoolean());
+                } else if (cl == Byte.TYPE) {
+                    return new Byte(readByte());
+                } else if (cl == Short.TYPE) {
+                    return new Short(readShort());
+                } else if (cl == Integer.TYPE) {
+                    return new Integer(readInt());
+                } else if (cl == Long.TYPE) {
+                    return new Long(readLong());
+                } else if (cl == Float.TYPE) {
+                    return new Float(readFloat());
+                } else if (cl == Double.TYPE) {
+                    return new Double(readDouble());
+                } else if (cl == Character.TYPE) {
+                    return new Character(readChar());
+                } else if (cl == Void.TYPE) {
+                    return null;
+                } else {
+                    throw new IOException("Unknown primitive class: " + cl);
+                }
+            } else {
+                return readObject();
+            }
+        } finally {
+            defaultLoader = null;
+        }
+    }
+
+    /**
+     * Returns true if this stream was created for handling a RemoteCall and
+     * false otherwise.
+     *
+     * @return true if this stream was created for handling a RemoteCall and
+     *         false otherwise
+     */
+    public boolean isRemoteCallStream() {
+        return isRCallStream;
+    }
+
+    /**
+     * Sets the flag of DGC ack call to the given value.
+     *
+     * @param need true if we need DGC ack call and false otherwise
+     */
+    public void needDGCAck(boolean need) {
+        needDGCAck = need;
+    }
+
+    /**
+     * Returns the value of DGC ack call field.
+     *
+     * @return the value of DGC ack call field
+     */
+    public boolean isDGCAckNeeded() {
+        return needDGCAck;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectOutputStream.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectOutputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectOutputStream.java Thu May 18 13:01:22 2006
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport;
+
+import java.io.OutputStream;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.rmi.Remote;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.RMIClassLoader;
+import java.rmi.server.UID;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.harmony.rmi.server.ExportManager;
+
+
+/**
+ * The RMIObjectOutputStream is a subclass of ObjectOutputStream performing
+ * serialization for RMI calls. The following rules are used in addition to
+ * normal serialization ones:
+ *   - if codebase URL is available for a class, the class will be annotated
+ *     with this URL
+ *   - remote objects are represented in RMIOutputStream by serialized forms
+ *     of their stubs
+ *
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class RMIObjectOutputStream extends ObjectOutputStream {
+
+    // ObjectOutputStream to write annotations.
+    private ObjectOutputStream locStream;
+
+    /** True if at least one of written annotations is not null. */
+    protected boolean hasAnnotations;
+
+    // True if this stream was created in RemoteCall.getResultStream() method.
+    private boolean isResultStream = false;
+
+    // UID to be written to the stream as DGC ack UID.
+    private UID uid = new UID();
+
+    /**
+     * Constructs a RMIObjectOutputStream that writes to the specified
+     * OutputStream.
+     *
+     * @param out underlying OutputStream
+     *
+     * @throws IOException if an I/O error occured during stream initialization
+     */
+    public RMIObjectOutputStream(OutputStream out) throws IOException {
+        this(out, false);
+    }
+
+    /**
+     * Constructs a RMIObjectOutputStream that writes to the specified
+     * OutputStream.
+     *
+     * @param out underlying OutputStream
+     * @param isResultStream true if this stream was created
+     *        in RemoteCall.getResultStream() method
+     *
+     * @throws IOException if an I/O error occured during stream initialization
+     */
+    public RMIObjectOutputStream(OutputStream out, boolean isResultStream)
+            throws IOException {
+        super(out);
+        this.isResultStream = isResultStream;
+        locStream = this;
+        hasAnnotations = false;
+        AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                enableReplaceObject(true);
+                return null;
+            }});
+    }
+
+    /**
+     * Replaces exported Remote objects with their stubs.
+     *
+     * @param obj Object to be replaced if needed
+     *
+     * @return stub for exported Remote object or unmodified object otherwise
+     *
+     * @throws IOException
+     */
+    protected Object replaceObject(Object obj) throws IOException {
+        return ((obj instanceof Remote) && !(obj instanceof RemoteStub)
+                && ExportManager.isExported((Remote) obj))
+                ? RemoteObject.toStub((Remote) obj) : obj;
+    }
+
+    /**
+     * Annotates specified class with it's codebase URL if available.
+     *
+     * @param cl class to be annotated
+     */
+    protected void annotateClass(Class cl) throws IOException {
+        String annot = RMIClassLoader.getClassAnnotation(cl);
+        hasAnnotations |= (annot != null);
+        locStream.writeObject(annot);
+    }
+
+    /**
+     * Annotates specified proxy class with it's codebase URL if avaliable.
+     *
+     * @param cl proxy class to be annotated
+     */
+    protected void annotateProxyClass(Class cl) throws IOException {
+        annotateClass(cl);
+    }
+
+    /**
+     * Flushes the stream.
+     *
+     * @throws IOException If an I/O error has occurred.
+     */
+    public void flush() throws IOException {
+        super.flush();
+
+        if (locStream != this) {
+            locStream.flush();
+        }
+    }
+
+    /**
+     * Sets annotation's stream to the value specified.
+     * Subclasses should call this method if they want to write annotations to
+     * the stream other then one for objects themselves.
+     *
+     * @param out stream for annotations
+     */
+    protected void setLocStream(ObjectOutputStream out) {
+        locStream = out;
+    }
+
+    /**
+     * Returns true if at least one of written annotations is not null and
+     * false otherwise.
+     *
+     * @return true if at least one of written annotations is not null
+     */
+    protected boolean hasAnnotations() {
+        return hasAnnotations;
+    }
+
+    /**
+     * Write specified obj (possibly primitive) to the stream.
+     *
+     * @param obj object (possibly primitive) to be written to the stream
+     * @param cl type of object to be written to the stream
+     *
+     * @throws IOException if an I/O error occured during serialization
+     */
+    public void writeRMIObject(Object obj, Class cl) throws IOException {
+        if (cl.isPrimitive()) {
+            if (cl == Boolean.TYPE) {
+                writeBoolean(((Boolean) obj).booleanValue());
+            } else if (cl == Byte.TYPE) {
+                writeByte(((Byte) obj).byteValue());
+            } else if (cl == Short.TYPE) {
+                writeShort(((Short) obj).shortValue());
+            } else if (cl == Integer.TYPE) {
+                writeInt(((Integer) obj).intValue());
+            } else if (cl == Long.TYPE) {
+                writeLong(((Long) obj).longValue());
+            } else if (cl == Float.TYPE) {
+                writeFloat(((Float) obj).floatValue());
+            } else if (cl == Double.TYPE) {
+                writeDouble(((Double) obj).doubleValue());
+            } else if (cl == Character.TYPE) {
+                writeChar(((Character) obj).charValue());
+            } else if (cl == Void.TYPE) {
+            } else {
+                throw new IOException("Unable to serialize primitive class: "
+                        + cl);
+            }
+        } else {
+            writeObject(obj);
+        }
+    }
+
+    /**
+     * Returns true if this stream was created in RemoteCall.getResultStream()
+     * method and false otherwise.
+     *
+     * @return true if this stream was created in RemoteCall.getResultStream()
+     *         method and false otherwise
+     */
+    public boolean isResultStream() {
+        return isResultStream;
+    }
+
+    /**
+     * Writes DGC ack UID to this stream.
+     *
+     * @throws IOException if any I/O error occured while writing
+     */
+    public void writeUID() throws IOException {
+        uid.write(this);
+    }
+
+    /**
+     * Returns uid used for DGC ack.
+     *
+     * @return uid used for DGC ack
+     */
+    public UID getUID() {
+        return uid;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIObjectOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIProtocolConstants.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIProtocolConstants.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIProtocolConstants.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIProtocolConstants.java Thu May 18 13:01:22 2006
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport;
+
+
+/**
+ * Constants for RMI Transport Protocol.
+ *
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public interface RMIProtocolConstants {
+
+    /** Indicates sequence for beginning of header */
+    public static final int RMI_HEADER = 0x4a524d49;
+
+    /** Indicates sequence for beginning of header */
+    public static final int HTTP_HEADER = 0x504f5354;
+
+    /** Indicates version of RMI Transport Protocol */
+    public static final short PROTOCOL_VER = 0x02;
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * Group of RMI protocols
+     * -------------------------------------------------------------------------
+     */
+
+    /** Indicates StreamProtocol */
+    public static final byte STREAM_PROTOCOL = 0x4b;
+
+    /** Indicates SingleOpProtocol */
+    public static final byte SINGLEOP_PROTOCOL = 0x4c;
+
+    /** Indicates MultiplexProtocol */
+    public static final byte MULTIPLEX_PROTOCOL = 0x4d;
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * Group of possible responses to protocol agreement messages
+     * -------------------------------------------------------------------------
+     */
+
+    /** Indicates protocol accepted response (ProtocolAck) */
+    public static final byte PROTOCOL_ACK = 0x4e;
+
+    /** Indicates protocol not supported response (ProtocolNotSupported) */
+    public static final byte PROTOCOL_NOT_SUPPORTED = 0x4f;
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * Group of possible messages types
+     * -------------------------------------------------------------------------
+     */
+
+    /** Indicates method invocation (Call message) */
+    public static final byte CALL_MSG = 0x50;
+
+    /** Indicates testing liveness of a remote VM (Ping message) */
+    public static final byte PING_MSG = 0x52;
+
+    /**
+     * Indicates, that remote objects have been received by client in a return
+     * value from server (DgcAck message)
+     */
+    public static final byte DGCACK_MSG = 0x54;
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * Group of possible responses to messages
+     * -------------------------------------------------------------------------
+     */
+
+    /**
+     * Indicates the result of a RMI call completion in response to Call message
+     */
+    public static final byte CALL_OK = 0x51;
+
+    /** Indicates that server is alive in response to Ping message */
+    public static final byte PING_ACK = 0x53;
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * Group of possible results of remote method invocation (after CALL_OK msg)
+     * -------------------------------------------------------------------------
+     */
+
+    /** Indicates that value is returned as a result of a RMI call */
+    public static final byte RETURN_VAL = 0x01;
+
+    /**
+     * Indicates that exception (not communication-related) is thrown
+     * as a result of a RMI call
+     */
+    public static final byte RETURN_EX = 0x02;
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/RMIProtocolConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/SocketWrapper.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/SocketWrapper.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/SocketWrapper.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/SocketWrapper.java Thu May 18 13:01:22 2006
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+package org.apache.harmony.rmi.transport;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+
+/**
+ * Wrapper for already opened socket.
+ * It just translates all requests to the underlying socket.
+ *
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+public class SocketWrapper extends Socket {
+
+    protected Socket s;
+    protected InputStream in;
+    protected OutputStream out;
+
+    protected SocketWrapper(Socket s) throws IOException {
+        this(s, null, null);
+    }
+
+    public SocketWrapper(Socket s, InputStream in, OutputStream out)
+            throws IOException {
+        this.s = s;
+        this.in = (in == null) ? s.getInputStream() : in;
+        this.out = (out == null) ? s.getOutputStream() : out;
+    }
+
+    public void connect(SocketAddress endpoint) throws IOException {
+        s.connect(endpoint);
+    }
+
+    public void connect(SocketAddress endpoint, int timeout)
+            throws IOException {
+        s.connect(endpoint, timeout);
+    }
+
+    public void bind(SocketAddress bindpoint) throws IOException {
+        s.bind(bindpoint);
+    }
+
+    public InetAddress getInetAddress() {
+        return s.getInetAddress();
+    }
+
+    public InetAddress getLocalAddress() {
+        return s.getLocalAddress();
+    }
+
+    public int getPort() {
+        return s.getPort();
+    }
+
+    public int getLocalPort() {
+        return s.getLocalPort();
+    }
+
+    public SocketAddress getRemoteSocketAddress() {
+        return s.getRemoteSocketAddress();
+    }
+
+    public SocketAddress getLocalSocketAddress() {
+        return s.getLocalSocketAddress();
+    }
+
+    //public SocketChannel getChannel() {
+    //    return s.getChannel();
+    //}
+
+    public InputStream getInputStream() throws IOException {
+        return in;
+    }
+
+    public OutputStream getOutputStream() throws IOException {
+        return out;
+    }
+
+    public void setTcpNoDelay(boolean on) throws SocketException {
+        s.setTcpNoDelay(on);
+    }
+
+    public boolean getTcpNoDelay() throws SocketException {
+        return s.getTcpNoDelay();
+    }
+
+    public void setSoLinger(boolean on, int linger) throws SocketException {
+        s.setSoLinger(on, linger);
+    }
+
+    public int getSoLinger() throws SocketException {
+        return s.getSoLinger();
+    }
+
+    public void sendUrgentData(int data) throws IOException {
+        s.sendUrgentData(data);
+    }
+
+    public void setOOBInline(boolean on) throws SocketException {
+        s.setOOBInline(on);
+    }
+
+    public boolean getOOBInline() throws SocketException {
+        return s.getOOBInline();
+    }
+
+    public void setSoTimeout(int timeout) throws SocketException {
+        s.setSoTimeout(timeout);
+    }
+
+    public int getSoTimeout() throws SocketException {
+        return s.getSoTimeout();
+    }
+
+    public void setSendBufferSize(int size) throws SocketException {
+        s.setSendBufferSize(size);
+    }
+
+    public int getSendBufferSize() throws SocketException {
+        return s.getSendBufferSize();
+    }
+
+    public void setReceiveBufferSize(int size) throws SocketException {
+        s.setReceiveBufferSize(size);
+    }
+
+    public int getReceiveBufferSize() throws SocketException {
+        return s.getReceiveBufferSize();
+    }
+
+    public void setKeepAlive(boolean on) throws SocketException {
+        s.setKeepAlive(on);
+    }
+
+    public boolean getKeepAlive() throws SocketException {
+        return s.getKeepAlive();
+    }
+
+    public void setTrafficClass(int tc) throws SocketException {
+        s.setTrafficClass(tc);
+    }
+
+    public int getTrafficClass() throws SocketException {
+        return s.getTrafficClass();
+    }
+
+    public void setReuseAddress(boolean on) throws SocketException {
+        s.setReuseAddress(on);
+    }
+
+    public boolean getReuseAddress() throws SocketException {
+        return s.getReuseAddress();
+    }
+
+    public void close() throws IOException {
+        s.close();
+    }
+
+    public void shutdownInput() throws IOException {
+        s.shutdownInput();
+    }
+
+    public void shutdownOutput() throws IOException {
+        s.shutdownOutput();
+    }
+
+    public String toString() {
+        return s.toString();
+    }
+
+    public boolean isConnected() {
+        return s.isConnected();
+    }
+
+    public boolean isBound() {
+        return s.isBound();
+    }
+
+    public boolean isClosed() {
+        return s.isClosed();
+    }
+
+    public boolean isInputShutdown() {
+        return s.isInputShutdown();
+    }
+
+    public boolean isOutputShutdown() {
+        return s.isOutputShutdown();
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/SocketWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/package.html
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/package.html?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/package.html (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/package.html Thu May 18 13:01:22 2006
@@ -0,0 +1,25 @@
+<html>
+<!--
+Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+
+Licensed 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.
+-->
+<!--
+Author:  Vasily Zakharov
+Version: $Revision: 1.1.2.1 $
+-->
+<body>
+RMI transport implementation classes.
+</body>
+</html>

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpConnection.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpConnection.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpConnection.java Thu May 18 13:01:22 2006
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.rmi.ConnectIOException;
+import java.rmi.RemoteException;
+
+import org.apache.harmony.rmi.client.ClientConnection;
+import org.apache.harmony.rmi.common.RMILog;
+import org.apache.harmony.rmi.transport.Endpoint;
+
+
+/**
+ * HTTP proxy connection.
+ *
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class HttpConnection extends ClientConnection
+        implements ProxyConstants {
+
+    /**
+     * @see ClientConnection(Socket, Endpoint)
+     */
+    public HttpConnection(Socket s, Endpoint ep) throws RemoteException {
+        super(s, ep);
+    }
+
+    /**
+     * Acknowledge protocol with server side.
+     *
+     * @return acknowledged protocol number
+     *
+     * @throws RemoteException if any I/O exception occured during protocol
+     *         acknowledgement
+     */
+    protected int serverProtocolAck() throws RemoteException {
+        try {
+            DataOutputStream dout = new DataOutputStream(out);
+
+            // write RMI header and protocol version
+            writeHeader(dout);
+
+            // write protocol type
+            dout.writeByte(SINGLEOP_PROTOCOL);
+            dout.flush();
+
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Using singleop RMI protocol");
+            }
+            dout.flush();
+        } catch (RemoteException re) {
+            close();
+            throw re;
+        } catch (IOException ioe) {
+            close();
+            throw new ConnectIOException(
+                    "Unable to acknowledge protocol with server", ioe);
+        }
+
+        // protocol is agreed
+        return SINGLEOP_PROTOCOL;
+    }
+
+    /**
+     * @see ClientConnection.done()
+     */
+    public void done() {
+        close();
+    }
+
+    /**
+     * Closes output stream and read protocol ack data.
+     */
+    public void releaseOutputStream() throws IOException {
+        out.close();
+    }
+
+    /**
+     * Always throws error because this connection is not reusable.
+     */
+    public boolean reuse() {
+        throw new Error(toString() + " is not reusable.");
+    }
+
+    /**
+     * @see ClientConnection.isAvailable()
+     */
+    public boolean isAvailable() {
+        return false;
+    }
+
+    /**
+     * Returns false because this connection could not be reused.
+     *
+     * @see ClientConnection.isReusable()
+     */
+    public boolean isReusable() {
+        return false;
+    }
+
+    /**
+     * Always throws error because this connection is not reusable.
+     */
+    public long getExpiration() {
+        throw new Error(toString() + " is not reusable.");
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInboundSocket.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInboundSocket.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInboundSocket.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInboundSocket.java Thu May 18 13:01:22 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.1 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import org.apache.harmony.rmi.transport.SocketWrapper;
+
+
+/**
+ * Inbound HTTP socket wrapper.
+ *
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.1 $
+ */
+public class HttpInboundSocket extends SocketWrapper {
+
+    /**
+     * Host to connect to.
+     */
+    private String host;
+
+    /**
+     * Port to connect to.
+     */
+    private int port;
+
+    /**
+     * Constructs this object by wrapping the specified socket.
+     *
+     * @param   s
+     *          Socket to wrap.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpInboundSocket(Socket s)
+            throws IOException {
+        this(s, null, null);
+    }
+
+    /**
+     * Constructs this object by wrapping the specified socket
+     * with the specified streams.
+     *
+     * @param   s
+     *          Socket to wrap.
+     *
+     * @param   in
+     *          Input stream.
+     *
+     * @param   out
+     *          Output stream.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpInboundSocket(Socket s, InputStream in, OutputStream out)
+            throws IOException {
+        super(s, in, out);
+        host = s.getInetAddress().getHostName();
+        port = s.getPort();
+        this.in = new HttpInputStream(this.in, true);
+        this.out = new HttpOutputStream(this.out, true, host, port);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return ("HttpInboundSocket[" + s.toString() + ", "
+                + host + ':' + port + ']');
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInboundSocket.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInputStream.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInputStream.java Thu May 18 13:01:22 2006
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.harmony.rmi.common.RMILog;
+
+
+/**
+ * InputStream for HTTP connections. Unwraps data from HTTP packets.
+ *
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class HttpInputStream extends FilterInputStream
+        implements ProxyConstants {
+
+    /**
+     * If this is inbound connection stream.
+     */
+    private boolean inbound;
+
+    /**
+     * Amount of data available in the stream.
+     */
+    private int available;
+
+    /**
+     * Constructs this stream from the given input stream.
+     * The stream is considered operational after <code>expect</code>
+     * string is received from the stream.
+     * If <code>expect</code> is <code>null</code>,
+     * the stream is considered operational immediately.
+     *
+     * @param   in
+     *          Input stream.
+     *
+     * @param   inbound
+     *          If this is inbound connection stream.
+     */
+    public HttpInputStream(InputStream in, boolean inbound) {
+        super(new DataInputStream(in));
+        this.inbound = inbound;
+        this.available = (-1);
+    }
+
+    /**
+     * Always returns <code>false</code> (mark operations are not supported).
+     *
+     * @return  <code>false</code>
+     */
+    public final boolean markSupported() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final int available() throws IOException {
+        if (available < 0) {
+            readHeader();
+        }
+
+        return available;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final int read() throws IOException {
+        if (available < 0) {
+            readHeader();
+        }
+
+        if (available < 1) {
+            return (-1);
+        }
+
+        int data = in.read();
+
+        if (data != (-1)) {
+            available--;
+
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Read 1 byte, " + available + " remaining.");
+            }
+        }
+
+        return data;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final int read(byte[] b, int off, int len) throws IOException {
+        if (available < 0) {
+            readHeader();
+        }
+
+        if (available < 1) {
+            return (-1);
+        }
+
+        if (len > available) {
+            len = available;
+        }
+
+        int readSize = in.read(b, off, len);
+
+        assert (readSize <= len) : "readSize is greater than len";
+
+        available -= readSize;
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE,
+                    "Read " + readSize + " bytes, " + available + " remaining.");
+        }
+
+        return readSize;
+    }
+
+    /**
+     * Reads the next line of text from the stream
+     * using {@link DataInputStream#readLine()}.
+     *
+     * @return  Next line of text from the input stream,
+     *          or <code>null</code> if end of file is encountered
+     *          before even one byte can be read.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public final String readLine() throws IOException {
+        if (available < 0) {
+            readHeader();
+        }
+
+        return ((DataInputStream) in).readLine();
+    }
+
+    /**
+     * Reads HTTP header, sets {@link #available} amount of data.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    private void readHeader() throws IOException {
+        String expectName;
+        String expectHeader;
+
+        if (inbound) {
+            expectName = "POST request";
+            expectHeader = HTTP_REQUEST_SIGNATURE;
+        } else {
+            expectName = "HTTP response";
+            expectHeader = HTTP_RESPONSE_HEADER_SIGNATURE;
+        }
+
+        String[] errorMessages = {
+                ("Unable to read header data, couldn't find " + expectName),
+                "Unable to read header data, Content-Length not specified",
+                "Unable to read input stream data, no data found"
+        };
+
+        // Looking for headers phases sequentially.
+        for (int phase = 0; ; phase++) {
+            assert ((phase >= 0) && (phase <= 2))
+                    : ("Incorrect phase: " + phase);
+
+            String expectSubject;
+            String expectString;
+            int expectStringLength;
+
+            switch (phase) {
+            case 0:
+                expectSubject = expectName;
+                expectString = expectHeader;
+                expectStringLength = expectHeader.length();
+                break;
+            case 1:
+                expectSubject = "Content-Length specification";
+                expectString = CONTENT_LENGTH_SIGNATURE;
+                expectStringLength = CONTENT_LENGTH_SIGNATURE_LENGTH;
+                break;
+            default: // 2
+                expectSubject = null;
+                expectString = null;
+                expectStringLength = 0;
+                break;
+            }
+
+            // Searching for the expected string for this phase.
+            //
+            // Note: here we ignore the following for simplicity:
+            //          Header fields can be extended over multiple lines
+            //          by preceding extra lines with spaces(s) or tab(s).
+            //          (See RFC 2616 4.2)
+            while (true) {
+                String line = ((DataInputStream) in).readLine();
+
+                // Checking for EOF.
+                if (line == null) {
+                    throw new EOFException(errorMessages[phase]);
+                }
+
+                // Diagnostic print.
+                if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                    proxyTransportLog.log(RMILog.VERBOSE,
+                            "Header line received: [" + line + "].");
+                }
+
+                // Checking for empty line.
+                if (line.length() < 1) {
+                    if (phase < 2) {
+                        throw new EOFException(errorMessages[phase]);
+                    } else { // phase == 2
+                        // Empty line found, end of headers, everything's fine.
+                        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                            proxyTransportLog.log(RMILog.VERBOSE,
+                                    "Input stream data found, stream ready.");
+                        }
+                        return;
+                    }
+                }
+
+                if (phase > 1) {
+                    // Just skip non-empty lines after Content-Length is found.
+                    continue;
+                }
+
+                // Checking for expected line, using case sensitive comparison
+                // for phase 0 and case insensitive comparison for phase 1.
+                //
+                // Note:    The reason phrase should be ignored.
+                //          (See RFC 2616 6.1.1)
+                //
+                // Note: here we ignore codes other than 200 for simplicity.
+                //          (See RFC 2616 6.1.1)
+                if (line.regionMatches(
+                        (phase == 1), 0, expectString, 0, expectStringLength)) {
+                    if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                        proxyTransportLog.log(RMILog.VERBOSE,
+                                expectSubject + " found.");
+                    }
+
+                    if (phase == 1) {
+                        // Found Content-Length specification.
+                        try {
+                            available = Integer.parseInt(
+                                    line.substring(expectStringLength).trim());
+                        } catch (NumberFormatException e) {
+                            throw new IOException(
+                                    "Content-Length specified incorrectly: "
+                                    + line);
+                        }
+
+                        if (available < 0) {
+                            throw new IOException(
+                                    "Invalid Content-Length: " + available);
+                        }
+
+                        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                            proxyTransportLog.log(RMILog.VERBOSE,
+                                    "Content-Length received: " + available);
+                        }
+                    }
+                    // Move to the next phase.
+                    break;
+                }
+                // Skipping this line.
+            }
+        }
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutboundSocket.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutboundSocket.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutboundSocket.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutboundSocket.java Thu May 18 13:01:22 2006
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.1 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.IOException;
+
+import org.apache.harmony.rmi.common.RMIConstants;
+import org.apache.harmony.rmi.transport.SocketWrapper;
+
+
+/**
+ * Outbound HTTP socket wrapper.
+ *
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.1 $
+ */
+public class HttpOutboundSocket extends SocketWrapper
+        implements ProxyConstants {
+
+    /**
+     * Host to connect to.
+     */
+    private String host;
+
+    /**
+     * Port to connect to.
+     */
+    private int port;
+
+    /**
+     * If this is a CGI socket.
+     */
+    private boolean cgi;
+
+    /**
+     * Returns new <code>HttpOutboundSocket</code> instance connected
+     * to specified host and port, probably through a proxy (if proxy is set).
+     * If proxy is not set, and direct HTTP connections are enabled,
+     * then direct connection is established.
+     *
+     * Equivalent to
+     * {@link #HttpOutboundSocket(Proxy, String, int, boolean)
+     * HttpOutboundSocket(new Proxy(), host, port, false)}.
+     *
+     * @param   host
+     *          Host to connect to.
+     *
+     * @param   port
+     *          Port to connect to.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpOutboundSocket(String host, int port) throws IOException {
+        this(new Proxy(), host, port, false);
+    }
+
+    /**
+     * Returns new <code>HttpOutboundSocket</code> instance connected
+     * to specified host and port, probably through a proxy (if proxy is set).
+     * If proxy is not set, and direct HTTP connections are enabled,
+     * then direct connection is established.
+     *
+     * Equivalent to
+     * {@link #HttpOutboundSocket(Proxy, String, int, boolean)
+     * HttpOutboundSocket(proxy, host, port, false)}.
+     *
+     * @param   proxy
+     *          Proxy configuration.
+     *
+     * @param   host
+     *          Host to connect to.
+     *
+     * @param   port
+     *          Port to connect to.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpOutboundSocket(Proxy proxy, String host, int port)
+            throws IOException {
+        this(proxy, host, port, false);
+    }
+
+    /**
+     * Returns new <code>HttpOutboundSocket</code> instance connected
+     * to specified host and port, probably through a proxy (if proxy is set).
+     * If proxy is not set, and direct HTTP connections are enabled,
+     * then direct connection is established.
+     *
+     * @param   proxy
+     *          Proxy configuration.
+     *
+     * @param   host
+     *          Host to connect to.
+     *
+     * @param   port
+     *          Port to connect to.
+     *
+     * @param   cgi
+     *          If this is CGI stream.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpOutboundSocket(Proxy proxy,
+            String host, int port, boolean cgi) throws IOException {
+        super(proxy.getSocket(host, (cgi ? RMIConstants.HTTP_DEFAULT_PORT : port)));
+        this.host = host;
+        this.port = port;
+        this.cgi = cgi;
+        in = new HttpInputStream(in, false);
+        out = new HttpOutputStream(out, false, host, port, cgi);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return ("HttpOutboundSocket[" + s.toString() + ", "
+                + host + ':' + port + ", " + (cgi ? "" : "non-") + "CGI]");
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutboundSocket.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutputStream.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutputStream.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutputStream.java Thu May 18 13:01:22 2006
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.AccessController;
+
+import org.apache.harmony.rmi.common.GetStringPropAction;
+import org.apache.harmony.rmi.common.RMIConstants;
+import org.apache.harmony.rmi.common.RMILog;
+
+
+/**
+ * Output stream for HTTP connections.
+ * It sends data only once, wrapped into HTTP response.
+ *
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class HttpOutputStream extends ByteArrayOutputStream
+        implements ProxyConstants {
+
+    /**
+     * Underlying output stream.
+     */
+    private DataOutputStream out;
+
+    /**
+     * If this is inbound connection stream.
+     */
+    private boolean inbound;
+
+    /**
+     * Target host name (for HTTP headers).
+     */
+    private String host;
+
+    /**
+     * Target port number (for HTTP headers).
+     */
+    private int port;
+
+    /**
+     * If this is CGI stream.
+     */
+    private boolean cgi;
+
+    /**
+     * If this stream was closed.
+     */
+    private boolean isClosed = false;
+
+    /**
+     * Constructs this stream by wrapping the specified output stream.
+     * The resulting stream doesn't use CGI.
+     *
+     * @param   out
+     *          Output stream to wrap.
+     *
+     * @param   inbound
+     *          If this is inbound connection stream.
+     *
+     * @param   host
+     *          Target host name.
+     *          Used for HTTP headers (for outbound streams)
+     *          and for diagnostics.
+     *          Optional (can be <code>null</code>) for inbound streams.
+     *
+     * @param   port
+     *          Target port number.
+     *          Used for HTTP headers (for outbound streams),
+     *          and for diagnostics.
+     *          Is ignored if <code>host</code> is <code>null</code>).
+     */
+    public HttpOutputStream(OutputStream out, boolean inbound,
+            String host, int port) {
+        this(out, inbound, host, port, false);
+    }
+
+    /**
+     * Constructs this stream by wrapping the specified output stream.
+     *
+     * @param   out
+     *          Output stream to wrap.
+     *
+     * @param   inbound
+     *          If this is inbound connection stream.
+     *
+     * @param   host
+     *          Target host name.
+     *          Used for HTTP headers for outbound streams,
+     *          may be used for diagnostics purposes for all streams.
+     *          Optional (can be <code>null</code>) for inbound streams.
+     *
+     * @param   port
+     *          Target port number.
+     *          Used for HTTP headers for outbound streams,
+     *          may be used for diagnostics purposes for all streams.
+     *          Optional for inbound streams.
+     *
+     * @param   cgi
+     *          If this is CGI stream (ignored for inbound streams).
+     */
+    public HttpOutputStream(OutputStream out, boolean inbound,
+            String host, int port, boolean cgi) {
+        super();
+        this.out = new DataOutputStream(out);
+        this.inbound = inbound;
+        this.host = host;
+        this.port = port;
+        this.cgi = (inbound ? false : cgi);
+    }
+
+    /**
+     * Converts the specified string to bytes using {@link String#getBytes()}
+     * and writes to the stream.
+     *
+     * @param   s
+     *          String to write.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     *
+     * @see     java.io.DataOutput#writeBytes(String)
+     */
+    public final void writeBytes(String s) throws IOException {
+        write(s.getBytes());
+    }
+
+    /**
+     * Wraps all data contained in this stream into HTTP response and writes it
+     * into the underlying output stream. This method can only be called once.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public synchronized void close() throws IOException {
+        if (isClosed) {
+            throw new IOException("Repeated attempt to close HttpOutputStream");
+        }
+
+        // Port the outbound connection is established to.
+        int connectPort = (cgi ? RMIConstants.HTTP_DEFAULT_PORT : port);
+
+        // Sending HTTP POST request or OK response.
+        //
+        // Note: the following things may need reconsidering in future:
+        //          - What headers should really be present here.
+        //          - Which HTTP protocol version should be used.
+        //          - What User-Agent name and version should be used.
+        //          - What proxy control headers should be included.
+        //
+        // Note: reference implementation uses the following headers
+        //      (retrieved using the black box testing by writing a dummy
+        //       socket server that logs everything that comes to it,
+        //       and making an RMI request to it with reference implementation):
+        //          POST http://HOST:PORT/ HTTP/1.1
+        //          Content-type: application/octet-stream
+        //          Cache-Control: no-cache
+        //          Pragma: no-cache
+        //          User-Agent: Java/1.4.2_04
+        //          Host: HOST:PORT
+        //          Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
+        //          Proxy-Connection: keep-alive
+        //          Content-Length: LENGTH
+        out.writeBytes((inbound ? HTTP_RESPONSE_HEADER :
+                (HTTP_REQUEST_SIGNATURE + "http://" + host + ':' + connectPort
+                    + '/' + (cgi ? ("cgi-bin/java-rmi?forward=" + port) : "")
+                    + " HTTP/1.1" + EOLN
+                + "Cache-Control: no-cache" + EOLN + "Pragma: no-cache" + EOLN
+                + "Host: " + host + ':' + connectPort + EOLN
+                + "Proxy-Connection: keep-alive" + EOLN
+                + "User-Agent: DRL/" + (String) AccessController.doPrivileged(
+                        new GetStringPropAction("java.version")))) + EOLN);
+
+        out.writeBytes("Content-type: application/octet-stream" + EOLN
+                + CONTENT_LENGTH_SIGNATURE + ' ' + count + EOLN + EOLN);
+        out.write(buf, 0, count);
+        out.flush();
+
+        reset();
+
+        isClosed = true;
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE,
+                    "HTTP " + (inbound ? "response" : "request")
+                    + ((host != null) ? (" to [" + host + ':' + port + ']')
+                            : "") + " sent.");
+        }
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpProxyRMISocketFactory.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpProxyRMISocketFactory.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpProxyRMISocketFactory.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpProxyRMISocketFactory.java Thu May 18 13:01:22 2006
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.AccessController;
+
+import org.apache.harmony.rmi.common.GetBooleanPropAction;
+import org.apache.harmony.rmi.common.RMILog;
+
+
+/**
+ * Socket factory for HTTP proxy connections. Returns {@link HttpOutboundSocket}
+ * for client and {@link HttpServerSocket} for server sockets.
+ *
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+public class HttpProxyRMISocketFactory extends ProxyRMISocketFactory
+        implements ProxyConstants  {
+
+    /**
+     * serialVersionUID
+     */
+    private static final long serialVersionUID = -8113740863920118588L;
+
+    /**
+     * {@inheritDoc}
+     */
+    public Socket createSocket(Proxy proxy, String host, int port)
+            throws IOException {
+        Socket s;
+
+        // Check if plain HTTP is disabled.
+        if (((Boolean) AccessController.doPrivileged(new GetBooleanPropAction(
+                DISABLE_PLAIN_HTTP_PROP))).booleanValue()) {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Plain HTTP connections disabled, "
+                        + "trying CGI connection.");
+            }
+        } else {
+            try {
+                // Try plain HTTP connection.
+                s = new HttpOutboundSocket(proxy, host, port, false);
+
+                if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                    proxyTransportLog.log(RMILog.VERBOSE,
+                            "Plain HTTP connection to [" + host + ':' + port
+                            + "] from port " + s.getLocalPort()+ " succeeded.");
+                }
+
+                return s;
+            } catch (IOException e) {
+                if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                    proxyTransportLog.log(RMILog.VERBOSE,
+                            "Plain HTTP connection to ["
+                            + host + ':' + port + "] failed: " + e
+                            + ". Trying CGI connection.");
+                }
+            }
+        }
+
+        try {
+            // Try CGI HTTP connection.
+            s = new HttpOutboundSocket(proxy, host, port, true);
+
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "CGI HTTP connection to [" + host + ':' + port
+                        + "] from port " + s.getLocalPort()+ " succeeded.");
+            }
+            return s;
+        } catch (IOException e) {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "CGI HTTP connection to ["
+                        + host + ':' + port + "] failed: " + e);
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ServerSocket createServerSocket(int port) throws IOException {
+        return new HttpServerSocket(port);
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpProxyRMISocketFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerConnection.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerConnection.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerConnection.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerConnection.java Thu May 18 13:01:22 2006
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.UID;
+
+import org.apache.harmony.rmi.common.RMILog;
+import org.apache.harmony.rmi.server.ServerConnection;
+import org.apache.harmony.rmi.server.ServerConnectionManager;
+
+
+/**
+ * Http extension of ServerConnection.
+ *
+ * @author  Mikhail A. Markov
+ * @version $Revision: 1.1.2.3 $
+ */
+public class HttpServerConnection extends ServerConnection
+        implements ProxyConstants {
+
+    // If true then this connection was closed.
+    private boolean isClosed = false;
+
+    /**
+     * Constructs HttpServerConnection working through socket specified.
+     *
+     * @param s Socket connected to the client
+     * @param mgr ConnectionManager managing this connection
+     *
+     * @throws IOException if an I/O error occured during getting
+     *         input/output streams from specified socket
+     */
+    public HttpServerConnection(Socket s, ServerConnectionManager mgr)
+            throws IOException {
+        super(s, mgr);
+    }
+
+    /**
+     * @see ServerConnection.clientProtocolAck()
+     */
+    protected int clientProtocolAck() throws IOException {
+        byte data;
+        DataInputStream din = new DataInputStream(in);
+
+        try {
+            // read RMI header
+            int header = din.readInt();
+
+            if (header != RMI_HEADER) {
+                throw new UnmarshalException("Unknown header: " + header);
+            }
+
+            // read RMI protocol version
+            short ver = din.readShort();
+
+            if (ver != PROTOCOL_VER) {
+                throw new UnmarshalException("Unknown RMI protocol version: "
+                        + ver);
+            }
+        } catch (IOException ioe) {
+            throw new UnmarshalException("Unable to read RMI protocol header",
+                    ioe);
+        }
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE, "Using protocol version "
+                    + PROTOCOL_VER);
+        }
+
+        // read protocol type
+        if (din.readByte() == SINGLEOP_PROTOCOL) {
+
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Using singleop RMI protocol");
+            }
+        } else {
+            return -1;
+        }
+
+        // protocol is agreed
+        return SINGLEOP_PROTOCOL;
+    }
+
+    /**
+     * @see ServerConnection.waitCallMsg()
+     */
+    protected int waitCallMsg() throws IOException {
+        if (isClosed) {
+            return -1;
+        }
+        int data;
+
+        try {
+            data = in.read();
+        } catch (IOException ioe) {
+            data = -1;
+        }
+
+        if (data == -1) {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Connection [" + toString() + "] is closed");
+            }
+            return -1;
+        }
+        DataOutputStream dout = new DataOutputStream(out);
+
+        if (data == PING_MSG) {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Got ping request");
+            }
+            releaseInputStream();
+
+            // send ping ack
+            dout.writeByte(PING_ACK);
+            dout.close();
+            return -1;
+        } else if (data == DGCACK_MSG) {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Got DGC ack request");
+            }
+            dgcUnregisterUID(UID.read(new DataInputStream(in)));
+            releaseInputStream();
+            dout.close();
+            return -1;
+        } else if (data == CALL_MSG) {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Got call request");
+            }
+            return data;
+        } else {
+            if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+                proxyTransportLog.log(RMILog.VERBOSE,
+                        "Unknown request got: " + data);
+            }
+            throw new RemoteException("Unknown message got: " + data);
+        }
+    }
+
+    /**
+     * Closes output stream. After that call this connection is treated as
+     * closed and could be reused.
+     */
+    public synchronized void releaseOutputStream() throws IOException {
+        if (isClosed) {
+            return;
+        }
+        isClosed = true;
+        out.close();
+    }
+
+    /**
+     * Returns string representation of this connection.
+     *
+     * @return string representation of this connection
+     */
+    public String toString() {
+        return "HttpServerConnection: remote endpoint:" + ep;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerSocket.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerSocket.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerSocket.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerSocket.java Thu May 18 13:01:22 2006
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.1 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.apache.harmony.rmi.common.RMILog;
+import org.apache.harmony.rmi.transport.SocketWrapper;
+
+
+/**
+ * HTTP server socket, detects connection type
+ * and forwards the HTTP requests to {@link HttpInboundSocket}.
+ *
+ * @author  Mikhail A. Markov, Vasily Zakharov
+ * @version $Revision: 1.1.2.1 $
+ */
+public class HttpServerSocket extends ServerSocket implements ProxyConstants {
+
+    /**
+     * Creates this socket bound to the specified port.
+     *
+     * @param   port
+     *          Port.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpServerSocket(int port) throws IOException {
+        super(port);
+    }
+
+    /**
+     * Creates this socket bound to the specified port,
+     * with the specified backlog.
+     *
+     * @param   port
+     *          Port.
+     *
+     * @param   backlog
+     *          Backlog.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public HttpServerSocket(int port, int backlog) throws IOException {
+        super(port, backlog);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Socket accept() throws IOException {
+        Socket s = super.accept();
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE, "Inbound connection from ["
+                    + s.getInetAddress().getHostName() + ':' + s.getPort()
+                    + "] to port " + s.getLocalPort() + " detected.");
+        }
+
+        // Detect if incoming request is using HTTP or direct socket.
+        //
+        // Note: here we ignore the following for simplicity:
+        //          Ignore CRLF if it's present before the POST line.
+        //          (See RFC 2616 4.1)
+        //
+        // Note: Theoretically, we SHOULD return
+        //          the status code 501 (Not Implemented)
+        //          if the method is not POST (the only method we support).
+        //          (See RFC 2616 5.1.1)
+        //          But we ignore this, since we need to fall back to direct
+        //          connection if HTTP connection cannot be established.
+        BufferedInputStream in = new BufferedInputStream(s.getInputStream());
+        byte[] buffer = new byte[HTTP_REQUEST_SIGNATURE_LENGTH];
+        in.mark(HTTP_REQUEST_SIGNATURE_LENGTH);
+
+        // Use read(), not read(byte[], int, int)
+        // because we need a blocking read operation here.
+        for (int i = 0; i < HTTP_REQUEST_SIGNATURE_LENGTH; i++) {
+            int c = in.read();
+
+            if (c < 0) {
+                break;
+            }
+            buffer[i] = (byte) c;
+        }
+        boolean isHttp = new String(buffer).equals(HTTP_REQUEST_SIGNATURE);
+        in.reset();
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE,
+                    "Inbound connection signature: ["
+                    + new String(buffer) + "].");
+        }
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE,
+                    (isHttp ? "HTTP" : "Direct socket") + " connection from ["
+                    + s.getInetAddress().getHostName() + ':' + s.getPort()
+                    + "] to port " + s.getLocalPort() + " detected.");
+        }
+
+        // Direct socket must be wrapped to avoid losing already read data.
+        return (isHttp ? new HttpInboundSocket(s, in, null)
+                       : new SocketWrapper(s, in, null));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return ("HttpServerSocket[" + super.toString() + "]");
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/HttpServerSocket.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/Proxy.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/Proxy.java?rev=407625&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/Proxy.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/Proxy.java Thu May 18 13:01:22 2006
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @author  Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+package org.apache.harmony.rmi.transport.proxy;
+
+import java.io.IOException;
+import java.net.NoRouteToHostException;
+import java.net.Socket;
+import java.security.AccessController;
+
+import org.apache.harmony.rmi.common.GetBooleanPropAction;
+import org.apache.harmony.rmi.common.GetLongPropAction;
+import org.apache.harmony.rmi.common.GetStringPropAction;
+import org.apache.harmony.rmi.common.RMIConstants;
+import org.apache.harmony.rmi.common.RMILog;
+
+
+/**
+ * Provides access to Java proxy system properties.
+ *
+ * Note: instances of this class and values returned by their methods
+ * should not be stored longer than is required to establish a particular
+ * connection. Instead, a new instance should be created and the methods
+ * of that instance called each time new connection is established.
+ *
+ * @author  Vasily Zakharov
+ * @version $Revision: 1.1.2.2 $
+ */
+public final class Proxy implements ProxyConstants {
+
+    /**
+     * HTTP proxy host name.
+     */
+    private final String proxyHost;
+
+    /**
+     * HTTP proxy port number.
+     */
+    private final int proxyPort;
+
+    /**
+     * If proxy is set.
+     */
+    private final boolean proxySet;
+
+    /**
+     * Should we enable direct (non-proxy) HTTP connections.
+     */
+    private final boolean enableDirect;
+
+    /**
+     * Creates instance of this class.
+     *
+     * Note: instances of this class and values returned by their methods
+     * should not be stored longer than is required to establish a particular
+     * connection. Instead, a new instance should be created and the methods
+     * of that instance called each time new connection is established.
+     */
+    public Proxy() {
+        proxyHost = getProxyHost();
+
+        if (proxyHost != null) {
+            proxySet = true;
+            proxyPort = getProxyPort();
+            enableDirect = false;
+        } else {
+            proxySet = false;
+            proxyPort = (-1);
+            enableDirect = isDirectEnabled();
+        }
+
+        if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
+            proxyTransportLog.log(RMILog.VERBOSE, "Proxy configuration: "
+                    + (proxySet ? (proxyHost + ':' + proxyPort)
+                            : ("proxy disabled, direct HTTP connections "
+                                + (enableDirect ? "enabled" : "disabled")
+                                + '.')));
+        }
+    }
+
+    /**
+     * Returns proxy host name or <code>null</code> if proxy host is not set.
+     *
+     * @return  Proxy host name or <code>null</code> if proxy host is not set.
+     */
+    public String getHost() {
+        return proxyHost;
+    }
+
+    /**
+     * Returns proxy port number or {@link #HTTP_DEFAULT_PORT} if proxy port
+     * is not set or <code>-1</code> if proxy host is not set.
+     *
+     * @return  Proxy port number or {@link #HTTP_DEFAULT_PORT} if proxy port
+     *          is not set or <code>-1</code> if proxy host is not set.
+     */
+    public int getPort() {
+        return proxyPort;
+    }
+
+    /**
+     * Returns <code>true</code> if proxy host is set in system environment,
+     * <code>false</code> otherwise.
+     *
+     * @return  <code>true</code> if proxy host is set in system environment,
+     *          <code>false</code> otherwise.
+     */
+    public boolean isSet() {
+        return proxySet;
+    }
+
+    /**
+     * Returns new socket connected to specified host and port, probably
+     * through a proxy (if proxy is set). If proxy is not set, then if direct
+     * HTTP connections are enabled, connection is established directly,
+     * otherwise {@link IOException} is thrown.
+     *
+     * @param   host
+     *          Host to connect to.
+     *z
+     * @param   port
+     *          Port to connect to.
+     *
+     * @return  New socket connected to the specified host and port,
+     *          probably through a proxy.
+     *
+     * @throws  IOException
+     *          If I/O error occurs.
+     */
+    public Socket getSocket(String host, int port) throws IOException {
+        if (proxySet) {
+            return new Socket(proxyHost, proxyPort);
+        } else if (enableDirect) {
+            return new Socket(host, port);
+        } else {
+            throw new NoRouteToHostException("HTTP proxy is not set");
+        }
+    }
+
+    /**
+     * Accesses {@link #PROXY_HOST_PROP} system property
+     * and retrives the proxy host name.
+     *
+     * @return  Proxy host name or <code>null</code> if proxy host is not set.
+     */
+    private static String getProxyHost() {
+        String host = (String) AccessController.doPrivileged(
+                                    new GetStringPropAction(PROXY_HOST_PROP));
+
+        if ((host == null) || (host.length() < 1)) {
+            return null;
+        }
+
+        host = host.trim();
+
+        return ((host.length() < 1) ? null : host);
+    }
+
+    /**
+     * Accesses {@link #PROXY_PORT_PROP} system property
+     * and retrives the proxy port number.
+     *
+     * @return  Proxy port number or {@link #HTTP_DEFAULT_PORT}
+     *          if proxy port is not set.
+     */
+    private static int getProxyPort() {
+        return ((Long) AccessController.doPrivileged(new GetLongPropAction(
+                PROXY_PORT_PROP, RMIConstants.HTTP_DEFAULT_PORT))).intValue();
+    }
+
+    /**
+     * Accesses {@link #ENABLE_DIRECT_HTTP_PROP} system property
+     * to find out if direct connections are allowed.
+     *
+     * @return  <code>true</code> if direct connections are allowed,
+     *          <code>false</code> otherwise.
+     */
+    private static boolean isDirectEnabled() {
+        return ((Boolean) AccessController.doPrivileged(
+                new GetBooleanPropAction(ENABLE_DIRECT_HTTP_PROP)))
+                        .booleanValue();
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/rmi3/src/common/javasrc/org/apache/harmony/rmi/transport/proxy/Proxy.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message