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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isNoContent()
|
||||
{
|
||||
return _noContent;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setPersistent(boolean persistent)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue