1 17 18 19 package org.apache.coyote.http11; 20 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.EOFException ; 24 25 import org.apache.tomcat.util.buf.ByteChunk; 26 import org.apache.tomcat.util.buf.MessageBytes; 27 import org.apache.tomcat.util.http.MimeHeaders; 28 import org.apache.tomcat.util.res.StringManager; 29 30 import org.apache.coyote.InputBuffer; 31 import org.apache.coyote.Request; 32 33 39 public class InternalInputBuffer implements InputBuffer { 40 41 42 44 45 47 48 51 public InternalInputBuffer(Request request) { 52 this(request, Constants.DEFAULT_HTTP_HEADER_BUFFER_SIZE); 53 } 54 55 56 59 public InternalInputBuffer(Request request, int headerBufferSize) { 60 61 this.request = request; 62 headers = request.getMimeHeaders(); 63 64 buf = new byte[headerBufferSize]; 65 66 inputStreamInputBuffer = new InputStreamInputBuffer(); 67 68 filterLibrary = new InputFilter[0]; 69 activeFilters = new InputFilter[0]; 70 lastActiveFilter = -1; 71 72 parsingHeader = true; 73 swallowInput = true; 74 75 } 76 77 78 80 81 84 protected static StringManager sm = 85 StringManager.getManager(Constants.Package); 86 87 88 90 91 94 protected Request request; 95 96 97 100 protected MimeHeaders headers; 101 102 103 106 protected boolean parsingHeader; 107 108 109 112 protected boolean swallowInput; 113 114 115 118 protected byte[] buf; 119 120 121 124 protected int lastValid; 125 126 127 130 protected int pos; 131 132 133 137 protected int end; 138 139 140 143 protected InputStream inputStream; 144 145 146 149 protected InputBuffer inputStreamInputBuffer; 150 151 152 156 protected InputFilter[] filterLibrary; 157 158 159 162 protected InputFilter[] activeFilters; 163 164 165 168 protected int lastActiveFilter; 169 170 171 173 174 177 public void setInputStream(InputStream inputStream) { 178 179 181 this.inputStream = inputStream; 182 183 } 184 185 186 189 public InputStream getInputStream() { 190 191 return inputStream; 192 193 } 194 195 196 199 public void addFilter(InputFilter filter) { 200 201 203 InputFilter[] newFilterLibrary = 204 new InputFilter[filterLibrary.length + 1]; 205 for (int i = 0; i < filterLibrary.length; i++) { 206 newFilterLibrary[i] = filterLibrary[i]; 207 } 208 newFilterLibrary[filterLibrary.length] = filter; 209 filterLibrary = newFilterLibrary; 210 211 activeFilters = new InputFilter[filterLibrary.length]; 212 213 } 214 215 216 219 public InputFilter[] getFilters() { 220 221 return filterLibrary; 222 223 } 224 225 226 229 public void clearFilters() { 230 231 filterLibrary = new InputFilter[0]; 232 lastActiveFilter = -1; 233 234 } 235 236 237 240 public void addActiveFilter(InputFilter filter) { 241 242 if (lastActiveFilter == -1) { 243 filter.setBuffer(inputStreamInputBuffer); 244 } else { 245 for (int i = 0; i <= lastActiveFilter; i++) { 246 if (activeFilters[i] == filter) 247 return; 248 } 249 filter.setBuffer(activeFilters[lastActiveFilter]); 250 } 251 252 activeFilters[++lastActiveFilter] = filter; 253 254 filter.setRequest(request); 255 256 } 257 258 259 262 public void setSwallowInput(boolean swallowInput) { 263 this.swallowInput = swallowInput; 264 } 265 266 267 269 270 274 public void recycle() { 275 276 request.recycle(); 278 279 inputStream = null; 280 lastValid = 0; 281 pos = 0; 282 lastActiveFilter = -1; 283 parsingHeader = true; 284 swallowInput = true; 285 286 } 287 288 289 295 public void nextRequest() { 296 297 request.recycle(); 299 300 if (lastValid - pos > 0) { 302 int npos = 0; 303 int opos = pos; 304 while (lastValid - opos > opos - npos) { 305 System.arraycopy(buf, opos, buf, npos, opos - npos); 306 npos += pos; 307 opos += pos; 308 } 309 System.arraycopy(buf, opos, buf, npos, lastValid - opos); 310 } 311 312 for (int i = 0; i <= lastActiveFilter; i++) { 314 activeFilters[i].recycle(); 315 } 316 317 lastValid = lastValid - pos; 319 pos = 0; 320 lastActiveFilter = -1; 321 parsingHeader = true; 322 swallowInput = true; 323 324 } 325 326 327 332 public void endRequest() 333 throws IOException { 334 335 if (swallowInput && (lastActiveFilter != -1)) { 336 int extraBytes = (int) activeFilters[lastActiveFilter].end(); 337 pos = pos - extraBytes; 338 } 339 340 } 341 342 343 352 public void parseRequestLine() 353 throws IOException { 354 355 int start = 0; 356 357 361 byte chr = 0; 362 do { 363 364 if (pos >= lastValid) { 366 if (!fill()) 367 throw new EOFException (sm.getString("iib.eof.error")); 368 } 369 370 chr = buf[pos++]; 371 372 } while ((chr == Constants.CR) || (chr == Constants.LF)); 373 374 pos--; 375 376 start = pos; 378 379 384 boolean space = false; 385 386 while (!space) { 387 388 if (pos >= lastValid) { 390 if (!fill()) 391 throw new EOFException (sm.getString("iib.eof.error")); 392 } 393 394 if (buf[pos] == Constants.SP) { 395 space = true; 396 request.method().setBytes(buf, start, pos - start); 397 } 398 399 pos++; 400 401 } 402 403 start = pos; 405 int end = 0; 406 int questionPos = -1; 407 408 412 space = false; 413 boolean eol = false; 414 415 while (!space) { 416 417 if (pos >= lastValid) { 419 if (!fill()) 420 throw new EOFException (sm.getString("iib.eof.error")); 421 } 422 423 if (buf[pos] == Constants.SP) { 424 space = true; 425 end = pos; 426 } else if ((buf[pos] == Constants.CR) 427 || (buf[pos] == Constants.LF)) { 428 eol = true; 430 space = true; 431 end = pos; 432 } else if ((buf[pos] == Constants.QUESTION) 433 && (questionPos == -1)) { 434 questionPos = pos; 435 } 436 437 pos++; 438 439 } 440 441 request.unparsedURI().setBytes(buf, start, end - start); 442 if (questionPos >= 0) { 443 request.queryString().setBytes(buf, questionPos + 1, 444 end - questionPos - 1); 445 request.requestURI().setBytes(buf, start, questionPos - start); 446 } else { 447 request.requestURI().setBytes(buf, start, end - start); 448 } 449 450 start = pos; 452 end = 0; 453 454 459 while (!eol) { 460 461 if (pos >= lastValid) { 463 if (!fill()) 464 throw new EOFException (sm.getString("iib.eof.error")); 465 } 466 467 if (buf[pos] == Constants.CR) { 468 end = pos; 469 } else if (buf[pos] == Constants.LF) { 470 if (end == 0) 471 end = pos; 472 eol = true; 473 } 474 475 pos++; 476 477 } 478 479 if ((end - start) > 0) { 480 request.protocol().setBytes(buf, start, end - start); 481 } else { 482 request.protocol().setString(""); 483 } 484 485 } 486 487 488 491 public void parseHeaders() 492 throws IOException { 493 494 while (parseHeader()) { 495 } 496 497 parsingHeader = false; 498 end = pos; 499 500 } 501 502 503 509 public boolean parseHeader() 510 throws IOException { 511 512 516 byte chr = 0; 517 while (true) { 518 519 if (pos >= lastValid) { 521 if (!fill()) 522 throw new EOFException (sm.getString("iib.eof.error")); 523 } 524 525 chr = buf[pos]; 526 527 if ((chr == Constants.CR) || (chr == Constants.LF)) { 528 if (chr == Constants.LF) { 529 pos++; 530 return false; 531 } 532 } else { 533 break; 534 } 535 536 pos++; 537 538 } 539 540 int start = pos; 542 543 548 boolean colon = false; 549 MessageBytes headerValue = null; 550 551 while (!colon) { 552 553 if (pos >= lastValid) { 555 if (!fill()) 556 throw new EOFException (sm.getString("iib.eof.error")); 557 } 558 559 if (buf[pos] == Constants.COLON) { 560 colon = true; 561 headerValue = headers.addValue(buf, start, pos - start); 562 } 563 chr = buf[pos]; 564 if ((chr >= Constants.A) && (chr <= Constants.Z)) { 565 buf[pos] = (byte) (chr - Constants.LC_OFFSET); 566 } 567 568 pos++; 569 570 } 571 572 start = pos; 574 int realPos = pos; 575 576 580 boolean eol = false; 581 boolean validLine = true; 582 583 while (validLine) { 584 585 boolean space = true; 586 587 while (space) { 589 590 if (pos >= lastValid) { 592 if (!fill()) 593 throw new EOFException (sm.getString("iib.eof.error")); 594 } 595 596 if ((buf[pos] == Constants.SP) || (buf[pos] == Constants.HT)) { 597 pos++; 598 } else { 599 space = false; 600 } 601 602 } 603 604 int lastSignificantChar = realPos; 605 606 while (!eol) { 608 609 if (pos >= lastValid) { 611 if (!fill()) 612 throw new EOFException (sm.getString("iib.eof.error")); 613 } 614 615 if (buf[pos] == Constants.CR) { 616 } else if (buf[pos] == Constants.LF) { 617 eol = true; 618 } else if (buf[pos] == Constants.SP) { 619 buf[realPos] = buf[pos]; 620 realPos++; 621 } else { 622 buf[realPos] = buf[pos]; 623 realPos++; 624 lastSignificantChar = realPos; 625 } 626 627 pos++; 628 629 } 630 631 realPos = lastSignificantChar; 632 633 636 if (pos >= lastValid) { 638 if (!fill()) 639 throw new EOFException (sm.getString("iib.eof.error")); 640 } 641 642 chr = buf[pos]; 643 if ((chr != Constants.SP) && (chr != Constants.HT)) { 644 validLine = false; 645 } else { 646 eol = false; 647 buf[realPos] = chr; 650 realPos++; 651 } 652 653 } 654 655 headerValue.setBytes(buf, start, realPos - start); 657 658 return true; 659 660 } 661 662 663 665 666 669 public int doRead(ByteChunk chunk, Request req) 670 throws IOException { 671 672 if (lastActiveFilter == -1) 673 return inputStreamInputBuffer.doRead(chunk, req); 674 else 675 return activeFilters[lastActiveFilter].doRead(chunk,req); 676 677 } 678 679 680 682 683 688 protected boolean fill() 689 throws IOException { 690 691 int nRead = 0; 692 693 if (parsingHeader) { 694 695 if (lastValid == buf.length) { 696 throw new IOException 697 (sm.getString("iib.requestheadertoolarge.error")); 698 } 699 700 nRead = inputStream.read(buf, pos, buf.length - lastValid); 701 if (nRead > 0) { 702 lastValid = pos + nRead; 703 } 704 705 } else { 706 707 if (buf.length - end < 4500) { 708 buf = new byte[buf.length]; 712 end = 0; 713 } 714 pos = end; 715 lastValid = pos; 716 nRead = inputStream.read(buf, pos, buf.length - lastValid); 717 if (nRead > 0) { 718 lastValid = pos + nRead; 719 } 720 721 } 722 723 return (nRead > 0); 724 725 } 726 727 728 730 731 735 protected class InputStreamInputBuffer 736 implements InputBuffer { 737 738 739 742 public int doRead(ByteChunk chunk, Request req ) 743 throws IOException { 744 745 if (pos >= lastValid) { 746 if (!fill()) 747 return -1; 748 } 749 750 int length = lastValid - pos; 751 chunk.setBytes(buf, pos, length); 752 pos = lastValid; 753 754 return (length); 755 756 } 757 758 759 } 760 761 762 } 763 | Popular Tags |