1 /*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 * ====================================================================
20 *
21 * This software consists of voluntary contributions made by many
22 * individuals on behalf of the Apache Software Foundation. For more
23 * information on the Apache Software Foundation, please see
24 * <http://www.apache.org/>.
25 *
26 */
27
28 package org.apache.http.util;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.Reader;
34 import java.io.UnsupportedEncodingException;
35 import java.nio.charset.Charset;
36 import java.nio.charset.UnsupportedCharsetException;
37
38 import org.apache.http.HeaderElement;
39 import org.apache.http.HttpEntity;
40 import org.apache.http.NameValuePair;
41 import org.apache.http.ParseException;
42 import org.apache.http.entity.ContentType;
43 import org.apache.http.protocol.HTTP;
44
45 /**
46 * Static helpers for dealing with {@link HttpEntity}s.
47 *
48 * @since 4.0
49 */
50 public final class EntityUtils {
51
52 private EntityUtils() {
53 }
54
55 /**
56 * Ensures that the entity content is fully consumed and the content stream, if exists,
57 * is closed. The process is done, <i>quietly</i> , without throwing any IOException.
58 *
59 * @param entity
60 *
61 *
62 * @since 4.2
63 */
64 public static void consumeQuietly(final HttpEntity entity) {
65 try {
66 consume(entity);
67 } catch (IOException ioex) {
68 }
69 }
70
71 /**
72 * Ensures that the entity content is fully consumed and the content stream, if exists,
73 * is closed.
74 *
75 * @param entity
76 * @throws IOException if an error occurs reading the input stream
77 *
78 * @since 4.1
79 */
80 public static void consume(final HttpEntity entity) throws IOException {
81 if (entity == null) {
82 return;
83 }
84 if (entity.isStreaming()) {
85 InputStream instream = entity.getContent();
86 if (instream != null) {
87 instream.close();
88 }
89 }
90 }
91
92 /**
93 * Read the contents of an entity and return it as a byte array.
94 *
95 * @param entity
96 * @return byte array containing the entity content. May be null if
97 * {@link HttpEntity#getContent()} is null.
98 * @throws IOException if an error occurs reading the input stream
99 * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
100 */
101 public static byte[] toByteArray(final HttpEntity entity) throws IOException {
102 if (entity == null) {
103 throw new IllegalArgumentException("HTTP entity may not be null");
104 }
105 InputStream instream = entity.getContent();
106 if (instream == null) {
107 return null;
108 }
109 try {
110 if (entity.getContentLength() > Integer.MAX_VALUE) {
111 throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
112 }
113 int i = (int)entity.getContentLength();
114 if (i < 0) {
115 i = 4096;
116 }
117 ByteArrayBuffer buffer = new ByteArrayBuffer(i);
118 byte[] tmp = new byte[4096];
119 int l;
120 while((l = instream.read(tmp)) != -1) {
121 buffer.append(tmp, 0, l);
122 }
123 return buffer.toByteArray();
124 } finally {
125 instream.close();
126 }
127 }
128
129 /**
130 * Obtains character set of the entity, if known.
131 *
132 * @param entity must not be null
133 * @return the character set, or null if not found
134 * @throws ParseException if header elements cannot be parsed
135 * @throws IllegalArgumentException if entity is null
136 *
137 * @deprecated (4.1.3) use {@link ContentType#getOrDefault(HttpEntity)}
138 */
139 @Deprecated
140 public static String getContentCharSet(final HttpEntity entity) throws ParseException {
141 if (entity == null) {
142 throw new IllegalArgumentException("HTTP entity may not be null");
143 }
144 String charset = null;
145 if (entity.getContentType() != null) {
146 HeaderElement values[] = entity.getContentType().getElements();
147 if (values.length > 0) {
148 NameValuePair param = values[0].getParameterByName("charset");
149 if (param != null) {
150 charset = param.getValue();
151 }
152 }
153 }
154 return charset;
155 }
156
157 /**
158 * Obtains mime type of the entity, if known.
159 *
160 * @param entity must not be null
161 * @return the character set, or null if not found
162 * @throws ParseException if header elements cannot be parsed
163 * @throws IllegalArgumentException if entity is null
164 *
165 * @since 4.1
166 *
167 * @deprecated (4.1.3) use {@link ContentType#getOrDefault(HttpEntity)}
168 */
169 @Deprecated
170 public static String getContentMimeType(final HttpEntity entity) throws ParseException {
171 if (entity == null) {
172 throw new IllegalArgumentException("HTTP entity may not be null");
173 }
174 String mimeType = null;
175 if (entity.getContentType() != null) {
176 HeaderElement values[] = entity.getContentType().getElements();
177 if (values.length > 0) {
178 mimeType = values[0].getName();
179 }
180 }
181 return mimeType;
182 }
183
184 /**
185 * Get the entity content as a String, using the provided default character set
186 * if none is found in the entity.
187 * If defaultCharset is null, the default "ISO-8859-1" is used.
188 *
189 * @param entity must not be null
190 * @param defaultCharset character set to be applied if none found in the entity
191 * @return the entity content as a String. May be null if
192 * {@link HttpEntity#getContent()} is null.
193 * @throws ParseException if header elements cannot be parsed
194 * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
195 * @throws IOException if an error occurs reading the input stream
196 */
197 public static String toString(
198 final HttpEntity entity, final Charset defaultCharset) throws IOException, ParseException {
199 if (entity == null) {
200 throw new IllegalArgumentException("HTTP entity may not be null");
201 }
202 InputStream instream = entity.getContent();
203 if (instream == null) {
204 return null;
205 }
206 try {
207 if (entity.getContentLength() > Integer.MAX_VALUE) {
208 throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
209 }
210 int i = (int)entity.getContentLength();
211 if (i < 0) {
212 i = 4096;
213 }
214 Charset charset = null;
215 try {
216 ContentType contentType = ContentType.get(entity);
217 if (contentType != null) {
218 charset = contentType.getCharset();
219 }
220 } catch (final UnsupportedCharsetException ex) {
221 throw new UnsupportedEncodingException(ex.getMessage());
222 }
223 if (charset == null) {
224 charset = defaultCharset;
225 }
226 if (charset == null) {
227 charset = HTTP.DEF_CONTENT_CHARSET;
228 }
229 Reader reader = new InputStreamReader(instream, charset);
230 CharArrayBuffer buffer = new CharArrayBuffer(i);
231 char[] tmp = new char[1024];
232 int l;
233 while((l = reader.read(tmp)) != -1) {
234 buffer.append(tmp, 0, l);
235 }
236 return buffer.toString();
237 } finally {
238 instream.close();
239 }
240 }
241
242 /**
243 * Get the entity content as a String, using the provided default character set
244 * if none is found in the entity.
245 * If defaultCharset is null, the default "ISO-8859-1" is used.
246 *
247 * @param entity must not be null
248 * @param defaultCharset character set to be applied if none found in the entity
249 * @return the entity content as a String. May be null if
250 * {@link HttpEntity#getContent()} is null.
251 * @throws ParseException if header elements cannot be parsed
252 * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
253 * @throws IOException if an error occurs reading the input stream
254 */
255 public static String toString(
256 final HttpEntity entity, final String defaultCharset) throws IOException, ParseException {
257 return toString(entity, defaultCharset != null ? Charset.forName(defaultCharset) : null);
258 }
259
260 /**
261 * Read the contents of an entity and return it as a String.
262 * The content is converted using the character set from the entity (if any),
263 * failing that, "ISO-8859-1" is used.
264 *
265 * @param entity
266 * @return String containing the content.
267 * @throws ParseException if header elements cannot be parsed
268 * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE
269 * @throws IOException if an error occurs reading the input stream
270 */
271 public static String toString(final HttpEntity entity)
272 throws IOException, ParseException {
273 return toString(entity, (Charset)null);
274 }
275
276 }