aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/poco/Net/src/MessageHeader.cpp
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:45:01 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:01 +0300
commit2d37894b1b037cf24231090eda8589bbb44fb6fc (patch)
treebe835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/poco/Net/src/MessageHeader.cpp
parent718c552901d703c502ccbefdfc3c9028d608b947 (diff)
downloadydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/poco/Net/src/MessageHeader.cpp')
-rw-r--r--contrib/libs/poco/Net/src/MessageHeader.cpp788
1 files changed, 394 insertions, 394 deletions
diff --git a/contrib/libs/poco/Net/src/MessageHeader.cpp b/contrib/libs/poco/Net/src/MessageHeader.cpp
index d98531487b..a684b3cf5d 100644
--- a/contrib/libs/poco/Net/src/MessageHeader.cpp
+++ b/contrib/libs/poco/Net/src/MessageHeader.cpp
@@ -1,394 +1,394 @@
-//
-// MessageHeader.cpp
-//
-// Library: Net
-// Package: Messages
-// Module: MessageHeader
-//
-// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
-// and Contributors.
-//
-// SPDX-License-Identifier: BSL-1.0
-//
-
-
-#include "Poco/Net/MessageHeader.h"
-#include "Poco/Net/NetException.h"
-#include "Poco/String.h"
-#include "Poco/Ascii.h"
-#include "Poco/TextConverter.h"
-#include "Poco/StringTokenizer.h"
-#include "Poco/Base64Decoder.h"
-#include "Poco/UTF8Encoding.h"
-#include <sstream>
-
-
-namespace Poco {
-namespace Net {
-
-
-MessageHeader::MessageHeader():
- _fieldLimit(DFL_FIELD_LIMIT)
-{
-}
-
-
-MessageHeader::MessageHeader(const MessageHeader& messageHeader):
- NameValueCollection(messageHeader),
- _fieldLimit(DFL_FIELD_LIMIT)
-{
-}
-
-
-MessageHeader::~MessageHeader()
-{
-}
-
-
-MessageHeader& MessageHeader::operator = (const MessageHeader& messageHeader)
-{
- NameValueCollection::operator = (messageHeader);
- return *this;
-}
-
-
-void MessageHeader::write(std::ostream& ostr) const
-{
- NameValueCollection::ConstIterator it = begin();
- while (it != end())
- {
- ostr << it->first << ": " << it->second << "\r\n";
- ++it;
- }
-}
-
-
-void MessageHeader::read(std::istream& istr)
-{
- static const int eof = std::char_traits<char>::eof();
- std::streambuf& buf = *istr.rdbuf();
-
- std::string name;
- std::string value;
- name.reserve(32);
- value.reserve(64);
- int ch = buf.sbumpc();
- int fields = 0;
- while (ch != eof && ch != '\r' && ch != '\n')
- {
- if (_fieldLimit > 0 && fields == _fieldLimit)
- throw MessageException("Too many header fields");
- name.clear();
- value.clear();
- while (ch != eof && ch != ':' && ch != '\n' && name.length() < MAX_NAME_LENGTH) { name += static_cast<char>(ch); ch = buf.sbumpc(); }
- if (ch == '\n') { ch = buf.sbumpc(); continue; } // ignore invalid header lines
- if (ch != ':') throw MessageException("Field name too long/no colon found");
- if (ch != eof) ch = buf.sbumpc(); // ':'
- while (ch != eof && Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n') ch = buf.sbumpc();
- while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += static_cast<char>(ch); ch = buf.sbumpc(); }
- if (ch == '\r') ch = buf.sbumpc();
- if (ch == '\n')
- ch = buf.sbumpc();
- else if (ch != eof)
- throw MessageException("Field value too long/no CRLF found");
- while (ch == ' ' || ch == '\t') // folding
- {
- while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += static_cast<char>(ch); ch = buf.sbumpc(); }
- if (ch == '\r') ch = buf.sbumpc();
- if (ch == '\n')
- ch = buf.sbumpc();
- else if (ch != eof)
- throw MessageException("Folded field value too long/no CRLF found");
- }
- Poco::trimRightInPlace(value);
- add(name, decodeWord(value));
- ++fields;
- }
- istr.putback(static_cast<char>(ch));
-}
-
-
-int MessageHeader::getFieldLimit() const
-{
- return _fieldLimit;
-}
-
-
-void MessageHeader::setFieldLimit(int limit)
-{
- poco_assert (limit >= 0);
-
- _fieldLimit = limit;
-}
-
-
-bool MessageHeader::hasToken(const std::string& fieldName, const std::string& token) const
-{
- std::string field = get(fieldName, "");
- std::vector<std::string> tokens;
- splitElements(field, tokens, true);
- for (std::vector<std::string>::const_iterator it = tokens.begin(); it != tokens.end(); ++it)
- {
- if (Poco::icompare(*it, token) == 0)
- return true;
- }
- return false;
-}
-
-
-void MessageHeader::splitElements(const std::string& s, std::vector<std::string>& elements, bool ignoreEmpty)
-{
- elements.clear();
- std::string::const_iterator it = s.begin();
- std::string::const_iterator end = s.end();
- std::string elem;
- elem.reserve(64);
- while (it != end)
- {
- if (*it == '"')
- {
- elem += *it++;
- while (it != end && *it != '"')
- {
- if (*it == '\\')
- {
- ++it;
- if (it != end) elem += *it++;
- }
- else elem += *it++;
- }
- if (it != end) elem += *it++;
- }
- else if (*it == '\\')
- {
- ++it;
- if (it != end) elem += *it++;
- }
- else if (*it == ',')
- {
- Poco::trimInPlace(elem);
- if (!ignoreEmpty || !elem.empty())
- elements.push_back(elem);
- elem.clear();
- ++it;
- }
- else elem += *it++;
- }
- if (!elem.empty())
- {
- Poco::trimInPlace(elem);
- if (!ignoreEmpty || !elem.empty())
- elements.push_back(elem);
- }
-}
-
-
-void MessageHeader::splitParameters(const std::string& s, std::string& value, NameValueCollection& parameters)
-{
- value.clear();
- parameters.clear();
- std::string::const_iterator it = s.begin();
- std::string::const_iterator end = s.end();
- while (it != end && Poco::Ascii::isSpace(*it)) ++it;
- while (it != end && *it != ';') value += *it++;
- Poco::trimRightInPlace(value);
- if (it != end) ++it;
- splitParameters(it, end, parameters);
-}
-
-
-void MessageHeader::splitParameters(const std::string::const_iterator& begin, const std::string::const_iterator& end, NameValueCollection& parameters)
-{
- std::string pname;
- std::string pvalue;
- pname.reserve(32);
- pvalue.reserve(64);
- std::string::const_iterator it = begin;
- while (it != end)
- {
- pname.clear();
- pvalue.clear();
- while (it != end && Poco::Ascii::isSpace(*it)) ++it;
- while (it != end && *it != '=' && *it != ';') pname += *it++;
- Poco::trimRightInPlace(pname);
- if (it != end && *it != ';') ++it;
- while (it != end && Poco::Ascii::isSpace(*it)) ++it;
- while (it != end && *it != ';')
- {
- if (*it == '"')
- {
- ++it;
- while (it != end && *it != '"')
- {
- if (*it == '\\')
- {
- ++it;
- if (it != end) pvalue += *it++;
- }
- else pvalue += *it++;
- }
- if (it != end) ++it;
- }
- else if (*it == '\\')
- {
- ++it;
- if (it != end) pvalue += *it++;
- }
- else pvalue += *it++;
- }
- Poco::trimRightInPlace(pvalue);
- if (!pname.empty()) parameters.add(pname, pvalue);
- if (it != end) ++it;
- }
-}
-
-
-void MessageHeader::quote(const std::string& value, std::string& result, bool allowSpace)
-{
- bool mustQuote = false;
- for (std::string::const_iterator it = value.begin(); !mustQuote && it != value.end(); ++it)
- {
- if (!Poco::Ascii::isAlphaNumeric(*it) && *it != '.' && *it != '_' && *it != '-' && !(Poco::Ascii::isSpace(*it) && allowSpace))
- mustQuote = true;
- }
- if (mustQuote) result += '"';
- result.append(value);
- if (mustQuote) result += '"';
-}
-
-
-void MessageHeader::decodeRFC2047(const std::string& ins, std::string& outs, const std::string& charset_to)
-{
- std::string tempout;
- StringTokenizer tokens(ins, "?");
-
- std::string charset = toUpper(tokens[0]);
- std::string encoding = toUpper(tokens[1]);
- std::string text = tokens[2];
-
- std::istringstream istr(text);
-
- if (encoding == "B")
- {
- // Base64 encoding.
- Base64Decoder decoder(istr);
- for (char c; decoder.get(c); tempout += c) {}
- }
- else if (encoding == "Q")
- {
- // Quoted encoding.
- for (char c; istr.get(c);)
- {
- if (c == '_')
- {
- //RFC 2047 _ is a space.
- tempout += " ";
- continue;
- }
-
- // FIXME: check that we have enought chars-
- if (c == '=')
- {
- // The next two chars are hex representation of the complete byte.
- std::string hex;
- for (int i = 0; i < 2; i++)
- {
- istr.get(c);
- hex += c;
- }
- hex = toUpper(hex);
- tempout += (char)(int)strtol(hex.c_str(), 0, 16);
- continue;
- }
- tempout += c;
- }
- }
- else
- {
- // Wrong encoding
- outs = ins;
- return;
- }
-
- // convert to the right charset.
- if (charset != charset_to)
- {
- try
- {
- TextEncoding& enc = TextEncoding::byName(charset);
- TextEncoding& dec = TextEncoding::byName(charset_to);
- TextConverter converter(enc, dec);
- converter.convert(tempout, outs);
- }
- catch (...)
- {
- // FIXME: Unsuported encoding...
- outs = tempout;
- }
- }
- else
- {
- // Not conversion necesary.
- outs = tempout;
- }
-}
-
-
-std::string MessageHeader::decodeWord(const std::string& text, const std::string& charset)
-{
- std::string outs, tmp = text;
- do {
- std::string tmp2;
- // find the begining of the next rfc2047 chunk
- size_t pos = tmp.find("=?");
- if (pos == std::string::npos) {
- // No more found, return
- outs += tmp;
- break;
- }
-
- // check if there are standar text before the rfc2047 chunk, and if so, copy it.
- if (pos > 0) {
- outs += tmp.substr(0, pos);
- }
-
- // remove text already copied.
- tmp = tmp.substr(pos + 2);
-
- // find the first separator
- size_t pos1 = tmp.find("?");
- if (pos1 == std::string::npos) {
- // not found.
- outs += tmp;
- break;
- }
-
- // find the second separator
- size_t pos2 = tmp.find("?", pos1 + 1);
- if (pos2 == std::string::npos) {
- // not found
- outs += tmp;
- break;
- }
-
- // find the end of the actual rfc2047 chunk
- size_t pos3 = tmp.find("?=", pos2 + 1);
- if (pos3 == std::string::npos) {
- // not found.
- outs += tmp;
- break;
-
- }
- // At this place, there are a valid rfc2047 chunk, so decode and copy the result.
- decodeRFC2047(tmp.substr(0, pos3), tmp2, charset);
- outs += tmp2;
-
- // Jump at the rest of the string and repeat the whole process.
- tmp = tmp.substr(pos3 + 2);
- } while (true);
-
- return outs;
-}
-
-
-} } // namespace Poco::Net
+//
+// MessageHeader.cpp
+//
+// Library: Net
+// Package: Messages
+// Module: MessageHeader
+//
+// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+
+#include "Poco/Net/MessageHeader.h"
+#include "Poco/Net/NetException.h"
+#include "Poco/String.h"
+#include "Poco/Ascii.h"
+#include "Poco/TextConverter.h"
+#include "Poco/StringTokenizer.h"
+#include "Poco/Base64Decoder.h"
+#include "Poco/UTF8Encoding.h"
+#include <sstream>
+
+
+namespace Poco {
+namespace Net {
+
+
+MessageHeader::MessageHeader():
+ _fieldLimit(DFL_FIELD_LIMIT)
+{
+}
+
+
+MessageHeader::MessageHeader(const MessageHeader& messageHeader):
+ NameValueCollection(messageHeader),
+ _fieldLimit(DFL_FIELD_LIMIT)
+{
+}
+
+
+MessageHeader::~MessageHeader()
+{
+}
+
+
+MessageHeader& MessageHeader::operator = (const MessageHeader& messageHeader)
+{
+ NameValueCollection::operator = (messageHeader);
+ return *this;
+}
+
+
+void MessageHeader::write(std::ostream& ostr) const
+{
+ NameValueCollection::ConstIterator it = begin();
+ while (it != end())
+ {
+ ostr << it->first << ": " << it->second << "\r\n";
+ ++it;
+ }
+}
+
+
+void MessageHeader::read(std::istream& istr)
+{
+ static const int eof = std::char_traits<char>::eof();
+ std::streambuf& buf = *istr.rdbuf();
+
+ std::string name;
+ std::string value;
+ name.reserve(32);
+ value.reserve(64);
+ int ch = buf.sbumpc();
+ int fields = 0;
+ while (ch != eof && ch != '\r' && ch != '\n')
+ {
+ if (_fieldLimit > 0 && fields == _fieldLimit)
+ throw MessageException("Too many header fields");
+ name.clear();
+ value.clear();
+ while (ch != eof && ch != ':' && ch != '\n' && name.length() < MAX_NAME_LENGTH) { name += static_cast<char>(ch); ch = buf.sbumpc(); }
+ if (ch == '\n') { ch = buf.sbumpc(); continue; } // ignore invalid header lines
+ if (ch != ':') throw MessageException("Field name too long/no colon found");
+ if (ch != eof) ch = buf.sbumpc(); // ':'
+ while (ch != eof && Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n') ch = buf.sbumpc();
+ while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += static_cast<char>(ch); ch = buf.sbumpc(); }
+ if (ch == '\r') ch = buf.sbumpc();
+ if (ch == '\n')
+ ch = buf.sbumpc();
+ else if (ch != eof)
+ throw MessageException("Field value too long/no CRLF found");
+ while (ch == ' ' || ch == '\t') // folding
+ {
+ while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += static_cast<char>(ch); ch = buf.sbumpc(); }
+ if (ch == '\r') ch = buf.sbumpc();
+ if (ch == '\n')
+ ch = buf.sbumpc();
+ else if (ch != eof)
+ throw MessageException("Folded field value too long/no CRLF found");
+ }
+ Poco::trimRightInPlace(value);
+ add(name, decodeWord(value));
+ ++fields;
+ }
+ istr.putback(static_cast<char>(ch));
+}
+
+
+int MessageHeader::getFieldLimit() const
+{
+ return _fieldLimit;
+}
+
+
+void MessageHeader::setFieldLimit(int limit)
+{
+ poco_assert (limit >= 0);
+
+ _fieldLimit = limit;
+}
+
+
+bool MessageHeader::hasToken(const std::string& fieldName, const std::string& token) const
+{
+ std::string field = get(fieldName, "");
+ std::vector<std::string> tokens;
+ splitElements(field, tokens, true);
+ for (std::vector<std::string>::const_iterator it = tokens.begin(); it != tokens.end(); ++it)
+ {
+ if (Poco::icompare(*it, token) == 0)
+ return true;
+ }
+ return false;
+}
+
+
+void MessageHeader::splitElements(const std::string& s, std::vector<std::string>& elements, bool ignoreEmpty)
+{
+ elements.clear();
+ std::string::const_iterator it = s.begin();
+ std::string::const_iterator end = s.end();
+ std::string elem;
+ elem.reserve(64);
+ while (it != end)
+ {
+ if (*it == '"')
+ {
+ elem += *it++;
+ while (it != end && *it != '"')
+ {
+ if (*it == '\\')
+ {
+ ++it;
+ if (it != end) elem += *it++;
+ }
+ else elem += *it++;
+ }
+ if (it != end) elem += *it++;
+ }
+ else if (*it == '\\')
+ {
+ ++it;
+ if (it != end) elem += *it++;
+ }
+ else if (*it == ',')
+ {
+ Poco::trimInPlace(elem);
+ if (!ignoreEmpty || !elem.empty())
+ elements.push_back(elem);
+ elem.clear();
+ ++it;
+ }
+ else elem += *it++;
+ }
+ if (!elem.empty())
+ {
+ Poco::trimInPlace(elem);
+ if (!ignoreEmpty || !elem.empty())
+ elements.push_back(elem);
+ }
+}
+
+
+void MessageHeader::splitParameters(const std::string& s, std::string& value, NameValueCollection& parameters)
+{
+ value.clear();
+ parameters.clear();
+ std::string::const_iterator it = s.begin();
+ std::string::const_iterator end = s.end();
+ while (it != end && Poco::Ascii::isSpace(*it)) ++it;
+ while (it != end && *it != ';') value += *it++;
+ Poco::trimRightInPlace(value);
+ if (it != end) ++it;
+ splitParameters(it, end, parameters);
+}
+
+
+void MessageHeader::splitParameters(const std::string::const_iterator& begin, const std::string::const_iterator& end, NameValueCollection& parameters)
+{
+ std::string pname;
+ std::string pvalue;
+ pname.reserve(32);
+ pvalue.reserve(64);
+ std::string::const_iterator it = begin;
+ while (it != end)
+ {
+ pname.clear();
+ pvalue.clear();
+ while (it != end && Poco::Ascii::isSpace(*it)) ++it;
+ while (it != end && *it != '=' && *it != ';') pname += *it++;
+ Poco::trimRightInPlace(pname);
+ if (it != end && *it != ';') ++it;
+ while (it != end && Poco::Ascii::isSpace(*it)) ++it;
+ while (it != end && *it != ';')
+ {
+ if (*it == '"')
+ {
+ ++it;
+ while (it != end && *it != '"')
+ {
+ if (*it == '\\')
+ {
+ ++it;
+ if (it != end) pvalue += *it++;
+ }
+ else pvalue += *it++;
+ }
+ if (it != end) ++it;
+ }
+ else if (*it == '\\')
+ {
+ ++it;
+ if (it != end) pvalue += *it++;
+ }
+ else pvalue += *it++;
+ }
+ Poco::trimRightInPlace(pvalue);
+ if (!pname.empty()) parameters.add(pname, pvalue);
+ if (it != end) ++it;
+ }
+}
+
+
+void MessageHeader::quote(const std::string& value, std::string& result, bool allowSpace)
+{
+ bool mustQuote = false;
+ for (std::string::const_iterator it = value.begin(); !mustQuote && it != value.end(); ++it)
+ {
+ if (!Poco::Ascii::isAlphaNumeric(*it) && *it != '.' && *it != '_' && *it != '-' && !(Poco::Ascii::isSpace(*it) && allowSpace))
+ mustQuote = true;
+ }
+ if (mustQuote) result += '"';
+ result.append(value);
+ if (mustQuote) result += '"';
+}
+
+
+void MessageHeader::decodeRFC2047(const std::string& ins, std::string& outs, const std::string& charset_to)
+{
+ std::string tempout;
+ StringTokenizer tokens(ins, "?");
+
+ std::string charset = toUpper(tokens[0]);
+ std::string encoding = toUpper(tokens[1]);
+ std::string text = tokens[2];
+
+ std::istringstream istr(text);
+
+ if (encoding == "B")
+ {
+ // Base64 encoding.
+ Base64Decoder decoder(istr);
+ for (char c; decoder.get(c); tempout += c) {}
+ }
+ else if (encoding == "Q")
+ {
+ // Quoted encoding.
+ for (char c; istr.get(c);)
+ {
+ if (c == '_')
+ {
+ //RFC 2047 _ is a space.
+ tempout += " ";
+ continue;
+ }
+
+ // FIXME: check that we have enought chars-
+ if (c == '=')
+ {
+ // The next two chars are hex representation of the complete byte.
+ std::string hex;
+ for (int i = 0; i < 2; i++)
+ {
+ istr.get(c);
+ hex += c;
+ }
+ hex = toUpper(hex);
+ tempout += (char)(int)strtol(hex.c_str(), 0, 16);
+ continue;
+ }
+ tempout += c;
+ }
+ }
+ else
+ {
+ // Wrong encoding
+ outs = ins;
+ return;
+ }
+
+ // convert to the right charset.
+ if (charset != charset_to)
+ {
+ try
+ {
+ TextEncoding& enc = TextEncoding::byName(charset);
+ TextEncoding& dec = TextEncoding::byName(charset_to);
+ TextConverter converter(enc, dec);
+ converter.convert(tempout, outs);
+ }
+ catch (...)
+ {
+ // FIXME: Unsuported encoding...
+ outs = tempout;
+ }
+ }
+ else
+ {
+ // Not conversion necesary.
+ outs = tempout;
+ }
+}
+
+
+std::string MessageHeader::decodeWord(const std::string& text, const std::string& charset)
+{
+ std::string outs, tmp = text;
+ do {
+ std::string tmp2;
+ // find the begining of the next rfc2047 chunk
+ size_t pos = tmp.find("=?");
+ if (pos == std::string::npos) {
+ // No more found, return
+ outs += tmp;
+ break;
+ }
+
+ // check if there are standar text before the rfc2047 chunk, and if so, copy it.
+ if (pos > 0) {
+ outs += tmp.substr(0, pos);
+ }
+
+ // remove text already copied.
+ tmp = tmp.substr(pos + 2);
+
+ // find the first separator
+ size_t pos1 = tmp.find("?");
+ if (pos1 == std::string::npos) {
+ // not found.
+ outs += tmp;
+ break;
+ }
+
+ // find the second separator
+ size_t pos2 = tmp.find("?", pos1 + 1);
+ if (pos2 == std::string::npos) {
+ // not found
+ outs += tmp;
+ break;
+ }
+
+ // find the end of the actual rfc2047 chunk
+ size_t pos3 = tmp.find("?=", pos2 + 1);
+ if (pos3 == std::string::npos) {
+ // not found.
+ outs += tmp;
+ break;
+
+ }
+ // At this place, there are a valid rfc2047 chunk, so decode and copy the result.
+ decodeRFC2047(tmp.substr(0, pos3), tmp2, charset);
+ outs += tmp2;
+
+ // Jump at the rest of the string and repeat the whole process.
+ tmp = tmp.substr(pos3 + 2);
+ } while (true);
+
+ return outs;
+}
+
+
+} } // namespace Poco::Net