420368 - Default content types for ContentProviders.

Introduced ContentProvider.Typed to specify a content type along with
the content.
This commit is contained in:
Simone Bordet 2014-05-14 23:29:40 +02:00
parent e0e00b0aed
commit bf7ab5d326
8 changed files with 94 additions and 11 deletions

View File

@ -110,6 +110,15 @@ public abstract class HttpConnection implements Connection
// Add content headers // Add content headers
if (content != null) if (content != null)
{ {
if (content instanceof ContentProvider.Typed)
{
if (!headers.containsKey(HttpHeader.CONTENT_TYPE.asString()))
{
String contentType = ((ContentProvider.Typed)content).getContentType();
if (contentType != null)
headers.put(HttpHeader.CONTENT_TYPE, contentType);
}
}
long contentLength = content.getLength(); long contentLength = content.getLength();
if (contentLength >= 0) if (contentLength >= 0)
{ {

View File

@ -549,9 +549,7 @@ public class HttpRequest implements Request
@Override @Override
public Request file(Path file, String contentType) throws IOException public Request file(Path file, String contentType) throws IOException
{ {
if (contentType != null) return content(new PathContentProvider(contentType, file));
header(HttpHeader.CONTENT_TYPE, contentType);
return content(new PathContentProvider(file));
} }
@Override @Override

View File

@ -37,8 +37,6 @@ import org.eclipse.jetty.client.util.PathContentProvider;
* <p/> * <p/>
* Applications should rely on utility classes such as {@link ByteBufferContentProvider} * Applications should rely on utility classes such as {@link ByteBufferContentProvider}
* or {@link PathContentProvider}. * or {@link PathContentProvider}.
* <p />
*
*/ */
public interface ContentProvider extends Iterable<ByteBuffer> public interface ContentProvider extends Iterable<ByteBuffer>
{ {
@ -46,4 +44,17 @@ public interface ContentProvider extends Iterable<ByteBuffer>
* @return the content length, if known, or -1 if the content length is unknown * @return the content length, if known, or -1 if the content length is unknown
*/ */
long getLength(); long getLength();
/**
* An extension of {@link ContentProvider} that provides a content type string
* to be used as a {@code Content-Type} HTTP header in requests.
*/
public interface Typed extends ContentProvider
{
/**
* @return the content type string such as "application/octet-stream" or
* "application/json;charset=UTF8", or null if no content type must be set
*/
public String getContentType();
}
} }

View File

@ -0,0 +1,37 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.client.util;
import org.eclipse.jetty.client.api.ContentProvider;
public abstract class AbstractTypedContentProvider implements ContentProvider.Typed
{
private final String contentType;
protected AbstractTypedContentProvider(String contentType)
{
this.contentType = contentType;
}
@Override
public String getContentType()
{
return contentType;
}
}

View File

@ -31,13 +31,19 @@ import org.eclipse.jetty.client.api.ContentProvider;
* and each invocation of the {@link #iterator()} method returns a {@link ByteBuffer#slice() slice} * and each invocation of the {@link #iterator()} method returns a {@link ByteBuffer#slice() slice}
* of the original {@link ByteBuffer}. * of the original {@link ByteBuffer}.
*/ */
public class ByteBufferContentProvider implements ContentProvider public class ByteBufferContentProvider extends AbstractTypedContentProvider
{ {
private final ByteBuffer[] buffers; private final ByteBuffer[] buffers;
private final int length; private final int length;
public ByteBufferContentProvider(ByteBuffer... buffers) public ByteBufferContentProvider(ByteBuffer... buffers)
{ {
this("application/octet-stream", buffers);
}
public ByteBufferContentProvider(String contentType, ByteBuffer... buffers)
{
super(contentType);
this.buffers = buffers; this.buffers = buffers;
int length = 0; int length = 0;
for (ByteBuffer buffer : buffers) for (ByteBuffer buffer : buffers)

View File

@ -27,13 +27,19 @@ import org.eclipse.jetty.client.api.ContentProvider;
/** /**
* A {@link ContentProvider} for byte arrays. * A {@link ContentProvider} for byte arrays.
*/ */
public class BytesContentProvider implements ContentProvider public class BytesContentProvider extends AbstractTypedContentProvider
{ {
private final byte[][] bytes; private final byte[][] bytes;
private final long length; private final long length;
public BytesContentProvider(byte[]... bytes) public BytesContentProvider(byte[]... bytes)
{ {
this("application/octet-stream", bytes);
}
public BytesContentProvider(String contentType, byte[]... bytes)
{
super(contentType);
this.bytes = bytes; this.bytes = bytes;
long length = 0; long length = 0;
for (byte[] buffer : bytes) for (byte[] buffer : bytes)

View File

@ -40,7 +40,7 @@ import org.eclipse.jetty.util.log.Logger;
* It is possible to specify, at the constructor, a buffer size used to read content from the * It is possible to specify, at the constructor, a buffer size used to read content from the
* stream, by default 4096 bytes. * stream, by default 4096 bytes.
*/ */
public class PathContentProvider implements ContentProvider public class PathContentProvider extends AbstractTypedContentProvider
{ {
private static final Logger LOG = Log.getLogger(PathContentProvider.class); private static final Logger LOG = Log.getLogger(PathContentProvider.class);
@ -55,6 +55,17 @@ public class PathContentProvider implements ContentProvider
public PathContentProvider(Path filePath, int bufferSize) throws IOException public PathContentProvider(Path filePath, int bufferSize) throws IOException
{ {
this("application/octet-stream", filePath, bufferSize);
}
public PathContentProvider(String contentType, Path filePath) throws IOException
{
this(contentType, filePath, 4096);
}
public PathContentProvider(String contentType, Path filePath, int bufferSize) throws IOException
{
super(contentType);
if (!Files.isRegularFile(filePath)) if (!Files.isRegularFile(filePath))
throw new NoSuchFileException(filePath.toString()); throw new NoSuchFileException(filePath.toString());
if (!Files.isReadable(filePath)) if (!Files.isReadable(filePath))

View File

@ -43,6 +43,11 @@ public class StringContentProvider extends BytesContentProvider
public StringContentProvider(String content, Charset charset) public StringContentProvider(String content, Charset charset)
{ {
super(content.getBytes(charset)); this("text/plain;charset=" + charset.name(), content, charset);
}
public StringContentProvider(String contentType, String content, Charset charset)
{
super(contentType, content.getBytes(charset));
} }
} }