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.hc.core5.http.io.entity;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35
36 import org.apache.hc.core5.http.HttpEntity;
37 import org.apache.hc.core5.util.Args;
38
39 /**
40 * A wrapping entity that buffers it content if necessary.
41 * The buffered entity is always repeatable.
42 * If the wrapped entity is repeatable itself, calls are passed through.
43 * If the wrapped entity is not repeatable, the content is read into a
44 * buffer once and provided from there as often as required.
45 *
46 * @since 4.0
47 */
48 public class BufferedHttpEntity extends HttpEntityWrapper {
49
50 private final byte[] buffer;
51
52 /**
53 * Creates a new buffered entity wrapper.
54 *
55 * @param entity the entity to wrap, not null
56 * @throws IllegalArgumentException if wrapped is null
57 */
58 public BufferedHttpEntity(final HttpEntity entity) throws IOException {
59 super(entity);
60 if (!entity.isRepeatable() || entity.getContentLength() < 0) {
61 final ByteArrayOutputStream out = new ByteArrayOutputStream();
62 entity.writeTo(out);
63 out.flush();
64 this.buffer = out.toByteArray();
65 } else {
66 this.buffer = null;
67 }
68 }
69
70 @Override
71 public long getContentLength() {
72 if (this.buffer != null) {
73 return this.buffer.length;
74 }
75 return super.getContentLength();
76 }
77
78 @Override
79 public InputStream getContent() throws IOException {
80 if (this.buffer != null) {
81 return new ByteArrayInputStream(this.buffer);
82 }
83 return super.getContent();
84 }
85
86 /**
87 * Tells that this entity does not have to be chunked.
88 *
89 * @return {@code false}
90 */
91 @Override
92 public boolean isChunked() {
93 return (buffer == null) && super.isChunked();
94 }
95
96 /**
97 * Tells that this entity is repeatable.
98 *
99 * @return {@code true}
100 */
101 @Override
102 public boolean isRepeatable() {
103 return true;
104 }
105
106
107 @Override
108 public void writeTo(final OutputStream outStream) throws IOException {
109 Args.notNull(outStream, "Output stream");
110 if (this.buffer != null) {
111 outStream.write(this.buffer);
112 } else {
113 super.writeTo(outStream);
114 }
115 }
116
117
118 // non-javadoc, see interface HttpEntity
119 @Override
120 public boolean isStreaming() {
121 return (buffer == null) && super.isStreaming();
122 }
123
124 } // class BufferedHttpEntity