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 */
027package org.apache.http.impl.execchain;
028
029import java.io.IOException;
030import java.io.InputStream;
031import java.io.OutputStream;
032
033import org.apache.http.Header;
034import org.apache.http.HttpEntity;
035import org.apache.http.HttpEntityEnclosingRequest;
036import org.apache.http.HttpRequest;
037
038/**
039 * A Proxy class for {@link org.apache.http.HttpEntity} enclosed in a request message.
040 *
041 * @since 4.3
042 */
043class RequestEntityProxy implements HttpEntity  {
044
045    static void enhance(final HttpEntityEnclosingRequest request) {
046        final HttpEntity entity = request.getEntity();
047        if (entity != null && !entity.isRepeatable() && !isEnhanced(entity)) {
048            request.setEntity(new RequestEntityProxy(entity));
049        }
050    }
051
052    static boolean isEnhanced(final HttpEntity entity) {
053        return entity instanceof RequestEntityProxy;
054    }
055
056    static boolean isRepeatable(final HttpRequest request) {
057        if (request instanceof HttpEntityEnclosingRequest) {
058            final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
059            if (entity != null) {
060                if (isEnhanced(entity)) {
061                    final RequestEntityProxy proxy = (RequestEntityProxy) entity;
062                    if (!proxy.isConsumed()) {
063                        return true;
064                    }
065                }
066                return entity.isRepeatable();
067            }
068        }
069        return true;
070    }
071
072    private final HttpEntity original;
073    private boolean consumed = false;
074
075    RequestEntityProxy(final HttpEntity original) {
076        super();
077        this.original = original;
078    }
079
080    public HttpEntity getOriginal() {
081        return original;
082    }
083
084    public boolean isConsumed() {
085        return consumed;
086    }
087
088    @Override
089    public boolean isRepeatable() {
090        return original.isRepeatable();
091    }
092
093    @Override
094    public boolean isChunked() {
095        return original.isChunked();
096    }
097
098    @Override
099    public long getContentLength() {
100        return original.getContentLength();
101    }
102
103    @Override
104    public Header getContentType() {
105        return original.getContentType();
106    }
107
108    @Override
109    public Header getContentEncoding() {
110        return original.getContentEncoding();
111    }
112
113    @Override
114    public InputStream getContent() throws IOException, IllegalStateException {
115        return original.getContent();
116    }
117
118    @Override
119    public void writeTo(final OutputStream outstream) throws IOException {
120        consumed = true;
121        original.writeTo(outstream);
122    }
123
124    @Override
125    public boolean isStreaming() {
126        return original.isStreaming();
127    }
128
129    @Override
130    @Deprecated
131    public void consumeContent() throws IOException {
132        consumed = true;
133        original.consumeContent();
134    }
135
136    @Override
137    public String toString() {
138        final StringBuilder sb = new StringBuilder("RequestEntityProxy{");
139        sb.append(original);
140        sb.append('}');
141        return sb.toString();
142    }
143
144}