001 package railo.commons.net; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.IOException; 005 import java.io.InputStream; 006 import java.io.UnsupportedEncodingException; 007 import java.net.MalformedURLException; 008 import java.net.URI; 009 import java.net.URISyntaxException; 010 import java.net.URL; 011 import java.util.HashMap; 012 import java.util.Map; 013 014 import javax.servlet.RequestDispatcher; 015 import javax.servlet.ServletContext; 016 import javax.servlet.ServletException; 017 import javax.servlet.ServletRequest; 018 import javax.servlet.ServletResponse; 019 020 import org.apache.commons.httpclient.Header; 021 import org.apache.commons.httpclient.HostConfiguration; 022 import org.apache.commons.httpclient.HttpClient; 023 import org.apache.commons.httpclient.HttpMethod; 024 import org.apache.commons.httpclient.HttpState; 025 import org.apache.commons.httpclient.UsernamePasswordCredentials; 026 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; 027 import org.apache.commons.httpclient.methods.DeleteMethod; 028 import org.apache.commons.httpclient.methods.EntityEnclosingMethod; 029 import org.apache.commons.httpclient.methods.GetMethod; 030 import org.apache.commons.httpclient.methods.HeadMethod; 031 import org.apache.commons.httpclient.methods.InputStreamRequestEntity; 032 import org.apache.commons.httpclient.methods.PostMethod; 033 import org.apache.commons.httpclient.methods.PutMethod; 034 import org.apache.commons.httpclient.methods.RequestEntity; 035 import org.apache.commons.httpclient.methods.StringRequestEntity; 036 037 import railo.aprint; 038 import railo.commons.io.IOUtil; 039 import railo.commons.io.res.ContentType; 040 import railo.commons.io.res.ContentTypeImpl; 041 import railo.commons.lang.StringList; 042 import railo.commons.lang.StringUtil; 043 import railo.runtime.PageContext; 044 import railo.runtime.PageContextImpl; 045 import railo.runtime.PageSource; 046 import railo.runtime.PageSourceImpl; 047 import railo.runtime.config.Config; 048 import railo.runtime.engine.ThreadLocalPageContext; 049 import railo.runtime.exp.ApplicationException; 050 import railo.runtime.exp.PageException; 051 import railo.runtime.exp.PageServletException; 052 import railo.runtime.net.http.HTTPServletRequestWrap; 053 import railo.runtime.net.http.HttpClientUtil; 054 import railo.runtime.net.http.HttpServletResponseWrap; 055 import railo.runtime.net.http.ReqRspUtil; 056 import railo.runtime.net.proxy.ProxyData; 057 import railo.runtime.net.proxy.ProxyDataImpl; 058 import railo.runtime.op.Caster; 059 import railo.runtime.op.Decision; 060 import railo.runtime.type.List; 061 062 /** 063 * 064 */ 065 public final class HTTPUtil { 066 067 /** 068 * Field <code>ACTION_POST</code> 069 */ 070 public static final short ACTION_POST=0; 071 072 /** 073 * Field <code>ACTION_GET</code> 074 */ 075 public static final short ACTION_GET=1; 076 077 /** 078 * Field <code>STATUS_OK</code> 079 */ 080 public static final int STATUS_OK=200; 081 //private static final String NO_MIMETYPE="Unable to determine MIME type of file."; 082 083 /** 084 * make a http requst to given url 085 * @param url 086 * @param username 087 * @param password 088 * @param timeout 089 * @param charset 090 * @param useragent 091 * @param proxyserver 092 * @param proxyport 093 * @param proxyuser 094 * @param proxypassword 095 * @param headers 096 * @return 097 * @throws IOException 098 */ 099 public static HttpMethod invoke(URL url, String username, String password, long timeout, 100 String charset, String useragent, 101 String proxyserver, int proxyport, String proxyuser, 102 String proxypassword, Header[] headers) throws IOException { 103 104 HttpClient client = new HttpClient(); 105 HttpMethod httpMethod=new GetMethod(url.toExternalForm()); 106 HostConfiguration config = client.getHostConfiguration(); 107 108 HttpState state = client.getState(); 109 110 setHeader(httpMethod,headers); 111 setContentType(httpMethod,charset); 112 setUserAgent(httpMethod,useragent); 113 setTimeout(client,timeout); 114 setCredentials(client,httpMethod,username,password); 115 setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword); 116 117 /*if(followRedirects!=null){ 118 client.executeMethod(httpMethod); 119 } 120 else */ 121 httpMethod = HttpClientUtil.execute(client,httpMethod,true); 122 123 return httpMethod; 124 } 125 126 public static HttpMethod post(URL url, String username, String password, long timeout, 127 String charset, String useragent, 128 String proxyserver, int proxyport, String proxyuser, 129 String proxypassword, Header[] headers) throws IOException { 130 131 HttpClient client = new HttpClient(); 132 HttpMethod httpMethod=new PostMethod(url.toExternalForm()); 133 HostConfiguration config = client.getHostConfiguration(); 134 135 HttpState state = client.getState(); 136 137 setHeader(httpMethod,headers); 138 setContentType(httpMethod,charset); 139 setUserAgent(httpMethod,useragent); 140 setTimeout(client,timeout); 141 setCredentials(client,httpMethod,username,password); 142 setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword); 143 144 /*if(followRedirects!=null){ 145 client.executeMethod(httpMethod); 146 } 147 else */ 148 httpMethod = HttpClientUtil.execute(client,httpMethod,true); 149 150 return httpMethod; 151 } 152 153 154 /** 155 * cast a string to a url 156 * @param strUrl string represent a url 157 * @return url from string 158 * @throws MalformedURLException 159 */ 160 public static URL toURL(String strUrl) throws MalformedURLException { 161 return toURL(strUrl,-1); 162 } 163 164 public static URL toURL(String strUrl,URL defaultValue){ 165 try { 166 return toURL(strUrl,-1); 167 } catch (MalformedURLException e) { 168 return defaultValue; 169 } 170 } 171 172 173 public static String validateURL(String strUrl,String defaultValue){ 174 try { 175 return toURL(strUrl,-1).toExternalForm(); 176 } catch (MalformedURLException e) { 177 return defaultValue; 178 } 179 } 180 181 /** 182 * cast a string to a url 183 * @param strUrl string represent a url 184 * @return url from string 185 * @throws MalformedURLException 186 */ 187 188 public static URL toURL(String strUrl, int port) throws MalformedURLException { 189 URL url; 190 try { 191 url=new URL(strUrl); 192 } 193 catch(MalformedURLException mue) { 194 url=new URL("http://"+strUrl); 195 } 196 return toURL(url, port); 197 } 198 199 200 private static URL toURL(URL url, int port) throws MalformedURLException { 201 202 203 204 205 206 207 // file 208 String path=url.getPath(); 209 //String file=url.getFile(); 210 String query = url.getQuery(); 211 String ref = url.getRef(); 212 String user=url.getUserInfo(); 213 if(port<=0) port=url.getPort(); 214 215 // decode path 216 if(!StringUtil.isEmpty(path)) { 217 int sqIndex=path.indexOf(';'); 218 String q=null; 219 if(sqIndex!=-1) { 220 q=path.substring(sqIndex+1); 221 path=path.substring(0,sqIndex); 222 } 223 224 StringBuilder res=new StringBuilder(); 225 226 StringList list = List.toListTrim(path, '/'); 227 String str; 228 229 while(list.hasNext()){ 230 str=list.next(); 231 //str=URLDecoder.decode(str); 232 233 if(StringUtil.isEmpty(str)) continue; 234 res.append("/"); 235 res.append(escapeQSValue(str)); 236 } 237 if(StringUtil.endsWith(path, '/')) res.append('/'); 238 path=res.toString(); 239 240 if(sqIndex!=-1) { 241 path+=decodeQuery(q,';'); 242 } 243 244 } 245 246 // decode query 247 query=decodeQuery(query,'?'); 248 249 250 251 String file=path+query; 252 253 // decode ref/anchor 254 if(ref!=null) { 255 file+="#"+escapeQSValue(ref); 256 } 257 258 // user/pasword 259 if(!StringUtil.isEmpty(user)) { 260 int index=user.indexOf(':'); 261 if(index!=-1) { 262 user=escapeQSValue(user.substring(0,index))+":"+escapeQSValue(user.substring(index+1)); 263 } 264 else user=escapeQSValue(user); 265 266 String strUrl = getProtocol(url)+"://"+user+"@"+url.getHost(); 267 if(port>0)strUrl+=":"+port; 268 strUrl+=file; 269 return new URL(strUrl); 270 } 271 272 273 274 // port 275 if(port<=0) return new URL(url.getProtocol(),url.getHost(),file); 276 return new URL(url.getProtocol(),url.getHost(),port,file); 277 278 279 } 280 281 private static String decodeQuery(String query,char startDelimeter) { 282 if(!StringUtil.isEmpty(query)) { 283 StringBuilder res=new StringBuilder(); 284 285 StringList list = List.toList(query, '&'); 286 String str; 287 int index; 288 char del=startDelimeter; 289 while(list.hasNext()){ 290 res.append(del); 291 del='&'; 292 str=list.next(); 293 index=str.indexOf('='); 294 if(index==-1)res.append(escapeQSValue(str)); 295 else { 296 res.append(escapeQSValue(str.substring(0,index))); 297 res.append('='); 298 res.append(escapeQSValue(str.substring(index+1))); 299 } 300 } 301 query=res.toString(); 302 } 303 else query=""; 304 return query; 305 } 306 307 308 public static URI toURI(String strUrl) throws URISyntaxException { 309 return toURI(strUrl,-1); 310 } 311 312 public static URI toURI(String strUrl, int port) throws URISyntaxException { 313 314 //print.o((strUrl)); 315 URI uri = new URI(strUrl); 316 317 String host = uri.getHost(); 318 String fragment = uri.getRawFragment(); 319 String path = uri.getRawPath(); 320 String query= uri.getRawQuery(); 321 322 String scheme = uri.getScheme(); 323 String userInfo = uri.getRawUserInfo(); 324 if(port<=0) port=uri.getPort(); 325 326 327 // decode path 328 if(!StringUtil.isEmpty(path)) { 329 330 int sqIndex=path.indexOf(';'); 331 String q=null; 332 if(sqIndex!=-1) { 333 q=path.substring(sqIndex+1); 334 path=path.substring(0,sqIndex); 335 } 336 337 338 StringBuilder res=new StringBuilder(); 339 340 StringList list = List.toListTrim(path, '/'); 341 String str; 342 343 while(list.hasNext()){ 344 str=list.next(); 345 //str=URLDecoder.decode(str); 346 347 if(StringUtil.isEmpty(str)) continue; 348 res.append("/"); 349 res.append(escapeQSValue(str)); 350 } 351 if(StringUtil.endsWith(path, '/')) res.append('/'); 352 path=res.toString(); 353 354 if(sqIndex!=-1) { 355 path+=decodeQuery(q,';'); 356 } 357 } 358 359 // decode query 360 query=decodeQuery(query,'?'); 361 362 363 364 // decode ref/anchor 365 if(!StringUtil.isEmpty(fragment)) { 366 fragment=escapeQSValue(fragment); 367 } 368 369 // user/pasword 370 if(!StringUtil.isEmpty(userInfo)) { 371 int index=userInfo.indexOf(':'); 372 if(index!=-1) { 373 userInfo=escapeQSValue(userInfo.substring(0,index))+":"+escapeQSValue(userInfo.substring(index+1)); 374 } 375 else userInfo=escapeQSValue(userInfo); 376 } 377 378 /*print.o("- fragment:"+fragment); 379 print.o("- host:"+host); 380 print.o("- path:"+path); 381 print.o("- query:"+query); 382 print.o("- scheme:"+scheme); 383 print.o("- userInfo:"+userInfo); 384 print.o("- port:"+port); 385 print.o("- absolute:"+uri.isAbsolute()); 386 print.o("- opaque:"+uri.isOpaque());*/ 387 388 StringBuilder rtn=new StringBuilder(); 389 if(scheme!=null) { 390 rtn.append(scheme); 391 rtn.append("://"); 392 } 393 if(userInfo!=null) { 394 rtn.append(userInfo); 395 rtn.append("@"); 396 } 397 if(host!=null) { 398 rtn.append(host); 399 } 400 if(port>0) { 401 rtn.append(":"); 402 rtn.append(port); 403 } 404 if(path!=null) { 405 rtn.append(path); 406 } 407 if(query!=null) { 408 //rtn.append("?"); 409 rtn.append(query); 410 } 411 if(fragment!=null) { 412 rtn.append("#"); 413 rtn.append(fragment); 414 } 415 416 return new URI(rtn.toString()); 417 } 418 419 private static void test(String str) throws URISyntaxException { 420 //print.o(str); 421 int port=-1; 422 String res; 423 try { 424 res=toURL(new URL(str),port).toString(); 425 } catch (MalformedURLException e) { 426 res=toURI(str).toString(); 427 } 428 String res2 = encode(str); 429 430 if(res.equals(res2)){ 431 aprint.o(res); 432 } 433 else { 434 aprint.e(str); 435 aprint.e("- uri:"+res); 436 aprint.e("- enc:"+res2); 437 } 438 439 440 /*String uri = toURI(str).toString(); 441 String url = toURL(str).toString(); 442 443 if(uri.equals(url)){ 444 print.o(uri); 445 } 446 else { 447 print.e(str); 448 print.e("uri:"+uri); 449 print.e("url:"+url); 450 }*/ 451 452 } 453 454 public static void main(String[] args) throws Exception { 455 456 // valid urls 457 test("http://localhost:8080/jm/test/tags/_http.cfm;jsessionid=48lhqe568il0d?CFID=2fa614d8-9deb-4051-92e9-100ed44fd2df&CFTOKEN=0&jsessionid=48lhqe568il0d"); 458 test("http://www.railo.ch"); 459 test("http://www.railo.ch/"); 460 test("http://www.railo.ch/a.cfm"); 461 test("http://www.railo.ch/a.cfm?"); 462 test("http://www.railo.ch/a.cfm?test=1"); 463 test("http://www.railo.ch/a.cfm?test=1&"); 464 test("http://www.railo.ch:80/a.cfm?test=1&"); 465 test("http://hans@www.railo.ch:80/a.cfm?test=1&"); 466 test("http://hans:peter@www.railo.ch:80/a.cfm?test=1&x"); 467 test("http://hans:peter@www.railo.ch:80/a.cfm?test=1&x#"); 468 test("http://hans:peter@www.railo.ch:80/a.cfm?test=1&x#xx"); 469 470 test("http://www.railo.ch"); 471 test("http://www.railo.ch/"); 472 test("http://www.railo.ch/�.cfm"); 473 test("http://www.railo.ch/�.cfm?"); 474 test("http://www.railo.ch/�.cfm?test�=�"); 475 test("http://www.railo.ch/�.cfm?test�=�&"); 476 test("http://www.railo.ch:80/�.cfm?test�=�&"); 477 test("http://h�ns@www.railo.ch:80/�.cfm?test�=�&"); 478 test("http://h�ns:p�ter@www.railo.ch:80/�.cfm?test�=�&x"); 479 test("http://h�ns:p�ter@www.railo.ch:80/�.cfm?test�=�&x#"); 480 test("http://h�ns:p�ter@www.railo.ch:80/�.cfm?test�=�&x#�"); 481 482 test("/"); 483 test("/a.cfm"); 484 test("/a.cfm?"); 485 test("/a.cfm?test=1"); 486 test("/a.cfm?test=1&"); 487 test("/a.cfm?test=1&"); 488 test("/a.cfm?test=1&"); 489 test("/a.cfm?test=1&x"); 490 test("/a.cfm?test=1&x#"); 491 test("/a.cfm?test=1&x#xx"); 492 493 494 test("/"); 495 test("/�.cfm"); 496 test("/�.cfm?"); 497 test("/�.cfm?test�=1�"); 498 test("/�.cfm?test�=1�&"); 499 test("/�.cfm?test�=1�&"); 500 test("/�.cfm?test�=1�&"); 501 test("/�.cfm?test�=1�&x"); 502 test("/�.cfm?test�=1�&x#"); 503 test("/�.cfm?test�=1�&x#xx�"); 504 //test("http://ha�ns:gehe�im@www.example.org:80/d�emo/example.cgi?lan�d=de&stadt=aa#geschi�chte"); 505 //print.o(toURI("http://www.railo.ch/te�st.cfm?do=p�hoto.view&id=289#commentAdd")); 506 //print.o(toURI("/test.cfm?do=photo.view&id=289#commentAdd")); 507 //print.o(toURI("http://localhost/testingapp/index.cfm?do=photo.view&id=289#commentAdd")); 508 } 509 510 511 512 513 private static String getProtocol(URI uri) { 514 String p=uri.getRawSchemeSpecificPart(); 515 if(p==null) return null; 516 if(p.indexOf('/')==-1) return p; 517 if(p.indexOf("https")!=-1) return "https"; 518 if(p.indexOf("http")!=-1) return "http"; 519 return p; 520 } 521 522 private static String getProtocol(URL url) { 523 String p=url.getProtocol().toLowerCase(); 524 if(p.indexOf('/')==-1) return p; 525 if(p.indexOf("https")!=-1) return "https"; 526 if(p.indexOf("http")!=-1) return "http"; 527 return p; 528 } 529 530 531 /*public static void main(String[] args) throws MalformedURLException { 532 print.o(toURL("http://www.railo.ch/index.cfm#susi")); 533 print.o(toURL("http://www.railo.ch/index.cfm#���")); 534 print.o(toURL("http://hans:geheim@www.example.org:80/demo/example.cgi?land=de&stadt=aa#geschichte")); 535 print.o(toURL("http://ha�ns:gehe�im@www.example.org/d�emo/example.cgi?lan�d=de&stadt=aa#geschi�chte")); 536 // 537 }*/ 538 539 540 541 542 public static String escapeQSValue(String str) { 543 if(!ReqRspUtil.needEncoding(str,true)) return str; 544 Config config = ThreadLocalPageContext.getConfig(); 545 if(config!=null){ 546 try { 547 return URLEncoder.encode(str,config.getWebCharset()); 548 } 549 catch (UnsupportedEncodingException e) {} 550 } 551 return URLEncoder.encode(str); 552 } 553 554 public static HttpMethod put(URL url, String username, String password, int timeout, 555 String charset, String useragent, 556 String proxyserver, int proxyport, String proxyuser, 557 String proxypassword, Header[] headers, RequestEntity body) throws IOException { 558 559 560 HttpClient client = new HttpClient(); 561 PutMethod httpMethod=new PutMethod(url.toExternalForm()); 562 HostConfiguration config = client.getHostConfiguration(); 563 564 HttpState state = client.getState(); 565 566 setHeader(httpMethod,headers); 567 setContentType(httpMethod,charset); 568 setUserAgent(httpMethod,useragent); 569 setTimeout(client,timeout); 570 setCredentials(client,httpMethod,username,password); 571 setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword); 572 setBody(httpMethod,body); 573 574 575 return HttpClientUtil.execute(client,httpMethod,true); 576 577 } 578 579 public static HttpMethod delete(URL url, String username, String password, int timeout, 580 String charset, String useragent, 581 String proxyserver, int proxyport, String proxyuser, 582 String proxypassword, Header[] headers) throws IOException { 583 584 585 HttpClient client = new HttpClient(); 586 DeleteMethod httpMethod=new DeleteMethod(url.toExternalForm()); 587 HostConfiguration config = client.getHostConfiguration(); 588 589 HttpState state = client.getState(); 590 591 setHeader(httpMethod,headers); 592 setContentType(httpMethod,charset); 593 setUserAgent(httpMethod,useragent); 594 setTimeout(client,timeout); 595 setCredentials(client,httpMethod,username,password); 596 setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword); 597 598 599 return HttpClientUtil.execute(client,httpMethod,true); 600 601 } 602 603 public static HttpMethod head(URL url, String username, String password, int timeout, 604 String charset, String useragent, 605 String proxyserver, int proxyport, String proxyuser, 606 String proxypassword, Header[] headers) throws IOException { 607 608 609 HttpClient client = new HttpClient(); 610 HeadMethod httpMethod=new HeadMethod(url.toExternalForm()); 611 HostConfiguration config = client.getHostConfiguration(); 612 613 HttpState state = client.getState(); 614 615 setHeader(httpMethod,headers); 616 setContentType(httpMethod,charset); 617 setUserAgent(httpMethod,useragent); 618 setTimeout(client,timeout); 619 setCredentials(client,httpMethod,username,password); 620 setProxy(config,state,proxyserver,proxyport,proxyuser,proxypassword); 621 622 623 return HttpClientUtil.execute(client,httpMethod,true); 624 625 } 626 627 628 629 private static void setBody(EntityEnclosingMethod httpMethod, RequestEntity body) { 630 // body 631 if(body!=null)httpMethod.setRequestEntity(body); 632 } 633 634 private static void setProxy(HostConfiguration config, HttpState state, String proxyserver,int proxyport, String proxyuser, String proxypassword) { 635 636 // set Proxy 637 if(!StringUtil.isEmpty(proxyserver)) { 638 config.setProxy(proxyserver,proxyport); 639 if(!StringUtil.isEmpty(proxyuser)) { 640 if(proxypassword==null)proxypassword=""; 641 state.setProxyCredentials(null,null,new UsernamePasswordCredentials(proxyuser,proxypassword)); 642 } 643 } 644 } 645 646 private static void setCredentials(HttpClient client, HttpMethod httpMethod, String username,String password) { 647 // set Username and Password 648 if(username!=null) { 649 if(password==null)password=""; 650 client.getState().setCredentials(null,null,new UsernamePasswordCredentials(username, password)); 651 httpMethod.setDoAuthentication( true ); 652 } 653 } 654 655 private static void setTimeout(HttpClient client, long timeout) { 656 if(timeout>0){ 657 658 client.setConnectionTimeout((int)timeout); 659 client.setTimeout((int)timeout); 660 } 661 } 662 663 private static void setUserAgent(HttpMethod httpMethod, String useragent) { 664 if(useragent!=null)httpMethod.setRequestHeader("User-Agent",useragent); 665 } 666 667 private static void setContentType(HttpMethod httpMethod, String charset) { 668 if(charset!=null)httpMethod.addRequestHeader("Content-type", "text/html; charset="+charset ); 669 } 670 671 private static void setHeader(HttpMethod httpMethod,Header[] headers) { 672 if(headers!=null) { 673 for(int i=0;i<headers.length;i++) 674 httpMethod.addRequestHeader(headers[i].getName(), headers[i].getValue()); 675 } 676 } 677 678 public static RequestEntity toRequestEntity(Object value) throws PageException { 679 if(value instanceof RequestEntity) return (RequestEntity) value; 680 else if(value instanceof InputStream) { 681 return new InputStreamRequestEntity((InputStream)value,"application/octet-stream"); 682 } 683 else if(Decision.isCastableToBinary(value,false)){ 684 return new ByteArrayRequestEntity(Caster.toBinary(value)); 685 } 686 else { 687 return new StringRequestEntity(Caster.toString(value)); 688 } 689 } 690 691 692 public static URL removeRef(URL url) throws MalformedURLException{ 693 int port=url.getPort(); 694 if(port==80 && url.getProtocol().equalsIgnoreCase("http")) 695 port=-1; 696 else if(port==443 && url.getProtocol().equalsIgnoreCase("https")) 697 port=-1; 698 699 700 701 URL u=new URL(url.getProtocol(),url.getHost(),port,url.getFile()); 702 return u; 703 } 704 705 public static String removeRef(String url) throws MalformedURLException{ 706 return removeRef(new URL(url)).toExternalForm(); 707 } 708 709 710 711 public static URL toURL(HttpMethod httpMethod) { 712 HostConfiguration config = httpMethod.getHostConfiguration(); 713 714 try { 715 String qs = httpMethod.getQueryString(); 716 if(StringUtil.isEmpty(qs)) 717 return new URL(config.getProtocol().getScheme(),config.getHost(),config.getPort(),httpMethod.getPath()); 718 return new URL(config.getProtocol().getScheme(),config.getHost(),config.getPort(),httpMethod.getPath()+"?"+qs); 719 } catch (MalformedURLException e) { 720 return null; 721 } 722 } 723 724 public static String optimizeRealPath(PageContext pc,String realPath) { 725 int index; 726 String requestURI=realPath,queryString=null; 727 if((index=realPath.indexOf('?'))!=-1){ 728 requestURI=realPath.substring(0,index); 729 queryString=realPath.substring(index+1); 730 } 731 PageSource ps = PageSourceImpl.best(((PageContextImpl)pc).getRelativePageSources(requestURI)); 732 requestURI=ps.getFullRealpath(); 733 if(queryString!=null) return requestURI+"?"+queryString; 734 return requestURI; 735 } 736 737 public static void forward(PageContext pc,String realPath) throws ServletException, IOException { 738 ServletContext context = pc.getServletContext(); 739 realPath=HTTPUtil.optimizeRealPath(pc,realPath); 740 741 try{ 742 pc.getHttpServletRequest().setAttribute("railo.forward.request_uri", realPath); 743 744 RequestDispatcher disp = context.getRequestDispatcher(realPath); 745 if(disp==null) 746 throw new PageServletException(new ApplicationException("Page "+realPath+" not found")); 747 748 //populateRequestAttributes(); 749 disp.forward(removeWrap(pc.getHttpServletRequest()),pc.getHttpServletResponse()); 750 } 751 finally{ 752 ThreadLocalPageContext.register(pc); 753 } 754 } 755 756 public static ServletRequest removeWrap(ServletRequest req) { 757 while(req instanceof HTTPServletRequestWrap) 758 return ((HTTPServletRequestWrap)req).getOriginalRequest(); 759 return req; 760 } 761 762 763 public static void include(PageContext pc,String realPath) throws ServletException,IOException { 764 include(pc, pc.getHttpServletRequest(),pc.getHttpServletResponse(),realPath); 765 } 766 767 public static void include(PageContext pc,ServletRequest req, ServletResponse rsp, String realPath) throws ServletException,IOException { 768 realPath=optimizeRealPath(pc,realPath); 769 boolean inline=HttpServletResponseWrap.get(); 770 //print.out(rsp+":"+pc.getResponse()); 771 RequestDispatcher disp = getRequestDispatcher(pc,realPath); 772 773 if(inline) { 774 //RequestDispatcher disp = getRequestDispatcher(pc,realPath); 775 disp.include(req,rsp); 776 return; 777 } 778 779 try { 780 ByteArrayOutputStream baos=new ByteArrayOutputStream(); 781 HttpServletResponseWrap hsrw=new HttpServletResponseWrap(pc.getHttpServletResponse(),baos); 782 HttpServletResponseWrap.set(true); 783 784 //RequestDispatcher disp = getRequestDispatcher(pc,realPath); 785 786 disp.include(req,hsrw); 787 if(!hsrw.isCommitted())hsrw.flushBuffer(); 788 pc.write(IOUtil.toString(baos.toByteArray(), hsrw.getCharacterEncoding())); 789 } 790 finally{ 791 HttpServletResponseWrap.release(); 792 ThreadLocalPageContext.register(pc); 793 } 794 } 795 796 private static RequestDispatcher getRequestDispatcher(PageContext pc,String realPath) throws PageServletException { 797 RequestDispatcher disp = pc.getServletContext().getRequestDispatcher(realPath); 798 if(disp==null) throw new PageServletException(new ApplicationException("Page "+realPath+" not found")); 799 return disp; 800 } 801 802 803 // MUST create a copy from toURL and rename toURI and rewrite for URI, pherhaps it is possible to merge them somehow 804 public static String encode(String realpath) { 805 806 807 int qIndex=realpath.indexOf('?'); 808 809 if(qIndex==-1) return realpath; 810 811 String file=realpath.substring(0,qIndex); 812 String query=realpath.substring(qIndex+1); 813 int sIndex=query.indexOf('#'); 814 815 String anker=null; 816 if(sIndex!=-1){ 817 //print.o(sIndex); 818 anker=query.substring(sIndex+1); 819 query=query.substring(0,sIndex); 820 } 821 822 StringBuilder res=new StringBuilder(file); 823 824 825 // query 826 if(!StringUtil.isEmpty(query)){ 827 828 StringList list = List.toList(query, '&'); 829 String str; 830 int index; 831 char del='?'; 832 while(list.hasNext()){ 833 res.append(del); 834 del='&'; 835 str=list.next(); 836 index=str.indexOf('='); 837 if(index==-1)res.append(escapeQSValue(str)); 838 else { 839 res.append(escapeQSValue(str.substring(0,index))); 840 res.append('='); 841 res.append(escapeQSValue(str.substring(index+1))); 842 } 843 } 844 } 845 846 // anker 847 if(anker!=null) { 848 res.append('#'); 849 res.append(escapeQSValue(anker)); 850 } 851 852 853 return res.toString(); 854 } 855 856 857 public static int getPort(URL url) { 858 if(url.getPort()!=-1) return url.getPort(); 859 if("https".equalsIgnoreCase(url.getProtocol())) 860 return 443; 861 return 80; 862 } 863 864 865 /** 866 * return the length of a file defined by a url. 867 * @param dataUrl 868 * @return 869 */ 870 public static long length(URL url) { 871 long length=0; 872 873 // check response header "content-length" 874 ProxyData pd=ProxyDataImpl.NO_PROXY; 875 try { 876 HttpMethod http = HTTPUtil.head(url, null, null, -1,null, "Railo", pd.getServer(), pd.getPort(),pd.getUsername(), pd.getPassword(),null); 877 Header cl = http.getResponseHeader("content-length"); 878 if(cl!=null) { 879 length=Caster.toIntValue(cl.getValue(),-1); 880 if(length!=-1) return length; 881 } 882 } 883 catch (IOException e) {} 884 885 // get it for size 886 try { 887 HttpMethod http = HTTPUtil.invoke(url, null, null, -1,null, "Railo", pd.getServer(), pd.getPort(),pd.getUsername(), pd.getPassword(),null); 888 InputStream is = http.getResponseBodyAsStream(); 889 byte[] buffer = new byte[1024]; 890 int len; 891 length=0; 892 while((len = is.read(buffer)) !=-1){ 893 length+=len; 894 } 895 } 896 catch (IOException e) {} 897 return length; 898 } 899 900 public static ContentType getContentType(HttpMethod http) { 901 Header[] headers = http.getResponseHeaders(); 902 for(int i=0;i<headers.length;i++){ 903 if("Content-Type".equalsIgnoreCase(headers[i].getName())){ 904 String[] mimeCharset = splitMimeTypeAndCharset(headers[i].getValue()); 905 String[] typeSub = splitTypeAndSubType(mimeCharset[0]); 906 return new ContentTypeImpl(typeSub[0],typeSub[1],mimeCharset[1]); 907 } 908 } 909 return null; 910 } 911 912 913 914 public static Map<String, String> parseParameterList(String _str, boolean decode,String charset) { 915 //return railo.commons.net.HTTPUtil.toURI(strUrl,port); 916 Map<String,String> data=new HashMap<String, String>(); 917 StringList list = List.toList(_str, '&'); 918 String str; 919 int index; 920 while(list.hasNext()){ 921 str=list.next(); 922 index=str.indexOf('='); 923 if(index==-1){ 924 data.put(decode(str,decode), ""); 925 } 926 else { 927 data.put( 928 decode(str.substring(0,index),decode), 929 decode(str.substring(index+1),decode)); 930 } 931 } 932 return data; 933 } 934 935 private static String decode(String str, boolean encode) { 936 // TODO Auto-generated method stub 937 return str; 938 } 939 940 941 942 public static String[] splitMimeTypeAndCharset(String mimetype) { 943 String[] types=mimetype.split(";"); 944 String[] rtn=new String[2]; 945 946 if(types.length>0){ 947 rtn[0]=types[0].trim(); 948 if(types.length>1) { 949 String tmp=types[types.length-1].trim(); 950 int index=tmp.indexOf("charset="); 951 if(index!=-1) { 952 rtn[1]= StringUtil.removeQuotes(tmp.substring(index+8),true); 953 } 954 } 955 } 956 return rtn; 957 } 958 959 960 public static String[] splitTypeAndSubType(String mimetype) { 961 String[] types=List.listToStringArray(mimetype, '/'); 962 String[] rtn=new String[2]; 963 964 if(types.length>0){ 965 rtn[0]=types[0].trim(); 966 if(types.length>1) { 967 rtn[1]=types[1].trim(); 968 } 969 } 970 return rtn; 971 } 972 973 public static boolean isSecure(URL url) { 974 return StringUtil.indexOfIgnoreCase(url.getProtocol(),"https")!=-1; 975 } 976 }