Merge remote-tracking branch 'origin/jetty-9.2.x'
This commit is contained in:
commit
bb2d77f00b
|
@ -157,6 +157,12 @@ public class HttpGenerator
|
||||||
return _endOfContent==EndOfContent.CHUNKED_CONTENT;
|
return _endOfContent==EndOfContent.CHUNKED_CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public boolean isNoContent()
|
||||||
|
{
|
||||||
|
return _noContent;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public void setPersistent(boolean persistent)
|
public void setPersistent(boolean persistent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,7 +72,40 @@ public class HttpGeneratorServerTest
|
||||||
assertThat(response, containsString("Content-Length: 10"));
|
assertThat(response, containsString("Content-Length: 10"));
|
||||||
assertThat(response, containsString("\r\n0123456789"));
|
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
|
@Test
|
||||||
public void testComplexChars() throws Exception
|
public void testComplexChars() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -537,8 +537,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
|
||||||
}
|
}
|
||||||
case FLUSH:
|
case FLUSH:
|
||||||
{
|
{
|
||||||
// Don't write the chunk or the content if this is a HEAD response
|
// 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())
|
if (_channel.getRequest().isHead() || _generator.isNoContent())
|
||||||
{
|
{
|
||||||
BufferUtil.clear(chunk);
|
BufferUtil.clear(chunk);
|
||||||
BufferUtil.clear(_content);
|
BufferUtil.clear(_content);
|
||||||
|
|
|
@ -388,7 +388,7 @@ public class Request implements HttpServletRequest
|
||||||
public AsyncContext getAsyncContext()
|
public AsyncContext getAsyncContext()
|
||||||
{
|
{
|
||||||
HttpChannelState state = getHttpChannelState();
|
HttpChannelState state = getHttpChannelState();
|
||||||
if (_async==null || state.isInitial() && !state.isAsync())
|
if (_async==null || !state.isAsyncStarted())
|
||||||
throw new IllegalStateException(state.getStatusString());
|
throw new IllegalStateException(state.getStatusString());
|
||||||
|
|
||||||
return _async;
|
return _async;
|
||||||
|
|
|
@ -583,6 +583,17 @@ public class AsyncServletTest
|
||||||
@Override
|
@Override
|
||||||
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
|
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());
|
// System.err.println(request.getDispatcherType()+" "+request.getRequestURI());
|
||||||
response.addHeader("history",request.getDispatcherType()+" "+request.getRequestURI());
|
response.addHeader("history",request.getDispatcherType()+" "+request.getRequestURI());
|
||||||
if (request instanceof ServletRequestWrapper || response instanceof ServletResponseWrapper)
|
if (request instanceof ServletRequestWrapper || response instanceof ServletResponseWrapper)
|
||||||
|
|
|
@ -35,6 +35,8 @@ import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
@ -68,7 +70,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
* minutes</li>
|
* minutes</li>
|
||||||
* <li><b>allowCredentials</b>, a boolean indicating if the resource allows
|
* <li><b>allowCredentials</b>, a boolean indicating if the resource allows
|
||||||
* requests with credentials. Default value is <b>false</b></li>
|
* 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
|
* are allowed to be exposed on the client. Default value is the
|
||||||
* <b>empty list</b></li>
|
* <b>empty list</b></li>
|
||||||
* <li><b>chainPreflight</b>, if true preflight requests are chained to their
|
* <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)
|
private void handleSimpleResponse(HttpServletRequest request, HttpServletResponse response, String origin)
|
||||||
{
|
{
|
||||||
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, 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)
|
if (allowCredentials)
|
||||||
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
|
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
|
||||||
if (!exposedHeaders.isEmpty())
|
if (!exposedHeaders.isEmpty())
|
||||||
|
@ -354,6 +359,9 @@ public class CrossOriginFilter implements Filter
|
||||||
if (!headersAllowed)
|
if (!headersAllowed)
|
||||||
return;
|
return;
|
||||||
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, 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)
|
if (allowCredentials)
|
||||||
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
|
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
|
||||||
if (preflightMaxAge > 0)
|
if (preflightMaxAge > 0)
|
||||||
|
|
|
@ -97,6 +97,30 @@ public class CrossOriginFilterTest
|
||||||
Assert.assertFalse(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
Assert.assertFalse(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
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
|
@Test
|
||||||
public void testSimpleRequestWithMatchingWildcardOrigin() throws Exception
|
public void testSimpleRequestWithMatchingWildcardOrigin() throws Exception
|
||||||
|
@ -119,6 +143,7 @@ public class CrossOriginFilterTest
|
||||||
Assert.assertTrue(response.contains("HTTP/1.1 200"));
|
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_ORIGIN_HEADER));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||||
|
Assert.assertTrue(response.contains("Vary"));
|
||||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
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("HTTP/1.1 200"));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||||
|
Assert.assertTrue(response.contains("Vary"));
|
||||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
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("HTTP/1.1 200"));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||||
|
Assert.assertTrue(response.contains("Vary"));
|
||||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
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("HTTP/1.1 200"));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
|
||||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
|
||||||
|
Assert.assertTrue(response.contains("Vary"));
|
||||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue