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    
022    import javax.servlet.http.HttpServletRequest;
023    import javax.servlet.http.HttpServletResponse;
024    
025    import org.apache.camel.ExchangePattern;
026    import org.apache.camel.PollingConsumer;
027    import org.apache.camel.Producer;
028    import org.apache.camel.impl.DefaultPollingEndpoint;
029    import org.apache.camel.spi.HeaderFilterStrategy;
030    import org.apache.commons.httpclient.HttpClient;
031    import org.apache.commons.httpclient.HttpConnectionManager;
032    import org.apache.commons.httpclient.params.HttpClientParams;
033    import org.apache.commons.logging.Log;
034    import org.apache.commons.logging.LogFactory;
035    
036    /**
037     * Represents a <a href="http://activemq.apache.org/camel/http.html">HTTP
038     * endpoint</a>
039     *
040     * @version $Revision: 955530 $
041     */
042    public class HttpEndpoint extends DefaultPollingEndpoint<HttpExchange> {
043    
044        private static final transient Log LOG = LogFactory.getLog(HttpEndpoint.class);
045        private HttpBinding binding;
046        private HttpComponent component;
047        private URI httpUri;
048        private HttpClientParams clientParams;
049        private HttpClientConfigurer httpClientConfigurer;
050        private HttpConnectionManager httpConnectionManager;
051        private boolean chunked = true;
052    
053        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, HttpConnectionManager httpConnectionManager) throws URISyntaxException {
054            this(endPointURI, component, httpURI, new HttpClientParams(), httpConnectionManager, null);
055        }
056    
057        public HttpEndpoint(String endPointURI, HttpComponent component, URI httpURI, HttpClientParams clientParams,
058                            HttpConnectionManager httpConnectionManager, HttpClientConfigurer clientConfigurer) throws URISyntaxException {
059            super(endPointURI, component);
060            this.component = component;
061            this.httpUri = httpURI;
062            this.clientParams = clientParams;
063            this.httpClientConfigurer = clientConfigurer;
064            this.httpConnectionManager = httpConnectionManager;
065        }
066    
067        public Producer<HttpExchange> createProducer() throws Exception {
068            return new HttpProducer(this);
069        }
070    
071        @Override
072        public PollingConsumer<HttpExchange> createPollingConsumer() throws Exception {
073            return new HttpPollingConsumer(this);
074        }
075    
076        public HttpExchange createExchange(ExchangePattern pattern) {
077            return new HttpExchange(this, pattern);
078        }
079    
080        public HttpExchange createExchange(HttpServletRequest request, HttpServletResponse response) {
081            return new HttpExchange(this, request, response);
082        }
083    
084        /**
085         * Factory method used by producers and consumers to create a new {@link HttpClient} instance
086         */
087        public HttpClient createHttpClient() {
088            HttpClient answer = new HttpClient(getClientParams());
089    
090            // configure http proxy if defined as system property
091            // http://java.sun.com/javase/6/docs/technotes/guides/net/proxies.html
092            if (System.getProperty("http.proxyHost") != null && System.getProperty("http.proxyPort") != null) {
093                String host = System.getProperty("http.proxyHost");
094                int port = Integer.parseInt(System.getProperty("http.proxyPort"));
095                if (LOG.isDebugEnabled()) {
096                    LOG.debug("Java System Property http.proxyHost and http.proxyPort detected. Using http proxy host: "
097                            + host + " port: " + port);
098                }
099                answer.getHostConfiguration().setProxy(host, port);
100            }
101    
102            answer.setHttpConnectionManager(httpConnectionManager);
103            HttpClientConfigurer configurer = getHttpClientConfigurer();
104            if (configurer != null) {
105                configurer.configureHttpClient(answer);
106            }
107            return answer;
108        }
109    
110        public void connect(HttpConsumer consumer) throws Exception {
111            component.connect(consumer);
112        }
113    
114        public void disconnect(HttpConsumer consumer) throws Exception {
115            component.disconnect(consumer);
116        }
117    
118        @Override
119        public boolean isLenientProperties() {
120            // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
121            return true;
122        }
123    
124        // Properties
125        //-------------------------------------------------------------------------
126    
127    
128        /**
129         * Provide access to the client parameters used on new {@link HttpClient} instances
130         * used by producers or consumers of this endpoint.
131         */
132        public HttpClientParams getClientParams() {
133            return clientParams;
134        }
135    
136        /**
137         * Provide access to the client parameters used on new {@link HttpClient} instances
138         * used by producers or consumers of this endpoint.
139         */
140        public void setClientParams(HttpClientParams clientParams) {
141            this.clientParams = clientParams;
142        }
143    
144        public HttpClientConfigurer getHttpClientConfigurer() {
145            return httpClientConfigurer;
146        }
147    
148        /**
149         * Register a custom configuration strategy for new {@link HttpClient} instances
150         * created by producers or consumers such as to configure authentication mechanisms etc
151         *
152         * @param httpClientConfigurer the strategy for configuring new {@link HttpClient} instances
153         */
154        public void setHttpClientConfigurer(HttpClientConfigurer httpClientConfigurer) {
155            this.httpClientConfigurer = httpClientConfigurer;
156        }
157        
158        public boolean isChunked() {
159            return this.chunked;
160        }
161        
162        public void setChunked(boolean chunked) {
163            this.chunked = chunked;
164        }
165    
166        public HttpBinding getBinding() {
167            if (binding == null) {
168                binding = new DefaultHttpBinding(getHeaderFilterStrategy());
169            }
170            return binding;
171        }
172    
173        public HeaderFilterStrategy getHeaderFilterStrategy() {
174            return component.getHeaderFilterStrategy();
175        }
176    
177        public void setBinding(HttpBinding binding) {
178            this.binding = binding;
179        }
180    
181        public boolean isSingleton() {
182            return true;
183        }
184    
185        public String getPath() {
186            return httpUri.getPath();
187        }
188    
189        public int getPort() {
190            if (httpUri.getPort() == -1) {
191                if ("https".equals(getProtocol())) {
192                    return 443;
193                } else {
194                    return 80;
195                }
196            }
197            return httpUri.getPort();
198        }
199    
200        public String getProtocol() {
201            return httpUri.getScheme();
202        }
203    
204        public URI getHttpUri() {
205            return httpUri;
206        }
207    
208        public void setHttpUri(URI httpUri) {
209            this.httpUri = httpUri;
210        }
211    }