1 18 19 package org.apache.jmeter.protocol.http.control; 20 21 import java.io.BufferedReader; 22 import java.io.File; 23 import java.io.FileReader; 24 import java.io.FileWriter; 25 import java.io.IOException; 26 import java.io.PrintWriter; 27 import java.io.Serializable; 28 import java.net.URL; 29 import java.text.ParseException; 30 import java.text.SimpleDateFormat; 31 import java.util.ArrayList; 32 import java.util.Date; 33 import java.util.Enumeration; 34 import java.util.Locale; 35 import java.util.StringTokenizer; 36 import java.util.TimeZone; 37 import java.util.Vector; 38 39 import junit.framework.TestCase; 40 41 import org.apache.jmeter.config.ConfigTestElement; 42 import org.apache.jmeter.engine.event.LoopIterationEvent; 43 import org.apache.jmeter.protocol.http.sampler.HTTPSampler; 44 import org.apache.jmeter.testelement.TestListener; 45 import org.apache.jmeter.testelement.property.BooleanProperty; 46 import org.apache.jmeter.testelement.property.CollectionProperty; 47 import org.apache.jmeter.testelement.property.PropertyIterator; 48 import org.apache.jmeter.threads.JMeterContext; 49 import org.apache.jmeter.threads.JMeterContextService; 50 import org.apache.jmeter.util.JMeterUtils; 51 import org.apache.jorphan.logging.LoggingManager; 52 import org.apache.log.Logger; 53 54 61 public class CookieManager 62 extends ConfigTestElement 63 implements TestListener, Serializable 64 { 65 transient private static Logger log = LoggingManager.getLoggerForClass(); 66 67 public static final String CLEAR = "CookieManager.clearEachIteration"; 68 public static final String COOKIES = "CookieManager.cookies"; 69 70 private SimpleDateFormat dateFormat = 74 new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss zzz",Locale.US); 75 76 private static final boolean DELETE_NULL_COOKIES = 78 JMeterUtils.getPropDefault("CookieManager.delete_null_cookies",true); 80 public CookieManager() 81 { 82 dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); 86 87 setProperty(new CollectionProperty(COOKIES, new ArrayList())); 88 setProperty(new BooleanProperty(CLEAR, false)); 89 } 90 91 public CollectionProperty getCookies() 92 { 93 return (CollectionProperty) getProperty(COOKIES); 94 } 95 96 public int getCookieCount() 97 { 98 return getCookies().size(); 99 } 100 101 public boolean getClearEachIteration() 102 { 103 return getPropertyAsBoolean(CLEAR); 104 } 105 106 public void setClearEachIteration(boolean clear) 107 { 108 setProperty(new BooleanProperty(CLEAR, clear)); 109 } 110 111 118 public Cookie getCookie(int row) 119 { 120 return (Cookie) getCookies().get(row); 121 } 122 123 126 public void save(String authFile) throws IOException 127 { 128 File file = new File(authFile); 129 if (!file.isAbsolute()) 130 file = 131 new File( 132 System.getProperty("user.dir") + File.separator + authFile); 133 PrintWriter writer = new PrintWriter(new FileWriter(file)); 134 writer.println("# JMeter generated Cookie file"); 135 PropertyIterator cookies = getCookies().iterator(); 136 while (cookies.hasNext()) 137 { 138 Cookie cook = (Cookie) cookies.next().getObjectValue(); 139 writer.println(cook.toString()); 140 } 141 writer.flush(); 142 writer.close(); 143 } 144 145 148 public void addFile(String cookieFile) throws IOException 149 { 150 File file = new File(cookieFile); 151 if (!file.isAbsolute()) 152 file = 153 new File( 154 System.getProperty("user.dir") 155 + File.separator 156 + cookieFile); 157 BufferedReader reader = null; 158 if (file.canRead()) 159 { 160 reader = new BufferedReader(new FileReader(file)); 161 } 162 else 163 { 164 throw new IOException("The file you specified cannot be read."); 165 } 166 167 String line; 168 while ((line = reader.readLine()) != null) 169 { 170 try 171 { 172 if (line.startsWith("#") || line.trim().length() == 0) 173 continue; 174 String[] st = split(line, "\t", " "); 175 int domain = 0; 176 int path = 2; 177 if (st[path].equals(" ")) 178 st[path] = "/"; 179 boolean secure = Boolean.valueOf(st[3]).booleanValue(); 180 long expires = new Long(st[4]).longValue(); 181 int name = 5; 182 int value = 6; 183 Cookie cookie = 184 new Cookie( 185 st[name], 186 st[value], 187 st[domain], 188 st[path], 189 secure, 190 expires); 191 getCookies().addItem(cookie); 192 } 193 catch (Exception e) 194 { 195 reader.close(); 196 throw new IOException( 197 "Error parsing cookie line\n\t'" + line + "'\n\t" + e); 198 } 199 } 200 reader.close(); 201 } 202 203 public void recoverRunningVersion() 204 { 205 } 207 208 public void setRunningVersion(boolean running) 209 { 210 } 212 213 216 public void add(Cookie c) 217 { 218 String cv = c.getValue(); 219 if (DELETE_NULL_COOKIES && (null == cv || "".equals(cv))){ 220 removeCookieNamed(c.getName()); 221 } else { 222 JMeterContext context = getThreadContext(); 223 getCookies().addItem(c); 224 if(context.isSamplingStarted()) 225 { 226 context.getVariables().put(c.getName(),c.getValue()); 227 } 228 } 229 } 230 231 240 243 public void clear() 244 { 245 248 setProperty(new CollectionProperty(COOKIES, new ArrayList())); 249 } 250 251 254 public void remove(int index) 255 { 256 getCookies().remove(index); 257 } 258 259 262 public int size() 263 { 264 return getCookies().size(); 265 } 266 267 270 public Cookie get(int i) 271 { 272 return (Cookie) getCookies().get(i); 273 } 274 275 public String convertLongToDateFormatStr(long dateLong) 276 { 277 return dateFormat.format(new Date(dateLong)); 278 } 279 280 287 public String getCookieHeaderForURL(URL url) 288 { 289 if (!url.getProtocol().toUpperCase().trim().equals("HTTP") 290 && !url.getProtocol().toUpperCase().trim().equals("HTTPS")) 291 return null; 292 293 StringBuffer header = new StringBuffer(); 294 for (PropertyIterator enum = getCookies().iterator(); enum.hasNext();) 295 { 296 Cookie cookie = (Cookie) enum.next().getObjectValue(); 297 String host= "."+url.getHost(); 301 if (host.endsWith(cookie.getDomain()) 302 && url.getFile().startsWith(cookie.getPath()) 303 && ((cookie.getExpires()==0) || 305 (System.currentTimeMillis() / 1000) <= cookie.getExpires()) ) 306 { 307 if (header.length() > 0) 308 { 309 header.append("; "); 310 } 311 header.append(cookie.getName()).append("=").append( 312 cookie.getValue()); 313 } 314 } 315 316 if (header.length() != 0) 317 { 318 return header.toString(); 319 } 320 else 321 { 322 return null; 323 } 324 } 325 326 333 public void addCookieFromHeader(String cookieHeader, URL url) 334 { 335 StringTokenizer st = new StringTokenizer(cookieHeader, ";"); 336 String nvp; 337 338 nvp = st.nextToken(); 340 int index = nvp.indexOf("="); 341 String name = nvp.substring(0, index); 342 String value = nvp.substring(index + 1); 343 String domain = "."+url.getHost(); String path = "/"; 348 Cookie newCookie = 349 new Cookie( 350 name, 351 value, 352 domain, 353 path, 354 false, 355 System.currentTimeMillis() + 1000 * 60 * 60 * 24); 356 while (st.hasMoreTokens()) 358 { 359 nvp = st.nextToken(); 360 nvp = nvp.trim(); 361 index = nvp.indexOf("="); 362 if (index == -1) 363 { 364 index = nvp.length(); 365 } 366 String key = nvp.substring(0, index); 367 if (key.equalsIgnoreCase("expires")) 368 { 369 try 370 { 371 String expires = nvp.substring(index + 1); 372 Date date = dateFormat.parse(expires); 373 newCookie.setExpires(date.getTime()); 375 } 376 catch (ParseException pe) 377 { 378 log.error("Couldn't parse Cookie expiration time.", pe); 381 } 382 catch (Exception e) 383 { 384 log.error( 393 "Couln't parse Cookie expiration time: likely JDK bug.", 394 e); 395 } 396 } 397 else if (key.equalsIgnoreCase("domain")) 398 { 399 domain= nvp.substring(index + 1).trim(); 402 403 if (!domain.startsWith(".")) 407 { 408 domain= "."+domain; 409 } 410 411 newCookie.setDomain(domain); 412 } 413 else if (key.equalsIgnoreCase("path")) 414 { 415 newCookie.setPath(nvp.substring(index + 1)); 416 } 417 else if (key.equalsIgnoreCase("secure")) 418 { 419 newCookie.setSecure(true); 420 } 421 } 422 423 Vector removeIndices = new Vector(); 424 for (int i = getCookies().size() - 1; i >= 0; i--) 425 { 426 Cookie cookie = (Cookie) getCookies().get(i).getObjectValue(); 427 if (cookie == null) 428 continue; 429 if (cookie.getPath().equals(newCookie.getPath()) 430 && cookie.getDomain().equals(newCookie.getDomain()) 431 && cookie.getName().equals(newCookie.getName())) 432 { 433 removeIndices.addElement(new Integer(i)); 434 } 435 } 436 437 for (Enumeration e = removeIndices.elements(); e.hasMoreElements();) 438 { 439 index = ((Integer) e.nextElement()).intValue(); 440 remove(index); 441 } 442 443 if (newCookie.getExpires() >= System.currentTimeMillis()) 444 { 445 add(newCookie); 446 } 447 } 448 449 public void removeCookieNamed(String name) 450 { 451 PropertyIterator iter = getCookies().iterator(); 452 while (iter.hasNext()) 453 { 454 Cookie cookie = (Cookie) iter.next().getObjectValue(); 455 if (cookie.getName().equals(name)) 456 { 457 iter.remove(); 458 } 459 } 460 } 461 462 472 public String[] split(String splittee, String splitChar, String def) 473 { 474 if (splittee == null || splitChar == null) 475 return new String[0]; 476 StringTokenizer tokens; 477 String temp; 478 int spot; 479 while ((spot = splittee.indexOf(splitChar + splitChar)) != -1) 480 splittee = 481 splittee.substring(0, spot + splitChar.length()) 482 + def 483 + splittee.substring( 484 spot + 1 * splitChar.length(), 485 splittee.length()); 486 Vector returns = new Vector(); 487 tokens = new StringTokenizer(splittee, splitChar); 488 while (tokens.hasMoreTokens()) 489 { 490 temp = (String) tokens.nextToken(); 491 returns.addElement(temp); 492 } 493 String[] values = new String[returns.size()]; 494 returns.copyInto(values); 495 return values; 496 } 497 498 public String getClassLabel() 499 { 500 return JMeterUtils.getResString("cookie_manager_title"); 501 } 502 503 public void testStarted() 504 { 505 } 506 507 public void testEnded() 508 { 509 } 510 511 public void testStarted(String host) 512 { 513 } 514 515 public void testEnded(String host) 516 { 517 } 518 519 public void testIterationStart(LoopIterationEvent event) 520 { 521 if (getClearEachIteration()) 522 clear(); 523 } 524 525 public static class Test extends TestCase 526 { 527 CookieManager man = null; 528 529 public Test(String name) 530 { 531 super(name); 532 } 533 private JMeterContext jmctx = null; 534 535 public void setUp() 536 { 537 jmctx = JMeterContextService.getContext(); 538 man = new CookieManager(); 539 man.setThreadContext(jmctx); 540 } 541 542 543 public void testRemoveCookie() throws Exception 544 { 545 man.setThreadContext(jmctx); 546 man.add(new Cookie("id", "me", "127.0.0.1", "/", false, 0)); 547 man.removeCookieNamed("id"); 548 assertEquals(0, man.getCookieCount()); 549 } 550 551 public void testSendCookie() throws Exception 552 { 553 man.add( 554 new Cookie( 555 "id", 556 "value", 557 "jakarta.apache.org", 558 "/", 559 false, 560 9999999999L)); 561 HTTPSampler sampler = new HTTPSampler(); 562 sampler.setDomain("jakarta.apache.org"); 563 sampler.setPath("/index.html"); 564 sampler.setMethod(HTTPSampler.GET); 565 assertNotNull(man.getCookieHeaderForURL(sampler.getUrl())); 566 } 567 568 public void testSendCookie2() throws Exception 569 { 570 man.add( 571 new Cookie( 572 "id", 573 "value", 574 ".apache.org", 575 "/", 576 false, 577 9999999999L)); 578 HTTPSampler sampler = new HTTPSampler(); 579 sampler.setDomain("jakarta.apache.org"); 580 sampler.setPath("/index.html"); 581 sampler.setMethod(HTTPSampler.GET); 582 assertNotNull(man.getCookieHeaderForURL(sampler.getUrl())); 583 } 584 585 589 public void testDomainHandling() throws Exception 590 { 591 URL url= new URL("http://jakarta.apache.org/"); 592 man.addCookieFromHeader("test=1;domain=.jakarta.apache.org", url); 593 assertNotNull(man.getCookieHeaderForURL(url)); 594 } 595 596 600 public void testSimilarHostNames() throws Exception 601 { 602 URL url= new URL("http://ache.org/"); 603 man.addCookieFromHeader("test=1", url); 604 url= new URL("http://jakarta.apache.org/"); 605 assertNull(man.getCookieHeaderForURL(url)); 606 } 607 } 608 } | Popular Tags |