Issue #845 data rate limits

Added data rate unit tests
This commit is contained in:
Greg Wilkins 2016-08-16 17:09:46 +10:00
parent 3d93d39b39
commit 34f22dcbce
4 changed files with 122 additions and 34 deletions

View File

@ -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));
}
}
}
}

View File

@ -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
{

View File

@ -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<minRequestDataRate)
throw new IOException(String.format("Request Data rate %d < %d B/s",data_rate,minRequestDataRate));
throw new BadMessageException(HttpStatus.REQUEST_TIMEOUT_408,String.format("Request Data rate %f < %d B/s",data_rate,minRequestDataRate));
}
}

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -73,7 +75,11 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
{
super.before();
if (_httpConfiguration!=null)
{
_httpConfiguration.setBlockingTimeout(-1L);
_httpConfiguration.setMinRequestDataRate(-1);
}
}
@Test(timeout=60000)
@ -766,8 +772,119 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
Assert.assertTrue(System.currentTimeMillis() - start > 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