You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2005/04/25 20:40:55 UTC
svn commit: r164621 - in /jakarta/httpclient/trunk/http-common/src:
examples/org/apache/http/examples/ java/org/apache/http/impl/
test/org/apache/http/mockup/
Author: olegk
Date: Mon Apr 25 11:40:54 2005
New Revision: 164621
URL: http://svn.apache.org/viewcvs?rev=164621&view=rev
Log:
Socket read timeout implementation based on NIO
Modified:
jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/AbstractHttpConnection.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataTransmitter.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataTransmitter.java
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataTransmitterMockup.java
Modified: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java (original)
+++ jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java Mon Apr 25 11:40:54 2005
@@ -199,7 +199,7 @@
super();
this.conn = conn;
this.params = new DefaultHttpParams(null);
- new HttpConnectionParams(this.params).setSoTimeout(15000);
+ new HttpConnectionParams(this.params).setSoTimeout(5000);
this.handler = new RequestHandler();
}
@@ -221,7 +221,6 @@
while (!Thread.interrupted()) {
BasicHttpResponse response = new BasicHttpResponse();
try {
- this.conn.setSocketTimeout(100);
HttpRequest request = this.conn.receiveRequest(this.params);
System.out.println("Request received");
this.handler.handleRequest(request, response);
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/AbstractHttpConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/AbstractHttpConnection.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/AbstractHttpConnection.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/AbstractHttpConnection.java Mon Apr 25 11:40:54 2005
@@ -106,15 +106,17 @@
}
public void close() throws IOException {
- HttpDataTransmitter tmp1 = this.datatransmitter;
- if (tmp1 != null) {
- tmp1.flush();
+ HttpDataTransmitter tmptransmitter = this.datatransmitter;
+ if (tmptransmitter != null) {
+ tmptransmitter.flush();
}
this.datareceiver = null;
this.datatransmitter = null;
- Socket tmp2 = this.socket;
- if (tmp2 != null) {
- tmp2.close();
+ Socket tmpsocket = this.socket;
+ if (tmpsocket != null) {
+ tmpsocket.shutdownOutput();
+ tmpsocket.shutdownInput();
+ tmpsocket.close();
}
this.socket = null;
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java Mon Apr 25 11:40:54 2005
@@ -219,6 +219,6 @@
((ChunkedOutputStream) outstream).finish();
}
outstream.flush();
- }
-
+ }
+
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java Mon Apr 25 11:40:54 2005
@@ -32,7 +32,6 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
-import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
@@ -56,23 +55,16 @@
private static final int CR = 13;
private static final int LF = 10;
- private ReadableByteChannel channel = null;
private ByteBuffer buffer = null;
private Charset charset = null;
- protected void init(final ReadableByteChannel channel, int buffersize) {
- if (channel == null) {
- throw new IllegalArgumentException("Channel may not be null");
- }
- this.channel = channel;
-
+ protected void initBuffer(int buffersize) {
if ((buffersize > 2048) || (buffersize <= 0)) {
buffersize = 2048;
}
this.buffer = ByteBuffer.allocateDirect(buffersize);
this.buffer.flip();
-
this.charset = Charset.forName("US-ASCII");
}
@@ -88,9 +80,11 @@
return chardecoder;
}
+ protected abstract int readFromChannel(ByteBuffer dst) throws IOException;
+
protected int fillBuffer() throws IOException {
this.buffer.compact();
- int i = this.channel.read(this.buffer);
+ int i = readFromChannel(this.buffer);
this.buffer.flip();
return i;
}
@@ -222,9 +216,5 @@
}
return line.toString();
}
-
- public boolean isDataAvailable(int timeout) throws IOException {
- return this.channel.isOpen();
- }
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataTransmitter.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataTransmitter.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataTransmitter.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataTransmitter.java Mon Apr 25 11:40:54 2005
@@ -32,7 +32,6 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
-import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
@@ -57,17 +56,11 @@
private static final int LF = 10;
private static final byte[] CRLF = new byte[] {CR, LF};
- private WritableByteChannel channel = null;
private ByteBuffer buffer = null;
private Charset charset = null;
- protected void init(final WritableByteChannel channel, int buffersize) {
- if (channel == null) {
- throw new IllegalArgumentException("Channel may not be null");
- }
- this.channel = channel;
-
+ protected void initBuffer(int buffersize) {
if ((buffersize > 2048) || (buffersize <= 0)) {
buffersize = 2048;
}
@@ -80,16 +73,18 @@
this.charset = Charset.forName(protocolParams.getHttpElementCharset());
}
+ protected abstract void writeToChannel(ByteBuffer src) throws IOException;
+
protected void flushBuffer() throws IOException {
this.buffer.flip();
- this.channel.write(this.buffer);
+ writeToChannel(this.buffer);
this.buffer.compact();
}
public void flush() throws IOException {
this.buffer.flip();
while (this.buffer.hasRemaining()) {
- this.channel.write(this.buffer);
+ writeToChannel(this.buffer);
}
this.buffer.clear();
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java Mon Apr 25 11:40:54 2005
@@ -31,8 +31,14 @@
import java.io.IOException;
import java.net.Socket;
-import java.net.SocketException;
import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
/**
* <p>
@@ -45,9 +51,12 @@
*/
public class NIOSocketHttpDataReceiver extends NIOHttpDataReceiver {
- private final Socket socket;
+ private final SocketChannel channel;
+ private final Selector selector;
+
+ private long readTimeout = 0;
- protected NIOSocketHttpDataReceiver(final Socket socket) throws SocketException {
+ protected NIOSocketHttpDataReceiver(final Socket socket) throws IOException {
super();
if (socket == null) {
throw new IllegalArgumentException("Socket may not be null");
@@ -55,26 +64,37 @@
if (socket.getChannel() == null) {
throw new IllegalArgumentException("Socket does not implement NIO channel");
}
- init(socket.getChannel(), socket.getReceiveBufferSize());
- this.socket = socket;
+ this.channel = socket.getChannel();
+ this.channel.configureBlocking(false);
+ this.selector = Selector.open();
+ this.channel.register(this.selector, SelectionKey.OP_READ);
+ initBuffer(socket.getReceiveBufferSize());
}
+ public void reset(final HttpParams params) {
+ HttpConnectionParams connParams = new HttpConnectionParams(params);
+ this.readTimeout = connParams.getSoTimeout();
+ super.reset(params);
+ }
+
+ protected int readFromChannel(final ByteBuffer dst) throws IOException {
+ if (dst == null) {
+ throw new IllegalArgumentException("Byte buffer may not be null");
+ }
+ this.selector.select(this.readTimeout);
+ int result = this.channel.read(dst);
+ if (result == 0) {
+ throw new SocketTimeoutException("Socket read timeout after "
+ + this.readTimeout + " ms");
+ }
+ return result;
+ }
+
public boolean isDataAvailable(int timeout) throws IOException {
if (hasDataInBuffer()) {
return true;
} else {
- boolean result = false;
- int oldtimeout = this.socket.getSoTimeout();
- try {
- this.socket.setSoTimeout(timeout);
- fillBuffer();
- result = true;
- } catch (SocketTimeoutException e) {
- // no data available
- } finally {
- socket.setSoTimeout(oldtimeout);
- }
- return result;
+ return this.selector.select(timeout) > 0;
}
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataTransmitter.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataTransmitter.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataTransmitter.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataTransmitter.java Mon Apr 25 11:40:54 2005
@@ -29,8 +29,11 @@
package org.apache.http.impl;
+import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
/**
* <p>
@@ -43,7 +46,7 @@
*/
public class NIOSocketHttpDataTransmitter extends NIOHttpDataTransmitter {
- private final Socket socket;
+ private final SocketChannel channel;
protected NIOSocketHttpDataTransmitter(final Socket socket) throws SocketException {
super();
@@ -53,8 +56,12 @@
if (socket.getChannel() == null) {
throw new IllegalArgumentException("Socket does not implement NIO channel");
}
- init(socket.getChannel(), socket.getSendBufferSize());
- this.socket = socket;
+ this.channel = socket.getChannel();
+ initBuffer(socket.getSendBufferSize());
}
-
+
+ protected void writeToChannel(final ByteBuffer src) throws IOException {
+ this.channel.write(src);
+ }
+
}
Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java Mon Apr 25 11:40:54 2005
@@ -1,7 +1,9 @@
package org.apache.http.mockup;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
@@ -16,23 +18,25 @@
public static int BUFFER_SIZE = 16;
+ private final ReadableByteChannel channel;
+
public HttpDataReceiverMockup(final ReadableByteChannel channel, int buffersize) {
super();
- init(channel, buffersize);
+ if (channel == null) {
+ throw new IllegalArgumentException("Channel may not be null");
+ }
+ this.channel = channel;
+ initBuffer(buffersize);
}
public HttpDataReceiverMockup(final byte[] bytes) {
- super();
- init(Channels.newChannel(
- new ByteArrayInputStream(bytes)),
- BUFFER_SIZE);
+ this(bytes, BUFFER_SIZE);
}
public HttpDataReceiverMockup(final byte[] bytes, int buffersize) {
super();
- init(Channels.newChannel(
- new ByteArrayInputStream(bytes)),
- buffersize);
+ this.channel = Channels.newChannel(new ByteArrayInputStream(bytes));
+ initBuffer(buffersize);
}
public HttpDataReceiverMockup(final String s, final String charset, int buffersize)
@@ -45,4 +49,16 @@
this(s.getBytes(charset));
}
+
+ protected int readFromChannel(final ByteBuffer dst) throws IOException {
+ if (dst == null) {
+ throw new IllegalArgumentException("Byte buffer may not be null");
+ }
+ return this.channel.read(dst);
+ }
+
+ public boolean isDataAvailable(int timeout) throws IOException {
+ return this.channel.isOpen();
+ }
+
}
Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataTransmitterMockup.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataTransmitterMockup.java?rev=164621&r1=164620&r2=164621&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataTransmitterMockup.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataTransmitterMockup.java Mon Apr 25 11:40:54 2005
@@ -1,6 +1,8 @@
package org.apache.http.mockup;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
@@ -17,16 +19,27 @@
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ private final WritableByteChannel channel;
+
public HttpDataTransmitterMockup(final WritableByteChannel channel, int buffersize) {
super();
- init(channel, buffersize);
+ if (channel == null) {
+ throw new IllegalArgumentException("Channel may not be null");
+ }
+ this.channel = channel;
+ initBuffer(buffersize);
}
public HttpDataTransmitterMockup() {
super();
- init(Channels.newChannel(this.buffer), BUFFER_SIZE);
+ this.channel = Channels.newChannel(this.buffer);
+ initBuffer(BUFFER_SIZE);
}
+ protected void writeToChannel(final ByteBuffer src) throws IOException {
+ this.channel.write(src);
+ }
+
public byte[] getData() {
return this.buffer.toByteArray();
}