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