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