pt 1 in reviving the android build (copied from pm 28a1, wish me luck)

This commit is contained in:
wuggy 2026-04-08 15:43:25 -07:00
commit d7788a6d6d
4249 changed files with 468189 additions and 0 deletions

View file

@ -0,0 +1,191 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.IOException;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.message.BasicHeader;
import ch.boye.httpclientandroidlib.protocol.HTTP;
/**
* Abstract base class for entities.
* Provides the commonly used attributes for streamed and self-contained
* implementations of {@link HttpEntity HttpEntity}.
*
* @since 4.0
*/
@NotThreadSafe
public abstract class AbstractHttpEntity implements HttpEntity {
/**
* Buffer size for output stream processing.
*
* @since 4.3
*/
protected static final int OUTPUT_BUFFER_SIZE = 4096;
protected Header contentType;
protected Header contentEncoding;
protected boolean chunked;
/**
* Protected default constructor.
* The contentType, contentEncoding and chunked attributes of the created object are set to
* <code>null</code>, <code>null</code> and <code>false</code>, respectively.
*/
protected AbstractHttpEntity() {
super();
}
/**
* Obtains the Content-Type header.
* The default implementation returns the value of the
* {@link #contentType contentType} attribute.
*
* @return the Content-Type header, or <code>null</code>
*/
public Header getContentType() {
return this.contentType;
}
/**
* Obtains the Content-Encoding header.
* The default implementation returns the value of the
* {@link #contentEncoding contentEncoding} attribute.
*
* @return the Content-Encoding header, or <code>null</code>
*/
public Header getContentEncoding() {
return this.contentEncoding;
}
/**
* Obtains the 'chunked' flag.
* The default implementation returns the value of the
* {@link #chunked chunked} attribute.
*
* @return the 'chunked' flag
*/
public boolean isChunked() {
return this.chunked;
}
/**
* Specifies the Content-Type header.
* The default implementation sets the value of the
* {@link #contentType contentType} attribute.
*
* @param contentType the new Content-Encoding header, or
* <code>null</code> to unset
*/
public void setContentType(final Header contentType) {
this.contentType = contentType;
}
/**
* Specifies the Content-Type header, as a string.
* The default implementation calls
* {@link #setContentType(Header) setContentType(Header)}.
*
* @param ctString the new Content-Type header, or
* <code>null</code> to unset
*/
public void setContentType(final String ctString) {
Header h = null;
if (ctString != null) {
h = new BasicHeader(HTTP.CONTENT_TYPE, ctString);
}
setContentType(h);
}
/**
* Specifies the Content-Encoding header.
* The default implementation sets the value of the
* {@link #contentEncoding contentEncoding} attribute.
*
* @param contentEncoding the new Content-Encoding header, or
* <code>null</code> to unset
*/
public void setContentEncoding(final Header contentEncoding) {
this.contentEncoding = contentEncoding;
}
/**
* Specifies the Content-Encoding header, as a string.
* The default implementation calls
* {@link #setContentEncoding(Header) setContentEncoding(Header)}.
*
* @param ceString the new Content-Encoding header, or
* <code>null</code> to unset
*/
public void setContentEncoding(final String ceString) {
Header h = null;
if (ceString != null) {
h = new BasicHeader(HTTP.CONTENT_ENCODING, ceString);
}
setContentEncoding(h);
}
/**
* Specifies the 'chunked' flag.
* <p>
* Note that the chunked setting is a hint only.
* If using HTTP/1.0, chunking is never performed.
* Otherwise, even if chunked is false, HttpClient must
* use chunk coding if the entity content length is
* unknown (-1).
* <p>
* The default implementation sets the value of the
* {@link #chunked chunked} attribute.
*
* @param b the new 'chunked' flag
*/
public void setChunked(final boolean b) {
this.chunked = b;
}
/**
* The default implementation does not consume anything.
*
* @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that;
* otherwise call {@link #writeTo(java.io.OutputStream)} which is required to free the resources.
*/
@Deprecated
public void consumeContent() throws IOException {
}
}

View file

@ -0,0 +1,125 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
import ch.boye.httpclientandroidlib.util.Asserts;
/**
* A generic streamed, non-repeatable entity that obtains its content
* from an {@link InputStream}.
*
* @since 4.0
*/
@NotThreadSafe
public class BasicHttpEntity extends AbstractHttpEntity {
private InputStream content;
private long length;
/**
* Creates a new basic entity.
* The content is initially missing, the content length
* is set to a negative number.
*/
public BasicHttpEntity() {
super();
this.length = -1;
}
public long getContentLength() {
return this.length;
}
/**
* Obtains the content, once only.
*
* @return the content, if this is the first call to this method
* since {@link #setContent setContent} has been called
*
* @throws IllegalStateException
* if the content has not been provided
*/
public InputStream getContent() throws IllegalStateException {
Asserts.check(this.content != null, "Content has not been provided");
return this.content;
}
/**
* Tells that this entity is not repeatable.
*
* @return <code>false</code>
*/
public boolean isRepeatable() {
return false;
}
/**
* Specifies the length of the content.
*
* @param len the number of bytes in the content, or
* a negative number to indicate an unknown length
*/
public void setContentLength(final long len) {
this.length = len;
}
/**
* Specifies the content.
*
* @param instream the stream to return with the next call to
* {@link #getContent getContent}
*/
public void setContent(final InputStream instream) {
this.content = instream;
}
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
final InputStream instream = getContent();
try {
int l;
final byte[] tmp = new byte[OUTPUT_BUFFER_SIZE];
while ((l = instream.read(tmp)) != -1) {
outstream.write(tmp, 0, l);
}
} finally {
instream.close();
}
}
public boolean isStreaming() {
return this.content != null;
}
}

View file

@ -0,0 +1,125 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
import ch.boye.httpclientandroidlib.util.EntityUtils;
/**
* A wrapping entity that buffers it content if necessary.
* The buffered entity is always repeatable.
* If the wrapped entity is repeatable itself, calls are passed through.
* If the wrapped entity is not repeatable, the content is read into a
* buffer once and provided from there as often as required.
*
* @since 4.0
*/
@NotThreadSafe
public class BufferedHttpEntity extends HttpEntityWrapper {
private final byte[] buffer;
/**
* Creates a new buffered entity wrapper.
*
* @param entity the entity to wrap, not null
* @throws IllegalArgumentException if wrapped is null
*/
public BufferedHttpEntity(final HttpEntity entity) throws IOException {
super(entity);
if (!entity.isRepeatable() || entity.getContentLength() < 0) {
this.buffer = EntityUtils.toByteArray(entity);
} else {
this.buffer = null;
}
}
@Override
public long getContentLength() {
if (this.buffer != null) {
return this.buffer.length;
} else {
return super.getContentLength();
}
}
@Override
public InputStream getContent() throws IOException {
if (this.buffer != null) {
return new ByteArrayInputStream(this.buffer);
} else {
return super.getContent();
}
}
/**
* Tells that this entity does not have to be chunked.
*
* @return <code>false</code>
*/
@Override
public boolean isChunked() {
return (buffer == null) && super.isChunked();
}
/**
* Tells that this entity is repeatable.
*
* @return <code>true</code>
*/
@Override
public boolean isRepeatable() {
return true;
}
@Override
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
if (this.buffer != null) {
outstream.write(this.buffer);
} else {
super.writeTo(outstream);
}
}
// non-javadoc, see interface HttpEntity
@Override
public boolean isStreaming() {
return (buffer == null) && super.isStreaming();
}
} // class BufferedHttpEntity

View file

