jetty-9: HTTP client: improvements.
Request now supports opaque attributes. ContentResponse supports a contentAsString() method, along with BufferingResponseListener.
This commit is contained in:
parent
1b0499b91c
commit
d742578353
|
@ -78,7 +78,7 @@ public class AuthenticationProtocolHandler implements ProtocolHandler
|
|||
public void onComplete(Result result)
|
||||
{
|
||||
Request request = result.getRequest();
|
||||
ContentResponse response = new HttpContentResponse(result.getResponse(), getContent());
|
||||
ContentResponse response = new HttpContentResponse(result.getResponse(), getContent(), getEncoding());
|
||||
if (result.isFailed())
|
||||
{
|
||||
Throwable failure = result.getFailure();
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
|
@ -27,11 +30,13 @@ public class HttpContentResponse implements ContentResponse
|
|||
{
|
||||
private final Response response;
|
||||
private final byte[] content;
|
||||
private final String encoding;
|
||||
|
||||
public HttpContentResponse(Response response, byte[] content)
|
||||
public HttpContentResponse(Response response, byte[] content, String encoding)
|
||||
{
|
||||
this.response = response;
|
||||
this.content = content;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,4 +80,18 @@ public class HttpContentResponse implements ContentResponse
|
|||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String contentAsString()
|
||||
{
|
||||
String encoding = this.encoding;
|
||||
try
|
||||
{
|
||||
return new String(content(), encoding == null ? "UTF-8" : encoding);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new UnsupportedCharsetException(encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.net.URI;
|
|||
import java.net.URLDecoder;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
|
@ -45,6 +47,7 @@ public class HttpRequest implements Request
|
|||
|
||||
private final HttpFields headers = new HttpFields();
|
||||
private final Fields params = new Fields();
|
||||
private final Map<String, Object> attributes = new HashMap<>();
|
||||
private final HttpClient client;
|
||||
private final long id;
|
||||
private final String host;
|
||||
|
@ -215,6 +218,19 @@ public class HttpRequest implements Request
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request attribute(String name, Object value)
|
||||
{
|
||||
attributes.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> attributes()
|
||||
{
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpFields headers()
|
||||
{
|
||||
|
|
|
@ -27,4 +27,10 @@ public interface ContentResponse extends Response
|
|||
* @return the response content
|
||||
*/
|
||||
byte[] content();
|
||||
|
||||
/**
|
||||
* @return the response content as a string, decoding the bytes using the charset
|
||||
* provided by the {@code Content-Type} header, if any, or UTF-8.
|
||||
*/
|
||||
String contentAsString();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.client.api;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
|
@ -128,6 +129,18 @@ public interface Request
|
|||
*/
|
||||
Request header(String name, String value);
|
||||
|
||||
/**
|
||||
* @param name the name of the attribute
|
||||
* @param value the value of the attribute
|
||||
* @return this request object
|
||||
*/
|
||||
Request attribute(String name, Object value);
|
||||
|
||||
/**
|
||||
* @return the attributes of this request
|
||||
*/
|
||||
Map<String, Object> attributes();
|
||||
|
||||
/**
|
||||
* @return the content provider of this request
|
||||
*/
|
||||
|
|
|
@ -66,7 +66,7 @@ public class BlockingResponseListener extends BufferingResponseListener implemen
|
|||
public void onComplete(Result result)
|
||||
{
|
||||
super.onComplete(result);
|
||||
response = new HttpContentResponse(result.getResponse(), getContent());
|
||||
response = new HttpContentResponse(result.getResponse(), getContent(), getEncoding());
|
||||
failure = result.getFailure();
|
||||
latch.countDown();
|
||||
}
|
||||
|
|
|
@ -23,22 +23,65 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
||||
/**
|
||||
* <p>Implementation of {@link Response.Listener} that buffers the content up to a maximum length
|
||||
* specified to the constructors.</p>
|
||||
* <p>The content may be retrieved from {@link #onSuccess(Response)} or {@link #onComplete(Result)}
|
||||
* via {@link #getContent()} or {@link #getContentAsString()}.</p>
|
||||
*/
|
||||
public class BufferingResponseListener extends Response.Listener.Empty
|
||||
{
|
||||
private final int maxLength;
|
||||
private volatile byte[] buffer = new byte[0];
|
||||
private volatile String encoding;
|
||||
|
||||
/**
|
||||
* Creates an instance with a default maximum length of 2 MiB.
|
||||
*/
|
||||
public BufferingResponseListener()
|
||||
{
|
||||
this(2 * 1024 * 1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given maximum length
|
||||
*
|
||||
* @param maxLength the maximum length of the content
|
||||
*/
|
||||
public BufferingResponseListener(int maxLength)
|
||||
{
|
||||
this.maxLength = maxLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeaders(Response response)
|
||||
{
|
||||
HttpFields headers = response.headers();
|
||||
long length = headers.getLongField(HttpHeader.CONTENT_LENGTH.asString());
|
||||
if (length > maxLength)
|
||||
response.abort();
|
||||
|
||||
String contentType = headers.get(HttpHeader.CONTENT_TYPE);
|
||||
if (contentType != null)
|
||||
{
|
||||
String charset = "charset=";
|
||||
int index = contentType.toLowerCase().indexOf(charset);
|
||||
if (index > 0)
|
||||
{
|
||||
String encoding = contentType.substring(index + charset.length());
|
||||
// Sometimes charsets arrive with an ending semicolon
|
||||
index = encoding.indexOf(';');
|
||||
if (index > 0)
|
||||
encoding = encoding.substring(0, index);
|
||||
this.encoding = encoding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContent(Response response, ByteBuffer content)
|
||||
{
|
||||
|
@ -52,12 +95,39 @@ public class BufferingResponseListener extends Response.Listener.Empty
|
|||
buffer = newBuffer;
|
||||
}
|
||||
|
||||
public String getEncoding()
|
||||
{
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the content as bytes
|
||||
* @see #getContentAsString()
|
||||
*/
|
||||
public byte[] getContent()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public String getContent(String encoding)
|
||||
/**
|
||||
* @return the content as a string, using the "Content-Type" header to detect the encoding
|
||||
* or defaulting to UTF-8 if the encoding could not be detected.
|
||||
* @see #getContentAsString(String)
|
||||
*/
|
||||
public String getContentAsString()
|
||||
{
|
||||
String encoding = this.encoding;
|
||||
if (encoding == null)
|
||||
encoding = "UTF-8";
|
||||
return getContentAsString(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param encoding the encoding of the content bytes
|
||||
* @return the content as a string, with the specified encoding
|
||||
* @see #getContentAsString()
|
||||
*/
|
||||
public String getContentAsString(String encoding)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -128,7 +128,7 @@ public class HttpReceiverTest
|
|||
Assert.assertNotNull(headers);
|
||||
Assert.assertEquals(1, headers.size());
|
||||
Assert.assertEquals(String.valueOf(content.length()), headers.get(HttpHeader.CONTENT_LENGTH));
|
||||
String received = listener.getContent("UTF-8");
|
||||
String received = listener.getContentAsString("UTF-8");
|
||||
Assert.assertEquals(content, received);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue