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.util.Map;
021    
022    import org.apache.camel.Endpoint;
023    import org.apache.camel.ResolveEndpointFailedException;
024    import org.apache.camel.impl.HeaderFilterStrategyComponent;
025    import org.apache.camel.util.CastUtils;
026    import org.apache.camel.util.IntrospectionSupport;
027    import org.apache.camel.util.URISupport;
028    import org.apache.commons.httpclient.HttpConnectionManager;
029    import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
030    import org.apache.commons.httpclient.params.HttpClientParams;
031    
032    /**
033     * Defines the <a href="http://camel.apache.org/http.html">HTTP
034     * Component</a>
035     *
036     * @version $Revision: 890042 $
037     */
038    public class HttpComponent extends HeaderFilterStrategyComponent {
039        protected HttpClientConfigurer httpClientConfigurer;
040        protected HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
041        protected HttpBinding httpBinding;
042       
043        
044        /**
045         * Connects the URL specified on the endpoint to the specified processor.
046         *
047         * @param  consumer the consumer
048         * @throws Exception can be thrown
049         */
050        public void connect(HttpConsumer consumer) throws Exception {
051        }
052    
053        /**
054         * Disconnects the URL specified on the endpoint from the specified processor.
055         *
056         * @param  consumer the consumer
057         * @throws Exception can be thrown
058         */
059        public void disconnect(HttpConsumer consumer) throws Exception {
060        }
061    
062        /** 
063         * Setting http binding and http client configurer according to the parameters
064         * Also setting the BasicAuthenticationHttpClientConfigurer if the username 
065         * and password option are not null.
066         * 
067         * @param parameters the map of parameters 
068         */
069        protected void configureParameters(Map<String, Object> parameters) {
070            // lookup http binding in registry if provided
071            httpBinding = resolveAndRemoveReferenceParameter(
072                    parameters, "httpBindingRef", HttpBinding.class);
073            
074            // lookup http client front configurer in the registry if provided
075            httpClientConfigurer = resolveAndRemoveReferenceParameter(
076                    parameters, "httpClientConfigurerRef", HttpClientConfigurer.class);
077            
078            // check the user name and password for basic authentication
079            String username = getAndRemoveParameter(parameters, "username", String.class);
080            String password = getAndRemoveParameter(parameters, "password", String.class);
081            String domain = getAndRemoveParameter(parameters, "domain", String.class);
082            String host = getAndRemoveParameter(parameters, "host", String.class);
083            if (username != null && password != null) {
084                httpClientConfigurer = CompositeHttpConfigurer.combineConfigurers(
085                    httpClientConfigurer, 
086                    new BasicAuthenticationHttpClientConfigurer(username, password, domain, host));
087            }
088            
089            // check the proxy details for proxy configuration
090            String proxyHost = getAndRemoveParameter(parameters, "proxyHost", String.class);
091            Integer proxyPort = getAndRemoveParameter(parameters, "proxyPort", Integer.class);
092            if (proxyHost != null && proxyPort != null) {
093                String proxyUsername = getAndRemoveParameter(parameters, "proxyUsername", String.class);
094                String proxyPassword = getAndRemoveParameter(parameters, "proxyPassword", String.class);
095                String proxyDomain = getAndRemoveParameter(parameters, "proxyDomain", String.class);
096                String proxyNtHost = getAndRemoveParameter(parameters, "proxyNtHost", String.class);
097                if (proxyUsername != null && proxyPassword != null) {
098                    httpClientConfigurer = CompositeHttpConfigurer.combineConfigurers(
099                        httpClientConfigurer, new ProxyHttpClientConfigurer(proxyHost, proxyPort, proxyUsername, proxyPassword, proxyDomain, proxyNtHost));
100                } else {
101                    httpClientConfigurer = CompositeHttpConfigurer.combineConfigurers(
102                        httpClientConfigurer, new ProxyHttpClientConfigurer(proxyHost, proxyPort));
103                }
104            }
105            
106        }
107        
108        @Override
109        protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
110    
111            // http client can be configured from URI options
112            HttpClientParams clientParams = new HttpClientParams();
113            IntrospectionSupport.setProperties(clientParams, parameters, "httpClient.");
114            // validate that we could resolve all httpClient. parameters as this component is lenient
115            validateParameters(uri, parameters, "httpClient.");
116    
117            configureParameters(parameters);
118    
119            // should we use an exception for failed error codes?
120            Boolean throwExceptionOnFailure = getAndRemoveParameter(parameters, "throwExceptionOnFailure", Boolean.class);
121    
122            Boolean bridgeEndpoint = getAndRemoveParameter(parameters, "bridgeEndpoint", Boolean.class);
123            
124            Boolean matchOnUriPrefix = Boolean.parseBoolean(getAndRemoveParameter(parameters, "matchOnUriPrefix", String.class));
125            // restructure uri to be based on the parameters left as we dont want to include the Camel internal options
126            URI httpUri = URISupport.createRemainingURI(new URI(uri), CastUtils.cast(parameters));
127            uri = httpUri.toString();
128    
129            // validate http uri that end-user did not duplicate the http part that can be a common error
130            String part = httpUri.getSchemeSpecificPart();
131            if (part != null) {
132                part = part.toLowerCase();
133                if (part.startsWith("//http//") || part.startsWith("//https//")) {
134                    throw new ResolveEndpointFailedException(uri,
135                            "The uri part is not configured correctly. You have duplicated the http(s) protocol.");
136                }
137            }
138    
139            HttpEndpoint endpoint = new HttpEndpoint(uri, this, httpUri, clientParams, httpConnectionManager, httpClientConfigurer);
140            if (httpBinding != null) {
141                endpoint.setBinding(httpBinding);
142            }
143            setEndpointHeaderFilterStrategy(endpoint);
144            if (throwExceptionOnFailure != null) {
145                endpoint.setThrowExceptionOnFailure(throwExceptionOnFailure);
146            }
147            if (bridgeEndpoint != null) {
148                endpoint.setBridgeEndpoint(bridgeEndpoint);
149            }
150            if (matchOnUriPrefix != null) {
151                endpoint.setMatchOnUriPrefix(matchOnUriPrefix);
152            }
153            setProperties(endpoint, parameters);
154            return endpoint;
155        }    
156       
157        @Override
158        protected boolean useIntrospectionOnEndpoint() {
159            return false;
160        }
161    
162        public HttpClientConfigurer getHttpClientConfigurer() {
163            return httpClientConfigurer;
164        }
165    
166        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
167            this.httpClientConfigurer = httpClientConfigurer;
168        }
169    
170        public HttpConnectionManager getHttpConnectionManager() {
171            return httpConnectionManager;
172        }
173    
174        public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
175            this.httpConnectionManager = httpConnectionManager;
176        }
177    
178        public HttpBinding getHttpBinding() {
179            return httpBinding;
180        }
181    
182        public void setHttpBinding(HttpBinding httpBinding) {
183            this.httpBinding = httpBinding;
184        }
185        
186    }