@ -0,0 +1,131 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
/**
* A self contained, repeatable entity that obtains its content from a byte array.
*
* @since 4.0
*/
@NotThreadSafe
public class ByteArrayEntity extends AbstractHttpEntity implements Cloneable {
/**
* @deprecated (4.2)
*/
@Deprecated
protected final byte[] content;
private final byte[] b;
private final int off, len;
/**
* @since 4.2
*/
@SuppressWarnings("deprecation")
public ByteArrayEntity(final byte[] b, final ContentType contentType) {
super();
Args.notNull(b, "Source byte array");
this.content = b;
this.b = b;
this.off = 0;
this.len = this.b.length;
if (contentType != null) {
setContentType(contentType.toString());
}
}
/**
* @since 4.2
*/
@SuppressWarnings("deprecation")
public ByteArrayEntity(final byte[] b, final int off, final int len, final ContentType contentType) {
super();
Args.notNull(b, "Source byte array");
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) < 0) || ((off + len) > b.length)) {
throw new IndexOutOfBoundsException("off: " + off + " len: " + len + " b.length: " + b.length);
}
this.content = b;
this.b = b;
this.off = off;
this.len = len;
if (contentType != null) {
setContentType(contentType.toString());
}
}
public ByteArrayEntity(final byte[] b) {
this(b, null);
}
public ByteArrayEntity(final byte[] b, final int off, final int len) {
this(b, off, len, null);
}
public boolean isRepeatable() {
return true;
}
public long getContentLength() {
return this.len;
}
public InputStream getContent() {
return new ByteArrayInputStream(this.b, this.off, this.len);
}
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
outstream.write(this.b, this.off, this.len);
outstream.flush();
}
/**
* Tells that this entity is not streaming.
*
* @return <code>false</code>
*/
public boolean isStreaming() {
return false;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
} // class ByteArrayEntity

View file

@ -0,0 +1,57 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import ch.boye.httpclientandroidlib.HttpException;
import ch.boye.httpclientandroidlib.HttpMessage;
/**
* Represents a strategy to determine length of the enclosed content entity
* based on properties of the HTTP message.
*
* @since 4.0
*/
public interface ContentLengthStrategy {
public static final int IDENTITY = -1;
public static final int CHUNKED = -2;
/**
* Returns length of the given message in bytes. The returned value
* must be a non-negative number, {@link #IDENTITY} if the end of the
* message will be delimited by the end of connection, or {@link #CHUNKED}
* if the message is chunk coded
*
* @param message HTTP message
* @return content length, {@link #IDENTITY}, or {@link #CHUNKED}
*
* @throws HttpException in case of HTTP protocol violation
*/
long determineLength(HttpMessage message) throws HttpException;
}

View file

@ -0,0 +1,44 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.IOException;
import java.io.OutputStream;
/**
* An abstract entity content producer.
*<p>Content producers are expected to be able to produce their
* content multiple times</p>
*
* @since 4.0
*/
public interface ContentProducer {
void writeTo(OutputStream outstream) throws IOException;
}

View file

@ -0,0 +1,305 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Locale;
import ch.boye.httpclientandroidlib.Consts;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HeaderElement;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.NameValuePair;
import ch.boye.httpclientandroidlib.ParseException;
import ch.boye.httpclientandroidlib.annotation.Immutable;
import ch.boye.httpclientandroidlib.message.BasicHeaderValueFormatter;
import ch.boye.httpclientandroidlib.message.BasicHeaderValueParser;
import ch.boye.httpclientandroidlib.message.ParserCursor;
import ch.boye.httpclientandroidlib.util.Args;
import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
import ch.boye.httpclientandroidlib.util.TextUtils;
/**
* Content type information consisting of a MIME type and an optional charset.
* <p/>
* This class makes no attempts to verify validity of the MIME type.
* The input parameters of the {@link #create(String, String)} method, however, may not
* contain characters <">, <;>, <,> reserved by the HTTP specification.
*
* @since 4.2
*/
@Immutable
public final class ContentType implements Serializable {
private static final long serialVersionUID = -7768694718232371896L;
// constants
public static final ContentType APPLICATION_ATOM_XML = create(
"application/atom+xml", Consts.ISO_8859_1);
public static final ContentType APPLICATION_FORM_URLENCODED = create(
"application/x-www-form-urlencoded", Consts.ISO_8859_1);
public static final ContentType APPLICATION_JSON = create(
"application/json", Consts.UTF_8);
public static final ContentType APPLICATION_OCTET_STREAM = create(
"application/octet-stream", (Charset) null);
public static final ContentType APPLICATION_SVG_XML = create(
"application/svg+xml", Consts.ISO_8859_1);
public static final ContentType APPLICATION_XHTML_XML = create(
"application/xhtml+xml", Consts.ISO_8859_1);
public static final ContentType APPLICATION_XML = create(
"application/xml", Consts.ISO_8859_1);
public static final ContentType MULTIPART_FORM_DATA = create(
"multipart/form-data", Consts.ISO_8859_1);
public static final ContentType TEXT_HTML = create(
"text/html", Consts.ISO_8859_1);
public static final ContentType TEXT_PLAIN = create(
"text/plain", Consts.ISO_8859_1);
public static final ContentType TEXT_XML = create(
"text/xml", Consts.ISO_8859_1);
public static final ContentType WILDCARD = create(
"*/*", (Charset) null);
// defaults
public static final ContentType DEFAULT_TEXT = TEXT_PLAIN;
public static final ContentType DEFAULT_BINARY = APPLICATION_OCTET_STREAM;
private final String mimeType;
private final Charset charset;
private final NameValuePair[] params;
ContentType(
final String mimeType,
final Charset charset) {
this.mimeType = mimeType;
this.charset = charset;
this.params = null;
}
ContentType(
final String mimeType,
final NameValuePair[] params) throws UnsupportedCharsetException {
this.mimeType = mimeType;
this.params = params;
final String s = getParameter("charset");
this.charset = !TextUtils.isBlank(s) ? Charset.forName(s) : null;
}
public String getMimeType() {
return this.mimeType;
}
public Charset getCharset() {
return this.charset;
}
/**
* @since 4.3
*/
public String getParameter(final String name) {
Args.notEmpty(name, "Parameter name");
if (this.params == null) {
return null;
}
for (final NameValuePair param: this.params) {
if (param.getName().equalsIgnoreCase(name)) {
return param.getValue();
}
}
return null;
}
/**
* Generates textual representation of this content type which can be used as the value
* of a <code>Content-Type</code> header.
*/
@Override
public String toString() {
final CharArrayBuffer buf = new CharArrayBuffer(64);
buf.append(this.mimeType);
if (this.params != null) {
buf.append("; ");
BasicHeaderValueFormatter.INSTANCE.formatParameters(buf, this.params, false);
} else if (this.charset != null) {
buf.append("; charset=");
buf.append(this.charset.name());
}
return buf.toString();
}
private static boolean valid(final String s) {
for (int i = 0; i < s.length(); i++) {
final char ch = s.charAt(i);
if (ch == '"' || ch == ',' || ch == ';') {
return false;
}
}
return true;
}
/**
* Creates a new instance of {@link ContentType}.
*
* @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
* characters <">, <;>, <,> reserved by the HTTP specification.
* @param charset charset.
* @return content type
*/
public static ContentType create(final String mimeType, final Charset charset) {
final String type = Args.notBlank(mimeType, "MIME type").toLowerCase(Locale.US);
Args.check(valid(type), "MIME type may not contain reserved characters");
return new ContentType(type, charset);
}
/**
* Creates a new instance of {@link ContentType} without a charset.
*
* @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
* characters <">, <;>, <,> reserved by the HTTP specification.
* @return content type
*/
public static ContentType create(final String mimeType) {
return new ContentType(mimeType, (Charset) null);
}
/**
* Creates a new instance of {@link ContentType}.
*
* @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
* characters <">, <;>, <,> reserved by the HTTP specification.
* @param charset charset. It may not contain characters <">, <;>, <,> reserved by the HTTP
* specification. This parameter is optional.
* @return content type
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
*/
public static ContentType create(
final String mimeType, final String charset) throws UnsupportedCharsetException {
return create(mimeType, !TextUtils.isBlank(charset) ? Charset.forName(charset) : null);
}
private static ContentType create(final HeaderElement helem) {
final String mimeType = helem.getName();
final NameValuePair[] params = helem.getParameters();
return new ContentType(mimeType, params != null && params.length > 0 ? params : null);
}
/**
* Parses textual representation of <code>Content-Type</code> value.
*
* @param s text
* @return content type
* @throws ParseException if the given text does not represent a valid
* <code>Content-Type</code> value.
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
*/
public static ContentType parse(
final String s) throws ParseException, UnsupportedCharsetException {
Args.notNull(s, "Content type");
final CharArrayBuffer buf = new CharArrayBuffer(s.length());
buf.append(s);
final ParserCursor cursor = new ParserCursor(0, s.length());
final HeaderElement[] elements = BasicHeaderValueParser.INSTANCE.parseElements(buf, cursor);
if (elements.length > 0) {
return create(elements[0]);
} else {
throw new ParseException("Invalid content type: " + s);
}
}
/**
* Extracts <code>Content-Type</code> value from {@link HttpEntity} exactly as
* specified by the <code>Content-Type</code> header of the entity. Returns <code>null</code>
* if not specified.
*
* @param entity HTTP entity
* @return content type
* @throws ParseException if the given text does not represent a valid
* <code>Content-Type</code> value.
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
*/
public static ContentType get(
final HttpEntity entity) throws ParseException, UnsupportedCharsetException {
if (entity == null) {
return null;
}
final Header header = entity.getContentType();
if (header != null) {
final HeaderElement[] elements = header.getElements();
if (elements.length > 0) {
return create(elements[0]);
}
}
return null;
}
/**
* Extracts <code>Content-Type</code> value from {@link HttpEntity} or returns the default value
* {@link #DEFAULT_TEXT} if not explicitly specified.
*
* @param entity HTTP entity
* @return content type
* @throws ParseException if the given text does not represent a valid
* <code>Content-Type</code> value.
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
*/
public static ContentType getOrDefault(
final HttpEntity entity) throws ParseException, UnsupportedCharsetException {
final ContentType contentType = get(entity);
return contentType != null ? contentType : DEFAULT_TEXT;
}
/**
* Creates a new instance with this MIME type and the given Charset.
*
* @param charset charset
* @return a new instance with this MIME type and the given Charset.
* @since 4.3
*/
public ContentType withCharset(final Charset charset) {
return create(this.getMimeType(), charset);
}
/**
* Creates a new instance with this MIME type and the given Charset name.
*
* @param charset name
* @return a new instance with this MIME type and the given Charset name.
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
* @since 4.3
*/
public ContentType withCharset(final String charset) {
return create(this.getMimeType(), charset);
}
}

