357240 work in progress

This commit is contained in:
Greg Wilkins 2011-09-28 16:21:57 +10:00
parent c20ce1fc4e
commit 6eaa1364e3
9 changed files with 130 additions and 71 deletions

View File

@ -355,6 +355,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
}
}
/* TODO - is this needed ?
if (_generator.isComplete() && !_parser.isComplete())
{
if (!_endp.isOpen() || _endp.isInputShutdown())
@ -364,6 +365,7 @@ public class HttpConnection extends AbstractConnection implements Dumpable
close();
}
}
*/
if (complete || failed)
{
@ -669,6 +671,9 @@ public class HttpConnection extends AbstractConnection implements Dumpable
case HttpExchange.STATUS_EXCEPTED:
case HttpExchange.STATUS_EXPIRED:
break;
case HttpExchange.STATUS_PARSING_CONTENT:
if (_endp.isInputShutdown() && _parser.isState(HttpParser.STATE_EOF_CONTENT))
break;
default:
String exch= exchange.toString();
String reason = _endp.isOpen()?(_endp.isInputShutdown()?"half closed: ":"local close: "):"closed: ";

View File

@ -107,8 +107,10 @@ public class HttpExchange
private long _timeout = -1;
private volatile Timeout.Task _timeoutTask;
private long _lastStateChange=-1;
private long _lastStateChange=System.currentTimeMillis();
private long _sent=-1;
private int _lastState=-1;
private int _lastStatePeriod=-1;
boolean _onRequestCompleteDone;
boolean _onResponseCompleteDone;
@ -188,7 +190,10 @@ public class HttpExchange
boolean set = false;
if (oldStatus!=newStatus)
{
_lastStateChange=System.currentTimeMillis();
long now = System.currentTimeMillis();
_lastStatePeriod=(int)(now-_lastStateChange);
_lastState=oldStatus;
_lastStateChange=now;
if (newStatus==STATUS_SENDING_REQUEST)
_sent=_lastStateChange;
}
@ -816,8 +821,10 @@ public class HttpExchange
String state=toState(getStatus());
long now=System.currentTimeMillis();
long forMs = now -_lastStateChange;
String s= String.format("%s@%x=%s//%s%s#%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,state,forMs);
if (getStatus()>=STATUS_SENDING_REQUEST)
String s= _lastState>=0
?String.format("%s@%x=%s//%s%s#%s(%dms)->%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,toState(_lastState),_lastStatePeriod,state,forMs)
:String.format("%s@%x=%s//%s%s#%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,state,forMs);
if (getStatus()>=STATUS_SENDING_REQUEST && _sent>0)
s+="sent="+(now-_sent)+"ms";
return s;
}

View File

@ -16,6 +16,7 @@ package org.eclipse.jetty.client;
import org.eclipse.jetty.client.helperClasses.AsyncSslServerAndClientCreator;
import org.eclipse.jetty.client.helperClasses.ServerAndClientCreator;
import org.junit.BeforeClass;
import org.junit.Test;
public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
{
@ -35,6 +36,12 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
{
super.testPerf();
}
@Test
public void testPerf1() throws Exception
{
sender(1,true);
}
}

View File

@ -129,6 +129,7 @@ public class HttpExchangeTest
final CountDownLatch latch = new CountDownLatch(nb);
HttpExchange[] httpExchange = new HttpExchange[nb];
long start = System.currentTimeMillis();
final boolean verbose=false;
for (int i = 0; i < nb; i++)
{
final int n = i;
@ -142,6 +143,8 @@ public class HttpExchangeTest
@Override
protected void onRequestCommitted()
{
if (verbose)
System.err.println("[ ");
result = "committed";
}
@ -149,6 +152,8 @@ public class HttpExchangeTest
@Override
protected void onRequestComplete() throws IOException
{
if (verbose)
System.err.println("[ ==");
result = "sent";
}
@ -156,6 +161,8 @@ public class HttpExchangeTest
/* ------------------------------------------------------------ */
protected void onResponseStatus(Buffer version, int status, Buffer reason)
{
if (verbose)
System.err.println("] "+version+" "+status+" "+reason);
result = "status";
}
@ -163,12 +170,16 @@ public class HttpExchangeTest
@Override
protected void onResponseHeader(Buffer name, Buffer value)
{
if (verbose)
System.err.println("] "+name+": "+value);
}
/* ------------------------------------------------------------ */
@Override
protected void onResponseHeaderComplete() throws IOException
{
if (verbose)
System.err.println("] -");
result = "content";
super.onResponseHeaderComplete();
}
@ -178,18 +189,22 @@ public class HttpExchangeTest
protected void onResponseContent(Buffer content)
{
len += content.length();
if (verbose)
System.err.println("] "+content.length()+" -> "+len);
}
/* ------------------------------------------------------------ */
@Override
protected void onResponseComplete()
{
if (verbose)
System.err.println("] ==");
result = "complete";
if (len == 2009)
latch.countDown();
else
{
System.err.println(n + " ONLY " + len);
System.err.println(n + " ONLY " + len+ "/2009");
}
complete.countDown();
}
@ -198,6 +213,8 @@ public class HttpExchangeTest
@Override
protected void onConnectionFailed(Throwable ex)
{
if (verbose)
System.err.println("] "+ex);
complete.countDown();
result = "failed";
System.err.println(n + " FAILED " + ex);
@ -208,6 +225,8 @@ public class HttpExchangeTest
@Override
protected void onException(Throwable ex)
{
if (verbose)
System.err.println("] "+ex);
complete.countDown();
result = "excepted";
System.err.println(n + " EXCEPTED " + ex);
@ -218,6 +237,8 @@ public class HttpExchangeTest
@Override
protected void onExpire()
{
if (verbose)
System.err.println("] expired");
complete.countDown();
result = "expired";
System.err.println(n + " EXPIRED " + len);
@ -228,7 +249,7 @@ public class HttpExchangeTest
@Override
public String toString()
{
return n+" "+result+" "+len;
return n+"/"+result+"/"+len+"/"+super.toString();
}
};
@ -374,7 +395,50 @@ public class HttpExchangeTest
public void testBigPostWithContentExchange() throws Exception
{
int size =32;
ContentExchange httpExchange=new ContentExchange();
ContentExchange httpExchange=new ContentExchange()
{
@Override
protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
{
System.err.println("] "+version+" "+status+" "+reason);
// TODO Auto-generated method stub
super.onResponseStatus(version,status,reason);
}
@Override
protected synchronized void onResponseHeader(Buffer name, Buffer value) throws IOException
{
System.err.println("] "+name+": "+value);
// TODO Auto-generated method stub
super.onResponseHeader(name,value);
}
@Override
protected synchronized void onResponseContent(Buffer content) throws IOException
{
System.err.println("] "+content.length());
// TODO Auto-generated method stub
super.onResponseContent(content);
}
@Override
protected void onRequestComplete() throws IOException
{
System.err.println("] ==");
// TODO Auto-generated method stub
super.onRequestComplete();
}
@Override
protected void onResponseHeaderComplete() throws IOException
{
System.err.println("] --");
// TODO Auto-generated method stub
super.onResponseHeaderComplete();
}
};
Buffer babuf = new ByteArrayBuffer(size*36*1024);
Buffer niobuf = new DirectNIOBuffer(size*36*1024);
@ -394,7 +458,6 @@ public class HttpExchangeTest
_httpClient.send(httpExchange);
int status = httpExchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED,status);
String result=httpExchange.getResponseContent();
assertEquals(babuf.length(),result.length());
@ -406,9 +469,9 @@ public class HttpExchangeTest
httpExchange.setRequestContent(niobuf);
_httpClient.send(httpExchange);
status = httpExchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED, status);
result=httpExchange.getResponseContent();
assertEquals(niobuf.length(),result.length());
assertEquals(HttpExchange.STATUS_COMPLETED, status);
}
/* ------------------------------------------------------------ */

View File

@ -268,7 +268,7 @@ public class HttpParser implements Parser
{
long filled=fill();
if (filled < 0)
if (filled < 0 || _endp.isInputShutdown())
{
if (_headResponse && _state>STATE_END)
{

View File

@ -569,20 +569,20 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
catch (EofException e)
{
__log.debug("EOF", e);
try{close();}
try{getChannel().close();}
catch(IOException e2){__log.ignore(e2);}
}
catch (IOException e)
{
__log.warn(e.toString());
__log.debug(e);
try{close();}
try{getChannel().close();}
catch(IOException e2){__log.ignore(e2);}
}
catch (Throwable e)
{
__log.warn("handle failed", e);
try{close();}
try{getChannel().close();}
catch(IOException e2){__log.ignore(e2);}
}
dispatched=!undispatch();

View File

@ -330,6 +330,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
if (_debug) LOG.debug("{} received {} sent {}",_session,received,sent);
freeInBuffer();
return (received<0||sent<0)?-1:(received+sent);
}
@ -383,13 +385,15 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
buffer.setPutIndex(bbuf.position());
bbuf.position(0);
}
// return the number of unencrypted bytes filled.
int filled=buffer.length()-size;
if (filled>0)
_handshook=true;
return filled;
}
// return the number of unencrypted bytes filled.
int filled=buffer.length()-size;
if (filled>0)
_handshook=true;
else if (filled==0 && isInputShutdown())
return -1;
return filled;
}
/* ------------------------------------------------------------ */
@ -433,18 +437,30 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
public void flush() throws IOException
{
LOG.debug(_session+" flush");
if (!isOpen())
throw new EofException();
if (isBufferingOutput())
{
int flushed=super.flush(_outNIOBuffer);
if (_debug)
LOG.debug(_session+" flushed "+flushed+" left="+_outNIOBuffer.length());
}
else if (_engine.isOutboundDone() && !super.isOutputShutdown())
else if (_engine.isOutboundDone() && super.isOpen())
{
if (_debug)
LOG.debug(_session+" flush shutdownOutput");
super.shutdownOutput();
try
{
super.shutdownOutput();
}
catch(IOException e)
{
LOG.ignore(e);
}
}
freeOutBuffer();
}
/* ------------------------------------------------------------ */
@ -466,41 +482,21 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
needInBuffer();
ByteBuffer in_buffer=_inNIOBuffer.getByteBuffer();
if (_inNIOBuffer.hasContent())
_inNIOBuffer.compact();
else
_inNIOBuffer.clear();
_inNIOBuffer.compact();
int total_filled=0;
boolean remoteClosed = false;
// loop filling as much encrypted data as we can into the buffer
while (_inNIOBuffer.space()>0 && super.isOpen())
{
try
{
int filled=super.fill(_inNIOBuffer);
if (_debug) LOG.debug(_session+" filled "+filled);
if (filled < 0)
remoteClosed = true;
// break the loop if no progress is made (we have read everything there is to read)
if (filled<=0)
break;
total_filled+=filled;
}
catch(IOException e)
{
if (_inNIOBuffer.length()==0)
{
freeInBuffer();
if (_outNIOBuffer!=null)
{
_outNIOBuffer.clear();
freeOutBuffer();
}
throw e;
}
int filled=super.fill(_inNIOBuffer);
if (_debug) LOG.debug(_session+" filled "+filled);
if (filled < 0)
remoteClosed = true;
// break the loop if no progress is made (we have read everything there is to read)
if (filled<=0)
break;
}
total_filled+=filled;
}
// If we have no progress and no data
@ -521,9 +517,6 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
}
freeInBuffer();
freeOutBuffer();
if (!isOpen())
throw new EofException();
@ -548,7 +541,6 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
catch(SSLException e)
{
LOG.warn(getRemoteAddr() + ":" + getRemotePort() + " " + e);
freeOutBuffer();
super.close();
throw e;
}
@ -557,7 +549,6 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
// reset the buffer so it can be managed by the _inNIOBuffer again.
in_buffer.position(0);
in_buffer.limit(in_buffer.capacity());
freeInBuffer();
}
// handle the unwrap results
@ -650,9 +641,6 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
buffer.skip(len);
consumed-=len;
}
assert consumed==0;
freeOutBuffer();
}
}
}

