package railo.commons.net.http.httpclient4; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpMessage; import org.apache.http.NameValuePair; import org.apache.http.auth.AuthScope; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import railo.commons.io.IOUtil; import railo.commons.io.TemporaryStream; import railo.commons.io.res.Resource; import railo.commons.lang.ExceptionUtil; import railo.commons.lang.StringUtil; import railo.commons.net.http.Entity; import railo.commons.net.http.HTTPResponse; import railo.commons.net.http.httpclient4.entity.ByteArrayHttpEntity; import railo.commons.net.http.httpclient4.entity.EmptyHttpEntity; import railo.commons.net.http.httpclient4.entity.ResourceHttpEntity; import railo.commons.net.http.httpclient4.entity.TemporaryStreamHttpEntity; import railo.runtime.engine.ThreadLocalPageContext; import railo.runtime.exp.PageException; import railo.runtime.net.http.ReqRspUtil; import railo.runtime.net.proxy.ProxyData; import railo.runtime.net.proxy.ProxyDataImpl; import railo.runtime.op.Caster; import railo.runtime.op.Decision; import railo.runtime.type.util.CollectionUtil; public class HTTPEngine4Impl { /** * does a http get request * @param url * @param username * @param password * @param timeout * @param charset * @param useragent * @param proxyserver * @param proxyport * @param proxyuser * @param proxypassword * @param headers * @return * @throws IOException */ public static HTTPResponse get(URL url, String username,String password, long timeout, int maxRedirect, String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException { HttpGet get = new HttpGet(url.toExternalForm()); return _invoke(url,get, username, password, timeout,maxRedirect, charset, useragent, proxy, headers,null); } /** * does a http post request * @param url * @param username * @param password * @param timeout * @param charset * @param useragent * @param proxyserver * @param proxyport * @param proxyuser * @param proxypassword * @param headers * @return * @throws IOException */ public static HTTPResponse post(URL url, String username,String password, long timeout, int maxRedirect, String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException { HttpPost post = new HttpPost(url.toExternalForm()); return _invoke(url,post, username, password, timeout,maxRedirect, charset, useragent, proxy, headers,null); } public static HTTPResponse post(URL url, String username,String password, long timeout, int maxRedirect, String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers,Map<String,String> formfields) throws IOException { HttpPost post = new HttpPost(url.toExternalForm()); return _invoke(url,post, username, password, timeout,maxRedirect, charset, useragent, proxy, headers,formfields); } /** * does a http put request * @param url * @param username * @param password * @param timeout * @param charset * @param useragent * @param proxyserver * @param proxyport * @param proxyuser * @param proxypassword * @param headers * @param body * @return * @throws IOException * @throws PageException */ public static HTTPResponse put(URL url, String username,String password, long timeout, int maxRedirect, String mimetype,String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers, Object body) throws IOException { HttpPut put= new HttpPut(url.toExternalForm()); setBody(put,body,mimetype,charset); return _invoke(url,put, username, password, timeout, maxRedirect, charset, useragent, proxy, headers,null); } /** * does a http delete request * @param url * @param username * @param password * @param timeout * @param charset * @param useragent * @param proxyserver * @param proxyport * @param proxyuser * @param proxypassword * @param headers * @return * @throws IOException */ public static HTTPResponse delete(URL url, String username,String password, long timeout, int maxRedirect, String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException { HttpDelete delete= new HttpDelete(url.toExternalForm()); return _invoke(url,delete, username, password, timeout, maxRedirect, charset, useragent, proxy, headers,null); } /** * does a http head request * @param url * @param username * @param password * @param timeout * @param charset * @param useragent * @param proxyserver * @param proxyport * @param proxyuser * @param proxypassword * @param headers * @return * @throws IOException */ public static HTTPResponse head(URL url, String username,String password, long timeout, int maxRedirect, String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers) throws IOException { HttpHead head= new HttpHead(url.toExternalForm()); return _invoke(url,head, username, password, timeout, maxRedirect, charset, useragent, proxy, headers,null); } public static railo.commons.net.http.Header header(String name, String value) { return new HeaderImpl(name, value); } private static Header toHeader(railo.commons.net.http.Header header) { if(header instanceof Header) return (Header) header; if(header instanceof HeaderWrap) return ((HeaderWrap)header).header; return new HeaderImpl(header.getName(), header.getValue()); } private static HTTPResponse _invoke(URL url,HttpUriRequest request,String username,String password, long timeout, int maxRedirect, String charset, String useragent, ProxyData proxy, railo.commons.net.http.Header[] headers, Map<String,String> formfields) throws IOException { // TODO HttpConnectionManager manager=new SimpleHttpConnectionManager();//MultiThreadedHttpConnectionManager(); BasicHttpParams params = new BasicHttpParams(); DefaultHttpClient client = createClient(params,maxRedirect); HttpHost hh=new HttpHost(url.getHost(),url.getPort()); setHeader(request,headers); if(CollectionUtil.isEmpty(formfields))setContentType(request,charset); setFormFields(request,formfields,charset); setUserAgent(request,useragent); setTimeout(params,timeout); HttpContext context=setCredentials(client,hh, username, password,false); setProxy(client,request,proxy); if(context==null)context = new BasicHttpContext(); return new HTTPResponse4Impl(url,context,request,client.execute(request,context)); } private static void setFormFields(HttpUriRequest request, Map<String, String> formfields, String charset) throws IOException { if(!CollectionUtil.isEmpty(formfields)) { if(!(request instanceof HttpPost)) throw new IOException("form fields are only suppported for post request"); HttpPost post=(HttpPost) request; List<NameValuePair> list = new ArrayList<NameValuePair>(); Iterator<Entry<String, String>> it = formfields.entrySet().iterator(); Entry<String, String> e; while(it.hasNext()){ e = it.next(); list.add(new BasicNameValuePair(e.getKey(),e.getValue())); } if(StringUtil.isEmpty(charset)) charset=ThreadLocalPageContext.getConfig().getWebCharset(); post.setEntity(new org.apache.http.client.entity.UrlEncodedFormEntity(list,charset)); } } public static DefaultHttpClient createClient(BasicHttpParams params, int maxRedirect) { params.setParameter(ClientPNames.HANDLE_REDIRECTS, maxRedirect==0?Boolean.FALSE:Boolean.TRUE); if(maxRedirect>0)params.setParameter(ClientPNames.MAX_REDIRECTS, new Integer(maxRedirect)); params.setParameter(ClientPNames.REJECT_RELATIVE_REDIRECT, Boolean.FALSE); return new DefaultHttpClient(params); } private static void setUserAgent(HttpMessage hm, String useragent) { if(useragent!=null)hm.setHeader("User-Agent",useragent); } private static void setContentType(HttpMessage hm, String charset) { if(charset!=null) hm.setHeader("Content-type", "text/html; charset="+charset); } private static void setHeader(HttpMessage hm,railo.commons.net.http.Header[] headers) { addHeader(hm, headers); } private static void addHeader(HttpMessage hm,railo.commons.net.http.Header[] headers) { if(headers!=null) { for(int i=0;i<headers.length;i++) hm.addHeader(toHeader(headers[i])); } } public static void setTimeout(HttpParams params, long timeout) { if(timeout>0){ HttpConnectionParams.setConnectionTimeout(params, (int)timeout); HttpConnectionParams.setSoTimeout(params, (int)timeout); } } public static BasicHttpContext setCredentials(DefaultHttpClient client, HttpHost httpHost, String username,String password, boolean preAuth) { // set Username and Password if(!StringUtil.isEmpty(username,true)) { if(password==null)password=""; CredentialsProvider cp = client.getCredentialsProvider(); cp.setCredentials( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials(username,password)); BasicHttpContext httpContext = new BasicHttpContext(); if(preAuth) { AuthCache authCache = new BasicAuthCache(); authCache.put(httpHost, new BasicScheme()); httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache); } return httpContext; } return null; } public static void setNTCredentials(DefaultHttpClient client, String username,String password, String workStation, String domain) { // set Username and Password if(!StringUtil.isEmpty(username,true)) { if(password==null)password=""; CredentialsProvider cp = client.getCredentialsProvider(); cp.setCredentials( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new NTCredentials(username,password,workStation,domain)); //httpMethod.setDoAuthentication( true ); } } public static void setBody(HttpEntityEnclosingRequest req, Object body, String mimetype,String charset) throws IOException { if(body!=null)req.setEntity(toHttpEntity(body,mimetype,charset)); } public static void setProxy(DefaultHttpClient client, HttpUriRequest request, ProxyData proxy) { // set Proxy if(ProxyDataImpl.isValid(proxy)) { HttpHost host = new HttpHost(proxy.getServer(), proxy.getPort()==-1?80:proxy.getPort()); client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, host); if(!StringUtil.isEmpty(proxy.getUsername())) { client.getCredentialsProvider().setCredentials( new AuthScope(proxy.getServer(), proxy.getPort()), new UsernamePasswordCredentials(proxy.getUsername(),proxy.getPassword())); } } } public static void addCookie(DefaultHttpClient client, String domain, String name, String value, String path, String charset) { if(ReqRspUtil.needEncoding(name,false)) name=ReqRspUtil.encode(name, charset); if(ReqRspUtil.needEncoding(value,false)) value=ReqRspUtil.encode(value, charset); BasicClientCookie cookie = new BasicClientCookie(name, value); if(!StringUtil.isEmpty(domain,true))cookie.setDomain(domain); if(!StringUtil.isEmpty(path,true))cookie.setPath(path); client.getCookieStore().addCookie(cookie); } /** * convert input to HTTP Entity * @param value * @param mimetype not used for binary input * @param charset not used for binary input * @return * @throws IOException */ private static HttpEntity toHttpEntity(Object value, String mimetype, String charset) throws IOException { if(value instanceof HttpEntity) return (HttpEntity) value; try{ if(value instanceof InputStream) { return new ByteArrayEntity(IOUtil.toBytes((InputStream)value)); } else if(Decision.isCastableToBinary(value,false)){ return new ByteArrayEntity(Caster.toBinary(value)); } else { return new StringEntity(Caster.toString(value),mimetype,charset); } } catch(Exception e){ throw ExceptionUtil.toIOException(e); } } public static Entity getEmptyEntity(String contentType) { return new EmptyHttpEntity(contentType); } public static Entity getByteArrayEntity(byte[] barr, String contentType) { return new ByteArrayHttpEntity(barr,contentType); } public static Entity getTemporaryStreamEntity(TemporaryStream ts,String contentType) { return new TemporaryStreamHttpEntity(ts,contentType); } public static Entity getResourceEntity(Resource res, String contentType) { return new ResourceHttpEntity(res,contentType); } }