Merge remote-tracking branch 'origin/jetty-7' into jetty-8

Conflicts:
	jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
This commit is contained in:
Jan Bartel 2013-02-22 11:32:57 +11:00
commit 6a48749f0c
8 changed files with 169 additions and 18 deletions

View File

@ -25,12 +25,13 @@ import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.Loader;
@ -54,7 +55,7 @@ public class AnnotationParser
{ {
private static final Logger LOG = Log.getLogger(AnnotationParser.class); private static final Logger LOG = Log.getLogger(AnnotationParser.class);
protected List<String> _parsedClassNames = new ArrayList<String>(); protected Set<String> _parsedClassNames = new HashSet<String>();
protected List<Handler> _handlers = new ArrayList<Handler>(); protected List<Handler> _handlers = new ArrayList<Handler>();
public static String normalize (String name) public static String normalize (String name)

View File

@ -0,0 +1,64 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client;
import java.io.IOException;
import java.net.Socket;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
public class ExternalSiteTest
{
@Test
public void testExternalSSLSite() throws Exception
{
HttpClient client = new HttpClient(new SslContextFactory());
client.start();
String host = "api-3t.paypal.com";
int port = 443;
// Verify that we have connectivity
try
{
new Socket(host, port).close();
}
catch (IOException x)
{
Assume.assumeNoException(x);
}
ContentExchange exchange = new ContentExchange(true);
exchange.setScheme(HttpSchemes.HTTPS_BUFFER);
exchange.setAddress(new Address(host, port));
exchange.setRequestURI("/nvp");
client.send(exchange);
int done = exchange.waitForDone();
Assert.assertEquals(HttpExchange.STATUS_COMPLETED, done);
Assert.assertEquals(HttpStatus.OK_200, exchange.getResponseStatus());
Assert.assertNotNull(exchange.getResponseContentBytes());
client.stop();
}
}

View File

@ -18,8 +18,6 @@
package org.eclipse.jetty.client; package org.eclipse.jetty.client;
import static org.hamcrest.Matchers.*;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
@ -39,7 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
@ -72,6 +69,11 @@ import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.not;
public class SslBytesServerTest extends SslBytesTest public class SslBytesServerTest extends SslBytesTest
{ {
private final AtomicInteger sslHandles = new AtomicInteger(); private final AtomicInteger sslHandles = new AtomicInteger();
@ -847,7 +849,9 @@ public class SslBytesServerTest extends SslBytesTest
// Close the raw socket, this generates a truncation attack // Close the raw socket, this generates a truncation attack
proxy.flushToServer((TLSRecord)null); proxy.flushToServer((TLSRecord)null);
// Expect raw close from server // Expect alert + raw close from server
record = proxy.readFromServer();
Assert.assertEquals(TLSRecord.Type.ALERT, record.getType());
record = proxy.readFromServer(); record = proxy.readFromServer();
Assert.assertNull(String.valueOf(record), record); Assert.assertNull(String.valueOf(record), record);
proxy.flushToClient(record); proxy.flushToClient(record);
@ -1631,9 +1635,9 @@ public class SslBytesServerTest extends SslBytesTest
//System.err.println(((Dumpable)server.getConnectors()[0]).dump()); //System.err.println(((Dumpable)server.getConnectors()[0]).dump());
Assert.assertThat(((Dumpable)server.getConnectors()[0]).dump(),containsString("SCEP@")); Assert.assertThat(((Dumpable)server.getConnectors()[0]).dump(),containsString("SCEP@"));
completeClose(client); completeClose(client);
TimeUnit.MILLISECONDS.sleep(200); TimeUnit.MILLISECONDS.sleep(200);
//System.err.println(((Dumpable)server.getConnectors()[0]).dump()); //System.err.println(((Dumpable)server.getConnectors()[0]).dump());
Assert.assertThat(((Dumpable)server.getConnectors()[0]).dump(),not(containsString("SCEP@"))); Assert.assertThat(((Dumpable)server.getConnectors()[0]).dump(),not(containsString("SCEP@")));
@ -1748,13 +1752,13 @@ public class SslBytesServerTest extends SslBytesTest
// Close Alert // Close Alert
record = proxy.readFromServer(); record = proxy.readFromServer();
proxy.flushToClient(record); proxy.flushToClient(record);
// Socket close // Socket close
record = proxy.readFromServer(); record = proxy.readFromServer();
Assert.assertNull(String.valueOf(record), record); Assert.assertNull(String.valueOf(record), record);
proxy.flushToClient(record); proxy.flushToClient(record);
} }
private void completeClose(SSLSocket client) throws Exception private void completeClose(SSLSocket client) throws Exception
{ {
client.close(); client.close();
@ -1770,6 +1774,6 @@ public class SslBytesServerTest extends SslBytesTest
// Close Alert // Close Alert
record = proxy.readFromServer(); record = proxy.readFromServer();
proxy.flushToClient(record); proxy.flushToClient(record);
} }
} }

View File

