diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SlowGet.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SlowGet.java deleted file mode 100644 index e174dabf99d..00000000000 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SlowGet.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.eclipse.jetty.embedded; - -import java.io.InputStream; -import java.net.Socket; - -public class SlowGet -{ - public static void main(String... args) throws Exception - { - try(Socket socket = new Socket("localhost",8080)) - { - socket.getOutputStream().write("GET /data.txt HTTP/1.0\r\n\r\n".getBytes()); - socket.getOutputStream().flush(); - - InputStream in = socket.getInputStream(); - byte[] headers = new byte[1024]; - int len = in.read(headers); - - System.err.println("read="+len); - - int b=0; - while (b>=0) - { - b = in.read(); - if ((++len % 1024)==0) - System.err.println("read="+(++len)); - } - } - } -} diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java index 7ef57077531..27a914155b5 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java @@ -170,7 +170,6 @@ public class ChannelEndPoint extends AbstractEndPoint @Override public boolean flush(ByteBuffer... buffers) throws IOException { - System.err.println("FLUSH: "+Arrays.stream(buffers).map(b->BufferUtil.toDetailString(b)).collect(Collectors.toList())); long flushed=0; try { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java index 146c75039bc..0fa4ec79414 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java @@ -30,6 +30,8 @@ import java.util.concurrent.TimeoutException; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.util.BufferUtil; @@ -152,9 +154,9 @@ public class HttpInput extends ServletInputStream implements Runnable long period=now-_channelState.getHttpChannel().getRequest().getTimeStamp(); if (period>=1000) { - long data_rate = _contentArrived / (now-_channelState.getHttpChannel().getRequest().getTimeStamp()); + double data_rate = _contentArrived / (0.001*(now-_channelState.getHttpChannel().getRequest().getTimeStamp())); if (data_rate minimumTestRuntime); Assert.assertTrue(System.currentTimeMillis() - start < maximumTestRuntime); } - + @Test(timeout=60000) + public void testSlowClientRequestNoLimit() throws Exception + { + configureServer(new EchoHandler()); + Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort()); + client.setSoTimeout(10000); + + Assert.assertFalse(client.isClosed()); + + OutputStream os=client.getOutputStream(); + InputStream is=client.getInputStream(); + + os.write(( + "POST /echo HTTP/1.0\r\n"+ + "host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+ + "content-type: text/plain; charset=utf-8\r\n"+ + "content-length: 20\r\n"+ + "\r\n").getBytes("utf-8")); + os.flush(); + + for (int i=0;i<4;i++) + { + os.write("123\n".getBytes("utf-8")); + os.flush(); + Thread.sleep(1000); + } + os.write("===\n".getBytes("utf-8")); + os.flush(); + + String response =IO.toString(is); + Assert.assertThat(response,containsString(" 200 ")); + Assert.assertThat(response,containsString("===")); + } + + @Test(timeout=60000) + public void testSlowClientRequestLimited() throws Exception + { + _httpConfiguration.setMinRequestDataRate(20); + configureServer(new EchoHandler()); + Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort()); + client.setSoTimeout(10000); + + Assert.assertFalse(client.isClosed()); + + OutputStream os=client.getOutputStream(); + InputStream is=client.getInputStream(); + + os.write(( + "POST /echo HTTP/1.0\r\n"+ + "host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+ + "content-type: text/plain; charset=utf-8\r\n"+ + "content-length: 20\r\n"+ + "\r\n").getBytes("utf-8")); + os.flush(); + + try + { + for (int i=0;i<4;i++) + { + os.write("123\n".getBytes("utf-8")); + os.flush(); + Thread.sleep(500); + } + os.write("===\n".getBytes("utf-8")); + os.flush(); + + String response =IO.toString(is); + Assert.assertThat(response,containsString(" 408 ")); + Assert.assertThat(response,containsString("Request Data rate")); + } + catch (SocketException e) + {} + } + + @Test(timeout=60000) + public void testSlowClientRequestLimitExceeded() throws Exception + { + _httpConfiguration.setMinRequestDataRate(20); + configureServer(new EchoHandler()); + Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort()); + client.setSoTimeout(10000); + + Assert.assertFalse(client.isClosed()); + + OutputStream os=client.getOutputStream(); + InputStream is=client.getInputStream(); + + os.write(( + "POST /echo HTTP/1.0\r\n"+ + "host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+ + "content-type: text/plain; charset=utf-8\r\n"+ + "content-length: 100\r\n"+ + "\r\n").getBytes("utf-8")); + os.flush(); + + for (int i=0;i<9;i++) + { + os.write("123456789\n".getBytes("utf-8")); + os.flush(); + Thread.sleep(250); + } + os.write("=========\n".getBytes("utf-8")); + os.flush(); + + String response =IO.toString(is); + Assert.assertThat(response,containsString(" 200 ")); + Assert.assertThat(response,containsString("=========")); + } + + + + protected static class SlowResponseHandler extends AbstractHandler { @Override