001package lucee.runtime.tag; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.io.UnsupportedEncodingException; 006import java.net.MalformedURLException; 007import java.net.URL; 008import java.nio.charset.Charset; 009import java.util.zip.GZIPInputStream; 010 011import javax.servlet.jsp.JspException; 012import javax.servlet.jsp.PageContext; 013import javax.servlet.jsp.tagext.BodyContent; 014import javax.servlet.jsp.tagext.BodyTag; 015import javax.servlet.jsp.tagext.Tag; 016 017import lucee.commons.io.CharsetUtil; 018import lucee.commons.io.IOUtil; 019import lucee.commons.io.res.util.ResourceUtil; 020import lucee.commons.lang.ExceptionUtil; 021import lucee.commons.lang.StringUtil; 022import lucee.commons.net.HTTPUtil; 023import lucee.commons.net.URLEncoder; 024import lucee.commons.net.http.Header; 025import lucee.commons.net.http.httpclient4.HTTPResponse4Impl; 026import lucee.runtime.exp.PageException; 027import lucee.runtime.net.http.ReqRspUtil; 028 029import org.apache.http.HttpResponse; 030import org.apache.http.client.methods.HttpRequestBase; 031import org.apache.http.client.methods.HttpUriRequest; 032 033public class HttpImpl implements Http,BodyTag { 034 035 private Http instance; 036 037 public HttpImpl(){ 038 try{ 039 instance = new Http41(); // try to use the implemenation based on the newer apache library 040 } 041 catch(Throwable t){ 042 ExceptionUtil.rethrowIfNecessary(t); 043 instance = new Http4(); // if it fails we have a fallback to the old implementation 044 } 045 } 046 047 @Override 048 public void setParam(HttpParamBean param) { 049 instance.setParam(param); 050 } 051 052 @Override 053 public void setFirstrowasheaders(boolean firstrowasheaders) { 054 instance.setFirstrowasheaders(firstrowasheaders); 055 } 056 057 @Override 058 public void setEncodeurl(boolean encoded) { 059 instance.setEncodeurl(encoded); 060 } 061 062 @Override 063 public void setPassword(String password) { 064 instance.setPassword(password); 065 } 066 067 @Override 068 public void setProxypassword(String proxypassword) { 069 instance.setProxypassword(proxypassword); 070 } 071 072 @Override 073 public void setDelimiter(String delimiter) { 074 instance.setDelimiter(delimiter); 075 } 076 077 @Override 078 public void setResolveurl(boolean resolveurl) { 079 instance.setResolveurl(resolveurl); 080 } 081 082 @Override 083 public void setPreauth(boolean preauth) { 084 instance.setPreauth(preauth); 085 } 086 087 @Override 088 public void setTimeout(Object timeout) throws PageException { 089 instance.setTimeout(timeout); 090 } 091 092 @Override 093 public void setProxyserver(String proxyserver) { 094 instance.setProxyserver(proxyserver); 095 } 096 097 @Override 098 public void setProxyport(double proxyport) { 099 instance.setProxyport(proxyport); 100 } 101 102 @Override 103 public void setFile(String file) { 104 instance.setFile(file); 105 } 106 107 @Override 108 public void setThrowonerror(boolean throwonerror) { 109 instance.setThrowonerror(throwonerror); 110 } 111 112 @Override 113 public void setCharset(String charset) { 114 instance.setCharset(charset); 115 } 116 117 @Override 118 public void setColumns(String columns) throws PageException { 119 instance.setColumns(columns); 120 } 121 122 @Override 123 public void setPort(double port) { 124 instance.setPort(port); 125 } 126 127 @Override 128 public void setUseragent(String useragent) { 129 instance.setUseragent(useragent); 130 } 131 132 @Override 133 public void setTextqualifier(String textqualifier) { 134 instance.setTextqualifier(textqualifier); 135 } 136 137 @Override 138 public void setProxyuser(String proxyuser) { 139 instance.setProxyuser(proxyuser); 140 } 141 142 @Override 143 public void setUsername(String username) { 144 instance.setUsername(username); 145 } 146 147 @Override 148 public void setUrl(String url) { 149 instance.setUrl(url); 150 } 151 152 @Override 153 public void setRedirect(boolean redirect) { 154 instance.setRedirect(redirect); 155 } 156 157 @Override 158 public void setPath(String path) { 159 instance.setPath(path); 160 } 161 162 @Override 163 public void setName(String name) { 164 instance.setName(name); 165 } 166 167 @Override 168 public void setAuthtype(String strAuthType) throws PageException { 169 instance.setAuthtype(strAuthType); 170 } 171 172 @Override 173 public void setWorkstation(String workStation) { 174 instance.setWorkstation(workStation); 175 } 176 177 @Override 178 public void setDomain(String domain) { 179 instance.setDomain(domain); 180 } 181 182 @Override 183 public void setMethod(String method) throws PageException { 184 instance.setMethod(method); 185 } 186 187 @Override 188 public void setCompression(String strCompression) throws PageException { 189 instance.setCompression(strCompression); 190 } 191 192 @Override 193 public void setGetasbinary(String getAsBinary) { 194 instance.setGetasbinary(getAsBinary); 195 } 196 197 @Override 198 public void setMultipart(boolean multiPart) { 199 instance.setMultipart(multiPart); 200 } 201 202 @Override 203 public void setMultiparttype(String multiPartType) throws PageException { 204 instance.setMultiparttype(multiPartType); 205 } 206 207 @Override 208 public void setResult(String result) { 209 instance.setResult(result); 210 } 211 212 @Override 213 public void setAddtoken(boolean addtoken) { 214 instance.setAddtoken(addtoken); 215 } 216 217 218 @Override 219 public int doAfterBody() throws JspException { 220 return instance.doAfterBody(); 221 } 222 223 @Override 224 public int doEndTag() throws JspException { 225 return instance.doEndTag(); 226 } 227 228 @Override 229 public int doStartTag() throws JspException { 230 return instance.doStartTag(); 231 } 232 233 @Override 234 public Tag getParent() { 235 return instance.getParent(); 236 } 237 238 @Override 239 public void release() { 240 instance.release(); 241 } 242 243 @Override 244 public void setPageContext(PageContext pc) { 245 instance.setPageContext(pc); 246 } 247 248 @Override 249 public void setParent(Tag arg0) { 250 instance.setParent(arg0); 251 } 252 253 @Override 254 public void doInitBody() throws JspException { 255 instance.doInitBody(); 256 } 257 258 @Override 259 public void setBodyContent(BodyContent arg0) { 260 instance.setBodyContent(arg0); 261 } 262 263 static String headerValue(String value) { 264 if(value==null) return null; 265 value=value.trim(); 266 value=value.replace('\n', ' '); 267 value=value.replace('\r', ' '); 268 return value; 269 } 270 271 static boolean hasHeaderIgnoreCase(HttpRequestBase req,String name) { 272 org.apache.http.Header[] headers = req.getAllHeaders(); 273 if(headers==null) return false; 274 for(int i=0;i<headers.length;i++){ 275 if(name.equalsIgnoreCase(headers[i].getName())) return true; 276 } 277 return false; 278 } 279 280 static String urlenc(String str, String charset) throws UnsupportedEncodingException { 281 if(!ReqRspUtil.needEncoding(str,false)) return str; 282 return URLEncoder.encode(str,charset); 283 } 284 285 static Charset getCharset(String strCharset) { 286 if(!StringUtil.isEmpty(strCharset,true)) 287 return CharsetUtil.toCharset(strCharset); 288 return CharsetUtil.getWebCharset(); 289 } 290 291 static String getContentType(HttpParamBean param) { 292 String mimeType=param.getMimeType(); 293 if(StringUtil.isEmpty(mimeType,true)) { 294 mimeType=ResourceUtil.getMimeType(param.getFile(), ResourceUtil.MIMETYPE_CHECK_EXTENSION+ResourceUtil.MIMETYPE_CHECK_HEADER, null); 295 } 296 return mimeType; 297 } 298 299 static boolean isGzipEncoded(String contentEncoding) { 300 return !StringUtil.isEmpty(contentEncoding) && StringUtil.indexOfIgnoreCase(contentEncoding, "gzip")!=-1; 301 } 302 303 static boolean isStatusOK(int statusCode) { 304 return statusCode>=200 && statusCode<=299; 305 } 306 307 public static Object getOutput(InputStream is, String contentType, String contentEncoding, boolean closeIS) { 308 if(StringUtil.isEmpty(contentType))contentType="text/html"; 309 310 // Gzip 311 if(HttpImpl.isGzipEncoded(contentEncoding)){ 312 try { 313 is=new GZIPInputStream(is); 314 } 315 catch (IOException e) {} 316 } 317 318 try { 319 // text 320 if(HTTPUtil.isTextMimeType(contentType)) { 321 String[] tmp = HTTPUtil.splitMimeTypeAndCharset(contentType,null); 322 Charset cs=HttpImpl.getCharset(tmp[1]); 323 324 try { 325 return IOUtil.toString(is, cs); 326 } catch (IOException e) {} 327 } 328 // Binary 329 else { 330 try { 331 return IOUtil.toBytes(is); 332 } 333 catch (IOException e) {} 334 } 335 } 336 finally{ 337 if(closeIS)IOUtil.closeEL(is); 338 } 339 340 return ""; 341 } 342 343 static URL locationURL(HttpUriRequest req, HttpResponse rsp) { 344 URL url=null; 345 try { 346 url = req.getURI().toURL(); 347 } catch (MalformedURLException e1) { 348 return null; 349 } 350 351 Header h = HTTPResponse4Impl.getLastHeaderIgnoreCase(rsp, "location"); 352 if(h!=null) { 353 String str = h.getValue(); 354 try { 355 return new URL(str); 356 } catch (MalformedURLException e) { 357 try { 358 return new URL(url.getProtocol(), url.getHost(), url.getPort(), mergePath(url.getFile(), str)); 359 360 } catch (MalformedURLException e1) { 361 return null; 362 } 363 } 364 } 365 return null; 366 } 367 368 /** 369 * merge to pathes to one 370 * @param current 371 * @param relPath 372 * @return 373 * @throws MalformedURLException 374 */ 375 static String mergePath(String current, String relPath) throws MalformedURLException { 376 377 // get current directory 378 String currDir; 379 if(current==null || current.indexOf('/')==-1)currDir="/"; 380 else if(current.endsWith("/"))currDir=current; 381 else currDir=current.substring(0,current.lastIndexOf('/')+1); 382 383 // merge together 384 String path; 385 if(relPath.startsWith("./"))path=currDir+relPath.substring(2); 386 else if(relPath.startsWith("/"))path=relPath; 387 else if(!relPath.startsWith("../"))path=currDir+relPath; 388 else { 389 while(relPath.startsWith("../") || currDir.length()==0) { 390 relPath=relPath.substring(3); 391 currDir=currDir.substring(0,currDir.length()-1); 392 int index = currDir.lastIndexOf('/'); 393 if(index==-1)throw new MalformedURLException("invalid relpath definition for URL"); 394 currDir=currDir.substring(0,index+1); 395 } 396 path=currDir+relPath; 397 } 398 399 return path; 400 } 401 402 /** 403 * checks if status code is a redirect 404 * @param status 405 * @return is redirect 406 */ 407 408 static boolean isRedirect(int status) { 409 return 410 status==STATUS_REDIRECT_FOUND || 411 status==STATUS_REDIRECT_MOVED_PERMANENTLY || 412 status==STATUS_REDIRECT_SEE_OTHER || 413 status==STATUS_REDIRECT_TEMPORARY_REDIRECT; 414 } 415}