1 23 24 39 package com.sun.enterprise.web.connector.grizzly.algorithms; 40 41 import com.sun.enterprise.web.connector.grizzly.Constants; 42 import com.sun.enterprise.web.connector.grizzly.Handler; 43 import com.sun.enterprise.web.connector.grizzly.SelectorThread; 44 import com.sun.enterprise.web.connector.grizzly.handlers.ContentLengthHandler; 45 46 import java.nio.ByteBuffer ; 47 import java.nio.BufferUnderflowException ; 48 import java.util.logging.Level ; 49 50 import org.apache.tomcat.util.buf.Ascii; 51 52 64 public final class ContentLengthAlgorithm extends StreamAlgorithmBase{ 65 66 private final static byte[] POST_METHOD = "post".getBytes(); 67 private final static byte[] PUT_METHOD = "put".getBytes(); 68 69 private final static byte[] CL_HEADER = "content-length".getBytes(); 70 71 72 75 public byte[] ascbuf = new byte[Constants.CHANNEL_BYTE_SIZE]; 76 77 78 81 protected int lastValid; 82 83 84 87 protected int pos; 88 89 90 93 private boolean isFound = false; 94 95 96 99 private boolean requestLineParsed = false; 100 101 102 105 public int startReq = -1; 106 107 108 111 public int lengthReq = -1; 112 113 114 116 117 public ContentLengthAlgorithm() { 118 handler = new ContentLengthHandler(this); 119 } 120 121 122 137 public boolean parse(ByteBuffer byteBuffer){ 138 isFound = false; 139 140 curLimit = byteBuffer.limit(); 141 curPosition = byteBuffer.position(); 142 143 if ( contentLength != -1 ){ 146 isFound = 147 ((contentLength + headerLength) <= byteBuffer.position()); 148 149 if (isFound) 150 byteBuffer.flip(); 151 152 return isFound; 153 } 154 155 try{ 156 if (byteBuffer.position() == 0) 158 return false; 159 160 byteBuffer.flip(); 161 lastValid = byteBuffer.limit(); 162 163 if ( !requestLineParsed ) { 165 requestLineParsed = parseRequestLine(byteBuffer); 166 if ( !requestLineParsed ) { 167 return false; 168 } 169 } 170 171 while (parseHeader(byteBuffer)); 173 174 if ( headerLength != -1 && isFound ){ 177 isFound = ((contentLength + headerLength) 178 <= byteBuffer.limit()); 179 } else { 180 isFound = false; 183 } 184 185 return isFound; 186 } catch (BufferUnderflowException bue) { 187 SelectorThread.logger().log(Level.SEVERE, 188 "readTask.bufferunderflow", bue); 189 return false; 190 } finally { 191 byteBuffer.limit(curLimit); 192 byteBuffer.position(curPosition); 193 194 if (isFound){ 195 byteBuffer.flip(); 196 } 197 } 198 } 199 200 201 204 private boolean parseRequestLine(ByteBuffer byteBuffer){ 205 int start = 0; 206 byte chr = 0; 207 208 if ( state == 0 ){ 209 do { 210 if (pos >= lastValid) 211 return false; 212 213 chr = byteBuffer.get(pos++); 214 215 } while ((chr == Constants.CR) || (chr == Constants.LF)); 216 217 state = 1; 218 219 pos--; 220 byteBuffer.position(pos); 221 } 222 223 start = pos; 225 boolean space = false; 226 if ( state == 1 ) { 227 while (!space) { 228 if (pos >= lastValid) 229 return false; 230 231 byte c = byteBuffer.get(pos); 232 ascbuf[pos] = c; 233 234 if (c == Constants.SP) { 235 space = true; 236 if ( !isFound && 237 (findBytes(ascbuf,start, pos, POST_METHOD) == -1 238 || findBytes(ascbuf,start, pos, PUT_METHOD) == -1)){ 239 isFound = true; 240 } 241 } 242 243 pos++; 244 } 245 state = 2; 246 } 247 248 start = pos; 250 int end = 0; 251 space = false; 252 boolean eol = false; 253 int questionPos = -1; 254 if ( state == 2 ){ 255 while (!space) { 256 if (pos >= lastValid) 258 return false; 259 260 byte b = byteBuffer.get(pos); 261 ascbuf[pos] = b; 262 if ( b == Constants.SP) { 263 space = true; 264 end = pos; 265 } else if ((b == Constants.CR) 266 || (b == Constants.LF)) { 267 eol = true; 269 space = true; 270 end = pos; 271 } else if ((b == Constants.QUESTION) && (questionPos == -1)){ 272 questionPos = pos; 273 } 274 pos++; 275 276 } 277 state = 3; 278 279 startReq = start; 280 if (questionPos >= 0) { 281 lengthReq = questionPos - start; 282 } else { 283 lengthReq = end - start; 284 } 285 } 286 287 if ( state == 3 ) { 288 start = pos; 290 end = 0; 291 while (!eol) { 292 if (pos >= lastValid) 294 return false; 295 296 byte b = byteBuffer.get(pos); 297 298 if (b == Constants.CR) { 299 end = pos; 300 } else if (b == Constants.LF) { 301 if (end == 0) 302 end = pos; 303 eol = true; 304 } 305 pos++; 306 } 307 state = 4; 308 } 309 return eol; 310 } 311 312 313 316 public boolean parseHeader(ByteBuffer byteBuffer){ 317 318 boolean headerFound = false; 319 byte chr = 0; 320 321 if ( state == 4 ){ 322 while (true) { 323 if (pos >= lastValid) 325 return false; 326 327 chr = byteBuffer.get(pos); 328 329 if ((chr == Constants.CR) || (chr == Constants.LF)) { 330 if (chr == Constants.LF) { 331 pos++; 332 headerLength = pos; 333 isFound = true; 334 state = 4; 335 return false; 336 } 337 } else { 338 break; 339 } 340 341 pos++; 342 } 343 state = 5; 344 } 345 346 int start = pos; 348 349 if ( state == 5 ){ 350 boolean colon = false; 351 while (!colon) { 352 if (pos >= lastValid) 354 return false; 355 356 chr = byteBuffer.get(pos); 357 if (chr == Constants.COLON) { 358 colon = true; 359 360 if ( contentLength == -1 361 && findBytes(ascbuf, start, start + (pos - start), 362 CL_HEADER ) != -1){ 363 headerFound = true; 364 } 365 } 366 367 if ((chr >= Constants.A) && (chr <= Constants.Z)) { 368 chr = (byte) (chr - Constants.LC_OFFSET); 369 } 370 371 ascbuf[pos] = chr; 372 373 pos++; 374 } 375 state = 6; 376 } 377 378 start = pos; 380 int realPos = pos; 381 382 boolean eol = false; 383 boolean validLine = true; 384 385 while (validLine) { 386 387 boolean space = true; 388 389 if ( state == 6 ){ 390 while (space) { 392 if (pos >= lastValid) 394 return false; 395 396 chr = byteBuffer.get(pos); 397 if (( chr == Constants.SP) || (chr == Constants.HT)) { 398 pos++; 399 } else { 400 space = false; 401 } 402 } 403 state = 7; 404 } 405 406 int lastSignificantChar = realPos; 407 if ( state == 7){ 409 while (!eol) { 410 if (pos >= lastValid) 412 return false; 413 414 chr = byteBuffer.get(pos); 415 if (chr == Constants.CR) { 416 } else if (chr == Constants.LF) { 417 eol = true; 418 } else if (chr == Constants.SP) { 419 realPos++; 420 } else { 421 realPos++; 422 lastSignificantChar = realPos; 423 } 424 pos++; 425 } 426 state = 8; 427 realPos = lastSignificantChar; 428 } 429 430 if ( state == 8){ 431 if (pos >= lastValid) 433 return false; 434 435 chr = byteBuffer.get(pos); 436 if ((chr != Constants.SP) && (chr != Constants.HT)) { 437 validLine = false; 438 } else { 439 eol = false; 440 realPos++; 441 } 442 state = 4; 443 } 444 } 445 446 if ( headerFound ){ 447 byteBuffer.position(start+1); 448 StringBuilder sb = new StringBuilder (); 449 for(int i=0; i < realPos - start; i++) { 450 sb.append((char) byteBuffer.get()); 451 } 452 contentLength = Integer.parseInt(sb.toString()); 453 } 454 455 return true; 456 457 } 458 459 460 463 private int findBytes(byte[] buff, int start, int end, byte[] b) { 464 465 byte first = b[0]; 466 467 int srcEnd = b.length; 469 470 for (int i = start; i <= (end - srcEnd); i++) { 471 if (Ascii.toLower(buff[i]) != first) continue; 472 473 int myPos = i+1; 475 for (int srcPos = 1; srcPos < srcEnd; ) { 476 if (Ascii.toLower(buff[myPos++]) != b[srcPos++]) 477 break; 478 if (srcPos == srcEnd) return i - start; } 480 } 481 return -1; 482 483 } 484 485 486 489 public void recycle(){ 490 contentLength = -1; 491 headerLength = -1; 492 curLimit = -1; 493 curPosition = -1; 494 pos = 0; 495 lastValid = 0; 496 requestLineParsed = false; 497 isFound = false; 498 state = 0; 499 lengthReq = -1; 500 startReq = -1; 501 502 socketChannel = null; 503 if ( handler != null){ 504 ((ContentLengthHandler)handler).attachChannel(null); 505 } 506 } 507 508 509 512 public Handler getHandler(){ 513 ((ContentLengthHandler)handler).attachChannel(socketChannel); 514 return handler; 515 } 516 } 517 | Popular Tags |