View File

@ -600,12 +600,12 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
long[] times=new long[10];
for (int i=0;i<times.length;i++)
{
System.err.println("\nBLOCK "+request.getRequestURI()+" "+i);
// System.err.println("\nBLOCK "+request.getRequestURI()+" "+i);
long start=System.currentTimeMillis();
out.write(buf);
long end=System.currentTimeMillis();
times[i]=end-start;
System.err.println("Block "+request.getRequestURI()+" "+i+" "+times[i]);
// System.err.println("Block "+request.getRequestURI()+" "+i+" "+times[i]);
}
out.println();
for (long t : times)

View File

@ -159,17 +159,6 @@ public class SslTruncationAttackTest
Assert.assertTrue("endpoint not closed", endPointClosed.get());
}
/**
* This test is currently failing because we are looping on SslSCEP.unwrap()
* to fill the buffer, so there is a case where we loop once, read some data
* loop again and read -1, but we can't close the connection yet as we have
* to notify the application (not sure that this is necessary... must assume
* the data is truncated, so it's not that safe to pass it to the application).
* This case needs to be revisited, and it also requires a review of the
* Connection:close case, especially on the client side.
* @throws Exception if the test fails
*/
@Ignore
@Test
public void testTruncationAttackBeforeReading() throws Exception
{