//
// ========================================================================
// Copyright (c) 1995-2017 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.http.client;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.HttpResponse;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.http.HttpFields;
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.Assert;
import org.junit.Test;
public class HttpTrailersTest extends AbstractTest
{
public HttpTrailersTest(Transport transport)
{
super(transport == Transport.FCGI ? null : transport);
}
@Test
public void testRequestTrailersNoContent() throws Exception
{
testRequestTrailers(null);
}
@Test
public void testRequestTrailersWithContent() throws Exception
{
testRequestTrailers("abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.UTF_8));
}
private void testRequestTrailers(byte[] content) throws Exception
{
String trailerName = "Trailer";
String trailerValue = "value";
start(new AbstractHandler.ErrorDispatchHandler()
{
@Override
protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
jettyRequest.setHandled(true);
// Read the content first.
ServletInputStream input = jettyRequest.getInputStream();
while (true)
{
int read = input.read();
if (read < 0)
break;
}
// Now the trailers can be accessed.
HttpFields trailers = jettyRequest.getTrailerHttpFields();
Assert.assertNotNull(trailers);
Assert.assertEquals(trailerValue, trailers.get(trailerName));
}
});
HttpFields trailers = new HttpFields();
trailers.put(trailerName, trailerValue);
HttpRequest request = (HttpRequest)client.newRequest(newURI());
request = request.trailers(() -> trailers);
if (content != null)
request.method(HttpMethod.POST).content(new BytesContentProvider(content));
ContentResponse response = request.timeout(5, TimeUnit.SECONDS).send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testEmptyRequestTrailers() throws Exception
{
start(new AbstractHandler.ErrorDispatchHandler()
{
@Override
protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
jettyRequest.setHandled(true);
// Read the content first.
ServletInputStream input = jettyRequest.getInputStream();
while (true)
{
int read = input.read();
if (read < 0)
break;
}
// Now the trailers can be accessed.
HttpFields trailers = jettyRequest.getTrailerHttpFields();
Assert.assertNull(trailers);
}
});
HttpFields trailers = new HttpFields();
HttpRequest request = (HttpRequest)client.newRequest(newURI());
request = request.trailers(() -> trailers);
ContentResponse response = request.timeout(5, TimeUnit.SECONDS).send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testResponseTrailersNoContent() throws Exception
{
testResponseTrailers(null);
}
@Test
public void testResponseTrailersWithContent() throws Exception
{
testResponseTrailers("abcdefghijklmnopqrstuvwxyz".getBytes(StandardCharsets.UTF_8));
}
private void testResponseTrailers(byte[] content) throws Exception
{
String trailerName = "Trailer";
String trailerValue = "value";
start(new AbstractHandler.ErrorDispatchHandler()
{
@Override
protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
jettyRequest.setHandled(true);
HttpFields trailers = new HttpFields();
trailers.put(trailerName, trailerValue);
Response jettyResponse = (Response)response;
jettyResponse.setTrailerHttpFields(() -> trailers);
if (content != null)
response.getOutputStream().write(content);
}
});
AtomicReference<Throwable> failure = new AtomicReference<>(new Throwable("no_success"));
ContentResponse response = client.newRequest(newURI())
.onResponseSuccess(r ->
{
try
{
HttpResponse httpResponse = (HttpResponse)r;
HttpFields trailers = httpResponse.getTrailers();
Assert.assertNotNull(trailers);
Assert.assertEquals(trailerValue, trailers.get(trailerName));
failure.set(null);
}
catch (Throwable x)
{
failure.set(x);
}
})
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
Assert.assertNull(failure.get());
}
@Test
public void testEmptyResponseTrailers() throws Exception
{
start(new AbstractHandler.ErrorDispatchHandler()
{
@Override
protected void doNonErrorHandle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
jettyRequest.setHandled(true);
HttpFields trailers = new HttpFields();
Response jettyResponse = (Response)response;
jettyResponse.setTrailerHttpFields(() -> trailers);
}
});
AtomicReference<Throwable> failure = new AtomicReference<>(new Throwable("no_success"));
ContentResponse response = client.newRequest(newURI())
.onResponseSuccess(r ->
{
try
{
HttpResponse httpResponse = (HttpResponse)r;
HttpFields trailers = httpResponse.getTrailers();
Assert.assertNull(trailers);
failure.set(null);
}
catch (Throwable x)
{
failure.set(x);
}
})
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
Assert.assertNull(failure.get());
}
}