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.http;
018    
019    import java.net.URI;
020    import java.net.URISyntaxException;
021    import java.util.ArrayList;
022    import java.util.Iterator;
023    import java.util.List;
024    
025    import org.apache.camel.PollingConsumer;
026    import org.apache.camel.Producer;
027    import org.apache.camel.impl.DefaultPollingEndpoint;
028    import org.apache.camel.spi.HeaderFilterStrategy;
029    import org.apache.camel.spi.HeaderFilterStrategyAware;
030    import org.apache.camel.util.ObjectHelper;
031    import org.apache.commons.httpclient.HttpClient;
032    import org.apache.commons.httpclient.HttpConnectionManager;
033    import org.apache.commons.httpclient.auth.AuthPolicy;
034    import org.apache.commons.httpclient.params.HttpClientParams;
035    import org.slf4j.Logger;
036    import org.slf4j.LoggerFactory;
037    
038    /**
039     * Represents a <a href="http://camel.apache.org/http.html">HTTP endpoint</a>
040     *
041     * @version 
042     */
043    public class HttpEndpoint extends DefaultPollingEndpoint implements HeaderFilterStrategyAware {
044    
045        private static final transient Logger LOG = LoggerFactory.getLogger(HttpEndpoint.class);
046        private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
047        private HttpBinding binding;
048        private HttpComponent component;
049        private URI httpUri;
050        private HttpClientParams clientParams;
051        private HttpClientConfigurer httpClientConfigurer;
052        private HttpConnectionManager httpConnectionManager;
053        private boolean throwExceptionOnFailure = true;
054        private boolean bridgeEndpoint;
055        private boolean matchOnUriPrefix;
056        private boolean chunked = true;
057        private boolean disableStreamCache;
058        private String proxyHost;
059        private int proxyPort;
060        private String authMethodPriority;
061        private boolean transferException;
062    
063        public HttpEndpoint() {
064        }
065    
066        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI) throws URISyntaxException {
067            this(endPointURI, component, httpURI, null);
068        }
069    
070        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, HttpConnectionManager httpConnectionManager) throws URISyntaxException {
071            this(endPointURI, component, httpURI, new HttpClientParams(), httpConnectionManager, null);
072        }
073    
074        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, HttpClientParams clientParams,
075                            HttpConnectionManager httpConnectionManager, HttpClientConfigurer clientConfigurer) throws URISyntaxException {
076            super(endPointURI, component);
077            this.component = component;
078            this.httpUri = httpURI;
079            this.clientParams = clientParams;
080            this.httpClientConfigurer = clientConfigurer;
081            this.httpConnectionManager = httpConnectionManager;
082        }
083    
084        public Producer createProducer() throws Exception {
085            return new HttpProducer(this);
086        }
087    
088        public PollingConsumer createPollingConsumer() throws Exception {
089            return new HttpPollingConsumer(this);
090        }
091    
092        /**
093         * Factory method used by producers and consumers to create a new {@link HttpClient} instance
094         */
095        public HttpClient createHttpClient() {
096            ObjectHelper.notNull(clientParams, "clientParams");
097            ObjectHelper.notNull(httpConnectionManager, "httpConnectionManager");
098    
099            HttpClient answer = new HttpClient(getClientParams());
100    
101            // configure http proxy from camelContext
102            if (ObjectHelper.isNotEmpty(getCamelContext().getProperties().get("http.proxyHost")) && ObjectHelper.isNotEmpty(getCamelContext().getProperties().get("http.proxyPort"))) {
103                String host = getCamelContext().getProperties().get("http.proxyHost");
104                int port = Integer.parseInt(getCamelContext().getProperties().get("http.proxyPort"));
105                LOG.debug("CamelContext properties http.proxyHost and http.proxyPort detected. Using http proxy host: {} port: {}", host, port);
106                answer.getHostConfiguration().setProxy(host, port);
107            }
108    
109            if (proxyHost != null) {
110                LOG.debug("Using proxy: {}:{}", proxyHost, proxyPort);
111                answer.getHostConfiguration().setProxy(proxyHost, proxyPort);
112            }
113    
114            if (authMethodPriority != null) {
115                List<String> authPrefs = new ArrayList<String>();
116                Iterator it = getCamelContext().getTypeConverter().convertTo(Iterator.class, authMethodPriority);
117                int i = 1;
118                while (it.hasNext()) {
119                    Object value = it.next();
120                    AuthMethod auth = getCamelContext().getTypeConverter().convertTo(AuthMethod.class, value);
121                    if (auth == null) {
122                        throw new IllegalArgumentException("Unknown authMethod: " + value + " in authMethodPriority: " + authMethodPriority);
123                    }
124                    LOG.debug("Using authSchemePriority #{}: {}", i, auth);
125                    authPrefs.add(auth.name());
126                    i++;
127                }
128                if (!authPrefs.isEmpty()) {
129                    answer.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
130                }
131            }
132    
133            answer.setHttpConnectionManager(httpConnectionManager);
134            HttpClientConfigurer configurer = getHttpClientConfigurer();
135            if (configurer != null) {
136                configurer.configureHttpClient(answer);
137            }
138            return answer;
139        }
140    
141        public void connect(HttpConsumer consumer) throws Exception {
142            component.connect(consumer);
143        }
144    
145        public void disconnect(HttpConsumer consumer) throws Exception {
146            component.disconnect(consumer);
147        }
148    
149        public boolean isLenientProperties() {
150            // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
151            return true;
152        }
153    
154        public boolean isSingleton() {
155            return true;
156        }
157    
158    
159        // Properties
160        //-------------------------------------------------------------------------
161    
162        /**
163         * Provide access to the client parameters used on new {@link HttpClient} instances
164         * used by producers or consumers of this endpoint.
165         */
166        public HttpClientParams getClientParams() {
167            return clientParams;
168        }
169    
170        /**
171         * Provide access to the client parameters used on new {@link HttpClient} instances
172         * used by producers or consumers of this endpoint.
173         */
174        public void setClientParams(HttpClientParams clientParams) {
175            this.clientParams = clientParams;
176        }
177    
178        public HttpClientConfigurer getHttpClientConfigurer() {
179            return httpClientConfigurer;
180        }
181    
182        /**
183         * Register a custom configuration strategy for new {@link HttpClient} instances
184         * created by producers or consumers such as to configure authentication mechanisms etc
185         *
186         * @param httpClientConfigurer the strategy for configuring new {@link HttpClient} instances
187         */
188        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
189            this.httpClientConfigurer = httpClientConfigurer;
190        }
191    
192        public HttpBinding getBinding() {
193            if (binding == null) {
194                binding = new DefaultHttpBinding(this);
195            }
196            return binding;
197        }
198    
199        public void setBinding(HttpBinding binding) {
200            this.binding = binding;
201        }
202    
203        public String getPath() {
204            return httpUri.getPath();
205        }
206    
207        public int getPort() {
208            if (httpUri.getPort() == -1) {
209                if ("https".equals(getProtocol())) {
210                    return 443;
211                } else {
212                    return 80;
213                }
214            }
215            return httpUri.getPort();
216        }
217    
218        public String getProtocol() {
219            return httpUri.getScheme();
220        }
221    
222        public URI getHttpUri() {
223            return httpUri;
224        }
225    
226        public void setHttpUri(URI httpUri) {
227            this.httpUri = httpUri;
228        }
229    
230        public HttpConnectionManager getHttpConnectionManager() {
231            return httpConnectionManager;
232        }
233    
234        public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
235            this.httpConnectionManager = httpConnectionManager;
236        }
237    
238        public HeaderFilterStrategy getHeaderFilterStrategy() {
239            return headerFilterStrategy;
240        }
241    
242        public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
243            this.headerFilterStrategy = headerFilterStrategy;
244        }
245    
246        public boolean isThrowExceptionOnFailure() {
247            return throwExceptionOnFailure;
248        }
249    
250        public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
251            this.throwExceptionOnFailure = throwExceptionOnFailure;
252        }
253        
254        public boolean isBridgeEndpoint() {
255            return bridgeEndpoint;
256        }
257        
258        public void setBridgeEndpoint(boolean bridge) {
259            this.bridgeEndpoint = bridge;
260        }
261        
262        public boolean isMatchOnUriPrefix() {
263            return matchOnUriPrefix;
264        }
265        
266        public void setMatchOnUriPrefix(boolean match) {
267            this.matchOnUriPrefix = match;
268        }
269        
270        public boolean isDisableStreamCache() {
271            return this.disableStreamCache;
272        }
273        
274        public void setDisableStreamCache(boolean disable) {
275            this.disableStreamCache = disable;
276        }
277        
278        public boolean isChunked() {
279            return this.chunked;
280        }
281        
282        public void setChunked(boolean chunked) {
283            this.chunked = chunked;
284        }
285    
286        public String getProxyHost() {
287            return proxyHost;
288        }
289    
290        public void setProxyHost(String proxyHost) {
291            this.proxyHost = proxyHost;
292        }
293    
294        public int getProxyPort() {
295            return proxyPort;
296        }
297    
298        public void setProxyPort(int proxyPort) {
299            this.proxyPort = proxyPort;
300        }
301    
302        public String getAuthMethodPriority() {
303            return authMethodPriority;
304        }
305    
306        public void setAuthMethodPriority(String authMethodPriority) {
307            this.authMethodPriority = authMethodPriority;
308        }
309    
310        public boolean isTransferException() {
311            return transferException;
312        }
313    
314        public void setTransferException(boolean transferException) {
315            this.transferException = transferException;
316        }
317    }