1 17 package org.apache.jmeter.protocol.http.sampler; 18 19 import java.io.BufferedInputStream ; 20 import java.io.ByteArrayOutputStream ; 21 import java.io.IOException ; 22 23 import java.net.BindException ; 24 import java.net.HttpURLConnection ; 25 import java.net.MalformedURLException ; 26 import java.net.URL ; 27 import java.net.URLConnection ; 28 29 import java.util.zip.GZIPInputStream ; 30 31 import org.apache.jmeter.config.Arguments; 32 33 import org.apache.jmeter.protocol.http.control.AuthManager; 34 import org.apache.jmeter.protocol.http.control.CookieManager; 35 import org.apache.jmeter.protocol.http.control.Header; 36 import org.apache.jmeter.protocol.http.control.HeaderManager; 37 38 import org.apache.jmeter.testelement.property.CollectionProperty; 39 import org.apache.jmeter.testelement.property.PropertyIterator; 40 41 import org.apache.jmeter.util.JMeterUtils; 42 import org.apache.jmeter.util.SSLManager; 43 44 import org.apache.jorphan.logging.LoggingManager; 45 46 import org.apache.log.Logger; 47 48 54 public class HTTPSampler extends HTTPSamplerBase 55 { 56 transient private static Logger log= LoggingManager.getLoggerForClass(); 57 58 private static final int MAX_CONN_RETRIES = 10; 60 private static final PostWriter postWriter= new PostWriter(); 62 63 static { System.setProperty( 65 "java.protocol.handler.pkgs", 66 JMeterUtils.getPropDefault( 67 "ssl.pkgs", 68 "com.sun.net.ssl.internal.www.protocol")); 69 System.setProperty("javax.net.ssl.debug", "all"); 70 } 71 72 75 public HTTPSampler() 76 { 77 setArguments(new Arguments()); 78 } 79 80 86 public void setPostHeaders(URLConnection conn) throws IOException 87 { 88 postWriter.setHeaders(conn, this); 89 } 90 91 98 public void sendPostData(URLConnection connection) throws IOException 99 { 100 postWriter.sendPostData(connection, this); 101 } 102 103 116 protected HttpURLConnection setupConnection( 117 URL u, 118 String method, 119 HTTPSampleResult res) 120 throws IOException 121 { 122 HttpURLConnection conn; 123 134 HttpURLConnection.setFollowRedirects(getPropertyAsBoolean(AUTO_REDIRECTS)); 137 138 conn= (HttpURLConnection )u.openConnection(); 139 if ("https".equalsIgnoreCase(u.getProtocol())) 142 { 143 try 144 { 145 SSLManager.getInstance().setContext(conn); 146 } 147 catch (Exception e) 148 { 149 log.warn( 150 "You may have forgotten to set the ssl.provider property " 151 + "in jmeter.properties", 152 e); 153 } 154 } 155 156 if (getUseKeepAlive()) 161 { 162 conn.setRequestProperty("Connection", "keep-alive"); 163 } 164 else 165 { 166 conn.setRequestProperty("Connection", "close"); 167 } 168 169 conn.setRequestMethod(method); 170 String hdrs=setConnectionHeaders(conn, u, getHeaderManager()); 171 String cookies= setConnectionCookie(conn, u, getCookieManager()); 172 if (res != null) 173 { 174 StringBuffer sb= new StringBuffer (); 175 if (method.equals(POST)) 176 { 177 String q = this.getQueryString(); 178 res.setQueryString(q); 179 sb.append("Query data:\n"); 180 sb.append(q); 181 sb.append('\n'); 182 } 183 if (cookies != null) 184 { 185 res.setCookies(cookies); 186 sb.append("\nCookie Data:\n"); 187 sb.append(cookies); 188 sb.append('\n'); 189 } 190 res.setSamplerData(sb.toString()); 191 194 res.setURL(u); 195 res.setHTTPMethod(method); 196 res.setRequestHeaders(hdrs); 197 } 198 setConnectionAuthorization(conn, u, getAuthManager()); 199 if (method.equals(POST)) 200 { 201 setPostHeaders(conn); 202 } 203 return conn; 204 } 205 206 213 protected byte[] readResponse(HttpURLConnection conn) throws IOException 214 { 215 byte[] readBuffer= getThreadContext().getReadBuffer(); 216 BufferedInputStream in; 217 boolean logError=false; try 219 { 220 if ("gzip".equals(conn.getContentEncoding())) { 222 in= 223 new BufferedInputStream ( 224 new GZIPInputStream (conn.getInputStream())); 225 } 226 else 227 { 228 in= new BufferedInputStream (conn.getInputStream()); 229 } 230 } 231 catch (IOException e) 232 { 233 236 { 242 log.error(e.toString()); 243 logError=true; 248 } 249 in= new BufferedInputStream (conn.getErrorStream()); 250 } 251 catch (Exception e) 252 { 253 log.error(e.toString()); 254 in= new BufferedInputStream (conn.getErrorStream()); 259 logError=true; 260 } 261 java.io.ByteArrayOutputStream w= new ByteArrayOutputStream (); 262 int x= 0; 263 while ((x= in.read(readBuffer)) > -1) 264 { 265 w.write(readBuffer, 0, x); 266 } 267 in.close(); 268 w.flush(); 269 w.close(); 270 if (logError) 271 { 272 String s; 273 if (w.size() > 1000){ 274 s="\n"+w.toString().substring(0,1000)+"\n\t..."; 275 } else { 276 s="\n"+w.toString(); 277 } 278 log.error(s); 279 } 280 return w.toByteArray(); 281 } 282 283 289 protected String getResponseHeaders(HttpURLConnection conn) 290 throws IOException 291 { 292 StringBuffer headerBuf= new StringBuffer (); 293 headerBuf.append(conn.getHeaderField(0)); headerBuf.append("\n"); 300 301 for (int i= 1; conn.getHeaderFieldKey(i) != null; i++) 302 { 303 modifyHeaderValues(conn,i, headerBuf); 304 } 305 return headerBuf.toString(); 306 } 307 308 313 protected void modifyHeaderValues(HttpURLConnection conn, int headerIndex, StringBuffer resultBuf) 314 { 315 if ("transfer-encoding" .equalsIgnoreCase(conn.getHeaderFieldKey(headerIndex))) 318 { 319 return; 320 } 321 resultBuf.append(conn.getHeaderFieldKey(headerIndex)); 322 resultBuf.append(": "); 323 resultBuf.append(conn.getHeaderField(headerIndex)); 324 resultBuf.append("\n"); 325 } 326 327 337 private String setConnectionCookie( 338 HttpURLConnection conn, 339 URL u, 340 CookieManager cookieManager) 341 { 342 String cookieHeader= null; 343 if (cookieManager != null) 344 { 345 cookieHeader= cookieManager.getCookieHeaderForURL(u); 346 if (cookieHeader != null) 347 { 348 conn.setRequestProperty("Cookie", cookieHeader); 349 } 350 } 351 return cookieHeader; 352 } 353 354 365 private String setConnectionHeaders( 366 HttpURLConnection conn, 367 URL u, 368 HeaderManager headerManager) 369 { 370 StringBuffer hdrs = new StringBuffer (100); 371 if (headerManager != null) 372 { 373 CollectionProperty headers= headerManager.getHeaders(); 374 if (headers != null) 375 { 376 PropertyIterator i= headers.iterator(); 377 while (i.hasNext()) 378 { 379 Header header= (Header)i.next().getObjectValue(); 380 String n=header.getName(); 381 String v=header.getValue(); 382 conn.setRequestProperty(n,v); 383 hdrs.append(n); 384 hdrs.append(": "); 385 hdrs.append(v); 386 hdrs.append("\n"); 387 } 388 } 389 } 390 return hdrs.toString(); 391 } 392 393 403 private void setConnectionAuthorization( 404 HttpURLConnection conn, 405 URL u, 406 AuthManager authManager) 407 { 408 if (authManager != null) 409 { 410 String authHeader= authManager.getAuthHeaderForURL(u); 411 if (authHeader != null) 412 { 413 conn.setRequestProperty("Authorization", authHeader); 414 } 415 } 416 } 417 418 433 protected HTTPSampleResult sample( 434 URL url, 435 String method, 436 boolean areFollowingRedirect, 437 int frameDepth) 438 { 439 HttpURLConnection conn= null; 440 441 String urlStr = url.toString(); 442 log.debug("Start : sample" + urlStr); 443 444 HTTPSampleResult res= new HTTPSampleResult(); 445 if(this.getPropertyAsBoolean(MONITOR)){ 446 res.setMonitor(true); 447 } else { 448 res.setMonitor(false); 449 } 450 res.setSampleLabel(urlStr); 451 res.sampleStart(); 453 try 454 { 455 int retry; 458 for (retry= 1; retry <= MAX_CONN_RETRIES; retry++) 459 { 460 try 461 { 462 conn= setupConnection(url, method, res); 463 conn.connect(); 465 break; 466 } 467 catch (BindException e) 468 { 469 if (retry >= MAX_CONN_RETRIES) 470 { 471 log.error("Can't connect", e); 472 throw e; 473 } 474 log.debug("Bind exception, try again"); 475 conn.disconnect(); 476 this.setUseKeepAlive(false); 477 continue; } 479 catch (IOException e) 480 { 481 log.debug("Connection failed, giving up"); 482 throw e; 483 } 484 } 485 if (retry > MAX_CONN_RETRIES) 486 { 487 throw new BindException (); 489 } 490 if (method.equals(POST)) 492 { 493 sendPostData(conn); 494 } 495 byte[] responseData= readResponse(conn); 497 498 res.sampleEnd(); 499 501 503 res.setResponseData(responseData); 504 505 int errorLevel= conn.getResponseCode(); 506 res.setResponseCode(Integer.toString(errorLevel)); 507 res.setSuccessful(200 <= errorLevel && errorLevel <= 399); 508 509 res.setResponseMessage(conn.getResponseMessage()); 510 511 String ct= conn.getContentType(); res.setContentType(ct); if (ct != null) 514 { 515 String de=ct.toLowerCase(); 520 final String cs="charset="; 521 int cset= de.indexOf(cs); 522 if (cset >= 0) 523 { 524 res.setDataEncoding(de.substring(cset+cs.length())); 525 } 526 if (ct.startsWith("image/")) 527 { 528 res.setDataType(HTTPSampleResult.BINARY); 529 } 530 else 531 { 532 res.setDataType(HTTPSampleResult.TEXT); 533 } 534 } 535 536 res.setResponseHeaders(getResponseHeaders(conn)); 537 if (res.isRedirect()) 538 { 539 res.setRedirectLocation(conn.getHeaderField("Location")); 540 } 541 542 saveConnectionCookies(conn, url, getCookieManager()); 544 545 if (!areFollowingRedirect) 547 { 548 boolean didFollowRedirects= false; 549 if (res.isRedirect()) 550 { 551 log.debug("Location set to - " + res.getRedirectLocation()); 552 553 if (getFollowRedirects()) 554 { 555 res= followRedirects(res, frameDepth); 556 didFollowRedirects= true; 557 } 558 } 559 560 if (isImageParser() 561 && (HTTPSampleResult.TEXT).equals(res.getDataType()) 562 && res.isSuccessful()) 563 { 564 if (frameDepth > MAX_FRAME_DEPTH) 565 { 566 res.addSubResult( 567 errorResult( 568 new Exception ("Maximum frame/iframe nesting depth exceeded."), 569 null, 570 0)); 571 } 572 else 573 { 574 boolean createContainerResults= !didFollowRedirects; 576 577 res= 578 downloadPageResources( 579 res, 580 createContainerResults, 581 frameDepth); 582 } 583 } 584 } 585 586 log.debug("End : sample"); 587 return res; 588 } 589 catch (IOException e) 590 { 591 res.sampleEnd(); 592 return errorResult(e, url.toString(), res.getTime()); 593 } 594 finally 595 { 596 disconnect(conn); 600 } 601 } 602 603 616 private HTTPSampleResult followRedirects( 617 HTTPSampleResult res, 618 int frameDepth) 619 { 620 HTTPSampleResult totalRes= new HTTPSampleResult(res); 621 HTTPSampleResult lastRes= res; 622 623 int redirect; 624 for (redirect= 0; redirect < MAX_REDIRECTS; redirect++) 625 { 626 String location= encodeSpaces(lastRes.getRedirectLocation()); 627 try 631 { 632 lastRes= 633 sample( 634 new URL (lastRes.getURL(), location), 635 GET, 636 true, 637 frameDepth); 638 } 639 catch (MalformedURLException e) 640 { 641 lastRes= errorResult(e, location, 0); 642 } 643 totalRes.addSubResult(lastRes); 644 645 if (!lastRes.isRedirect()) 646 { 647 break; 648 } 649 } 650 if (redirect >= MAX_REDIRECTS) 651 { 652 lastRes= 653 errorResult( 654 new IOException ("Exceeeded maximum number of redirects: "+MAX_REDIRECTS), 655 null, 656 0); 657 totalRes.addSubResult(lastRes); 658 } 659 660 totalRes.setSampleLabel( 663 totalRes.getSampleLabel() + "->" + lastRes.getSampleLabel()); 664 totalRes.setURL(lastRes.getURL()); 669 totalRes.setHTTPMethod(lastRes.getHTTPMethod()); 670 totalRes.setRequestHeaders(lastRes.getRequestHeaders()); 671 672 totalRes.setResponseData(lastRes.getResponseData()); 673 totalRes.setResponseCode(lastRes.getResponseCode()); 674 totalRes.setSuccessful(lastRes.isSuccessful()); 675 totalRes.setResponseMessage(lastRes.getResponseMessage()); 676 totalRes.setDataType(lastRes.getDataType()); 677 totalRes.setResponseHeaders(lastRes.getResponseHeaders()); 678 return totalRes; 679 } 680 681 protected void disconnect(HttpURLConnection conn) 682 { 683 if (conn != null) 684 { 685 String connection= conn.getHeaderField("Connection"); 686 String protocol= conn.getHeaderField(0); 687 if ((connection == null && (protocol == null || !protocol.startsWith("HTTP/1.1"))) 688 || (connection != null && connection.equalsIgnoreCase("close"))) 689 { 690 conn.disconnect(); 691 } 692 } 693 } 694 695 705 private void saveConnectionCookies( 706 HttpURLConnection conn, 707 URL u, 708 CookieManager cookieManager) 709 { 710 if (cookieManager != null) 711 { 712 for (int i= 1; conn.getHeaderFieldKey(i) != null; i++) 713 { 714 if (conn.getHeaderFieldKey(i).equalsIgnoreCase("set-cookie")) 715 { 716 cookieManager.addCookieFromHeader( 717 conn.getHeaderField(i), 718 u); 719 } 720 } 721 } 722 } 723 724 public static class Test extends junit.framework.TestCase 725 { 726 public Test(String name) 727 { 728 super(name); 729 } 730 731 public void testArgumentWithoutEquals() throws Exception 732 { 733 HTTPSampler sampler= new HTTPSampler(); 734 sampler.setProtocol("http"); 735 sampler.setMethod(GET); 736 sampler.setPath("/index.html?pear"); 737 sampler.setDomain("www.apache.org"); 738 assertEquals( 739 "http://www.apache.org/index.html?pear", 740 sampler.getUrl().toString()); 741 } 742 743 public void testMakingUrl() throws Exception 744 { 745 HTTPSampler config= new HTTPSampler(); 746 config.setProtocol("http"); 747 config.setMethod(GET); 748 config.addArgument("param1", "value1"); 749 config.setPath("/index.html"); 750 config.setDomain("www.apache.org"); 751 assertEquals( 752 "http://www.apache.org/index.html?param1=value1", 753 config.getUrl().toString()); 754 } 755 public void testMakingUrl2() throws Exception 756 { 757 HTTPSampler config= new HTTPSampler(); 758 config.setProtocol("http"); 759 config.setMethod(GET); 760 config.addArgument("param1", "value1"); 761 config.setPath("/index.html?p1=p2"); 762 config.setDomain("www.apache.org"); 763 assertEquals( 764 "http://www.apache.org/index.html?param1=value1&p1=p2", 765 config.getUrl().toString()); 766 } 767 public void testMakingUrl3() throws Exception 768 { 769 HTTPSampler config= new HTTPSampler(); 770 config.setProtocol("http"); 771 config.setMethod(POST); 772 config.addArgument("param1", "value1"); 773 config.setPath("/index.html?p1=p2"); 774 config.setDomain("www.apache.org"); 775 assertEquals( 776 "http://www.apache.org/index.html?p1=p2", 777 config.getUrl().toString()); 778 } 779 780 783 public void testMakingUrl4() throws Exception 784 { 785 HTTPSampler config= new HTTPSampler(); 786 config.setProtocol("http"); 787 config.setMethod(GET); 788 config.addArgument("param1", "value1", "="); 789 config.setPath("/index.html"); 790 config.setDomain("www.apache.org"); 791 assertEquals( 792 "http://www.apache.org/index.html?param1=value1", 793 config.getUrl().toString()); 794 } 795 public void testMakingUrl5() throws Exception 796 { 797 HTTPSampler config= new HTTPSampler(); 798 config.setProtocol("http"); 799 config.setMethod(GET); 800 config.addArgument("param1", "", "="); 801 config.setPath("/index.html"); 802 config.setDomain("www.apache.org"); 803 assertEquals( 804 "http://www.apache.org/index.html?param1=", 805 config.getUrl().toString()); 806 } 807 public void testMakingUrl6() throws Exception 808 { 809 HTTPSampler config= new HTTPSampler(); 810 config.setProtocol("http"); 811 config.setMethod(GET); 812 config.addArgument("param1", "", ""); 813 config.setPath("/index.html"); 814 config.setDomain("www.apache.org"); 815 assertEquals( 816 "http://www.apache.org/index.html?param1", 817 config.getUrl().toString()); 818 } 819 820 823 public void testMakingUrl7() throws Exception 824 { 825 HTTPSampler config= new HTTPSampler(); 826 config.setProtocol("http"); 827 config.setMethod(GET); 828 config.parseArguments("param1=value1"); 829 config.setPath("/index.html"); 830 config.setDomain("www.apache.org"); 831 assertEquals( 832 "http://www.apache.org/index.html?param1=value1", 833 config.getUrl().toString()); 834 } 835 836 public void testMakingUrl8() throws Exception 837 { 838 HTTPSampler config= new HTTPSampler(); 839 config.setProtocol("http"); 840 config.setMethod(GET); 841 config.parseArguments("param1="); 842 config.setPath("/index.html"); 843 config.setDomain("www.apache.org"); 844 assertEquals( 845 "http://www.apache.org/index.html?param1=", 846 config.getUrl().toString()); 847 } 848 849 public void testMakingUrl9() throws Exception 850 { 851 HTTPSampler config= new HTTPSampler(); 852 config.setProtocol("http"); 853 config.setMethod(GET); 854 config.parseArguments("param1"); 855 config.setPath("/index.html"); 856 config.setDomain("www.apache.org"); 857 assertEquals( 858 "http://www.apache.org/index.html?param1", 859 config.getUrl().toString()); 860 } 861 862 public void testMakingUrl10() throws Exception 863 { 864 HTTPSampler config= new HTTPSampler(); 865 config.setProtocol("http"); 866 config.setMethod(GET); 867 config.parseArguments(""); 868 config.setPath("/index.html"); 869 config.setDomain("www.apache.org"); 870 assertEquals( 871 "http://www.apache.org/index.html", 872 config.getUrl().toString()); 873 } 874 } 875 } 876 | Popular Tags |