Merge remote-tracking branch 'origin/jetty-9.2.x'

This commit is contained in:
Greg Wilkins 2014-10-10 14:20:30 +11:00
commit bb2d77f00b
7 changed files with 90 additions and 4 deletions

View File

@ -157,6 +157,12 @@ public class HttpGenerator
return _endOfContent==EndOfContent.CHUNKED_CONTENT;
}
/* ------------------------------------------------------------ */
public boolean isNoContent()
{
return _noContent;
}
/* ------------------------------------------------------------ */
public void setPersistent(boolean persistent)
{

View File

@ -72,7 +72,40 @@ public class HttpGeneratorServerTest
assertThat(response, containsString("Content-Length: 10"));
assertThat(response, containsString("\r\n0123456789"));
}
@Test
public void test204() throws Exception
{
ByteBuffer header = BufferUtil.allocate(8096);
ByteBuffer content = BufferUtil.toBuffer("0123456789");
HttpGenerator gen = new HttpGenerator();
ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), 10, 204, "Foo", false);
info.getHttpFields().add("Content-Type", "test/data");
info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970);
HttpGenerator.Result result = gen.generateResponse(info, header, null, content, true);
assertEquals(gen.isNoContent(), true);
assertEquals(HttpGenerator.Result.FLUSH, result);
assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
String responseheaders = BufferUtil.toString(header);
BufferUtil.clear(header);
result = gen.generateResponse(null, null, null, content, false);
assertEquals(HttpGenerator.Result.DONE, result);
assertEquals(HttpGenerator.State.END, gen.getState());
assertThat(responseheaders, containsString("HTTP/1.1 204 Foo"));
assertThat(responseheaders, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT"));
assertThat(responseheaders, not(containsString("Content-Length: 10")));
//Note: the HttpConnection.process() method is responsible for actually
//excluding the content from the response based on generator.isNoContent()==true
}
@Test
public void testComplexChars() throws Exception
{

View File

@ -537,8 +537,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
}
case FLUSH:
{
// Don't write the chunk or the content if this is a HEAD response
if (_channel.getRequest().isHead())
// Don't write the chunk or the content if this is a HEAD response, or any other type of response that should have no content
if (_channel.getRequest().isHead() || _generator.isNoContent())
{
BufferUtil.clear(chunk);
BufferUtil.clear(_content);

View File

@ -388,7 +388,7 @@ public class Request implements HttpServletRequest
public AsyncContext getAsyncContext()
{
HttpChannelState state = getHttpChannelState();
if (_async==null || state.isInitial() && !state.isAsync())
if (_async==null || !state.isAsyncStarted())
throw new IllegalStateException(state.getStatusString());
return _async;

View File

@ -583,6 +583,17 @@ public class AsyncServletTest
@Override
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
{
// this should always fail at this point
try
{
request.getAsyncContext();
throw new IllegalStateException();
}
catch(IllegalStateException e)
{
// ignored
}
// System.err.println(request.getDispatcherType()+" "+request.getRequestURI());
response.addHeader("history",request.getDispatcherType()+" "+request.getRequestURI());
if (request instanceof ServletRequestWrapper || response instanceof ServletResponseWrapper)

View File

@ -35,6 +35,8 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -68,7 +70,7 @@ import org.eclipse.jetty.util.log.Logger;
* minutes</li>
* <li><b>allowCredentials</b>, a boolean indicating if the resource allows
* requests with credentials. Default value is <b>false</b></li>
* <li><b>exposeHeaders</b>, a comma separated list of HTTP headers that
* <li><b>exposedHeaders</b>, a comma separated list of HTTP headers that
* are allowed to be exposed on the client. Default value is the
* <b>empty list</b></li>
* <li><b>chainPreflight</b>, if true preflight requests are chained to their
@ -339,6 +341,9 @@ public class CrossOriginFilter implements Filter
private void handleSimpleResponse(HttpServletRequest request, HttpServletResponse response, String origin)
{
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
//W3C CORS spec http://www.w3.org/TR/cors/#resource-implementation
if (!anyOriginAllowed)
response.addHeader("Vary", ORIGIN_HEADER);
if (allowCredentials)
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
if (!exposedHeaders.isEmpty())
@ -354,6 +359,9 @@ public class CrossOriginFilter implements Filter
if (!headersAllowed)
return;
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
//W3C CORS spec http://www.w3.org/TR/cors/#resource-implementation
if (!anyOriginAllowed)
response.addHeader("Vary", ORIGIN_HEADER);
if (allowCredentials)
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
if (preflightMaxAge > 0)

View File

@ -97,6 +97,30 @@ public class CrossOriginFilterTest
Assert.assertFalse(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@Test
public void testSimpleRequestWithWildcardOrigin() throws Exception
{
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
tester.getContext().addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
CountDownLatch latch = new CountDownLatch(1);
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
String origin = "http://foo.example.com";
String request = "" +
"GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n" +
"Origin: "+origin+"\r\n" +
"\r\n";
String response = tester.getResponses(request);
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(!response.contains("Vary"));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@Test
public void testSimpleRequestWithMatchingWildcardOrigin() throws Exception
@ -119,6 +143,7 @@ public class CrossOriginFilterTest
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(response.contains("Vary"));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@ -143,6 +168,7 @@ public class CrossOriginFilterTest
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(response.contains("Vary"));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@ -167,6 +193,7 @@ public class CrossOriginFilterTest
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(response.contains("Vary"));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@ -193,6 +220,7 @@ public class CrossOriginFilterTest
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(response.contains("Vary"));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}