001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http;
029
030import java.io.IOException;
031import java.io.InputStream;
032import java.io.OutputStream;
033
034/**
035 * An entity that can be sent or received with an HTTP message.
036 * Entities can be found in some
037 * {@link HttpEntityEnclosingRequest requests} and in
038 * {@link HttpResponse responses}, where they are optional.
039 * <p>
040 * There are three distinct types of entities in HttpCore,
041 * depending on where their {@link #getContent content} originates:
042 * <ul>
043 * <li><b>streamed</b>: The content is received from a stream, or
044 *     generated on the fly. In particular, this category includes
045 *     entities being received from a {@link HttpConnection connection}.
046 *     {@link #isStreaming Streamed} entities are generally not
047 *      {@link #isRepeatable repeatable}.
048 *     </li>
049 * <li><b>self-contained</b>: The content is in memory or obtained by
050 *     means that are independent from a connection or other entity.
051 *     Self-contained entities are generally {@link #isRepeatable repeatable}.
052 *     </li>
053 * <li><b>wrapping</b>: The content is obtained from another entity.
054 *     </li>
055 * </ul>
056 * This distinction is important for connection management with incoming
057 * entities. For entities that are created by an application and only sent
058 * using the HTTP components framework, the difference between streamed
059 * and self-contained is of little importance. In that case, it is suggested
060 * to consider non-repeatable entities as streamed, and those that are
061 * repeatable (without a huge effort) as self-contained.
062 *
063 * @since 4.0
064 */
065public interface HttpEntity {
066
067    /**
068     * Tells if the entity is capable of producing its data more than once.
069     * A repeatable entity's getContent() and writeTo(OutputStream) methods
070     * can be called more than once whereas a non-repeatable entity's can not.
071     * @return true if the entity is repeatable, false otherwise.
072     */
073    boolean isRepeatable();
074
075    /**
076     * Tells about chunked encoding for this entity.
077     * The primary purpose of this method is to indicate whether
078     * chunked encoding should be used when the entity is sent.
079     * For entities that are received, it can also indicate whether
080     * the entity was received with chunked encoding.
081     * <p>
082     * The behavior of wrapping entities is implementation dependent,
083     * but should respect the primary purpose.
084     * </p>
085     *
086     * @return  {@code true} if chunked encoding is preferred for this
087     *          entity, or {@code false} if it is not
088     */
089    boolean isChunked();
090
091    /**
092     * Tells the length of the content, if known.
093     *
094     * @return  the number of bytes of the content, or
095     *          a negative number if unknown. If the content length is known
096     *          but exceeds {@link java.lang.Long#MAX_VALUE Long.MAX_VALUE},
097     *          a negative number is returned.
098     */
099    long getContentLength();
100
101    /**
102     * Obtains the Content-Type header, if known.
103     * This is the header that should be used when sending the entity,
104     * or the one that was received with the entity. It can include a
105     * charset attribute.
106     *
107     * @return  the Content-Type header for this entity, or
108     *          {@code null} if the content type is unknown
109     */
110    Header getContentType();
111
112    /**
113     * Obtains the Content-Encoding header, if known.
114     * This is the header that should be used when sending the entity,
115     * or the one that was received with the entity.
116     * Wrapping entities that modify the content encoding should
117     * adjust this header accordingly.
118     *
119     * @return  the Content-Encoding header for this entity, or
120     *          {@code null} if the content encoding is unknown
121     */
122    Header getContentEncoding();
123
124    /**
125     * Returns a content stream of the entity.
126     * {@link #isRepeatable Repeatable} entities are expected
127     * to create a new instance of {@link InputStream} for each invocation
128     * of this method and therefore can be consumed multiple times.
129     * Entities that are not {@link #isRepeatable repeatable} are expected
130     * to return the same {@link InputStream} instance and therefore
131     * may not be consumed more than once.
132     * <p>
133     * IMPORTANT: Please note all entity implementations must ensure that
134     * all allocated resources are properly deallocated after
135     * the {@link InputStream#close()} method is invoked.
136     *
137     * @return content stream of the entity.
138     *
139     * @throws IOException if the stream could not be created
140     * @throws UnsupportedOperationException
141     *  if entity content cannot be represented as {@link java.io.InputStream}.
142     *
143     * @see #isRepeatable()
144     */
145    InputStream getContent() throws IOException, UnsupportedOperationException;
146
147    /**
148     * Writes the entity content out to the output stream.
149     * <p>
150     * IMPORTANT: Please note all entity implementations must ensure that
151     * all allocated resources are properly deallocated when this method
152     * returns.
153     *
154     * @param outstream the output stream to write entity content to
155     *
156     * @throws IOException if an I/O error occurs
157     */
158    void writeTo(OutputStream outstream) throws IOException;
159
160    /**
161     * Tells whether this entity depends on an underlying stream.
162     * Streamed entities that read data directly from the socket should
163     * return {@code true}. Self-contained entities should return
164     * {@code false}. Wrapping entities should delegate this call
165     * to the wrapped entity.
166     *
167     * @return  {@code true} if the entity content is streamed,
168     *          {@code false} otherwise
169     */
170    boolean isStreaming(); // don't expect an exception here
171
172    /**
173     * This method is deprecated since version 4.1. Please use standard
174     * java convention to ensure resource deallocation by calling
175     * {@link InputStream#close()} on the input stream returned by
176     * {@link #getContent()}
177     * <p>
178     * This method is called to indicate that the content of this entity
179     * is no longer required. All entity implementations are expected to
180     * release all allocated resources as a result of this method
181     * invocation. Content streaming entities are also expected to
182     * dispose of the remaining content, if any. Wrapping entities should
183     * delegate this call to the wrapped entity.
184     * <p>
185     * This method is of particular importance for entities being
186     * received from a {@link HttpConnection connection}. The entity
187     * needs to be consumed completely in order to re-use the connection
188     * with keep-alive.
189     *
190     * @throws IOException if an I/O error occurs.
191     *
192     * @deprecated (4.1) Use {@link org.apache.http.util.EntityUtils#consume(HttpEntity)}
193     *
194     * @see #getContent() and #writeTo(OutputStream)
195     */
196    @Deprecated
197    void consumeContent() throws IOException;
198
199}