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
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();
if (contentLength >= 0)
{

View File

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

View File

@ -28,17 +28,15 @@ import org.eclipse.jetty.client.util.PathContentProvider;
/**
* {@link ContentProvider} provides a source of request content.
* <p />
* <p/>
* Implementations should return an {@link Iterator} over the request content.
* If the request content comes from a source that needs to be closed (for
* example, an {@link InputStream}), then the iterator implementation class
* must implement {@link Closeable} and will be closed when the request is
* completed (either successfully or failed).
* <p />
* <p/>
* Applications should rely on utility classes such as {@link ByteBufferContentProvider}
* or {@link PathContentProvider}.
* <p />
*
*/
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
*/
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}
* of the original {@link ByteBuffer}.
*/
public class ByteBufferContentProvider implements ContentProvider
public class ByteBufferContentProvider extends AbstractTypedContentProvider
{
private final ByteBuffer[] buffers;
private final int length;
public ByteBufferContentProvider(ByteBuffer... buffers)
{
this("application/octet-stream", buffers);
}
public ByteBufferContentProvider(String contentType, ByteBuffer... buffers)
{
super(contentType);
this.buffers = buffers;
int length = 0;
for (ByteBuffer buffer : buffers)

View File

@ -27,13 +27,19 @@ import org.eclipse.jetty.client.api.ContentProvider;
/**
* A {@link ContentProvider} for byte arrays.
*/
public class BytesContentProvider implements ContentProvider
public class BytesContentProvider extends AbstractTypedContentProvider
{
private final byte[][] bytes;
private final long length;
public BytesContentProvider(byte[]... bytes)
{
this("application/octet-stream", bytes);
}
public BytesContentProvider(String contentType, byte[]... bytes)
{
super(contentType);
this.bytes = bytes;
long length = 0;
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
* stream, by default 4096 bytes.
*/
public class PathContentProvider implements ContentProvider
public class PathContentProvider extends AbstractTypedContentProvider
{
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
{
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))
throw new NoSuchFileException(filePath.toString());
if (!Files.isReadable(filePath))

View File

@ -43,6 +43,11 @@ public class StringContentProvider extends BytesContentProvider
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));
}
}