aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java')
-rw-r--r--src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java b/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
new file mode 100644
index 000000000..229a2cebd
--- /dev/null
+++ b/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.rmi.transport.proxy;
+
+import java.io.*;
+
+import sun.rmi.runtime.Log;
+
+/**
+ * The HttpInputStream class assists the HttpSendSocket and HttpReceiveSocket
+ * classes by filtering out the header for the message as well as any
+ * data after its proper content length.
+ */
+class HttpInputStream extends FilterInputStream {
+
+ /** bytes remaining to be read from proper content of message */
+ protected int bytesLeft;
+
+ /** bytes remaining to be read at time of last mark */
+ protected int bytesLeftAtMark;
+
+ /**
+ * Create new filter on a given input stream.
+ * @param in the InputStream to filter from
+ */
+ public HttpInputStream(InputStream in) throws IOException
+ {
+ super(in);
+
+ if (in.markSupported())
+ in.mark(0); // prevent resetting back to old marks
+
+ // pull out header, looking for content length
+
+ DataInputStream dis = new DataInputStream(in);
+ String key = "Content-length:".toLowerCase();
+ boolean contentLengthFound = false;
+ String line;
+ do {
+ line = dis.readLine();
+
+ if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
+ RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
+ "received header line: \"" + line + "\"");
+ }
+
+ if (line == null)
+ throw new EOFException();
+
+ if (line.toLowerCase().startsWith(key)) {
+ if (contentLengthFound)
+ ; // what would we want to do in this case??
+ bytesLeft =
+ Integer.parseInt(line.substring(key.length()).trim());
+ contentLengthFound = true;
+ }
+
+ // The idea here is to go past the first blank line.
+ // Some DataInputStream.readLine() documentation specifies that
+ // it does include the line-terminating character(s) in the
+ // returned string, but it actually doesn't, so we'll cover
+ // all cases here...
+ } while ((line.length() != 0) &&
+ (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
+
+ if (!contentLengthFound || bytesLeft < 0) {
+ // This really shouldn't happen, but if it does, shoud we fail??
+ // For now, just give up and let a whole lot of bytes through...
+ bytesLeft = Integer.MAX_VALUE;
+ }
+ bytesLeftAtMark = bytesLeft;
+
+ if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
+ RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
+ "content length: " + bytesLeft);
+ }
+ }
+
+ /**
+ * Returns the number of bytes that can be read with blocking.
+ * Make sure that this does not exceed the number of bytes remaining
+ * in the proper content of the message.
+ */
+ public int available() throws IOException
+ {
+ int bytesAvailable = in.available();
+ if (bytesAvailable > bytesLeft)
+ bytesAvailable = bytesLeft;
+
+ return bytesAvailable;
+ }
+
+ /**
+ * Read a byte of data from the stream. Make sure that one is available
+ * from the proper content of the message, else -1 is returned to
+ * indicate to the user that the end of the stream has been reached.
+ */
+ public int read() throws IOException
+ {
+ if (bytesLeft > 0) {
+ int data = in.read();
+ if (data != -1)
+ -- bytesLeft;
+
+ if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
+ RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
+ "received byte: '" +
+ ((data & 0x7F) < ' ' ? " " : String.valueOf((char) data)) +
+ "' " + data);
+ }
+
+ return data;
+ }
+ else {
+ RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
+ "read past content length");
+
+ return -1;
+ }
+ }
+
+ public int read(byte b[], int off, int len) throws IOException
+ {
+ if (bytesLeft == 0 && len > 0) {
+ RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
+ "read past content length");
+
+ return -1;
+ }
+ if (len > bytesLeft)
+ len = bytesLeft;
+ int bytesRead = in.read(b, off, len);
+ bytesLeft -= bytesRead;
+
+ if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
+ RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
+ "read " + bytesRead + " bytes, " + bytesLeft + " remaining");
+ }
+
+ return bytesRead;
+ }
+
+ /**
+ * Mark the current position in the stream (for future calls to reset).
+ * Remember where we are within the proper content of the message, so
+ * that a reset method call can recreate our state properly.
+ * @param readlimit how many bytes can be read before mark becomes invalid
+ */
+ public void mark(int readlimit)
+ {
+ in.mark(readlimit);
+ if (in.markSupported())
+ bytesLeftAtMark = bytesLeft;
+ }
+
+ /**
+ * Repositions the stream to the last marked position. Make sure to
+ * adjust our position within the proper content accordingly.
+ */
+ public void reset() throws IOException
+ {
+ in.reset();
+ bytesLeft = bytesLeftAtMark;
+ }
+
+ /**
+ * Skips bytes of the stream. Make sure to adjust our
+ * position within the proper content accordingly.
+ * @param n number of bytes to be skipped
+ */
+ public long skip(long n) throws IOException
+ {
+ if (n > bytesLeft)
+ n = bytesLeft;
+ long bytesSkipped = in.skip(n);
+ bytesLeft -= bytesSkipped;
+ return bytesSkipped;
+ }
+}