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.client.methods;
029
030import java.net.URI;
031
032import org.apache.http.Header;
033import org.apache.http.HttpEntity;
034import org.apache.http.HttpEntityEnclosingRequest;
035import org.apache.http.HttpHost;
036import org.apache.http.HttpRequest;
037import org.apache.http.ProtocolVersion;
038import org.apache.http.RequestLine;
039import org.apache.http.message.AbstractHttpMessage;
040import org.apache.http.message.BasicRequestLine;
041import org.apache.http.params.HttpParams;
042import org.apache.http.protocol.HTTP;
043import org.apache.http.util.Args;
044
045/**
046 * A wrapper class for {@link HttpRequest} that can be used to change properties of the current
047 * request without modifying the original object.
048 *
049 * @since 4.3
050 */
051@SuppressWarnings("deprecation")
052public class HttpRequestWrapper extends AbstractHttpMessage implements HttpUriRequest {
053
054    private final HttpRequest original;
055    private final HttpHost target;
056    private final String method;
057    private RequestLine requestLine;
058    private ProtocolVersion version;
059    private URI uri;
060
061    private HttpRequestWrapper(final HttpRequest request, final HttpHost target) {
062        super();
063        this.original = Args.notNull(request, "HTTP request");
064        this.target = target;
065        this.version = this.original.getRequestLine().getProtocolVersion();
066        this.method = this.original.getRequestLine().getMethod();
067        if (request instanceof HttpUriRequest) {
068            this.uri = ((HttpUriRequest) request).getURI();
069        } else {
070            this.uri = null;
071        }
072        setHeaders(request.getAllHeaders());
073    }
074
075    @Override
076    public ProtocolVersion getProtocolVersion() {
077        return this.version != null ? this.version : this.original.getProtocolVersion();
078    }
079
080    public void setProtocolVersion(final ProtocolVersion version) {
081        this.version = version;
082        this.requestLine = null;
083    }
084
085    @Override
086    public URI getURI() {
087        return this.uri;
088    }
089
090    public void setURI(final URI uri) {
091        this.uri = uri;
092        this.requestLine = null;
093    }
094
095    @Override
096    public String getMethod() {
097        return method;
098    }
099
100    @Override
101    public void abort() throws UnsupportedOperationException {
102        throw new UnsupportedOperationException();
103    }
104
105    @Override
106    public boolean isAborted() {
107        return false;
108    }
109
110    @Override
111    public RequestLine getRequestLine() {
112        if (this.requestLine == null) {
113            String requestUri;
114            if (this.uri != null) {
115                requestUri = this.uri.toASCIIString();
116            } else {
117                requestUri = this.original.getRequestLine().getUri();
118            }
119            if (requestUri == null || requestUri.isEmpty()) {
120                requestUri = "/";
121            }
122            this.requestLine = new BasicRequestLine(this.method, requestUri, getProtocolVersion());
123        }
124        return this.requestLine;
125    }
126
127    public HttpRequest getOriginal() {
128        return this.original;
129    }
130
131    /**
132     * @since 4.4
133     */
134    public HttpHost getTarget() {
135        return target;
136    }
137
138    @Override
139    public String toString() {
140        return getRequestLine() + " " + this.headergroup;
141    }
142
143    static class HttpEntityEnclosingRequestWrapper extends HttpRequestWrapper
144        implements HttpEntityEnclosingRequest {
145
146        private HttpEntity entity;
147
148        HttpEntityEnclosingRequestWrapper(final HttpEntityEnclosingRequest request, final HttpHost target) {
149            super(request, target);
150            this.entity = request.getEntity();
151        }
152
153        @Override
154        public HttpEntity getEntity() {
155            return this.entity;
156        }
157
158        @Override
159        public void setEntity(final HttpEntity entity) {
160            this.entity = entity;
161        }
162
163        @Override
164        public boolean expectContinue() {
165            final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE);
166            return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue());
167        }
168
169    }
170
171    /**
172     * Creates a mutable wrapper of the original request.
173     *
174     * @param request original request
175     * @return mutable request wrappering the original one
176     */
177    public static HttpRequestWrapper wrap(final HttpRequest request) {
178        return wrap(request, null);
179    }
180
181
182    /**
183     * Creates a mutable wrapper of the original request.
184     *
185     * @param request original request
186     * @param target original target, if explicitly specified
187     * @return mutable request wrappering the original one
188     * @since 4.4
189     */
190    public static HttpRequestWrapper wrap(final HttpRequest request, final HttpHost target) {
191        Args.notNull(request, "HTTP request");
192        if (request instanceof HttpEntityEnclosingRequest) {
193            return new HttpEntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request, target);
194        } else {
195            return new HttpRequestWrapper(request, target);
196        }
197    }
198
199    /**
200     * @deprecated (4.3) use
201     *   {@link org.apache.http.client.config.RequestConfig}.
202     */
203    @Override
204    @Deprecated
205    public HttpParams getParams() {
206        if (this.params == null) {
207            this.params = original.getParams().copy();
208        }
209        return this.params;
210    }
211
212}