| 68 | |
| 69 | |
| 70 | void MessageHeader::read(std::istream& istr) |
| 71 | { |
| 72 | static const int eof = std::char_traits<char>::eof(); |
| 73 | std::streambuf& buf = *istr.rdbuf(); |
| 74 | |
| 75 | std::string name; |
| 76 | std::string value; |
| 77 | name.reserve(32); |
| 78 | value.reserve(64); |
| 79 | int ch = buf.sbumpc(); |
| 80 | int fields = 0; |
| 81 | while (ch != eof && ch != '\r' && ch != '\n') |
| 82 | { |
| 83 | if (_fieldLimit > 0 && fields == _fieldLimit) |
| 84 | throw MessageException("Too many header fields"); |
| 85 | name.clear(); |
| 86 | value.clear(); |
| 87 | while (ch != eof && ch != ':' && ch != '\n' && name.length() < _nameLengthLimit) { name += ch; ch = buf.sbumpc(); } |
| 88 | if (ch == '\n') { ch = buf.sbumpc(); continue; } // ignore invalid header lines |
| 89 | if (ch != ':') throw MessageException("Field name too long/no colon found"); |
| 90 | if (ch != eof) ch = buf.sbumpc(); // ':' |
| 91 | while (ch != eof && Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n') ch = buf.sbumpc(); |
| 92 | while (ch != eof && ch != '\r' && ch != '\n' && value.length() < _valueLengthLimit) { value += ch; ch = buf.sbumpc(); } |
| 93 | if (ch == '\r') ch = buf.sbumpc(); |
| 94 | if (ch == '\n') |
| 95 | ch = buf.sbumpc(); |
| 96 | else if (ch != eof) |
| 97 | throw MessageException("Field value too long/no CRLF found"); |
| 98 | while (ch == ' ' || ch == '\t') // folding |
| 99 | { |
| 100 | while (ch != eof && ch != '\r' && ch != '\n' && value.length() < _valueLengthLimit) { value += ch; ch = buf.sbumpc(); } |
| 101 | if (ch == '\r') ch = buf.sbumpc(); |
| 102 | if (ch == '\n') |
| 103 | ch = buf.sbumpc(); |
| 104 | else if (ch != eof) |
| 105 | throw MessageException("Folded field value too long/no CRLF found"); |
| 106 | } |
| 107 | Poco::trimRightInPlace(value); |
| 108 | add(name, decodeWord(value)); |
| 109 | ++fields; |
| 110 | } |
| 111 | istr.putback(ch); |
| 112 | } |
| 113 | |
| 114 | |
| 115 | int MessageHeader::getFieldLimit() const |