001    package railo.commons.net.http.httpclient4;
002    
003    import java.io.IOException;
004    import java.io.InputStream;
005    import java.net.URL;
006    
007    import org.apache.http.Header;
008    import org.apache.http.HttpEntity;
009    import org.apache.http.HttpEntityEnclosingRequest;
010    import org.apache.http.HttpHost;
011    import org.apache.http.HttpMessage;
012    import org.apache.http.auth.AuthScope;
013    import org.apache.http.auth.NTCredentials;
014    import org.apache.http.auth.UsernamePasswordCredentials;
015    import org.apache.http.client.AuthCache;
016    import org.apache.http.client.CredentialsProvider;
017    import org.apache.http.client.methods.HttpDelete;
018    import org.apache.http.client.methods.HttpGet;
019    import org.apache.http.client.methods.HttpHead;
020    import org.apache.http.client.methods.HttpPost;
021    import org.apache.http.client.methods.HttpPut;
022    import org.apache.http.client.methods.HttpUriRequest;
023    import org.apache.http.client.params.ClientPNames;
024    import org.apache.http.client.protocol.ClientContext;
025    import org.apache.http.conn.params.ConnRoutePNames;
026    import org.apache.http.entity.ByteArrayEntity;
027    import org.apache.http.entity.StringEntity;
028    import org.apache.http.impl.auth.BasicScheme;
029    import org.apache.http.impl.client.BasicAuthCache;
030    import org.apache.http.impl.client.DefaultHttpClient;
031    import org.apache.http.impl.cookie.BasicClientCookie;
032    import org.apache.http.params.BasicHttpParams;
033    import org.apache.http.params.HttpConnectionParams;
034    import org.apache.http.params.HttpParams;
035    import org.apache.http.protocol.BasicHttpContext;
036    import org.apache.http.protocol.HttpContext;
037    
038    import railo.commons.io.IOUtil;
039    import railo.commons.io.TemporaryStream;
040    import railo.commons.io.res.Resource;
041    import railo.commons.lang.ExceptionUtil;
042    import railo.commons.lang.StringUtil;
043    import railo.commons.net.http.Entity;
044    import railo.commons.net.http.HTTPResponse;
045    import railo.commons.net.http.httpclient4.entity.ByteArrayHttpEntity;
046    import railo.commons.net.http.httpclient4.entity.EmptyHttpEntity;
047    import railo.commons.net.http.httpclient4.entity.ResourceHttpEntity;
048    import railo.commons.net.http.httpclient4.entity.TemporaryStreamHttpEntity;
049    import railo.runtime.exp.PageException;
050    import railo.runtime.net.http.ReqRspUtil;
051    import railo.runtime.net.proxy.ProxyData;
052    import railo.runtime.net.proxy.ProxyDataImpl;
053    import railo.runtime.op.Caster;
054    import railo.runtime.op.Decision;
055    
056    public class HTTPEngine4Impl {
057            
058            /**
059             * does a http get request
060             * @param url
061             * @param username
062             * @param password
063             * @param timeout
064             * @param charset
065             * @param useragent
066             * @param proxyserver
067             * @param proxyport
068             * @param proxyuser
069             * @param proxypassword
070             * @param headers
071             * @return
072             * @throws IOException
073             */
074            public static HTTPResponse get(URL url, String username,String password, long timeout,  int maxRedirect,
075                String charset, String useragent,
076                ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException {
077                    HttpGet get = new HttpGet(url.toExternalForm());
078                    return _invoke(url,get, username, password, timeout,maxRedirect, charset, useragent, proxy, headers);
079            }
080    
081        /**
082             * does a http post request
083         * @param url
084         * @param username
085         * @param password
086         * @param timeout
087         * @param charset
088         * @param useragent
089         * @param proxyserver
090         * @param proxyport
091         * @param proxyuser
092         * @param proxypassword
093         * @param headers
094         * @return
095         * @throws IOException
096         */
097        public static HTTPResponse post(URL url, String username,String password, long timeout,  int maxRedirect,
098                String charset, String useragent,
099                ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException {
100            HttpPost post = new HttpPost(url.toExternalForm());
101            return _invoke(url,post, username, password, timeout,maxRedirect, charset, useragent, proxy, headers);
102        }
103        
104        /**
105             * does a http put request
106         * @param url
107         * @param username
108         * @param password
109         * @param timeout
110         * @param charset
111         * @param useragent
112         * @param proxyserver
113         * @param proxyport
114         * @param proxyuser
115         * @param proxypassword
116         * @param headers
117         * @param body
118         * @return
119         * @throws IOException
120         * @throws PageException 
121         */
122        public static HTTPResponse put(URL url, String username,String password, long timeout,  int maxRedirect,
123                    String mimetype,String charset, String useragent,
124                ProxyData proxy, railo.commons.net.http.Header[] headers, Object body) throws IOException {
125                    HttpPut put= new HttpPut(url.toExternalForm());
126                    setBody(put,body,mimetype,charset);
127            return _invoke(url,put, username, password, timeout, maxRedirect, charset, useragent, proxy, headers);
128                     
129            }
130        
131        /**
132             * does a http delete request
133         * @param url
134         * @param username
135         * @param password
136         * @param timeout
137         * @param charset
138         * @param useragent
139         * @param proxyserver
140         * @param proxyport
141         * @param proxyuser
142         * @param proxypassword
143         * @param headers
144         * @return
145         * @throws IOException
146         */
147        public static HTTPResponse delete(URL url, String username,String password, long timeout,  int maxRedirect,
148                String charset, String useragent,
149                ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException {
150            HttpDelete delete= new HttpDelete(url.toExternalForm());
151                    return _invoke(url,delete, username, password, timeout, maxRedirect, charset, useragent, proxy, headers);    
152            }
153    
154        /**
155             * does a http head request
156         * @param url
157         * @param username
158         * @param password
159         * @param timeout
160         * @param charset
161         * @param useragent
162         * @param proxyserver
163         * @param proxyport
164         * @param proxyuser
165         * @param proxypassword
166         * @param headers
167         * @return
168         * @throws IOException
169         */
170        public static HTTPResponse head(URL url, String username,String password, long timeout, int maxRedirect,
171                String charset, String useragent,
172                ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException {
173            HttpHead head= new HttpHead(url.toExternalForm());
174                    return _invoke(url,head, username, password, timeout, maxRedirect, charset, useragent, proxy, headers);    
175            }
176        
177            
178    
179            public static railo.commons.net.http.Header header(String name, String value) {
180                    return new HeaderImpl(name, value);
181            }
182            
183    
184            private static Header toHeader(railo.commons.net.http.Header header) {
185                    if(header instanceof Header) return (Header) header;
186                    if(header instanceof HeaderWrap) return ((HeaderWrap)header).header;
187                    return new HeaderImpl(header.getName(), header.getValue());
188            }
189            
190            private static HTTPResponse _invoke(URL url,HttpUriRequest request,String username,String password, long timeout, int maxRedirect,
191                String charset, String useragent,
192                ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException {
193            
194            // TODO HttpConnectionManager manager=new SimpleHttpConnectionManager();//MultiThreadedHttpConnectionManager();
195                    BasicHttpParams params = new BasicHttpParams();
196            DefaultHttpClient client = createClient(params,maxRedirect);
197            HttpHost hh=new HttpHost(url.getHost(),url.getPort());
198            setHeader(request,headers);
199            setContentType(request,charset);
200            setUserAgent(request,useragent);
201            setTimeout(params,timeout);
202            HttpContext context=setCredentials(client,hh, username, password,false);  
203            setProxy(client,request,proxy);
204            if(context==null)context = new BasicHttpContext();
205                    
206            return new HTTPResponse4Impl(url,context,request,client.execute(request,context));
207        }
208            
209            public static DefaultHttpClient createClient(BasicHttpParams params, int maxRedirect) {
210            params.setParameter(ClientPNames.HANDLE_REDIRECTS, maxRedirect==0?Boolean.FALSE:Boolean.TRUE);
211            if(maxRedirect>0)params.setParameter(ClientPNames.MAX_REDIRECTS, new Integer(maxRedirect));
212            params.setParameter(ClientPNames.REJECT_RELATIVE_REDIRECT, Boolean.FALSE);
213            return new DefaultHttpClient(params);
214            }
215    
216            private static void setUserAgent(HttpMessage hm, String useragent) {
217            if(useragent!=null)hm.setHeader("User-Agent",useragent);
218            }
219    
220            private static void setContentType(HttpMessage hm, String charset) {
221                    if(charset!=null) hm.setHeader("Content-type", "text/html; charset="+charset);
222            }
223    
224            private static void setHeader(HttpMessage hm,railo.commons.net.http.Header[] headers) {
225                    addHeader(hm, headers);
226            }
227            
228            private static void addHeader(HttpMessage hm,railo.commons.net.http.Header[] headers) {
229                    if(headers!=null) {
230                    for(int i=0;i<headers.length;i++)
231                            hm.addHeader(toHeader(headers[i]));
232            }
233            }
234    
235            public static void setTimeout(HttpParams params, long timeout) {
236            if(timeout>0){
237                    HttpConnectionParams.setConnectionTimeout(params, (int)timeout);
238                    HttpConnectionParams.setSoTimeout(params, (int)timeout);
239            }
240            }
241    
242            public static BasicHttpContext setCredentials(DefaultHttpClient client, HttpHost httpHost, String username,String password, boolean preAuth) {
243            // set Username and Password
244            if(!StringUtil.isEmpty(username,true)) {
245                if(password==null)password="";
246                CredentialsProvider cp = client.getCredentialsProvider();
247                cp.setCredentials(
248                    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
249                    new UsernamePasswordCredentials(username,password));
250                
251                
252                
253                BasicHttpContext httpContext = new BasicHttpContext();
254                if(preAuth) {
255                        AuthCache authCache = new BasicAuthCache();
256                        authCache.put(httpHost, new BasicScheme());
257                        httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
258                }
259                return httpContext;
260            }
261            return null;
262            }
263            
264            public static void setNTCredentials(DefaultHttpClient client, String username,String password, String workStation, String domain) {
265            // set Username and Password
266            if(!StringUtil.isEmpty(username,true)) {
267                if(password==null)password="";
268                CredentialsProvider cp = client.getCredentialsProvider();
269                cp.setCredentials(
270                    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
271                    new NTCredentials(username,password,workStation,domain));
272                //httpMethod.setDoAuthentication( true );
273            }
274            }
275    
276        public static void setBody(HttpEntityEnclosingRequest req, Object body, String mimetype,String charset) throws IOException {
277            if(body!=null)req.setEntity(toHttpEntity(body,mimetype,charset));
278            }
279    
280            public static void setProxy(DefaultHttpClient client, HttpUriRequest request, ProxyData proxy) {
281                    // set Proxy
282            if(ProxyDataImpl.isValid(proxy)) {
283                    HttpHost host = new HttpHost(proxy.getServer(), proxy.getPort()==-1?80:proxy.getPort());
284                    client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, host);
285                if(!StringUtil.isEmpty(proxy.getUsername())) {
286                    
287                    client.getCredentialsProvider().setCredentials(
288                            new AuthScope(proxy.getServer(), proxy.getPort()),
289                            new UsernamePasswordCredentials(proxy.getUsername(),proxy.getPassword()));
290                }
291            } 
292            }
293            
294            public static void addCookie(DefaultHttpClient client, String domain, String name, String value, String path, String charset) {
295                    if(ReqRspUtil.needEncoding(name,false)) name=ReqRspUtil.encode(name, charset);
296                    if(ReqRspUtil.needEncoding(value,false)) value=ReqRspUtil.encode(value, charset);
297                    BasicClientCookie cookie = new BasicClientCookie(name, value);
298                    if(!StringUtil.isEmpty(domain,true))cookie.setDomain(domain);
299                    if(!StringUtil.isEmpty(path,true))cookie.setPath(path);
300                    
301                    client.getCookieStore().addCookie(cookie);
302            }
303    
304            /**
305             * convert input to  HTTP Entity
306             * @param value
307             * @param mimetype not used for binary input
308             * @param charset not used for binary input
309             * @return
310             * @throws IOException
311             */
312            private static HttpEntity toHttpEntity(Object value, String mimetype, String charset) throws IOException {
313                    if(value instanceof HttpEntity) return (HttpEntity) value;
314            try{
315                    if(value instanceof InputStream) {
316                            return new ByteArrayEntity(IOUtil.toBytes((InputStream)value));
317                            }
318                            else if(Decision.isCastableToBinary(value,false)){
319                                    return new ByteArrayEntity(Caster.toBinary(value));
320                            }
321                            else {
322                                    return new StringEntity(Caster.toString(value),mimetype,charset);
323                            }
324            }
325            catch(Exception e){
326                    throw ExceptionUtil.toIOException(e);
327            }
328        }
329            
330    
331            public static Entity getEmptyEntity(String contentType) {
332                    return new EmptyHttpEntity(contentType);
333            }
334    
335            public static Entity getByteArrayEntity(byte[] barr, String contentType) {
336                    return new ByteArrayHttpEntity(barr,contentType);
337            }
338    
339            public static Entity getTemporaryStreamEntity(TemporaryStream ts,String contentType) {
340                    return new TemporaryStreamHttpEntity(ts,contentType);
341            }
342    
343            public static Entity getResourceEntity(Resource res, String contentType) {
344                    return new ResourceHttpEntity(res,contentType);
345            }
346    
347            
348    }