JETTY-1108 SSL EOF detection

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@889 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Greg Wilkins 2009-09-14 04:52:16 +00:00
parent 31f1684464
commit df989b3141
5 changed files with 77 additions and 44 deletions

View File

@ -17,6 +17,7 @@ jetty-7.0.0.RC6-SNAPSHOT
+ JETTY-1098 Default form encoding is UTF8
+ JETTY-1101 Updated servlet3 continuation constructor
+ JETTY-1105 Custom error pages aren't working
+ JETTY-1108 SSL EOF detection
+ 288514 AbstractConnector does not handle InterruptedExceptions on shutdown
+ 288466 LocalConnector is not thread safe
+ 288772 Failure to connect does not set status to EXCEPTED

View File

@ -27,6 +27,7 @@ import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import org.eclipse.jetty.http.Parser;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.nio.NIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager;
@ -586,21 +587,22 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
catch(IOException e)
{
if (_inNIOBuffer.length()==0)
{
_outNIOBuffer.clear();
throw e;
}
break;
}
}
// If we have no data
if (_inNIOBuffer.length()==0)
// If we have no progress and no data
if (total_filled==0 && _inNIOBuffer.length()==0)
{
// Check for EOF
// TODO - the EOF is delayed so that unwrappable data in the
// buffer is processed before the EoF. But what if there is
// insufficient data in the buffer to do an unwrap? Will EoF
// be totally ignored, or will it be thrown elsewhere????
if(!isOpen())
throw new org.eclipse.jetty.io.EofException();
{
_outNIOBuffer.clear();
throw new EofException();
}
return false;
}
@ -634,9 +636,17 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
throw new IllegalStateException(_result.toString());
case BUFFER_UNDERFLOW:
// Not enough data, so return and it will be tried again
// Not enough data,
// If we are closed, we will never get more, so EOF
// else return and we will be tried again
// later when more data arriving causes another dispatch.
if (Log.isDebugEnabled()) Log.debug("unwrap {}",_result);
if(!isOpen())
{
_inNIOBuffer.clear();
_outNIOBuffer.clear();
throw new EofException();
}
return (total_filled > 0);
case CLOSED:

View File

@ -712,6 +712,8 @@ public class AsyncContinuation implements AsyncContext, Continuation
{
case __IDLE:
case __DISPATCHED:
case __UNCOMPLETED:
case __COMPLETED:
return false;
default:

View File

@ -375,6 +375,9 @@ public class HttpConnection implements Connection
{
if (_request._async.isAsync())
{
// TODO - handle the case of input being read for a
// suspended request.
Log.debug("async request",_request);
if (!_request._async.isComplete())
handleRequest();
@ -419,8 +422,8 @@ public class HttpConnection implements Connection
if (!progress)
return;
progress=false;
}
progress=false;
}
catch (HttpException e)
{

View File

@ -28,6 +28,7 @@ import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -37,19 +38,22 @@ import junit.framework.TestCase;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
/**
* @version $Revision$ $Date$
*/
public class SslUploadTest extends TestCase
{
int _total;
public void test() throws Exception
{
Server server = new Server();
SslConnector connector = new SslSelectChannelConnector();
server.addConnector(connector);
String keystorePath = System.getProperty("basedir") + "/src/test/resources/keystore";
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
connector.setKeystore(keystorePath);
connector.setPassword("storepwd");
connector.setKeyPassword("keypwd");
@ -68,28 +72,11 @@ public class SslUploadTest extends TestCase
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
URL url = new URL("https://localhost:" + connector.getLocalPort() + "/");
final HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.setHostnameVerifier(new EmptyHostnameVerifier());
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.connect();
_total=0;
final SSLSocket socket = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost",connector.getLocalPort());
// 64 MiB
// byte[] requestContent = new byte[67108864];
// 16 MiB
byte[] requestContent = new byte[16777216];
Arrays.fill(requestContent, (byte)120);
OutputStream output = connection.getOutputStream();
output.write(requestContent);
output.flush();
/*
// Simulate async close
/*
new Thread()
{
@Override
@ -97,8 +84,12 @@ public class SslUploadTest extends TestCase
{
try
{
sleep(200);
connection.disconnect();
sleep(100);
socket.close();
}
catch (IOException x)
{
x.printStackTrace();
}
catch (InterruptedException x)
{
@ -106,19 +97,33 @@ public class SslUploadTest extends TestCase
}
}
}.start();
*/
*/
long start = System.nanoTime();
InputStream input = connection.getInputStream();
OutputStream out = socket.getOutputStream();
out.write("POST / HTTP/1.1\r\n".getBytes());
out.write("Host: localhost\r\n".getBytes());
out.write("Content-Length: 16777216\r\n".getBytes());
out.write("Content-Type: bytes\r\n".getBytes());
out.write("Connection: close\r\n".getBytes());
out.write("\r\n".getBytes());
out.flush();
byte[] requestContent = new byte[16777216];
Arrays.fill(requestContent, (byte)120);
out.write(requestContent);
out.flush();
InputStream in = socket.getInputStream();
String response = IO.toString(in);
// System.err.println(response);
long end = System.nanoTime();
System.out.println("upload time: " + TimeUnit.NANOSECONDS.toMillis(end - start));
BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
String line;
while ((line = reader.readLine()) != null)
System.err.println(line);
connection.disconnect();
assertEquals(requestContent.length,_total);
}
finally
{
@ -126,12 +131,24 @@ public class SslUploadTest extends TestCase
}
}
private static class EmptyHandler extends AbstractHandler
private class EmptyHandler extends AbstractHandler
{
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
{
System.out.println("path = " + path);
// System.out.println("path = " + path);
request.setHandled(true);
InputStream in = request.getInputStream();
byte[] b = new byte[4096*4];
int l;
while((l=in.read(b))>=0)
{
// System.out.println("Read "+l);
_total+=l;
}
System.err.println("Read "+_total);
}
}