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.http4;
018    
019    import java.net.URI;
020    import java.net.URISyntaxException;
021    
022    import org.apache.camel.PollingConsumer;
023    import org.apache.camel.Producer;
024    import org.apache.camel.impl.DefaultPollingEndpoint;
025    import org.apache.camel.spi.HeaderFilterStrategy;
026    import org.apache.camel.spi.HeaderFilterStrategyAware;
027    import org.apache.camel.util.ObjectHelper;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.http.HttpHost;
031    import org.apache.http.client.HttpClient;
032    import org.apache.http.conn.ClientConnectionManager;
033    import org.apache.http.conn.params.ConnRoutePNames;
034    import org.apache.http.impl.client.DefaultHttpClient;
035    import org.apache.http.params.BasicHttpParams;
036    import org.apache.http.params.HttpParams;
037    
038    /**
039     * Represents a <a href="http://camel.apache.org/http.html">HTTP endpoint</a>
040     *
041     * @version $Revision: 19375 $
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 HttpParams clientParams;
051        private HttpClientConfigurer httpClientConfigurer;
052        private ClientConnectionManager clientConnectionManager;
053        private HttpClient httpClient;
054        private boolean throwExceptionOnFailure = true;
055        private boolean bridgeEndpoint;
056        private boolean matchOnUriPrefix;
057        private boolean chunked = true;
058        private boolean disableStreamCache;
059    
060        public HttpEndpoint() {
061        }
062    
063        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI) throws URISyntaxException {
064            this(endPointURI, component, httpURI, null);
065        }
066    
067        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, ClientConnectionManager clientConnectionManager) throws URISyntaxException {
068            this(endPointURI, component, httpURI, new BasicHttpParams(), clientConnectionManager, null);
069        }
070    
071        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, HttpParams clientParams,
072                            ClientConnectionManager clientConnectionManager, HttpClientConfigurer clientConfigurer) throws URISyntaxException {
073            super(endPointURI, component);
074            this.component = component;
075            this.httpUri = httpURI;
076            this.clientParams = clientParams;
077            this.httpClientConfigurer = clientConfigurer;
078            this.clientConnectionManager = clientConnectionManager;
079        }
080    
081        public Producer createProducer() throws Exception {
082            return new HttpProducer(this);
083        }
084    
085        public PollingConsumer createPollingConsumer() throws Exception {
086            return new HttpPollingConsumer(this);
087        }
088    
089        /**
090         * Gets the HttpClient to be used by {@link org.apache.camel.component.http4.HttpProducer}
091         */
092        public synchronized HttpClient getHttpClient() {
093            if (httpClient == null) {
094                httpClient = createHttpClient();
095            }
096            return httpClient;
097        }
098    
099        public void setHttpClient(HttpClient httpClient) {
100            this.httpClient = httpClient;
101        }
102    
103        /**
104         * Factory method to create a new {@link HttpClient} instance
105         * <p/>
106         * Producers and consumers should use the {@link #getHttpClient()} method instead.
107         */
108        protected HttpClient createHttpClient() {
109            ObjectHelper.notNull(clientParams, "clientParams");
110            ObjectHelper.notNull(clientConnectionManager, "httpConnectionManager");
111    
112            HttpClient answer = new DefaultHttpClient(clientConnectionManager, getClientParams());
113    
114            // configure http proxy from camelContext
115            if (ObjectHelper.isNotEmpty(getCamelContext().getProperties().get("http.proxyHost")) && ObjectHelper.isNotEmpty(getCamelContext().getProperties().get("http.proxyPort"))) {
116                String host = getCamelContext().getProperties().get("http.proxyHost");
117                int port = Integer.parseInt(getCamelContext().getProperties().get("http.proxyPort"));
118                if (LOG.isDebugEnabled()) {
119                    LOG.debug("CamelContext properties http.proxyHost and http.proxyPort detected. Using http proxy host: "
120                            + host + " port: " + port);
121                }
122                HttpHost proxy = new HttpHost(host, port);
123                answer.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
124            }
125    
126            HttpClientConfigurer configurer = getHttpClientConfigurer();
127            if (configurer != null) {
128                configurer.configureHttpClient(answer);
129            }
130    
131            if (LOG.isDebugEnabled()) {
132                LOG.debug("Created HttpClient " + answer);
133            }
134            return answer;
135        }
136    
137        public void connect(HttpConsumer consumer) throws Exception {
138            component.connect(consumer);
139        }
140    
141        public void disconnect(HttpConsumer consumer) throws Exception {
142            component.disconnect(consumer);
143        }
144    
145        public boolean isLenientProperties() {
146            // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
147            return true;
148        }
149    
150        public boolean isSingleton() {
151            return true;
152        }
153    
154    
155        // Properties
156        //-------------------------------------------------------------------------
157    
158        /**
159         * Provide access to the client parameters used on new {@link HttpClient} instances
160         * used by producers or consumers of this endpoint.
161         */
162        public HttpParams getClientParams() {
163            return clientParams;
164        }
165    
166        /**
167         * Provide access to the client parameters used on new {@link HttpClient} instances
168         * used by producers or consumers of this endpoint.
169         */
170        public void setClientParams(HttpParams clientParams) {
171            this.clientParams = clientParams;
172        }
173    
174        public HttpClientConfigurer getHttpClientConfigurer() {
175            return httpClientConfigurer;
176        }
177    
178        /**
179         * Register a custom configuration strategy for new {@link HttpClient} instances
180         * created by producers or consumers such as to configure authentication mechanisms etc
181         *
182         * @param httpClientConfigurer the strategy for configuring new {@link HttpClient} instances
183         */
184        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
185            this.httpClientConfigurer = httpClientConfigurer;
186        }
187    
188        public HttpBinding getBinding() {
189            if (binding == null) {
190                binding = new DefaultHttpBinding(getHeaderFilterStrategy());
191            }
192            return binding;
193        }
194    
195        public void setBinding(HttpBinding binding) {
196            this.binding = binding;
197        }
198    
199        public String getPath() {
200            return httpUri.getPath();
201        }
202    
203        public int getPort() {
204            if (httpUri.getPort() == -1) {
205                if ("https".equals(getProtocol())) {
206                    return 443;
207                } else {
208                    return 80;
209                }
210            }
211            return httpUri.getPort();
212        }
213    
214        public String getProtocol() {
215            return httpUri.getScheme();
216        }
217    
218        public URI getHttpUri() {
219            return httpUri;
220        }
221    
222        public void setHttpUri(URI httpUri) {
223            this.httpUri = httpUri;
224        }
225    
226        public ClientConnectionManager getClientConnectionManager() {
227            return clientConnectionManager;
228        }
229    
230        public void setClientConnectionManager(ClientConnectionManager clientConnectionManager) {
231            this.clientConnectionManager = clientConnectionManager;
232        }
233    
234        public HeaderFilterStrategy getHeaderFilterStrategy() {
235            return headerFilterStrategy;
236        }
237    
238        public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
239            this.headerFilterStrategy = headerFilterStrategy;
240        }
241    
242        public boolean isThrowExceptionOnFailure() {
243            return throwExceptionOnFailure;
244        }
245    
246        public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
247            this.throwExceptionOnFailure = throwExceptionOnFailure;
248        }
249    
250        public boolean isBridgeEndpoint() {
251            return bridgeEndpoint;
252        }
253    
254        public void setBridgeEndpoint(boolean bridge) {
255            this.bridgeEndpoint = bridge;
256        }
257    
258        public boolean isMatchOnUriPrefix() {
259            return matchOnUriPrefix;
260        }
261    
262        public void setMatchOnUriPrefix(boolean match) {
263            this.matchOnUriPrefix = match;
264        }
265        
266        public boolean isDisableStreamCache() {
267            return this.disableStreamCache;
268        }
269           
270        public void setDisableStreamCache(boolean disable) {
271            this.disableStreamCache = disable;
272        }
273    
274        public boolean isChunked() {
275            return this.chunked;
276        }
277    
278        public void setChunked(boolean chunked) {
279            this.chunked = chunked;
280        }
281    
282    }