001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.http4;
018    
019    import java.net.URI;
020    import java.net.URISyntaxException;
021    
022    import org.apache.camel.PollingConsumer;
023    import org.apache.camel.Producer;
024    import org.apache.camel.impl.DefaultPollingEndpoint;
025    import org.apache.camel.spi.HeaderFilterStrategy;
026    import org.apache.camel.spi.HeaderFilterStrategyAware;
027    import org.apache.camel.util.ObjectHelper;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.http.HttpHost;
031    import org.apache.http.client.HttpClient;
032    import org.apache.http.conn.ClientConnectionManager;
033    import org.apache.http.conn.params.ConnRoutePNames;
034    import org.apache.http.impl.client.DefaultHttpClient;
035    import org.apache.http.params.BasicHttpParams;
036    import org.apache.http.params.HttpParams;
037    
038    /**
039     * Represents a <a href="http://camel.apache.org/http.html">HTTP endpoint</a>
040     *
041     * @version $Revision: 1053033 $
042     */
043    public class HttpEndpoint extends DefaultPollingEndpoint implements HeaderFilterStrategyAware {
044    
045        private static final transient Log LOG = LogFactory.getLog(HttpEndpoint.class);
046        private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
047        private HttpBinding binding;
048        private HttpComponent component;
049        private URI httpUri;
050        private HttpParams clientParams;
051        private HttpClientConfigurer httpClientConfigurer;
052        private ClientConnectionManager clientConnectionManager;
053        private HttpClient httpClient;
054        private boolean throwExceptionOnFailure = true;
055        private boolean bridgeEndpoint;
056        private boolean matchOnUriPrefix;
057        private boolean chunked = true;
058        private boolean disableStreamCache;
059        private boolean transferException;
060    
061        public HttpEndpoint() {
062        }
063    
064        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI) throws URISyntaxException {
065            this(endPointURI, component, httpURI, null);
066        }
067    
068        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, ClientConnectionManager clientConnectionManager) throws URISyntaxException {
069            this(endPointURI, component, httpURI, new BasicHttpParams(), clientConnectionManager, null);
070        }
071    
072        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, HttpParams clientParams,
073                            ClientConnectionManager clientConnectionManager, HttpClientConfigurer clientConfigurer) throws URISyntaxException {
074            super(endPointURI, component);
075            this.component = component;
076            this.httpUri = httpURI;
077            this.clientParams = clientParams;
078            this.httpClientConfigurer = clientConfigurer;
079            this.clientConnectionManager = clientConnectionManager;
080        }
081    
082        public Producer createProducer() throws Exception {
083            return new HttpProducer(this);
084        }
085    
086        public PollingConsumer createPollingConsumer() throws Exception {
087            return new HttpPollingConsumer(this);
088        }
089    
090        /**
091         * Gets the HttpClient to be used by {@link org.apache.camel.component.http4.HttpProducer}
092         */
093        public synchronized HttpClient getHttpClient() {
094            if (httpClient == null) {
095                httpClient = createHttpClient();
096            }
097            return httpClient;
098        }
099    
100        public void setHttpClient(HttpClient httpClient) {
101            this.httpClient = httpClient;
102        }
103    
104        /**
105         * Factory method to create a new {@link HttpClient} instance
106         * <p/>
107         * Producers and consumers should use the {@link #getHttpClient()} method instead.
108         */
109        protected HttpClient createHttpClient() {
110            ObjectHelper.notNull(clientParams, "clientParams");
111            ObjectHelper.notNull(clientConnectionManager, "httpConnectionManager");
112    
113            HttpClient answer = new DefaultHttpClient(clientConnectionManager, getClientParams());
114    
115            // configure http proxy from camelContext
116            if (ObjectHelper.isNotEmpty(getCamelContext().getProperties().get("http.proxyHost")) && ObjectHelper.isNotEmpty(getCamelContext().getProperties().get("http.proxyPort"))) {
117                String host = getCamelContext().getProperties().get("http.proxyHost");
118                int port = Integer.parseInt(getCamelContext().getProperties().get("http.proxyPort"));
119                if (LOG.isDebugEnabled()) {
120                    LOG.debug("CamelContext properties http.proxyHost and http.proxyPort detected. Using http proxy host: "
121                            + host + " port: " + port);
122                }
123                HttpHost proxy = new HttpHost(host, port);
124                answer.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
125            }
126    
127            HttpClientConfigurer configurer = getHttpClientConfigurer();
128            if (configurer != null) {
129                configurer.configureHttpClient(answer);
130            }
131    
132            if (LOG.isDebugEnabled()) {
133                LOG.debug("Created HttpClient " + answer);
134            }
135            return answer;
136        }
137    
138        public void connect(HttpConsumer consumer) throws Exception {
139            component.connect(consumer);
140        }
141    
142        public void disconnect(HttpConsumer consumer) throws Exception {
143            component.disconnect(consumer);
144        }
145    
146        public boolean isLenientProperties() {
147            // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
148            return true;
149        }
150    
151        public boolean isSingleton() {
152            return true;
153        }
154    
155    
156        // Properties
157        //-------------------------------------------------------------------------
158    
159        /**
160         * Provide access to the client parameters used on new {@link HttpClient} instances
161         * used by producers or consumers of this endpoint.
162         */
163        public HttpParams getClientParams() {
164            return clientParams;
165        }
166    
167        /**
168         * Provide access to the client parameters used on new {@link HttpClient} instances
169         * used by producers or consumers of this endpoint.
170         */
171        public void setClientParams(HttpParams clientParams) {
172            this.clientParams = clientParams;
173        }
174    
175        public HttpClientConfigurer getHttpClientConfigurer() {
176            return httpClientConfigurer;
177        }
178    
179        /**
180         * Register a custom configuration strategy for new {@link HttpClient} instances
181         * created by producers or consumers such as to configure authentication mechanisms etc
182         *
183         * @param httpClientConfigurer the strategy for configuring new {@link HttpClient} instances
184         */
185        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
186            this.httpClientConfigurer = httpClientConfigurer;
187        }
188    
189        public HttpBinding getBinding() {
190            if (binding == null) {
191                binding = new DefaultHttpBinding(this);
192            }
193            return binding;
194        }
195    
196        public void setBinding(HttpBinding binding) {
197            this.binding = binding;
198        }
199    
200        public String getPath() {
201            return httpUri.getPath();
202        }
203    
204        public int getPort() {
205            if (httpUri.getPort() == -1) {
206                if ("https".equals(getProtocol())) {
207                    return 443;
208                } else {
209                    return 80;
210                }
211            }
212            return httpUri.getPort();
213        }
214    
215        public String getProtocol() {
216            return httpUri.getScheme();
217        }
218    
219        public URI getHttpUri() {
220            return httpUri;
221        }
222    
223        public void setHttpUri(URI httpUri) {
224            this.httpUri = httpUri;
225        }
226    
227        public ClientConnectionManager getClientConnectionManager() {
228            return clientConnectionManager;
229        }
230    
231        public void setClientConnectionManager(ClientConnectionManager clientConnectionManager) {
232            this.clientConnectionManager = clientConnectionManager;
233        }
234    
235        public HeaderFilterStrategy getHeaderFilterStrategy() {
236            return headerFilterStrategy;
237        }
238    
239        public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
240            this.headerFilterStrategy = headerFilterStrategy;
241        }
242    
243        public boolean isThrowExceptionOnFailure() {
244            return throwExceptionOnFailure;
245        }
246    
247        public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
248            this.throwExceptionOnFailure = throwExceptionOnFailure;
249        }
250    
251        public boolean isBridgeEndpoint() {
252            return bridgeEndpoint;
253        }
254    
255        public void setBridgeEndpoint(boolean bridge) {
256            this.bridgeEndpoint = bridge;
257        }
258    
259        public boolean isMatchOnUriPrefix() {
260            return matchOnUriPrefix;
261        }
262    
263        public void setMatchOnUriPrefix(boolean match) {
264            this.matchOnUriPrefix = match;
265        }
266        
267        public boolean isDisableStreamCache() {
268            return this.disableStreamCache;
269        }
270           
271        public void setDisableStreamCache(boolean disable) {
272            this.disableStreamCache = disable;
273        }
274    
275        public boolean isChunked() {
276            return this.chunked;
277        }
278    
279        public void setChunked(boolean chunked) {
280            this.chunked = chunked;
281        }
282    
283        public boolean isTransferException() {
284            return transferException;
285        }
286    
287        public void setTransferException(boolean transferException) {
288            this.transferException = transferException;
289        }
290    }