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.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: 778701 $
037     */
038    public class HttpComponent extends HeaderFilterStrategyComponent {
039        protected HttpClientConfigurer httpClientConfigurer;
040        protected HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
041        protected HttpBinding httpBinding;
042        private boolean matchOnUriPrefix;
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 parameters) {
070            // lookup http binding in registry if provided
071            String ref = getAndRemoveParameter(parameters, "httpBindingRef", String.class);
072            if (ref != null) {
073                httpBinding = CamelContextHelper.mandatoryLookup(getCamelContext(), ref, HttpBinding.class);
074            }
075            
076            // lookup http client front configurer in the registry if provided
077            ref = getAndRemoveParameter(parameters, "httpClientConfigurerRef", String.class);
078            if (ref != null) {
079                httpClientConfigurer = CamelContextHelper.mandatoryLookup(getCamelContext(), ref, HttpClientConfigurer.class);
080            }
081            
082            // check the user name and password for basic authentication
083            String username = getAndRemoveParameter(parameters, "username", String.class);
084            String password = getAndRemoveParameter(parameters, "password", String.class);
085            if (username != null && password != null) {
086                
087                httpClientConfigurer = CompositeHttpConfigurer.combineConfigurers(
088                    httpClientConfigurer, 
089                    new BasicAuthenticationHttpClientConfigurer(username, password));
090            }
091            
092            // check the proxy details for proxy configuration
093            String host = getAndRemoveParameter(parameters, "proxyHost", String.class);
094            Integer port = getAndRemoveParameter(parameters, "proxyPort", Integer.class);
095            if (host != null && port != null) {
096                String proxyUsername = getAndRemoveParameter(parameters, "proxyUsername", String.class);
097                String proxyPassword = getAndRemoveParameter(parameters, "proxyPassword", String.class);
098                if (proxyUsername != null && proxyPassword != null) {
099                    httpClientConfigurer = CompositeHttpConfigurer.combineConfigurers(
100                        httpClientConfigurer, new ProxyHttpClientConfigurer(host, port, proxyUsername, proxyPassword));
101                } else {
102                    httpClientConfigurer = CompositeHttpConfigurer.combineConfigurers(
103                        httpClientConfigurer, new ProxyHttpClientConfigurer(host, port));
104                }
105            }
106            matchOnUriPrefix = Boolean.parseBoolean(getAndRemoveParameter(parameters, "matchOnUriPrefix", String.class));
107        }
108        
109        @Override
110        protected Endpoint createEndpoint(String uri, String remaining, Map parameters)
111            throws Exception {
112    
113            // http client can be configured from URI options
114            HttpClientParams clientParams = new HttpClientParams();
115            IntrospectionSupport.setProperties(clientParams, parameters, "httpClient.");
116            // validate that we could resolve all httpClient. parameters as this component is lenient
117            validateParameters(uri, parameters, "httpClient.");
118    
119            configureParameters(parameters);
120    
121            // should we use an exception for failed error codes?
122            Boolean throwExceptionOnFailure = getAndRemoveParameter(parameters, "throwExceptionOnFailure", Boolean.class);
123    
124            // restructure uri to be based on the parameters left as we dont want to include the Camel internal options
125            URI httpUri = URISupport.createRemainingURI(new URI(uri), parameters);
126            uri = httpUri.toString();
127    
128            // validate http uri that end-user did not duplicate the http part that can be a common error
129            String part = httpUri.getSchemeSpecificPart();
130            if (part != null) {
131                part = part.toLowerCase();
132                if (part.startsWith("//http//") || part.startsWith("//https//")) {
133                    throw new ResolveEndpointFailedException(uri,
134                            "The uri part is not configured correctly. You have duplicated the http(s) protocol.");
135                }
136            }
137    
138            HttpEndpoint endpoint = new HttpEndpoint(uri, this, httpUri, clientParams, httpConnectionManager, httpClientConfigurer);
139            if (httpBinding != null) {
140                endpoint.setBinding(httpBinding);
141            }
142            setEndpointHeaderFilterStrategy(endpoint);
143            if (throwExceptionOnFailure != null) {
144                endpoint.setThrowExceptionOnFailure(throwExceptionOnFailure);
145            }
146            setProperties(endpoint, parameters);
147            return endpoint;
148        }    
149       
150        @Override
151        protected boolean useIntrospectionOnEndpoint() {
152            return false;
153        }
154    
155        public HttpClientConfigurer getHttpClientConfigurer() {
156            return httpClientConfigurer;
157        }
158    
159        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
160            this.httpClientConfigurer = httpClientConfigurer;
161        }
162    
163        public HttpConnectionManager getHttpConnectionManager() {
164            return httpConnectionManager;
165        }
166    
167        public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
168            this.httpConnectionManager = httpConnectionManager;
169        }
170    
171        public HttpBinding getHttpBinding() {
172            return httpBinding;
173        }
174    
175        public void setHttpBinding(HttpBinding httpBinding) {
176            this.httpBinding = httpBinding;
177        }
178    
179        public boolean isMatchOnUriPrefix() {
180            return matchOnUriPrefix;
181        }  
182        
183    }