Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.

This commit is contained in:
Simone Bordet 2020-03-25 15:22:07 +01:00
commit 528d608860
2 changed files with 100 additions and 39 deletions

View File

@ -134,6 +134,7 @@ public class Response implements HttpServletResponse
_out.recycle();
_fields.clear();
_encodingFrom = EncodingFrom.NOT_SET;
_trailers = null;
}
public HttpOutput getHttpOutput()
@ -1113,6 +1114,7 @@ public class Response implements HttpServletResponse
_mimeType = null;
_characterEncoding = null;
_encodingFrom = EncodingFrom.NOT_SET;
_trailers = null;
// Clear all response headers
_fields.clear();
@ -1208,26 +1210,31 @@ public class Response implements HttpServletResponse
_out.reopen();
}
@Override
public void setTrailerFields(Supplier<Map<String, String>> trailers)
{
// TODO new for 4.0 - avoid transient supplier?
this._trailers = new HttpFieldsSupplier(trailers);
}
public Supplier<HttpFields> getTrailers()
{
return _trailers;
}
public void setTrailers(Supplier<HttpFields> trailers)
{
_trailers = trailers;
}
@Override
public Supplier<Map<String, String>> getTrailerFields()
{
if (_trailers instanceof HttpFieldsSupplier)
((HttpFieldsSupplier)_trailers).getSupplier();
return ((HttpFieldsSupplier)_trailers).getSupplier();
return null;
}
@Override
public void setTrailerFields(Supplier<Map<String, String>> trailers)
{
// TODO new for 4.0 - avoid transient supplier?
this._trailers = new HttpFieldsSupplier(trailers);
}
protected MetaData.Response newResponseMetaData()
{
MetaData.Response info = new MetaData.Response(_channel.getRequest().getHttpVersion(), getStatus(), getReason(), _fields, getLongContentLength());

View File

@ -23,7 +23,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import javax.servlet.ServletInputStream;
@ -41,7 +43,6 @@ import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@ -51,6 +52,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class HttpTrailersTest extends AbstractTest<TransportScenario>
{
@ -81,13 +83,11 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
{
String trailerName = "Trailer";
String trailerValue = "value";
scenario.start(new AbstractHandler()
scenario.start(new EmptyServerHandler()
{
@Override
public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
jettyRequest.setHandled(true);
// Read the content first.
ServletInputStream input = jettyRequest.getInputStream();
while (true)
@ -120,13 +120,11 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
public void testEmptyRequestTrailers(Transport transport) throws Exception
{
init(transport);
scenario.start(new AbstractHandler()
scenario.start(new EmptyServerHandler()
{
@Override
public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
jettyRequest.setHandled(true);
// Read the content first.
ServletInputStream input = jettyRequest.getInputStream();
while (true)
@ -167,21 +165,22 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
private void testResponseTrailers(byte[] content) throws Exception
{
AtomicBoolean once = new AtomicBoolean();
String trailerName = "Trailer";
String trailerValue = "value";
scenario.start(new AbstractHandler()
scenario.start(new EmptyServerHandler()
{
@Override
public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
jettyRequest.setHandled(true);
Response jettyResponse = jettyRequest.getResponse();
if (once.compareAndSet(false, true))
{
HttpFields trailers = new HttpFields();
trailers.put(trailerName, trailerValue);
Response jettyResponse = (Response)response;
jettyResponse.setTrailerFields(() ->
trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue)));
jettyResponse.setTrailers(() -> trailers);
}
if (content != null)
response.getOutputStream().write(content);
@ -209,6 +208,26 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
.send();
assertEquals(HttpStatus.OK_200, response.getStatus());
assertNull(failure.get());
// Subsequent requests should not have trailers.
response = scenario.client.newRequest(scenario.newURI())
.onResponseSuccess(r ->
{
try
{
HttpResponse httpResponse = (HttpResponse)r;
assertNull(httpResponse.getTrailers());
failure.set(null);
}
catch (Throwable x)
{
failure.set(x);
}
})
.timeout(5, TimeUnit.SECONDS)
.send();
assertEquals(HttpStatus.OK_200, response.getStatus());
assertNull(failure.get());
}
@ParameterizedTest
@ -216,17 +235,13 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
public void testEmptyResponseTrailers(Transport transport) throws Exception
{
init(transport);
scenario.start(new AbstractHandler()
scenario.start(new EmptyServerHandler()
{
@Override
public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
{
jettyRequest.setHandled(true);
HttpFields trailers = new HttpFields();
Response jettyResponse = (Response)response;
jettyResponse.setTrailerFields(() ->
response.setTrailerFields(() ->
trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue)));
}
});
@ -262,18 +277,15 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
String trailerName = "Trailer";
String trailerValue = "value";
init(transport);
scenario.start(new AbstractHandler()
scenario.start(new EmptyServerHandler()
{
@Override
public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
jettyRequest.setHandled(true);
HttpFields trailers = new HttpFields();
trailers.put(trailerName, trailerValue);
Response jettyResponse = (Response)response;
jettyResponse.setTrailerFields(() ->
response.setTrailerFields(() ->
trailers.stream().collect(Collectors.toMap(HttpField::getName, HttpField::getValue)));
// Write a large content
@ -309,4 +321,46 @@ public class HttpTrailersTest extends AbstractTest<TransportScenario>
assertNotNull(trailers);
assertEquals(trailerValue, trailers.get(trailerName));
}
@ParameterizedTest
@ArgumentsSource(TransportProvider.class)
public void testResponseResetAlsoResetsTrailers(Transport transport) throws Exception
{
init(transport);
scenario.start(new EmptyServerHandler()
{
@Override
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
Response jettyResponse = jettyRequest.getResponse();
HttpFields trailers = new HttpFields();
trailers.put("name", "value");
jettyResponse.setTrailers(() -> trailers);
// Fill some other response field.
response.setHeader("name", "value");
response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
response.getWriter();
// Reset the response.
response.reset();
// Must not throw because we have called
// getWriter() above, since we have reset().
response.getOutputStream();
}
});
CountDownLatch latch = new CountDownLatch(1);
scenario.client.newRequest(scenario.newURI())
.timeout(5, TimeUnit.SECONDS)
.send(result ->
{
HttpResponse response = (HttpResponse)result.getResponse();
assertEquals(HttpStatus.OK_200, response.getStatus());
assertNull(response.getTrailers());
assertNull(response.getHeaders().get("name"));
latch.countDown();
});
assertTrue(latch.await(5, TimeUnit.SECONDS));
}
}