View file

@ -0,0 +1,76 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Entity that delegates the process of content generation
* to a {@link ContentProducer}.
*
* @since 4.0
*/
public class EntityTemplate extends AbstractHttpEntity {
private final ContentProducer contentproducer;
public EntityTemplate(final ContentProducer contentproducer) {
super();
this.contentproducer = Args.notNull(contentproducer, "Content producer");
}
public long getContentLength() {
return -1;
}
public InputStream getContent() throws IOException {
final ByteArrayOutputStream buf = new ByteArrayOutputStream();
writeTo(buf);
return new ByteArrayInputStream(buf.toByteArray());
}
public boolean isRepeatable() {
return true;
}
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
this.contentproducer.writeTo(outstream);
}
public boolean isStreaming() {
return false;
}
}

View file

@ -0,0 +1,121 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
/**
* A self contained, repeatable entity that obtains its content from a file.
*
* @since 4.0
*/
@NotThreadSafe
public class FileEntity extends AbstractHttpEntity implements Cloneable {
protected final File file;
/**
* @deprecated (4.1.3) {@link #FileEntity(File, ContentType)}
*/
@Deprecated
public FileEntity(final File file, final String contentType) {
super();
this.file = Args.notNull(file, "File");
setContentType(contentType);
}
/**
* @since 4.2
*/
public FileEntity(final File file, final ContentType contentType) {
super();
this.file = Args.notNull(file, "File");
if (contentType != null) {
setContentType(contentType.toString());
}
}
/**
* @since 4.2
*/
public FileEntity(final File file) {
super();
this.file = Args.notNull(file, "File");
}
public boolean isRepeatable() {
return true;
}
public long getContentLength() {
return this.file.length();
}
public InputStream getContent() throws IOException {
return new FileInputStream(this.file);
}
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
final InputStream instream = new FileInputStream(this.file);
try {
final byte[] tmp = new byte[OUTPUT_BUFFER_SIZE];
int l;
while ((l = instream.read(tmp)) != -1) {
outstream.write(tmp, 0, l);
}
outstream.flush();
} finally {
instream.close();
}
}
/**
* Tells that this entity is not streaming.
*
* @return <code>false</code>
*/
public boolean isStreaming() {
return false;
}
@Override
public Object clone() throws CloneNotSupportedException {
// File instance is considered immutable
// No need to make a copy of it
return super.clone();
}
} // class FileEntity

View file

@ -0,0 +1,105 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Base class for wrapping entities.
* Keeps a {@link #wrappedEntity wrappedEntity} and delegates all
* calls to it. Implementations of wrapping entities can derive
* from this class and need to override only those methods that
* should not be delegated to the wrapped entity.
*
* @since 4.0
*/
@NotThreadSafe
public class HttpEntityWrapper implements HttpEntity {
/** The wrapped entity. */
protected HttpEntity wrappedEntity;
/**
* Creates a new entity wrapper.
*/
public HttpEntityWrapper(final HttpEntity wrappedEntity) {
super();
this.wrappedEntity = Args.notNull(wrappedEntity, "Wrapped entity");
} // constructor
public boolean isRepeatable() {
return wrappedEntity.isRepeatable();
}
public boolean isChunked() {
return wrappedEntity.isChunked();
}
public long getContentLength() {
return wrappedEntity.getContentLength();
}
public Header getContentType() {
return wrappedEntity.getContentType();
}
public Header getContentEncoding() {
return wrappedEntity.getContentEncoding();
}
public InputStream getContent()
throws IOException {
return wrappedEntity.getContent();
}
public void writeTo(final OutputStream outstream)
throws IOException {
wrappedEntity.writeTo(outstream);
}
public boolean isStreaming() {
return wrappedEntity.isStreaming();
}
/**
* @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that;
* otherwise call {@link #writeTo(OutputStream)} which is required to free the resources.
*/
@Deprecated
public void consumeContent() throws IOException {
wrappedEntity.consumeContent();
}
}

View file

@ -0,0 +1,155 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
/**
* A streamed, non-repeatable entity that obtains its content from
* an {@link InputStream}.
*
* @since 4.0
*/
@NotThreadSafe
public class InputStreamEntity extends AbstractHttpEntity {
private final InputStream content;
private final long length;
/**
* Creates an entity with an unknown length.
* Equivalent to {@code new InputStreamEntity(instream, -1)}.
*
* @param instream input stream
* @throws IllegalArgumentException if {@code instream} is {@code null}
* @since 4.3
*/
public InputStreamEntity(final InputStream instream) {
this(instream, -1);
}
/**
* Creates an entity with a specified content length.
*
* @param instream input stream
* @param length of the input stream, {@code -1} if unknown
* @throws IllegalArgumentException if {@code instream} is {@code null}
*/
public InputStreamEntity(final InputStream instream, final long length) {
this(instream, length, null);
}
/**
* Creates an entity with a content type and unknown length.
* Equivalent to {@code new InputStreamEntity(instream, -1, contentType)}.
*
* @param instream input stream
* @param contentType content type
* @throws IllegalArgumentException if {@code instream} is {@code null}
* @since 4.3
*/
public InputStreamEntity(final InputStream instream, final ContentType contentType) {
this(instream, -1, contentType);
}
/**
* @param instream input stream
* @param length of the input stream, {@code -1} if unknown
* @param contentType for specifying the {@code Content-Type} header, may be {@code null}
* @throws IllegalArgumentException if {@code instream} is {@code null}
* @since 4.2
*/
public InputStreamEntity(final InputStream instream, final long length, final ContentType contentType) {
super();
this.content = Args.notNull(instream, "Source input stream");
this.length = length;
if (contentType != null) {
setContentType(contentType.toString());
}
}
public boolean isRepeatable() {
return false;
}
/**
* @return the content length or {@code -1} if unknown
*/
public long getContentLength() {
return this.length;
}
public InputStream getContent() throws IOException {
return this.content;
}
/**
* Writes bytes from the {@code InputStream} this entity was constructed
* with to an {@code OutputStream}. The content length
* determines how many bytes are written. If the length is unknown ({@code -1}), the
* stream will be completely consumed (to the end of the stream).
*
*/
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
final InputStream instream = this.content;
try {
final byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
int l;
if (this.length < 0) {
// consume until EOF
while ((l = instream.read(buffer)) != -1) {
outstream.write(buffer, 0, l);
}
} else {
// consume no more than length
long remaining = this.length;
while (remaining > 0) {
l = instream.read(buffer, 0, (int)Math.min(OUTPUT_BUFFER_SIZE, remaining));
if (l == -1) {
break;
}
outstream.write(buffer, 0, l);
remaining -= l;
}
}
} finally {
instream.close();
}
}
public boolean isStreaming() {
return true;
}
}

