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
|