@ -225,8 +225,8 @@ public class HttpParser implements Parser
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** /**
* Parse until END state. * Parse until END state.
* This method will parse any remaining content in the current buffer. It does not care about the * This method will parse any remaining content in the current buffer as long as there is
* {@link #getState current state} of the parser. * no unconsumed content. It does not care about the {@link #getState current state} of the parser.
* @see #parse * @see #parse
* @see #parseNext * @see #parseNext
*/ */
@ -235,7 +235,7 @@ public class HttpParser implements Parser
boolean progress=parseNext()>0; boolean progress=parseNext()>0;
// continue parsing // continue parsing
while (!isComplete() && _buffer!=null && _buffer.length()>0) while (!isComplete() && _buffer!=null && _buffer.length()>0 && !_contentView.hasContent())
{ {
progress |= parseNext()>0; progress |= parseNext()>0;
} }

View File

@ -406,7 +406,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
// pass on ishut/oshut state // pass on ishut/oshut state
if (_endp.isOpen() && _endp.isInputShutdown() && !_inbound.hasContent()) if (_endp.isOpen() && _endp.isInputShutdown() && !_inbound.hasContent())
_engine.closeInbound(); closeInbound();
if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasContent()) if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasContent())
_endp.shutdownOutput(); _endp.shutdownOutput();
@ -428,6 +428,18 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
return some_progress; return some_progress;
} }
private void closeInbound()
{
try
{
_engine.closeInbound();
}
catch (SSLException x)
{
_logger.debug(x);
}
}
private synchronized boolean wrap(final Buffer buffer) throws IOException private synchronized boolean wrap(final Buffer buffer) throws IOException
{ {
ByteBuffer bbuf=extractByteBuffer(buffer); ByteBuffer bbuf=extractByteBuffer(buffer);

View File

@ -26,6 +26,7 @@ import java.nio.channels.SocketChannel;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
@ -188,12 +189,28 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
Assert.assertEquals("HelloWorld",reply); Assert.assertEquals("HelloWorld",reply);
SelectorManager.LOG.info("javax.net.ssl.SSLException: Inbound closed... is expected soon"); if (debug) System.err.println("Shutting down output");
if (debug) System.err.println("\nSudden Death");
client.socket().shutdownOutput(); client.socket().shutdownOutput();
filled=client.read(sslIn); filled=client.read(sslIn);
Assert.assertEquals(-1,filled); if (debug) System.err.println("in="+filled);
sslIn.flip();
try
{
// Since the client closed abruptly, the server is sending a close alert with a failure
engine.unwrap(sslIn, appIn);
Assert.fail();
}
catch (SSLException x)
{
// Expected
}
sslIn.clear();
filled = client.read(sslIn);
Assert.assertEquals(-1, filled);
Assert.assertFalse(server.isOpen());
} }
@Test @Test

View File

@ -581,6 +581,12 @@ public class ProxyServlet implements Servlet
String hdr = (String)enm.nextElement(); String hdr = (String)enm.nextElement();
String lhdr = hdr.toLowerCase(Locale.ENGLISH); String lhdr = hdr.toLowerCase(Locale.ENGLISH);
if ("transfer-encoding".equals(lhdr))
{
if (request.getHeader("transfer-encoding").indexOf("chunk")>=0)
hasContent = true;
}
if (_DontProxyHeaders.contains(lhdr)) if (_DontProxyHeaders.contains(lhdr))
continue; continue;
if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0) if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0)

View File

@ -32,6 +32,8 @@ import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.hamcrest.core.Is; import org.hamcrest.core.Is;
import org.hamcrest.core.IsEqual; import org.hamcrest.core.IsEqual;
import org.junit.After; import org.junit.After;
@ -44,6 +46,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.Socket;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -239,4 +242,48 @@ public class ProxyServletTest
exchange.waitForDone(); exchange.waitForDone();
assertThat(excepted.get(),equalTo(true)); assertThat(excepted.get(),equalTo(true));
} }
@Test
public void testChunkedPut() throws Exception
{
init(new HttpServlet()
{
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/plain");
String message=IO.toString(req.getInputStream());
resp.getOutputStream().print(message);
}
});
Socket client = new Socket("localhost",_connector.getLocalPort());
client.setSoTimeout(1000000);
client.getOutputStream().write((
"PUT /proxy/test HTTP/1.1\r\n"+
"Host: localhost:"+_connector.getLocalPort()+"\r\n"+
"Transfer-Encoding: chunked\r\n"+
"Connection: close\r\n"+
"\r\n"+
"A\r\n"+
"0123456789\r\n"+
"9\r\n"+
"ABCDEFGHI\r\n"+
"8\r\n"+
"JKLMNOPQ\r\n"+
"7\r\n"+
"RSTUVWX\r\n"+
"2\r\n"+
"YZ\r\n"+
"0\r\n"
).getBytes(StringUtil.__ISO_8859_1_CHARSET));
String response=IO.toString(client.getInputStream());
Assert.assertTrue(response.contains("200 OK"));
Assert.assertTrue(response.contains("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
}
} }