View file

@ -0,0 +1,126 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.util.Args;
/**
* A streamed entity that obtains its content from a {@link Serializable}.
* The content obtained from the {@link Serializable} instance can
* optionally be buffered in a byte array in order to make the
* entity self-contained and repeatable.
*
* @since 4.0
*/
@NotThreadSafe
public class SerializableEntity extends AbstractHttpEntity {
private byte[] objSer;
private Serializable objRef;
/**
* Creates new instance of this class.
*
* @param ser input
* @param bufferize tells whether the content should be
* stored in an internal buffer
* @throws IOException in case of an I/O error
*/
public SerializableEntity(final Serializable ser, final boolean bufferize) throws IOException {
super();
Args.notNull(ser, "Source object");
if (bufferize) {
createBytes(ser);
} else {
this.objRef = ser;
}
}
/**
* @since 4.3
*/
public SerializableEntity(final Serializable ser) {
super();
Args.notNull(ser, "Source object");
this.objRef = ser;
}
private void createBytes(final Serializable ser) throws IOException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(ser);
out.flush();
this.objSer = baos.toByteArray();
}
public InputStream getContent() throws IOException, IllegalStateException {
if (this.objSer == null) {
createBytes(this.objRef);
}
return new ByteArrayInputStream(this.objSer);
}
public long getContentLength() {
if (this.objSer == null) {
return -1;
} else {
return this.objSer.length;
}
}
public boolean isRepeatable() {
return true;
}
public boolean isStreaming() {
return this.objSer == null;
}
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
if (this.objSer == null) {
final ObjectOutputStream out = new ObjectOutputStream(outstream);
out.writeObject(this.objRef);
out.flush();
} else {
outstream.write(this.objSer);
outstream.flush();
}
}
}

View file

