1 17 18 package org.apache.tomcat.util.http; 19 20 import java.io.PrintWriter ; 21 import java.io.StringWriter ; 22 import java.util.StringTokenizer ; 23 24 import org.apache.tomcat.util.buf.ByteChunk; 25 import org.apache.tomcat.util.buf.MessageBytes; 26 27 36 public final class Cookies { 38 private static org.apache.commons.logging.Log log= 39 org.apache.commons.logging.LogFactory.getLog(Cookies.class ); 40 41 public static final int INITIAL_SIZE=4; 43 ServerCookie scookies[]=new ServerCookie[INITIAL_SIZE]; 44 int cookieCount=0; 45 boolean unprocessed=true; 46 47 MimeHeaders headers; 48 49 56 public Cookies(MimeHeaders headers) { 57 this.headers=headers; 58 } 59 60 64 public Cookies() { 67 } 68 69 76 public void setHeaders(MimeHeaders headers) { 79 recycle(); 80 this.headers=headers; 81 } 82 83 86 public void recycle() { 87 for( int i=0; i< cookieCount; i++ ) { 88 if( scookies[i]!=null ) 89 scookies[i].recycle(); 90 } 91 cookieCount=0; 92 unprocessed=true; 93 } 94 95 98 public String toString() { 99 StringWriter sw = new StringWriter (); 100 PrintWriter pw = new PrintWriter (sw); 101 pw.println("=== Cookies ==="); 102 int count = getCookieCount(); 103 for (int i = 0; i < count; ++i) { 104 pw.println(getCookie(i).toString()); 105 } 106 return sw.toString(); 107 } 108 109 111 public ServerCookie getCookie( int idx ) { 112 if( unprocessed ) { 113 getCookieCount(); } 115 return scookies[idx]; 116 } 117 118 public int getCookieCount() { 119 if( unprocessed ) { 120 unprocessed=false; 121 processCookies(headers); 122 } 123 return cookieCount; 124 } 125 126 128 132 public ServerCookie addCookie() { 133 if( cookieCount >= scookies.length ) { 134 ServerCookie scookiesTmp[]=new ServerCookie[2*cookieCount]; 135 System.arraycopy( scookies, 0, scookiesTmp, 0, cookieCount); 136 scookies=scookiesTmp; 137 } 138 139 ServerCookie c = scookies[cookieCount]; 140 if( c==null ) { 141 c= new ServerCookie(); 142 scookies[cookieCount]=c; 143 } 144 cookieCount++; 145 return c; 146 } 147 148 149 151 153 public void processCookies( MimeHeaders headers ) { 154 if( headers==null ) 155 return; int pos=0; 158 while( pos>=0 ) { 159 pos=headers.findHeader( "Cookie", pos ); 161 if( pos<0 ) break; 163 164 MessageBytes cookieValue=headers.getValue( pos ); 165 if( cookieValue==null || cookieValue.isNull() ) { 166 pos++; 167 continue; 168 } 169 170 if( cookieValue.getType() == MessageBytes.T_BYTES ) { 172 if( dbg>0 ) log( "Parsing b[]: " + cookieValue.toString()); 173 ByteChunk bc=cookieValue.getByteChunk(); 174 processCookieHeader( bc.getBytes(), 175 bc.getOffset(), 176 bc.getLength()); 177 } else { 178 if( dbg>0 ) log( "Parsing S: " + cookieValue.toString()); 179 processCookieHeader( cookieValue.toString() ); 180 } 181 pos++; } 183 } 184 185 188 void processCookieHeader( byte bytes[], int off, int len ) 189 { 190 if( len<=0 || bytes==null ) return; 191 int end=off+len; 192 int pos=off; 193 194 int version=0; ServerCookie sc=null; 196 197 198 while( pos<end ) { 199 byte cc; 200 if( dbg>0 ) log( "Start: " + pos + " " + end ); 202 203 pos=skipSpaces(bytes, pos, end); 204 if( pos>=end ) 205 return; int startName=pos; 207 if( dbg>0 ) log( "SN: " + pos ); 208 209 boolean isSpecial=false; 211 if(bytes[pos]=='$') { pos++; isSpecial=true; } 212 213 pos= findDelim1( bytes, startName, end); int endName=pos; 215 pos= skipSpaces( bytes, endName, end ); 217 if( dbg>0 ) log( "DELIM: " + endName + " " + (char)bytes[pos]); 218 219 if(pos >= end ) { 220 if( ! isSpecial ) { 222 sc=addCookie(); 223 sc.getName().setBytes( bytes, startName, 224 endName-startName ); 225 sc.getValue().setString(""); 226 sc.setVersion( version ); 227 if( dbg>0 ) log( "Name only, end: " + startName + " " + 228 endName); 229 } 230 return; 231 } 232 233 cc=bytes[pos]; 234 pos++; 235 if( cc==';' || cc==',' || pos>=end ) { 236 if( ! isSpecial && startName!= endName ) { 237 sc=addCookie(); 238 sc.getName().setBytes( bytes, startName, 239 endName-startName ); 240 sc.getValue().setString(""); 241 sc.setVersion( version ); 242 if( dbg>0 ) log( "Name only: " + startName + " " + endName); 243 } 244 continue; 245 } 246 247 int startValue=skipSpaces( bytes, pos, end); 249 int endValue=startValue; 250 251 cc=bytes[pos]; 252 if( cc== '\'' || cc=='"' ) { 253 startValue++; 254 endValue=indexOf( bytes, startValue, end, cc ); 255 pos=endValue+1; } else { 257 endValue=findDelim2( bytes, startValue, end ); 258 pos=endValue+1; 259 } 260 261 if( ! isSpecial ) { 263 sc=addCookie(); 264 sc.getName().setBytes( bytes, startName, endName-startName ); 265 sc.getValue().setBytes( bytes, startValue, endValue-startValue); 266 sc.setVersion( version ); 267 if( dbg>0 ) { 268 log( "New: " + sc.getName() + "X=X" + sc.getValue()); 269 } 270 continue; 271 } 272 273 if( dbg>0 ) log( "Special: " + startName + " " + endName); 275 if( equals( "$Version", bytes, startName, endName ) ) { 277 if(dbg>0 ) log( "Found version " ); 278 if( bytes[startValue]=='1' && endValue==startValue+1 ) { 279 version=1; 280 if(dbg>0 ) log( "Found version=1" ); 281 } 282 continue; 283 } 284 if( sc==null ) { 285 continue; 287 } 288 if( equals( "$Path", bytes, startName, endName ) ) { 289 sc.getPath().setBytes( bytes, 290 startValue, 291 endValue-startValue ); 292 } 293 if( equals( "$Domain", bytes, startName, endName ) ) { 294 sc.getDomain().setBytes( bytes, 295 startValue, 296 endValue-startValue ); 297 } 298 if( equals( "$Port", bytes, startName, endName ) ) { 299 } 303 } 304 } 305 306 public static int skipSpaces( byte bytes[], int off, int end ) { 308 while( off < end ) { 309 byte b=bytes[off]; 310 if( b!= ' ' ) return off; 311 off ++; 312 } 313 return off; 314 } 315 316 public static int findDelim1( byte bytes[], int off, int end ) 317 { 318 while( off < end ) { 319 byte b=bytes[off]; 320 if( b==' ' || b=='=' || b==';' || b==',' ) 321 return off; 322 off++; 323 } 324 return off; 325 } 326 327 public static int findDelim2( byte bytes[], int off, int end ) 328 { 329 while( off < end ) { 330 byte b=bytes[off]; 331 if( b==';' || b==',' ) 332 return off; 333 off++; 334 } 335 return off; 336 } 337 338 public static int indexOf( byte bytes[], int off, int end, byte qq ) 339 { 340 while( off < end ) { 341 byte b=bytes[off]; 342 if( b==qq ) 343 return off; 344 off++; 345 } 346 return off; 347 } 348 349 public static int indexOf( byte bytes[], int off, int end, char qq ) 350 { 351 while( off < end ) { 352 byte b=bytes[off]; 353 if( b==qq ) 354 return off; 355 off++; 356 } 357 return off; 358 } 359 360 public static boolean equals( String s, byte b[], int start, int end) { 362 int blen = end-start; 363 if (b == null || blen != s.length()) { 364 return false; 365 } 366 int boff = start; 367 for (int i = 0; i < blen; i++) { 368 if (b[boff++] != s.charAt(i)) { 369 return false; 370 } 371 } 372 return true; 373 } 374 375 376 379 private void processCookieHeader( String cookieString ) 380 { 381 if( dbg>0 ) log( "Parsing cookie header " + cookieString ); 382 386 StringTokenizer tok = new StringTokenizer (cookieString, 387 ";", false); 388 while (tok.hasMoreTokens()) { 389 String token = tok.nextToken(); 390 int i = token.indexOf("="); 391 if (i > -1) { 392 393 397 String name = token.substring(0, i).trim(); 398 String value = token.substring(i+1, token.length()).trim(); 399 value=stripQuote( value ); 401 ServerCookie cookie = addCookie(); 402 403 cookie.getName().setString(name); 404 cookie.getValue().setString(value); 405 if( dbg > 0 ) log( "Add cookie " + name + "=" + value); 406 } else { 407 } 409 } 410 } 411 412 423 private static String stripQuote( String value ) 424 { 425 if (((value.startsWith("\"")) && (value.endsWith("\""))) || 427 ((value.startsWith("'") && (value.endsWith("'"))))) { 428 try { 429 return value.substring(1,value.length()-1); 430 } catch (Exception ex) { 431 } 432 } 433 return value; 434 } 435 436 437 static final int dbg=0; 439 public void log(String s ) { 440 if (log.isDebugEnabled()) 441 log.debug("Cookies: " + s); 442 } 443 444 481 482 } 483 | Popular Tags |