/* */ #include "HttpHeader.h" #include "Range.h" #include "Util.h" #include namespace aria2 { void HttpHeader::put(const std::string& name, const std::string& value) { std::multimap::value_type vt(Util::toLower(name), value); table.insert(vt); } bool HttpHeader::defined(const std::string& name) const { return table.count(Util::toLower(name)) >= 1; } std::string HttpHeader::getFirst(const std::string& name) const { std::multimap::const_iterator itr = table.find(Util::toLower(name)); if(itr == table.end()) { return ""; } else { return (*itr).second; } } std::deque HttpHeader::get(const std::string& name) const { std::deque v; std::string n(Util::toLower(name)); for(std::multimap::const_iterator i = table.find(n); i != table.end() && (*i).first == n; ++i) { v.push_back((*i).second); } return v; } unsigned int HttpHeader::getFirstAsUInt(const std::string& name) const { return getFirstAsULLInt(name); } uint64_t HttpHeader::getFirstAsULLInt(const std::string& name) const { std::string value = getFirst(name); if(value == "") { return 0; } else { return Util::parseULLInt(value); } } RangeHandle HttpHeader::getRange() const { std::string rangeStr = getFirst("Content-Range"); if(rangeStr == "") { std::string contentLengthStr = getFirst("Content-Length"); if(contentLengthStr == "") { return SharedHandle(new Range()); } else { uint64_t contentLength = Util::parseULLInt(contentLengthStr); if(contentLength == 0) { return SharedHandle(new Range()); } else { return SharedHandle(new Range(0, contentLength-1, contentLength)); } } } std::string byteRangeSpec; { // we expect that rangeStr looks like 'bytes 100-199/100' // but some server returns '100-199/100', omitting bytes-unit sepcifier // 'bytes'. std::pair splist; Util::split(splist, rangeStr, ' '); if(splist.second.empty()) { // we assume bytes-unit specifier omitted. byteRangeSpec = splist.first; } else { byteRangeSpec = splist.second; } } std::pair byteRangeSpecPair; Util::split(byteRangeSpecPair, byteRangeSpec, '/'); std::pair byteRangeRespSpecPair; Util::split(byteRangeRespSpecPair, byteRangeSpecPair.first, '-'); off_t startByte = Util::parseLLInt(byteRangeRespSpecPair.first); off_t endByte = Util::parseLLInt(byteRangeRespSpecPair.second); uint64_t entityLength = Util::parseULLInt(byteRangeSpecPair.second); return SharedHandle(new Range(startByte, endByte, entityLength)); } const std::string& HttpHeader::getResponseStatus() const { return _responseStatus; } void HttpHeader::setResponseStatus(const std::string& responseStatus) { _responseStatus = responseStatus; } const std::string& HttpHeader::getVersion() const { return _version; } void HttpHeader::setVersion(const std::string& version) { _version = version; } void HttpHeader::fill(std::istream& in) { std::string line; while(std::getline(in, line)) { line = Util::trim(line); if(line.empty()) { break; } std::pair hp; Util::split(hp, line, ':'); put(hp.first, hp.second); } } } // namespace aria2