@ -0,0 +1,188 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
import ch.boye.httpclientandroidlib.protocol.HTTP;
import ch.boye.httpclientandroidlib.util.Args;
/**
* A self contained, repeatable entity that obtains its content from
* a {@link String}.
*
* @since 4.0
*/
@NotThreadSafe
public class StringEntity extends AbstractHttpEntity implements Cloneable {
protected final byte[] content;
/**
* Creates a StringEntity with the specified content and content type.
*
* @param string content to be used. Not {@code null}.
* @param contentType content type to be used. May be {@code null}, in which case the default
* MIME type {@link ContentType#TEXT_PLAIN} is assumed.
*
* @throws IllegalArgumentException if the string parameter is null
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
* @since 4.2
*/
public StringEntity(final String string, final ContentType contentType) throws UnsupportedCharsetException {
super();
Args.notNull(string, "Source string");
Charset charset = contentType != null ? contentType.getCharset() : null;
if (charset == null) {
charset = HTTP.DEF_CONTENT_CHARSET;
}
try {
this.content = string.getBytes(charset.name());
} catch (final UnsupportedEncodingException ex) {
// should never happen
throw new UnsupportedCharsetException(charset.name());
}
if (contentType != null) {
setContentType(contentType.toString());
}
}
/**
* Creates a StringEntity with the specified content, MIME type and charset
*
* @param string content to be used. Not {@code null}.
* @param mimeType MIME type to be used. May be {@code null}, in which case the default
* is {@link HTTP#PLAIN_TEXT_TYPE} i.e. "text/plain"
* @param charset character set to be used. May be {@code null}, in which case the default
* is {@link HTTP#DEF_CONTENT_CHARSET} i.e. "ISO-8859-1"
* @throws UnsupportedEncodingException If the named charset is not supported.
*
* @since 4.1
* @throws IllegalArgumentException if the string parameter is null
*
* @deprecated (4.1.3) use {@link #StringEntity(String, ContentType)}
*/
@Deprecated
public StringEntity(
final String string, final String mimeType, final String charset) throws UnsupportedEncodingException {
super();
Args.notNull(string, "Source string");
final String mt = mimeType != null ? mimeType : HTTP.PLAIN_TEXT_TYPE;
final String cs = charset != null ? charset :HTTP.DEFAULT_CONTENT_CHARSET;
this.content = string.getBytes(cs);
setContentType(mt + HTTP.CHARSET_PARAM + cs);
}
/**
* Creates a StringEntity with the specified content and charset. The MIME type defaults
* to "text/plain".
*
* @param string content to be used. Not {@code null}.
* @param charset character set to be used. May be {@code null}, in which case the default
* is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
*
* @throws IllegalArgumentException if the string parameter is null
* @throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
*/
public StringEntity(final String string, final String charset)
throws UnsupportedCharsetException {
this(string, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
}
/**
* Creates a StringEntity with the specified content and charset. The MIME type defaults
* to "text/plain".
*
* @param string content to be used. Not {@code null}.
* @param charset character set to be used. May be {@code null}, in which case the default
* is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
*
* @throws IllegalArgumentException if the string parameter is null
*
* @since 4.2
*/
public StringEntity(final String string, final Charset charset) {
this(string, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
}
/**
* Creates a StringEntity with the specified content. The content type defaults to
* {@link ContentType#TEXT_PLAIN}.
*
* @param string content to be used. Not {@code null}.
*
* @throws IllegalArgumentException if the string parameter is null
* @throws UnsupportedEncodingException if the default HTTP charset is not supported.
*/
public StringEntity(final String string)
throws UnsupportedEncodingException {
this(string, ContentType.DEFAULT_TEXT);
}
public boolean isRepeatable() {
return true;
}
public long getContentLength() {
return this.content.length;
}
public InputStream getContent() throws IOException {
return new ByteArrayInputStream(this.content);
}
public void writeTo(final OutputStream outstream) throws IOException {
Args.notNull(outstream, "Output stream");
outstream.write(this.content);
outstream.flush();
}
/**
* Tells that this entity is not streaming.
*
* @return <code>false</code>
*/
public boolean isStreaming() {
return false;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
} // class StringEntity

View file

@ -0,0 +1,211 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.List;
import ch.boye.httpclientandroidlib.entity.mime.content.ContentBody;
import ch.boye.httpclientandroidlib.util.Args;
import ch.boye.httpclientandroidlib.util.ByteArrayBuffer;
/**
* HttpMultipart represents a collection of MIME multipart encoded content bodies. This class is
* capable of operating either in the strict (RFC 822, RFC 2045, RFC 2046 compliant) or
* the browser compatible modes.
*
* @since 4.3
*/
abstract class AbstractMultipartForm {
private static ByteArrayBuffer encode(
final Charset charset, final String string) {
final ByteBuffer encoded = charset.encode(CharBuffer.wrap(string));
final ByteArrayBuffer bab = new ByteArrayBuffer(encoded.remaining());
bab.append(encoded.array(), encoded.position(), encoded.remaining());
return bab;
}
private static void writeBytes(
final ByteArrayBuffer b, final OutputStream out) throws IOException {
out.write(b.buffer(), 0, b.length());
}
private static void writeBytes(
final String s, final Charset charset, final OutputStream out) throws IOException {
final ByteArrayBuffer b = encode(charset, s);
writeBytes(b, out);
}
private static void writeBytes(
final String s, final OutputStream out) throws IOException {
final ByteArrayBuffer b = encode(MIME.DEFAULT_CHARSET, s);
writeBytes(b, out);
}
protected static void writeField(
final MinimalField field, final OutputStream out) throws IOException {
writeBytes(field.getName(), out);
writeBytes(FIELD_SEP, out);
writeBytes(field.getBody(), out);
writeBytes(CR_LF, out);
}
protected static void writeField(
final MinimalField field, final Charset charset, final OutputStream out) throws IOException {
writeBytes(field.getName(), charset, out);
writeBytes(FIELD_SEP, out);
writeBytes(field.getBody(), charset, out);
writeBytes(CR_LF, out);
}
private static final ByteArrayBuffer FIELD_SEP = encode(MIME.DEFAULT_CHARSET, ": ");
private static final ByteArrayBuffer CR_LF = encode(MIME.DEFAULT_CHARSET, "\r\n");
private static final ByteArrayBuffer TWO_DASHES = encode(MIME.DEFAULT_CHARSET, "--");
private final String subType;
protected final Charset charset;
private final String boundary;
/**
* Creates an instance with the specified settings.
*
* @param subType MIME subtype - must not be {@code null}
* @param charset the character set to use. May be {@code null}, in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used.
* @param boundary to use - must not be {@code null}
* @throws IllegalArgumentException if charset is null or boundary is null
*/
public AbstractMultipartForm(final String subType, final Charset charset, final String boundary) {
super();
Args.notNull(subType, "Multipart subtype");
Args.notNull(boundary, "Multipart boundary");
this.subType = subType;
this.charset = charset != null ? charset : MIME.DEFAULT_CHARSET;
this.boundary = boundary;
}
public AbstractMultipartForm(final String subType, final String boundary) {
this(subType, null, boundary);
}
public String getSubType() {
return this.subType;
}
public Charset getCharset() {
return this.charset;
}
public abstract List<FormBodyPart> getBodyParts();
public String getBoundary() {
return this.boundary;
}
void doWriteTo(
final OutputStream out,
final boolean writeContent) throws IOException {
final ByteArrayBuffer boundary = encode(this.charset, getBoundary());
for (final FormBodyPart part: getBodyParts()) {
writeBytes(TWO_DASHES, out);
writeBytes(boundary, out);
writeBytes(CR_LF, out);
formatMultipartHeader(part, out);
writeBytes(CR_LF, out);
if (writeContent) {
part.getBody().writeTo(out);
}
writeBytes(CR_LF, out);
}
writeBytes(TWO_DASHES, out);
writeBytes(boundary, out);
writeBytes(TWO_DASHES, out);
writeBytes(CR_LF, out);
}
/**
* Write the multipart header fields; depends on the style.
*/
protected abstract void formatMultipartHeader(
final FormBodyPart part,
final OutputStream out) throws IOException;
/**
* Writes out the content in the multipart/form encoding. This method
* produces slightly different formatting depending on its compatibility
* mode.
*/
public void writeTo(final OutputStream out) throws IOException {
doWriteTo(out, true);
}
/**
* Determines the total length of the multipart content (content length of
* individual parts plus that of extra elements required to delimit the parts
* from one another). If any of the @{link BodyPart}s contained in this object
* is of a streaming entity of unknown length the total length is also unknown.
* <p/>
* This method buffers only a small amount of data in order to determine the
* total length of the entire entity. The content of individual parts is not
* buffered.
*
* @return total length of the multipart entity if known, <code>-1</code>
* otherwise.
*/
public long getTotalLength() {
long contentLen = 0;
for (final FormBodyPart part: getBodyParts()) {
final ContentBody body = part.getBody();
final long len = body.getContentLength();
if (len >= 0) {
contentLen += len;
} else {
return -1;
}
}
final ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
doWriteTo(out, false);
final byte[] extra = out.toByteArray();
return contentLen + extra.length;
} catch (final IOException ex) {
// Should never happen
return -1;
}
}
}

View file

@ -0,0 +1,116 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.content.AbstractContentBody;
import ch.boye.httpclientandroidlib.entity.mime.content.ContentBody;
import ch.boye.httpclientandroidlib.util.Args;
/**
* FormBodyPart class represents a content body that can be used as a part of multipart encoded
* entities. This class automatically populates the header with standard fields based on
* the content description of the enclosed body.
*
* @since 4.0
*/
public class FormBodyPart {
private final String name;
private final Header header;
private final ContentBody body;
public FormBodyPart(final String name, final ContentBody body) {
super();
Args.notNull(name, "Name");
Args.notNull(body, "Body");
this.name = name;
this.body = body;
this.header = new Header();
generateContentDisp(body);
generateContentType(body);
generateTransferEncoding(body);
}
public String getName() {
return this.name;
}
public ContentBody getBody() {
return this.body;
}
public Header getHeader() {
return this.header;
}
public void addField(final String name, final String value) {
Args.notNull(name, "Field name");
this.header.addField(new MinimalField(name, value));
}
protected void generateContentDisp(final ContentBody body) {
final StringBuilder buffer = new StringBuilder();
buffer.append("form-data; name=\"");
buffer.append(getName());
buffer.append("\"");
if (body.getFilename() != null) {
buffer.append("; filename=\"");
buffer.append(body.getFilename());
buffer.append("\"");
}
addField(MIME.CONTENT_DISPOSITION, buffer.toString());
}
protected void generateContentType(final ContentBody body) {
final ContentType contentType;
if (body instanceof AbstractContentBody) {
contentType = ((AbstractContentBody) body).getContentType();
} else {
contentType = null;
}
if (contentType != null) {
addField(MIME.CONTENT_TYPE, contentType.toString());
} else {
final StringBuilder buffer = new StringBuilder();
buffer.append(body.getMimeType()); // MimeType cannot be null
if (body.getCharset() != null) { // charset may legitimately be null
buffer.append("; charset=");
buffer.append(body.getCharset());
}
addField(MIME.CONTENT_TYPE, buffer.toString());
}
}
protected void generateTransferEncoding(final ContentBody body) {
addField(MIME.CONTENT_TRANSFER_ENC, body.getTransferEncoding()); // TE cannot be null
}
}

View file

@ -0,0 +1,144 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* The header of an entity (see RFC 2045).
*/
public class Header implements Iterable<MinimalField> {
private final List<MinimalField> fields;
private final Map<String, List<MinimalField>> fieldMap;
public Header() {
super();
this.fields = new LinkedList<MinimalField>();
this.fieldMap = new HashMap<String, List<MinimalField>>();
}
public void addField(final MinimalField field) {
if (field == null) {
return;
}
final String key = field.getName().toLowerCase(Locale.ENGLISH);
List<MinimalField> values = this.fieldMap.get(key);
if (values == null) {
values = new LinkedList<MinimalField>();
this.fieldMap.put(key, values);
}
values.add(field);
this.fields.add(field);
}
public List<MinimalField> getFields() {
return new ArrayList<MinimalField>(this.fields);
}
public MinimalField getField(final String name) {
if (name == null) {
return null;
}
final String key = name.toLowerCase(Locale.ENGLISH);
final List<MinimalField> list = this.fieldMap.get(key);
if (list != null && !list.isEmpty()) {
return list.get(0);
}
return null;
}
public List<MinimalField> getFields(final String name) {
if (name == null) {
return null;
}
final String key = name.toLowerCase(Locale.ENGLISH);
final List<MinimalField> list = this.fieldMap.get(key);
if (list == null || list.isEmpty()) {
return Collections.emptyList();
} else {
return new ArrayList<MinimalField>(list);
}
}
public int removeFields(final String name) {
if (name == null) {
return 0;
}
final String key = name.toLowerCase(Locale.ENGLISH);
final List<MinimalField> removed = fieldMap.remove(key);
if (removed == null || removed.isEmpty()) {
return 0;
}
this.fields.removeAll(removed);
return removed.size();
}
public void setField(final MinimalField field) {
if (field == null) {
return;
}
final String key = field.getName().toLowerCase(Locale.ENGLISH);
final List<MinimalField> list = fieldMap.get(key);
if (list == null || list.isEmpty()) {
addField(field);
return;
}
list.clear();
list.add(field);
int firstOccurrence = -1;
int index = 0;
for (final Iterator<MinimalField> it = this.fields.iterator(); it.hasNext(); index++) {
final MinimalField f = it.next();
if (f.getName().equalsIgnoreCase(field.getName())) {
it.remove();
if (firstOccurrence == -1) {
firstOccurrence = index;
}
}
}
this.fields.add(firstOccurrence, field);
}
public Iterator<MinimalField> iterator() {
return Collections.unmodifiableList(fields).iterator();
}
@Override
public String toString() {
return this.fields.toString();
}
}

View file

@ -0,0 +1,79 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
/**
* HttpBrowserCompatibleMultipart represents a collection of MIME multipart encoded
* content bodies. This class is emulates browser compatibility, e.g. IE 5 or earlier.
*
* @since 4.3
*/
class HttpBrowserCompatibleMultipart extends AbstractMultipartForm {
private final List<FormBodyPart> parts;
public HttpBrowserCompatibleMultipart(
final String subType,
final Charset charset,
final String boundary,
final List<FormBodyPart> parts) {
super(subType, charset, boundary);
this.parts = parts;
}
@Override
public List<FormBodyPart> getBodyParts() {
return this.parts;
}
/**
* Write the multipart header fields; depends on the style.
*/
@Override
protected void formatMultipartHeader(
final FormBodyPart part,
final OutputStream out) throws IOException {
// For browser-compatible, only write Content-Disposition
// Use content charset
final Header header = part.getHeader();
final MinimalField cd = header.getField(MIME.CONTENT_DISPOSITION);
writeField(cd, this.charset, out);
final String filename = part.getBody().getFilename();
if (filename != null) {
final MinimalField ct = header.getField(MIME.CONTENT_TYPE);
writeField(ct, this.charset, out);
}
}
}

View file

@ -0,0 +1,43 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
/**
*
* @since 4.0
*/
public enum HttpMultipartMode {
/** RFC 822, RFC 2045, RFC 2046 compliant */
STRICT,
/** browser-compatible mode, i.e. only write Content-Disposition; use content charset */
BROWSER_COMPATIBLE,
/** RFC 6532 compliant */
RFC6532
}

View file

@ -0,0 +1,72 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
/**
* HttpRFC6532Multipart represents a collection of MIME multipart encoded content bodies,
* implementing the strict (RFC 822, RFC 2045, RFC 2046 compliant) interpretation
* of the spec, with the exception of allowing UTF-8 headers, as per RFC6532.
*
* @since 4.3
*/
class HttpRFC6532Multipart extends AbstractMultipartForm {
private final List<FormBodyPart> parts;
public HttpRFC6532Multipart(
final String subType,
final Charset charset,
final String boundary,
final List<FormBodyPart> parts) {
super(subType, charset, boundary);
this.parts = parts;
}
@Override
public List<FormBodyPart> getBodyParts() {
return this.parts;
}
@Override
protected void formatMultipartHeader(
final FormBodyPart part,
final OutputStream out) throws IOException {
// For RFC6532, we output all fields with UTF-8 encoding.
final Header header = part.getHeader();
for (final MinimalField field: header) {
writeField(field, MIME.UTF8_CHARSET, out);
}
}
}

View file

@ -0,0 +1,72 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
/**
* HttpStrictMultipart represents a collection of MIME multipart encoded content bodies,
* implementing the strict (RFC 822, RFC 2045, RFC 2046 compliant) interpretation
* of the spec.
*
* @since 4.3
*/
class HttpStrictMultipart extends AbstractMultipartForm {
private final List<FormBodyPart> parts;
public HttpStrictMultipart(
final String subType,
final Charset charset,
final String boundary,
final List<FormBodyPart> parts) {
super(subType, charset, boundary);
this.parts = parts;
}
@Override
public List<FormBodyPart> getBodyParts() {
return this.parts;
}
@Override
protected void formatMultipartHeader(
final FormBodyPart part,
final OutputStream out) throws IOException {
// For strict, we output all fields with MIME-standard encoding.
final Header header = part.getHeader();
for (final MinimalField field: header) {
writeField(field, out);
}
}
}

View file

@ -0,0 +1,53 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import ch.boye.httpclientandroidlib.Consts;
import java.nio.charset.Charset;
/**
*
* @since 4.0
*/
public final class MIME {
public static final String CONTENT_TYPE = "Content-Type";
public static final String CONTENT_TRANSFER_ENC = "Content-Transfer-Encoding";
public static final String CONTENT_DISPOSITION = "Content-Disposition";
public static final String ENC_8BIT = "8bit";
public static final String ENC_BINARY = "binary";
/** The default character set to be used, i.e. "US-ASCII" */
public static final Charset DEFAULT_CHARSET = Consts.ASCII;
/** UTF-8 is used for RFC6532 */
public static final Charset UTF8_CHARSET = Consts.UTF_8;
}

View file

@ -0,0 +1,63 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
/**
* Minimal MIME field.
*
* @since 4.0
*/
public class MinimalField {
private final String name;
private final String value;
public MinimalField(final String name, final String value) {
super();
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public String getBody() {
return this.value;
}
@Override
public String toString() {
final StringBuilder buffer = new StringBuilder();
buffer.append(this.name);
buffer.append(": ");
buffer.append(this.value);
return buffer.toString();
}
}

View file

@ -0,0 +1,207 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import java.io.File;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.content.ByteArrayBody;
import ch.boye.httpclientandroidlib.entity.mime.content.ContentBody;
import ch.boye.httpclientandroidlib.entity.mime.content.FileBody;
import ch.boye.httpclientandroidlib.entity.mime.content.InputStreamBody;
import ch.boye.httpclientandroidlib.entity.mime.content.StringBody;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Builder for multipart {@link HttpEntity}s.
*
* @since 4.3
*/
public class MultipartEntityBuilder {
/**
* The pool of ASCII chars to be used for generating a multipart boundary.
*/
private final static char[] MULTIPART_CHARS =
"-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
.toCharArray();
private final static String DEFAULT_SUBTYPE = "form-data";
private String subType = DEFAULT_SUBTYPE;
private HttpMultipartMode mode = HttpMultipartMode.STRICT;
private String boundary = null;
private Charset charset = null;
private List<FormBodyPart> bodyParts = null;
public static MultipartEntityBuilder create() {
return new MultipartEntityBuilder();
}
MultipartEntityBuilder() {
super();
}
public MultipartEntityBuilder setMode(final HttpMultipartMode mode) {
this.mode = mode;
return this;
}
public MultipartEntityBuilder setLaxMode() {
this.mode = HttpMultipartMode.BROWSER_COMPATIBLE;
return this;
}
public MultipartEntityBuilder setStrictMode() {
this.mode = HttpMultipartMode.STRICT;
return this;
}
public MultipartEntityBuilder setBoundary(final String boundary) {
this.boundary = boundary;
return this;
}
public MultipartEntityBuilder setCharset(final Charset charset) {
this.charset = charset;
return this;
}
MultipartEntityBuilder addPart(final FormBodyPart bodyPart) {
if (bodyPart == null) {
return this;
}
if (this.bodyParts == null) {
this.bodyParts = new ArrayList<FormBodyPart>();
}
this.bodyParts.add(bodyPart);
return this;
}
public MultipartEntityBuilder addPart(final String name, final ContentBody contentBody) {
Args.notNull(name, "Name");
Args.notNull(contentBody, "Content body");
return addPart(new FormBodyPart(name, contentBody));
}
public MultipartEntityBuilder addTextBody(
final String name, final String text, final ContentType contentType) {
return addPart(name, new StringBody(text, contentType));
}
public MultipartEntityBuilder addTextBody(
final String name, final String text) {
return addTextBody(name, text, ContentType.DEFAULT_TEXT);
}
public MultipartEntityBuilder addBinaryBody(
final String name, final byte[] b, final ContentType contentType, final String filename) {
return addPart(name, new ByteArrayBody(b, contentType, filename));
}
public MultipartEntityBuilder addBinaryBody(
final String name, final byte[] b) {
return addBinaryBody(name, b, ContentType.DEFAULT_BINARY, null);
}
public MultipartEntityBuilder addBinaryBody(
final String name, final File file, final ContentType contentType, final String filename) {
return addPart(name, new FileBody(file, contentType, filename));
}
public MultipartEntityBuilder addBinaryBody(
final String name, final File file) {
return addBinaryBody(name, file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null);
}
public MultipartEntityBuilder addBinaryBody(
final String name, final InputStream stream, final ContentType contentType,
final String filename) {
return addPart(name, new InputStreamBody(stream, contentType, filename));
}
public MultipartEntityBuilder addBinaryBody(final String name, final InputStream stream) {
return addBinaryBody(name, stream, ContentType.DEFAULT_BINARY, null);
}
private String generateContentType(
final String boundary,
final Charset charset) {
final StringBuilder buffer = new StringBuilder();
buffer.append("multipart/form-data; boundary=");
buffer.append(boundary);
if (charset != null) {
buffer.append("; charset=");
buffer.append(charset.name());
}
return buffer.toString();
}
private String generateBoundary() {
final StringBuilder buffer = new StringBuilder();
final Random rand = new Random();
final int count = rand.nextInt(11) + 30; // a random size from 30 to 40
for (int i = 0; i < count; i++) {
buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
}
return buffer.toString();
}
MultipartFormEntity buildEntity() {
final String st = subType != null ? subType : DEFAULT_SUBTYPE;
final Charset cs = charset;
final String b = boundary != null ? boundary : generateBoundary();
final List<FormBodyPart> bps = bodyParts != null ? new ArrayList<FormBodyPart>(bodyParts) :
Collections.<FormBodyPart>emptyList();
final HttpMultipartMode m = mode != null ? mode : HttpMultipartMode.STRICT;
final AbstractMultipartForm form;
switch (m) {
case BROWSER_COMPATIBLE:
form = new HttpBrowserCompatibleMultipart(st, cs, b, bps);
break;
case RFC6532:
form = new HttpRFC6532Multipart(st, cs, b, bps);
break;
default:
form = new HttpStrictMultipart(st, cs, b, bps);
}
return new MultipartFormEntity(form, generateContentType(b, cs), form.getTotalLength());
}
public HttpEntity build() {
return buildEntity();
}
}

View file

@ -0,0 +1,100 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.message.BasicHeader;
import ch.boye.httpclientandroidlib.protocol.HTTP;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
class MultipartFormEntity implements HttpEntity {
private final AbstractMultipartForm multipart;
private final Header contentType;
private final long contentLength;
MultipartFormEntity(
final AbstractMultipartForm multipart,
final String contentType,
final long contentLength) {
super();
this.multipart = multipart;
this.contentType = new BasicHeader(HTTP.CONTENT_TYPE, contentType);
this.contentLength = contentLength;
}
AbstractMultipartForm getMultipart() {
return this.multipart;
}
public boolean isRepeatable() {
return this.contentLength != -1;
}
public boolean isChunked() {
return !isRepeatable();
}
public boolean isStreaming() {
return !isRepeatable();
}
public long getContentLength() {
return this.contentLength;
}
public Header getContentType() {
return this.contentType;
}
public Header getContentEncoding() {
return null;
}
public void consumeContent()
throws IOException, UnsupportedOperationException{
if (isStreaming()) {
throw new UnsupportedOperationException(
"Streaming entity does not implement #consumeContent()");
}
}
public InputStream getContent() throws IOException {
throw new UnsupportedOperationException(
"Multipart form entity does not implement #getContent()");
}
public void writeTo(final OutputStream outstream) throws IOException {
this.multipart.writeTo(outstream);
}
}

View file

@ -0,0 +1,96 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
import java.nio.charset.Charset;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.util.Args;
/**
*
* @since 4.0
*/
public abstract class AbstractContentBody implements ContentBody {
private final ContentType contentType;
/**
* @since 4.3
*/
public AbstractContentBody(final ContentType contentType) {
super();
Args.notNull(contentType, "Content type");
this.contentType = contentType;
}
/**
* @deprecated (4.3) use {@link AbstractContentBody#AbstractContentBody(ContentType)}
*/
@Deprecated
public AbstractContentBody(final String mimeType) {
this(ContentType.parse(mimeType));
}
/**
* @since 4.3
*/
public ContentType getContentType() {
return this.contentType;
}
public String getMimeType() {
return this.contentType.getMimeType();
}
public String getMediaType() {
final String mimeType = this.contentType.getMimeType();
final int i = mimeType.indexOf('/');
if (i != -1) {
return mimeType.substring(0, i);
} else {
return mimeType;
}
}
public String getSubType() {
final String mimeType = this.contentType.getMimeType();
final int i = mimeType.indexOf('/');
if (i != -1) {
return mimeType.substring(i + 1);
} else {
return null;
}
}
public String getCharset() {
final Charset charset = this.contentType.getCharset();
return charset != null ? charset.name() : null;
}
}

View file

@ -0,0 +1,111 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
import java.io.IOException;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.MIME;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Binary body part backed by a byte array.
*
* @see ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder
*
* @since 4.1
*/
public class ByteArrayBody extends AbstractContentBody {
/**
* The contents of the file contained in this part.
*/
private final byte[] data;
/**
* The name of the file contained in this part.
*/
private final String filename;
/**
* Creates a new ByteArrayBody.
*
* @param data The contents of the file contained in this part.
* @param mimeType The MIME type of the file contained in this part.
* @param filename The name of the file contained in this part.
*
* @deprecated (4.3) use {@link ByteArrayBody#ByteArrayBody(byte[], ContentType, String)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public ByteArrayBody(final byte[] data, final String mimeType, final String filename) {
this(data, ContentType.create(mimeType), filename);
}
/**
* @since 4.3
*/
public ByteArrayBody(final byte[] data, final ContentType contentType, final String filename) {
super(contentType);
Args.notNull(data, "byte[]");
this.data = data;
this.filename = filename;
}
/**
* Creates a new ByteArrayBody.
*
* @param data The contents of the file contained in this part.
* @param filename The name of the file contained in this part.
*/
public ByteArrayBody(final byte[] data, final String filename) {
this(data, "application/octet-stream", filename);
}
public String getFilename() {
return filename;
}
public void writeTo(final OutputStream out) throws IOException {
out.write(data);
}
@Override
public String getCharset() {
return null;
}
public String getTransferEncoding() {
return MIME.ENC_BINARY;
}
public long getContentLength() {
return data.length;
}
}

View file

@ -0,0 +1,43 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
import java.io.IOException;
import java.io.OutputStream;
/**
*
* @since 4.0
*/
public interface ContentBody extends ContentDescriptor {
String getFilename();
void writeTo(OutputStream out) throws IOException;
}

View file

@ -0,0 +1,89 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
/**
* Represents common content properties.
*/
public interface ContentDescriptor {
/**
* Returns the body descriptors MIME type.
* @see #getMediaType()
* @see #getSubType()
* @return The MIME type, which has been parsed from the
* content-type definition. Must not be null, but
* "text/plain", if no content-type was specified.
*/
String getMimeType();
/**
* Gets the defaulted MIME media type for this content.
* For example <code>TEXT</code>, <code>IMAGE</code>, <code>MULTIPART</code>
* @see #getMimeType()
* @return the MIME media type when content-type specified,
* otherwise the correct default (<code>TEXT</code>)
*/
String getMediaType();
/**
* Gets the defaulted MIME sub type for this content.
* @see #getMimeType()
* @return the MIME media type when content-type is specified,
* otherwise the correct default (<code>PLAIN</code>)
*/
String getSubType();
/**
* <p>The body descriptors character set, defaulted appropriately for the MIME type.</p>
* <p>
* For <code>TEXT</code> types, this will be defaulted to <code>us-ascii</code>.
* For other types, when the charset parameter is missing this property will be null.
* </p>
* @return Character set, which has been parsed from the
* content-type definition. Not null for <code>TEXT</code> types, when unset will
* be set to default <code>us-ascii</code>. For other types, when unset,
* null will be returned.
*/
String getCharset();
/**
* Returns the body descriptors transfer encoding.
* @return The transfer encoding. Must not be null, but "7bit",
* if no transfer-encoding was specified.
*/
String getTransferEncoding();
/**
* Returns the body descriptors content-length.
* @return Content length, if known, or -1, to indicate the absence of a
* content-length header.
*/
long getContentLength();
}

View file

@ -0,0 +1,144 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.MIME;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Binary body part backed by a file.
*
* @see ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder
*
* @since 4.0
*/
public class FileBody extends AbstractContentBody {
private final File file;
private final String filename;
/**
* @since 4.1
*
* @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType, String)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public FileBody(final File file,
final String filename,
final String mimeType,
final String charset) {
this(file, ContentType.create(mimeType, charset), filename);
}
/**
* @since 4.1
*
* @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public FileBody(final File file,
final String mimeType,
final String charset) {
this(file, null, mimeType, charset);
}
/**
* @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public FileBody(final File file, final String mimeType) {
this(file, ContentType.create(mimeType), null);
}
public FileBody(final File file) {
this(file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null);
}
/**
* @since 4.3
*/
public FileBody(final File file, final ContentType contentType, final String filename) {
super(contentType);
Args.notNull(file, "File");
this.file = file;
this.filename = filename;
}
/**
* @since 4.3
*/
public FileBody(final File file, final ContentType contentType) {
this(file, contentType, null);
}
public InputStream getInputStream() throws IOException {
return new FileInputStream(this.file);
}
public void writeTo(final OutputStream out) throws IOException {
Args.notNull(out, "Output stream");
final InputStream in = new FileInputStream(this.file);
try {
final byte[] tmp = new byte[4096];
int l;
while ((l = in.read(tmp)) != -1) {
out.write(tmp, 0, l);
}
out.flush();
} finally {
in.close();
}
}
public String getTransferEncoding() {
return MIME.ENC_BINARY;
}
public long getContentLength() {
return this.file.length();
}
public String getFilename() {
return filename;
}
public File getFile() {
return this.file;
}
}

View file

@ -0,0 +1,112 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.MIME;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Binary body part backed by an input stream.
*
* @see ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder
*
* @since 4.0
*/
public class InputStreamBody extends AbstractContentBody {
private final InputStream in;
private final String filename;
/**
* @since 4.1
*
* @deprecated (4.3) use {@link InputStreamBody#InputStreamBody(InputStream, ContentType,
* String)} or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public InputStreamBody(final InputStream in, final String mimeType, final String filename) {
this(in, ContentType.create(mimeType), filename);
}
public InputStreamBody(final InputStream in, final String filename) {
this(in, ContentType.DEFAULT_BINARY, filename);
}
/**
* @since 4.3
*/
public InputStreamBody(final InputStream in, final ContentType contentType, final String filename) {
super(contentType);
Args.notNull(in, "Input stream");
this.in = in;
this.filename = filename;
}
/**
* @since 4.3
*/
public InputStreamBody(final InputStream in, final ContentType contentType) {
this(in, contentType, null);
}
public InputStream getInputStream() {
return this.in;
}
public void writeTo(final OutputStream out) throws IOException {
Args.notNull(out, "Output stream");
try {
final byte[] tmp = new byte[4096];
int l;
while ((l = this.in.read(tmp)) != -1) {
out.write(tmp, 0, l);
}
out.flush();
} finally {
this.in.close();
}
}
public String getTransferEncoding() {
return MIME.ENC_BINARY;
}
public long getContentLength() {
return -1;
}
public String getFilename() {
return this.filename;
}
}

View file

@ -0,0 +1,197 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package ch.boye.httpclientandroidlib.entity.mime.content;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import ch.boye.httpclientandroidlib.Consts;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.MIME;
import ch.boye.httpclientandroidlib.util.Args;
/**
* Text body part backed by a byte array.
*
* @see ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder
*
* @since 4.0
*/
public class StringBody extends AbstractContentBody {
private final byte[] content;
/**
* @since 4.1
*
* @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public static StringBody create(
final String text,
final String mimeType,
final Charset charset) throws IllegalArgumentException {
try {
return new StringBody(text, mimeType, charset);
} catch (final UnsupportedEncodingException ex) {
throw new IllegalArgumentException("Charset " + charset + " is not supported", ex);
}
}
/**
* @since 4.1
*
* @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public static StringBody create(
final String text, final Charset charset) throws IllegalArgumentException {
return create(text, null, charset);
}
/**
* @since 4.1
*
* @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public static StringBody create(final String text) throws IllegalArgumentException {
return create(text, null, null);
}
/**
* Create a StringBody from the specified text, MIME type and character set.
*
* @param text to be used for the body, not {@code null}
* @param mimeType the MIME type, not {@code null}
* @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used
* @throws UnsupportedEncodingException
* @throws IllegalArgumentException if the {@code text} parameter is null
*
* @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public StringBody(
final String text,
final String mimeType,
final Charset charset) throws UnsupportedEncodingException {
this(text, ContentType.create(mimeType, charset));
}
/**
* Create a StringBody from the specified text and character set.
* The MIME type is set to "text/plain".
*
* @param text to be used for the body, not {@code null}
* @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used
* @throws UnsupportedEncodingException
* @throws IllegalArgumentException if the {@code text} parameter is null
*
* @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public StringBody(final String text, final Charset charset) throws UnsupportedEncodingException {
this(text, "text/plain", charset);
}
/**
* Create a StringBody from the specified text.
* The MIME type is set to "text/plain".
* The {@linkplain Consts#ASCII ASCII} charset is used.
*
* @param text to be used for the body, not {@code null}
* @throws UnsupportedEncodingException
* @throws IllegalArgumentException if the {@code text} parameter is null
*
* @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)}
* or {@link ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder}
*/
@Deprecated
public StringBody(final String text) throws UnsupportedEncodingException {
this(text, "text/plain", Consts.ASCII);
}
/**
* @since 4.3
*/
public StringBody(final String text, final ContentType contentType) {
super(contentType);
Args.notNull(text, "Text");
final Charset charset = contentType.getCharset();
final String csname = charset != null ? charset.name() : Consts.ASCII.name();
try {
this.content = text.getBytes(csname);
} catch (final UnsupportedEncodingException ex) {
// Should never happen
throw new UnsupportedCharsetException(csname);
}
}
public Reader getReader() {
final Charset charset = getContentType().getCharset();
return new InputStreamReader(
new ByteArrayInputStream(this.content),
charset != null ? charset : Consts.ASCII);
}
public void writeTo(final OutputStream out) throws IOException {
Args.notNull(out, "Output stream");
final InputStream in = new ByteArrayInputStream(this.content);
final byte[] tmp = new byte[4096];
int l;
while ((l = in.read(tmp)) != -1) {
out.write(tmp, 0, l);
}
out.flush();
}
public String getTransferEncoding() {
return MIME.ENC_8BIT;
}
public long getContentLength() {
return this.content.length;
}
public String getFilename() {
return null;
}
}

View file

@ -0,0 +1,31 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
/**
* MIME body part implementations.
*/
package ch.boye.httpclientandroidlib.entity.mime.content;

View file

@ -0,0 +1,31 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
/**
* MIME coded HTTP entity implementations.
*/
package ch.boye.httpclientandroidlib.entity.mime;

View file

@ -0,0 +1,31 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
/**
* Core HTTP entity implementations.
*/
package ch.boye.httpclientandroidlib.entity;