Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 51839 invoked from network); 18 May 2006 20:03:12 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 18 May 2006 20:03:12 -0000 Received: (qmail 69333 invoked by uid 500); 18 May 2006 20:03:11 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 69277 invoked by uid 500); 18 May 2006 20:03:11 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 69260 invoked by uid 99); 18 May 2006 20:03:10 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 May 2006 13:03:10 -0700 X-ASF-Spam-Status: No, hits=0.6 required=10.0 tests=NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 May 2006 13:02:52 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 05D701A9838; Thu, 18 May 2006 13:02:07 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: harmony-commits@incubator.apache.org From: gharley@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060518200207.05D701A9838@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N 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 @@ + + + + +RMI transport implementation classes. + + 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 expect + * string is received from the stream. + * If expect is null, + * 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 false (mark operations are not supported). + * + * @return false + */ + 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 null 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 HttpOutboundSocket 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 HttpOutboundSocket 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 HttpOutboundSocket 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 null) for inbound streams. + * + * @param port + * Target port number. + * Used for HTTP headers (for outbound streams), + * and for diagnostics. + * Is ignored if host is null). + */ + 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 null) 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 null if proxy host is not set. + * + * @return Proxy host name or null 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 -1 if proxy host is not set. + * + * @return Proxy port number or {@link #HTTP_DEFAULT_PORT} if proxy port + * is not set or -1 if proxy host is not set. + */ + public int getPort() { + return proxyPort; + } + + /** + * Returns true if proxy host is set in system environment, + * false otherwise. + * + * @return true if proxy host is set in system environment, + * false 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 null 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 true if direct connections are allowed, + * false 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