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.apache.commons.logging.Log;
036    import org.apache.commons.logging.LogFactory;
037    
038    /**
039     * Represents a <a href="http://camel.apache.org/http.html">HTTP endpoint</a>
040     *
041     * @version $Revision: 1053029 $
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 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                if (LOG.isDebugEnabled()) {
106                    LOG.debug("CamelContext properties http.proxyHost and http.proxyPort detected. Using http proxy host: "
107                            + host + " port: " + port);
108                }
109                answer.getHostConfiguration().setProxy(host, port);
110            }
111    
112            if (proxyHost != null) {
113                if (LOG.isDebugEnabled()) {
114                    LOG.debug("Using proxy: " + proxyHost + ":" + proxyPort);
115                }
116                answer.getHostConfiguration().setProxy(proxyHost, proxyPort);
117            }
118    
119            if (authMethodPriority != null) {
120                List<String> authPrefs = new ArrayList<String>();
121                Iterator it = getCamelContext().getTypeConverter().convertTo(Iterator.class, authMethodPriority);
122                int i = 1;
123                while (it.hasNext()) {
124                    Object value = it.next();
125                    AuthMethod auth = getCamelContext().getTypeConverter().convertTo(AuthMethod.class, value);
126                    if (auth == null) {
127                        throw new IllegalArgumentException("Unknown authMethod: " + value + " in authMethodPriority: " + authMethodPriority);
128                    }
129                    if (LOG.isDebugEnabled()) {
130                        LOG.debug("Using authSchemePriority #" + i + ": " + auth);
131                    }
132                    authPrefs.add(auth.name());
133                    i++;
134                }
135                if (!authPrefs.isEmpty()) {
136                    answer.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
137                }
138            }
139    
140            answer.setHttpConnectionManager(httpConnectionManager);
141            HttpClientConfigurer configurer = getHttpClientConfigurer();
142            if (configurer != null) {
143                configurer.configureHttpClient(answer);
144            }
145            return answer;
146        }
147    
148        public void connect(HttpConsumer consumer) throws Exception {
149            component.connect(consumer);
150        }
151    
152        public void disconnect(HttpConsumer consumer) throws Exception {
153            component.disconnect(consumer);
154        }
155    
156        public boolean isLenientProperties() {
157            // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
158            return true;
159        }
160    
161        public boolean isSingleton() {
162            return true;
163        }
164    
165    
166        // Properties
167        //-------------------------------------------------------------------------
168    
169        /**
170         * Provide access to the client parameters used on new {@link HttpClient} instances
171         * used by producers or consumers of this endpoint.
172         */
173        public HttpClientParams getClientParams() {
174            return clientParams;
175        }
176    
177        /**
178         * Provide access to the client parameters used on new {@link HttpClient} instances
179         * used by producers or consumers of this endpoint.
180         */
181        public void setClientParams(HttpClientParams clientParams) {
182            this.clientParams = clientParams;
183        }
184    
185        public HttpClientConfigurer getHttpClientConfigurer() {
186            return httpClientConfigurer;
187        }
188    
189        /**
190         * Register a custom configuration strategy for new {@link HttpClient} instances
191         * created by producers or consumers such as to configure authentication mechanisms etc
192         *
193         * @param httpClientConfigurer the strategy for configuring new {@link HttpClient} instances
194         */
195        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
196            this.httpClientConfigurer = httpClientConfigurer;
197        }
198    
199        public HttpBinding getBinding() {
200            if (binding == null) {
201                binding = new DefaultHttpBinding(this);
202            }
203            return binding;
204        }
205    
206        public void setBinding(HttpBinding binding) {
207            this.binding = binding;
208        }
209    
210        public String getPath() {
211            return httpUri.getPath();
212        }
213    
214        public int getPort() {
215            if (httpUri.getPort() == -1) {
216                if ("https".equals(getProtocol())) {
217                    return 443;
218                } else {
219                    return 80;
220                }
221            }
222            return httpUri.getPort();
223        }
224    
225        public String getProtocol() {
226            return httpUri.getScheme();
227        }
228    
229        public URI getHttpUri() {
230            return httpUri;
231        }
232    
233        public void setHttpUri(URI httpUri) {
234            this.httpUri = httpUri;
235        }
236    
237        public HttpConnectionManager getHttpConnectionManager() {
238            return httpConnectionManager;
239        }
240    
241        public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
242            this.httpConnectionManager = httpConnectionManager;
243        }
244    
245        public HeaderFilterStrategy getHeaderFilterStrategy() {
246            return headerFilterStrategy;
247        }
248    
249        public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
250            this.headerFilterStrategy = headerFilterStrategy;
251        }
252    
253        public boolean isThrowExceptionOnFailure() {
254            return throwExceptionOnFailure;
255        }
256    
257        public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
258            this.throwExceptionOnFailure = throwExceptionOnFailure;
259        }
260        
261        public boolean isBridgeEndpoint() {
262            return bridgeEndpoint;
263        }
264        
265        public void setBridgeEndpoint(boolean bridge) {
266            this.bridgeEndpoint = bridge;
267        }
268        
269        public boolean isMatchOnUriPrefix() {
270            return matchOnUriPrefix;
271        }
272        
273        public void setMatchOnUriPrefix(boolean match) {
274            this.matchOnUriPrefix = match;
275        }
276        
277        public boolean isDisableStreamCache() {
278            return this.disableStreamCache;
279        }
280        
281        public void setDisableStreamCache(boolean disable) {
282            this.disableStreamCache = disable;
283        }
284        
285        public boolean isChunked() {
286            return this.chunked;
287        }
288        
289        public void setChunked(boolean chunked) {
290            this.chunked = chunked;
291        }
292    
293        public String getProxyHost() {
294            return proxyHost;
295        }
296    
297        public void setProxyHost(String proxyHost) {
298            this.proxyHost = proxyHost;
299        }
300    
301        public int getProxyPort() {
302            return proxyPort;
303        }
304    
305        public void setProxyPort(int proxyPort) {
306            this.proxyPort = proxyPort;
307        }
308    
309        public String getAuthMethodPriority() {
310            return authMethodPriority;
311        }
312    
313        public void setAuthMethodPriority(String authMethodPriority) {
314            this.authMethodPriority = authMethodPriority;
315        }
316    
317        public boolean isTransferException() {
318            return transferException;
319        }
320    
321        public void setTransferException(boolean transferException) {
322            this.transferException = transferException;
323        }
324    }