OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
5 * Copyright (C) 2009 Google Inc. All rights reserved. | 5 * Copyright (C) 2009 Google Inc. All rights reserved. |
6 * Copyright (C) 2011 Apple Inc. All Rights Reserved. | 6 * Copyright (C) 2011 Apple Inc. All Rights Reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
600 else if (httpVersionString[7] == '0') | 600 else if (httpVersionString[7] == '0') |
601 httpVersion = HTTP_1_0; | 601 httpVersion = HTTP_1_0; |
602 else if (httpVersionString[7] == '1') | 602 else if (httpVersionString[7] == '1') |
603 httpVersion = HTTP_1_1; | 603 httpVersion = HTTP_1_1; |
604 else | 604 else |
605 httpVersion = Unknown; | 605 httpVersion = Unknown; |
606 | 606 |
607 return end - data; | 607 return end - data; |
608 } | 608 } |
609 | 609 |
610 size_t parseHTTPHeader(const char* start, size_t length, String& failureReason, AtomicString& nameStr, AtomicString& valueStr) | 610 static bool parseHTTPHeaderName(const char* s, size_t start, size_t size, String & failureReason, size_t* position, AtomicString* name) |
611 { | 611 { |
612 const char* p = start; | 612 size_t nameBegin = start; |
613 const char* end = start + length; | 613 for (size_t i = start; i < size; ++i) { |
614 | 614 switch (s[i]) { |
615 Vector<char> name; | |
616 Vector<char> value; | |
617 nameStr = nullAtom; | |
618 valueStr = nullAtom; | |
619 | |
620 for (; p < end; p++) { | |
621 switch (*p) { | |
622 case '\r': | 615 case '\r': |
623 if (name.isEmpty()) { | 616 failureReason = "Unexpected CR in name at " + trimInputSample(&s[nam eBegin], i - nameBegin); |
624 if (p + 1 < end && *(p + 1) == '\n') | 617 return false; |
625 return (p + 2) - start; | 618 case '\n': |
626 failureReason = "CR doesn't follow LF at " + trimInputSample(p, end - p); | 619 failureReason = "Unexpected LF in name at " + trimInputSample(&s[nam eBegin], i - nameBegin); |
627 return 0; | 620 return false; |
621 case ':': | |
622 if (i == nameBegin) { | |
623 failureReason = "Header name is missing"; | |
624 return false; | |
628 } | 625 } |
629 failureReason = "Unexpected CR in name at " + trimInputSample(name.d ata(), name.size()); | 626 *name = AtomicString::fromUTF8(&s[nameBegin], i - nameBegin); |
630 return 0; | 627 if (name->isNull()) { |
631 case '\n': | 628 failureReason = "Invalid UTF-8 sequence in header name"; |
632 failureReason = "Unexpected LF in name at " + trimInputSample(name.d ata(), name.size()); | 629 return false; |
633 return 0; | 630 } |
634 case ':': | 631 *position = i; |
635 break; | 632 return true; |
636 default: | 633 default: |
637 name.append(*p); | |
638 continue; | |
639 } | |
640 if (*p == ':') { | |
641 ++p; | |
642 break; | 634 break; |
643 } | 635 } |
644 } | 636 } |
637 failureReason = "Unterminated header name"; | |
638 return false; | |
639 } | |
645 | 640 |
646 for (; p < end && *p == 0x20; p++) { } | 641 static bool parseHTTPHeaderValue(const char* s, size_t start, size_t size, Strin g& failureReason, size_t* position, AtomicString* value) |
642 { | |
643 size_t i = start; | |
644 for (; i < size && s[i] == ' '; ++i) { | |
645 } | |
646 size_t valueBegin = i; | |
647 | 647 |
648 for (; p < end; p++) { | 648 for (; i < size && s[i] != '\r'; ++i) { |
649 switch (*p) { | 649 if (s[i] == '\n') { |
650 case '\r': | 650 failureReason = "Unexpected LF in value at " + trimInputSample(&s[va lueBegin], i - valueBegin); |
651 break; | 651 return false; |
652 case '\n': | |
653 failureReason = "Unexpected LF in value at " + trimInputSample(value .data(), value.size()); | |
654 return 0; | |
655 default: | |
656 value.append(*p); | |
657 } | |
658 if (*p == '\r') { | |
659 ++p; | |
660 break; | |
661 } | 652 } |
662 } | 653 } |
663 if (p >= end || *p != '\n') { | 654 if (i == size) { |
664 failureReason = "CR doesn't follow LF after value at " + trimInputSample (p, end - p); | 655 failureReason = "Unterminated header value"; |
656 return false; | |
657 } | |
658 | |
659 ASSERT(i < size && s[i] == '\r'); | |
660 if (i + 1 >= size || s[i + 1] != '\n') { | |
661 failureReason = "LF doesn't follow CR after value at " + trimInputSample (&s[i + 1], size - i - 1); | |
662 return false; | |
663 } | |
664 | |
665 *value = AtomicString::fromUTF8(&s[valueBegin], i - valueBegin); | |
666 if (i != valueBegin && value->isNull()) { | |
667 failureReason = "Invalid UTF-8 sequence in header value"; | |
668 return false; | |
tyoshino (SeeGerritForStatus)
2014/06/05 02:07:32
nice!
| |
669 } | |
670 | |
671 *position = i + 1; | |
672 return true; | |
673 } | |
674 | |
675 // Note that the header is already parsed and re-formatted in chromium side. | |
676 // We assume that the input is more restricted than RFC2616. | |
677 size_t parseHTTPHeader(const char* s, size_t size, String& failureReason, Atomic String& name, AtomicString& value) | |
678 { | |
679 name = nullAtom; | |
680 value = nullAtom; | |
681 if (size >= 1 && s[0] == '\r') { | |
682 if (size >= 2 && s[1] == '\n') { | |
683 // Skip an empty line. | |
684 return 2; | |
685 } | |
686 failureReason = "LF doesn't follow CR at " + trimInputSample(0, size); | |
665 return 0; | 687 return 0; |
666 } | 688 } |
667 nameStr = AtomicString::fromUTF8(name.data(), name.size()); | 689 size_t current = 0; |
668 valueStr = AtomicString::fromUTF8(value.data(), value.size()); | 690 if (!parseHTTPHeaderName(s, current, size, failureReason, ¤t, &name)) { |
669 if (nameStr.isNull()) { | |
670 failureReason = "Invalid UTF-8 sequence in header name"; | |
671 return 0; | 691 return 0; |
672 } | 692 } |
673 if (valueStr.isNull()) { | 693 ASSERT(s[current] == ':'); |
674 failureReason = "Invalid UTF-8 sequence in header value"; | 694 ++current; |
695 | |
696 if (!parseHTTPHeaderValue(s, current, size, failureReason, ¤t, &value) ) { | |
675 return 0; | 697 return 0; |
676 } | 698 } |
677 return p - start; | 699 |
700 return current; | |
678 } | 701 } |
679 | 702 |
680 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body) | 703 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body) |
681 { | 704 { |
682 body.clear(); | 705 body.clear(); |
683 body.append(data, length); | 706 body.append(data, length); |
684 | 707 |
685 return length; | 708 return length; |
686 } | 709 } |
687 | 710 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
821 if (!cacheControlHeader.containsNoCache) { | 844 if (!cacheControlHeader.containsNoCache) { |
822 // Handle Pragma: no-cache | 845 // Handle Pragma: no-cache |
823 // This is deprecated and equivalent to Cache-control: no-cache | 846 // This is deprecated and equivalent to Cache-control: no-cache |
824 // Don't bother tokenizing the value, it is not important | 847 // Don't bother tokenizing the value, it is not important |
825 cacheControlHeader.containsNoCache = pragmaValue.lower().contains(noCach eDirective); | 848 cacheControlHeader.containsNoCache = pragmaValue.lower().contains(noCach eDirective); |
826 } | 849 } |
827 return cacheControlHeader; | 850 return cacheControlHeader; |
828 } | 851 } |
829 | 852 |
830 } | 853 } |
OLD | NEW |