/* */ #include "NsCookieParser.h" #include #include #include #include "util.h" #include "A2STR.h" #include "DlAbortEx.h" #include "fmt.h" #include "Cookie.h" #include "cookie_helper.h" #include "BufferedFile.h" #include "array_fun.h" namespace aria2 { NsCookieParser::NsCookieParser() = default; NsCookieParser::~NsCookieParser() = default; namespace { std::unique_ptr parseNsCookie(const std::string& cookieStr, time_t creationTime) { std::vector vs; util::splitIter(cookieStr.begin(), cookieStr.end(), std::back_inserter(vs), '\t', true); if (vs.size() < 6) { return nullptr; } vs[0].first = util::lstripIter(vs[0].first, vs[0].second, '.'); if (vs[5].first == vs[5].second || vs[0].first == vs[0].second || !cookie::goodPath(vs[2].first, vs[2].second)) { return nullptr; } int64_t expiryTime; { // chrome extension uses subsecond resolution for expiry time. double expiryTimeDouble; if (!util::parseDoubleNoThrow(expiryTimeDouble, std::string(vs[4].first, vs[4].second))) { return nullptr; } expiryTime = static_cast(expiryTimeDouble); } if (std::numeric_limits::max() < expiryTime) { expiryTime = std::numeric_limits::max(); } else if (std::numeric_limits::min() > expiryTime) { expiryTime = std::numeric_limits::min(); } auto cookie = make_unique(); cookie->setName(vs[5].first, vs[5].second); if (vs.size() >= 7) { cookie->setValue(vs[6].first, vs[6].second); } else { cookie->setValue(""); } cookie->setExpiryTime(expiryTime == 0 ? std::numeric_limits::max() : expiryTime); // aria2 treats expiryTime == 0 means session cookie-> cookie->setPersistent(expiryTime != 0); cookie->setDomain(vs[0].first, vs[0].second); cookie->setHostOnly(util::isNumericHost(cookie->getDomain()) || !util::streq(vs[1].first, vs[1].second, "TRUE")); cookie->setPath(vs[2].first, vs[2].second); cookie->setSecure(util::streq(vs[3].first, vs[3].second, "TRUE")); cookie->setCreationTime(creationTime); return cookie; } } // namespace std::vector> NsCookieParser::parse(const std::string& filename, time_t creationTime) { BufferedFile fp{filename.c_str(), BufferedFile::READ}; if (!fp) { throw DL_ABORT_EX(fmt("Failed to open file %s", filename.c_str())); } std::vector> cookies; while (1) { std::string line = fp.getLine(); if (line.empty()) { if (fp.eof()) { break; } else if (!fp) { throw DL_ABORT_EX("CookieParser:I/O error."); } else { continue; } } if (line[0] == '#') { continue; } auto c = parseNsCookie(line, creationTime); if (c) { cookies.push_back(std::move(c)); } } return cookies; } } // namespace aria2