1 17 18 19 package org.apache.coyote.http11; 20 21 import java.io.IOException ; 22 import java.io.EOFException ; 23 import java.nio.ByteBuffer ; 24 25 import org.apache.tomcat.jni.Socket; 26 import org.apache.tomcat.jni.Status; 27 import org.apache.tomcat.util.buf.ByteChunk; 28 import org.apache.tomcat.util.buf.MessageBytes; 29 import org.apache.tomcat.util.http.MimeHeaders; 30 import org.apache.tomcat.util.res.StringManager; 31 32 import org.apache.coyote.InputBuffer; 33 import org.apache.coyote.Request; 34 35 41 public class InternalAprInputBuffer implements InputBuffer { 42 43 44 46 47 49 50 53 public InternalAprInputBuffer(Request request, int headerBufferSize, 54 long readTimeout) { 55 56 this.request = request; 57 headers = request.getMimeHeaders(); 58 59 buf = new byte[headerBufferSize]; 60 if (headerBufferSize < (8 * 1024)) { 61 bbuf = ByteBuffer.allocateDirect(6 * 1500); 62 } else { 63 bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500); 64 } 65 66 inputStreamInputBuffer = new SocketInputBuffer(); 67 68 filterLibrary = new InputFilter[0]; 69 activeFilters = new InputFilter[0]; 70 lastActiveFilter = -1; 71 72 parsingHeader = true; 73 swallowInput = true; 74 75 if (readTimeout < 0) { 76 this.readTimeout = -1; 77 } else { 78 this.readTimeout = readTimeout * 1000; 79 } 80 81 } 82 83 84 86 87 90 protected static StringManager sm = 91 StringManager.getManager(Constants.Package); 92 93 94 96 97 100 protected Request request; 101 102 103 106 protected MimeHeaders headers; 107 108 109 112 protected boolean parsingHeader; 113 114 115 118 protected boolean swallowInput; 119 120 121 124 protected byte[] buf; 125 126 127 130 protected int lastValid; 131 132 133 136 protected int pos; 137 138 139 143 protected int end; 144 145 146 149 protected ByteBuffer bbuf; 150 151 152 155 protected long socket; 156 157 158 161 protected InputBuffer inputStreamInputBuffer; 162 163 164 168 protected InputFilter[] filterLibrary; 169 170 171 174 protected InputFilter[] activeFilters; 175 176 177 180 protected int lastActiveFilter; 181 182 183 187 protected long readTimeout; 188 189 190 192 193 196 public void setSocket(long socket) { 197 this.socket = socket; 198 Socket.setrbb(this.socket, bbuf); 199 } 200 201 202 205 public long getSocket() { 206 return socket; 207 } 208 209 210 213 public void addFilter(InputFilter filter) { 214 215 InputFilter[] newFilterLibrary = 216 new InputFilter[filterLibrary.length + 1]; 217 for (int i = 0; i < filterLibrary.length; i++) { 218 newFilterLibrary[i] = filterLibrary[i]; 219 } 220 newFilterLibrary[filterLibrary.length] = filter; 221 filterLibrary = newFilterLibrary; 222 223 activeFilters = new InputFilter[filterLibrary.length]; 224 225 } 226 227 228 231 public InputFilter[] getFilters() { 232 233 return filterLibrary; 234 235 } 236 237 238 241 public void clearFilters() { 242 243 filterLibrary = new InputFilter[0]; 244 lastActiveFilter = -1; 245 246 } 247 248 249 252 public void addActiveFilter(InputFilter filter) { 253 254 if (lastActiveFilter == -1) { 255 filter.setBuffer(inputStreamInputBuffer); 256 } else { 257 for (int i = 0; i <= lastActiveFilter; i++) { 258 if (activeFilters[i] == filter) 259 return; 260 } 261 filter.setBuffer(activeFilters[lastActiveFilter]); 262 } 263 264 activeFilters[++lastActiveFilter] = filter; 265 266 filter.setRequest(request); 267 268 } 269 270 271 274 public void setSwallowInput(boolean swallowInput) { 275 this.swallowInput = swallowInput; 276 } 277 278 279 281 282 286 public void recycle() { 287 288 request.recycle(); 290 291 socket = 0; 292 lastValid = 0; 293 pos = 0; 294 lastActiveFilter = -1; 295 parsingHeader = true; 296 swallowInput = true; 297 298 } 299 300 301 307 public void nextRequest() { 308 309 request.recycle(); 311 312 if (lastValid - pos > 0) { 315 int npos = 0; 316 int opos = pos; 317 while (lastValid - opos > opos - npos) { 318 System.arraycopy(buf, opos, buf, npos, opos - npos); 319 npos += pos; 320 opos += pos; 321 } 322 System.arraycopy(buf, opos, buf, npos, lastValid - opos); 323 } 324 325 for (int i = 0; i <= lastActiveFilter; i++) { 327 activeFilters[i].recycle(); 328 } 329 330 lastValid = lastValid - pos; 332 pos = 0; 333 lastActiveFilter = -1; 334 parsingHeader = true; 335 swallowInput = true; 336 337 } 338 339 340 345 public void endRequest() 346 throws IOException { 347 348 if (swallowInput && (lastActiveFilter != -1)) { 349 int extraBytes = (int) activeFilters[lastActiveFilter].end(); 350 pos = pos - extraBytes; 351 } 352 353 } 354 355 356 367 public boolean parseRequestLine(boolean useAvailableData) 368 throws IOException { 369 370 int start = 0; 371 372 376 byte chr = 0; 377 do { 378 379 if (pos >= lastValid) { 381 if (useAvailableData) { 382 return false; 383 } 384 if (readTimeout == -1) { 385 if (!fill()) 386 throw new EOFException (sm.getString("iib.eof.error")); 387 } else { 388 bbuf.clear(); 390 int nRead = Socket.recvbbt 391 (socket, 0, buf.length - lastValid, readTimeout); 392 if (nRead > 0) { 393 bbuf.limit(nRead); 394 bbuf.get(buf, pos, nRead); 395 lastValid = pos + nRead; 396 } else { 397 if ((-nRead) == Status.ETIMEDOUT || (-nRead) == Status.TIMEUP) { 398 return false; 399 } else { 400 throw new IOException (sm.getString("iib.failedread")); 401 } 402 } 403 } 404 } 405 406 chr = buf[pos++]; 407 408 } while ((chr == Constants.CR) || (chr == Constants.LF)); 409 410 pos--; 411 412 start = pos; 414 415 if (pos >= lastValid) { 416 if (useAvailableData) { 417 return false; 418 } 419 if (readTimeout == -1) { 420 if (!fill()) 421 throw new EOFException (sm.getString("iib.eof.error")); 422 } else { 423 bbuf.clear(); 425 int nRead = Socket.recvbbt 426 (socket, 0, buf.length - lastValid, readTimeout); 427 if (nRead > 0) { 428 bbuf.limit(nRead); 429 bbuf.get(buf, pos, nRead); 430 lastValid = pos + nRead; 431 } else { 432 if ((-nRead) == Status.ETIMEDOUT || (-nRead) == Status.TIMEUP) { 433 return false; 434 } else { 435 throw new IOException (sm.getString("iib.failedread")); 436 } 437 } 438 } 439 } 440 441 446 boolean space = false; 447 448 while (!space) { 449 450 if (pos >= lastValid) { 452 if (!fill()) 453 throw new EOFException (sm.getString("iib.eof.error")); 454 } 455 456 if (buf[pos] == Constants.SP) { 457 space = true; 458 request.method().setBytes(buf, start, pos - start); 459 } 460 461 pos++; 462 463 } 464 465 start = pos; 467 int end = 0; 468 int questionPos = -1; 469 470 474 space = false; 475 boolean eol = false; 476 477 while (!space) { 478 479 if (pos >= lastValid) { 481 if (!fill()) 482 throw new EOFException (sm.getString("iib.eof.error")); 483 } 484 485 if (buf[pos] == Constants.SP) { 486 space = true; 487 end = pos; 488 } else if ((buf[pos] == Constants.CR) 489 || (buf[pos] == Constants.LF)) { 490 eol = true; 492 space = true; 493 end = pos; 494 } else if ((buf[pos] == Constants.QUESTION) 495 && (questionPos == -1)) { 496 questionPos = pos; 497 } 498 499 pos++; 500 501 } 502 503 request.unparsedURI().setBytes(buf, start, end - start); 504 if (questionPos >= 0) { 505 request.queryString().setBytes(buf, questionPos + 1, 506 end - questionPos - 1); 507 request.requestURI().setBytes(buf, start, questionPos - start); 508 } else { 509 request.requestURI().setBytes(buf, start, end - start); 510 } 511 512 start = pos; 514 end = 0; 515 516 521 while (!eol) { 522 523 if (pos >= lastValid) { 525 if (!fill()) 526 throw new EOFException (sm.getString("iib.eof.error")); 527 } 528 529 if (buf[pos] == Constants.CR) { 530 end = pos; 531 } else if (buf[pos] == Constants.LF) { 532 if (end == 0) 533 end = pos; 534 eol = true; 535 } 536 537 pos++; 538 539 } 540 541 if ((end - start) > 0) { 542 request.protocol().setBytes(buf, start, end - start); 543 } else { 544 request.protocol().setString(""); 545 } 546 547 return true; 548 549 } 550 551 552 555 public void parseHeaders() 556 throws IOException { 557 558 while (parseHeader()) { 559 } 560 561 parsingHeader = false; 562 end = pos; 563 564 } 565 566 567 573 public boolean parseHeader() 574 throws IOException { 575 576 580 byte chr = 0; 581 while (true) { 582 583 if (pos >= lastValid) { 585 if (!fill()) 586 throw new EOFException (sm.getString("iib.eof.error")); 587 } 588 589 chr = buf[pos]; 590 591 if ((chr == Constants.CR) || (chr == Constants.LF)) { 592 if (chr == Constants.LF) { 593 pos++; 594 return false; 595 } 596 } else { 597 break; 598 } 599 600 pos++; 601 602 } 603 604 int start = pos; 606 607 612 boolean colon = false; 613 MessageBytes headerValue = null; 614 615 while (!colon) { 616 617 if (pos >= lastValid) { 619 if (!fill()) 620 throw new EOFException (sm.getString("iib.eof.error")); 621 } 622 623 if (buf[pos] == Constants.COLON) { 624 colon = true; 625 headerValue = headers.addValue(buf, start, pos - start); 626 } 627 chr = buf[pos]; 628 if ((chr >= Constants.A) && (chr <= Constants.Z)) { 629 buf[pos] = (byte) (chr - Constants.LC_OFFSET); 630 } 631 632 pos++; 633 634 } 635 636 start = pos; 638 int realPos = pos; 639 640 644 boolean eol = false; 645 boolean validLine = true; 646 647 while (validLine) { 648 649 boolean space = true; 650 651 while (space) { 653 654 if (pos >= lastValid) { 656 if (!fill()) 657 throw new EOFException (sm.getString("iib.eof.error")); 658 } 659 660 if ((buf[pos] == Constants.SP) || (buf[pos] == Constants.HT)) { 661 pos++; 662 } else { 663 space = false; 664 } 665 666 } 667 668 int lastSignificantChar = realPos; 669 670 while (!eol) { 672 673 if (pos >= lastValid) { 675 if (!fill()) 676 throw new EOFException (sm.getString("iib.eof.error")); 677 } 678 679 if (buf[pos] == Constants.CR) { 680 } else if (buf[pos] == Constants.LF) { 681 eol = true; 682 } else if (buf[pos] == Constants.SP) { 683 buf[realPos] = buf[pos]; 684 realPos++; 685 } else { 686 buf[realPos] = buf[pos]; 687 realPos++; 688 lastSignificantChar = realPos; 689 } 690 691 pos++; 692 693 } 694 695 realPos = lastSignificantChar; 696 697 700 if (pos >= lastValid) { 702 if (!fill()) 703 throw new EOFException (sm.getString("iib.eof.error")); 704 } 705 706 chr = buf[pos]; 707 if ((chr != Constants.SP) && (chr != Constants.HT)) { 708 validLine = false; 709 } else { 710 eol = false; 711 buf[realPos] = chr; 714 realPos++; 715 } 716 717 } 718 719 headerValue.setBytes(buf, start, realPos - start); 721 722 return true; 723 724 } 725 726 727 729 730 733 public int doRead(ByteChunk chunk, Request req) 734 throws IOException { 735 736 if (lastActiveFilter == -1) 737 return inputStreamInputBuffer.doRead(chunk, req); 738 else 739 return activeFilters[lastActiveFilter].doRead(chunk,req); 740 741 } 742 743 744 746 747 752 protected boolean fill() 753 throws IOException { 754 755 int nRead = 0; 756 757 if (parsingHeader) { 758 759 if (lastValid == buf.length) { 760 throw new IOException 761 (sm.getString("iib.requestheadertoolarge.error")); 762 } 763 764 bbuf.clear(); 765 nRead = Socket.recvbb(socket, 0, buf.length - lastValid); 766 if (nRead > 0) { 767 bbuf.limit(nRead); 768 bbuf.get(buf, pos, nRead); 769 lastValid = pos + nRead; 770 } else { 771 if ((-nRead) == Status.EAGAIN) { 772 return false; 773 } else { 774 throw new IOException (sm.getString("iib.failedread")); 775 } 776 } 777 778 } else { 779 780 if (buf.length - end < 4500) { 781 buf = new byte[buf.length]; 785 end = 0; 786 } 787 pos = end; 788 lastValid = pos; 789 bbuf.clear(); 790 nRead = Socket.recvbb(socket, 0, buf.length - lastValid); 791 if (nRead > 0) { 792 bbuf.limit(nRead); 793 bbuf.get(buf, pos, nRead); 794 lastValid = pos + nRead; 795 } else { 796 throw new IOException (sm.getString("iib.failedread")); 797 } 798 799 } 800 801 return (nRead > 0); 802 803 } 804 805 806 808 809 813 protected class SocketInputBuffer 814 implements InputBuffer { 815 816 817 820 public int doRead(ByteChunk chunk, Request req ) 821 throws IOException { 822 823 if (pos >= lastValid) { 824 if (!fill()) 825 return -1; 826 } 827 828 int length = lastValid - pos; 829 chunk.setBytes(buf, pos, length); 830 pos = lastValid; 831 832 return (length); 833 834 } 835 836 837 } 838 839 840 } 841 | Popular Tags |