/* */ #include "HttpResponse.h" #include "Request.h" #include "Segment.h" #include "CookieBox.h" #include "HttpRequest.h" #include "HttpHeader.h" #include "Range.h" #include "LogFactory.h" #include "Logger.h" #include "ChunkedEncoding.h" #include "Util.h" #include "message.h" #include "DlAbortEx.h" #include "StringFormat.h" #include namespace aria2 { HttpResponse::HttpResponse():cuid(0), logger(LogFactory::getInstance()) {} HttpResponse::~HttpResponse() {} void HttpResponse::validateResponse() const { const std::string& status = getResponseStatus(); if(status == "401") { throw DlAbortEx(EX_AUTH_FAILED); } if(status == "404") { throw DlAbortEx(MSG_RESOURCE_NOT_FOUND); } if(status >= "400") { throw DlAbortEx (StringFormat(EX_BAD_STATUS, Util::parseUInt(status)).str()); } if(status >= "300") { if(!httpHeader->defined("Location")) { throw DlAbortEx (StringFormat(EX_LOCATION_HEADER_REQUIRED, Util::parseUInt(status)).str()); } } else { if(!httpHeader->defined("Transfer-Encoding")) { // compare the received range against the requested range RangeHandle responseRange = httpHeader->getRange(); if(!httpRequest->isRangeSatisfied(responseRange)) { throw DlAbortEx (StringFormat(EX_INVALID_RANGE_HEADER, Util::itos(httpRequest->getStartByte(), true).c_str(), Util::itos(httpRequest->getEndByte(), true).c_str(), Util::uitos(httpRequest->getEntityLength(), true).c_str(), Util::itos(responseRange->getStartByte(), true).c_str(), Util::itos(responseRange->getEndByte(), true).c_str(), Util::uitos(responseRange->getEntityLength(), true).c_str() ).str()); } } } } std::string HttpResponse::determinFilename() const { std::string contentDisposition = Util::getContentDispositionFilename(httpHeader->getFirst("Content-Disposition")); if(contentDisposition.empty()) { return Util::urldecode(httpRequest->getFile()); } else { logger->info(MSG_CONTENT_DISPOSITION_DETECTED, cuid, contentDisposition.c_str()); return Util::urldecode(contentDisposition); } } void HttpResponse::retrieveCookie() { std::deque v = httpHeader->get("Set-Cookie"); for(std::deque::const_iterator itr = v.begin(); itr != v.end(); itr++) { std::string domain = httpRequest->getHost(); std::string path = httpRequest->getDir(); httpRequest->getRequest()->cookieBox->add(*itr, domain, path); } } bool HttpResponse::isRedirect() const { const std::string& status = getResponseStatus(); return "300" <= status && status < "400" && httpHeader->defined("Location"); } void HttpResponse::processRedirect() { httpRequest->getRequest()->redirectUrl(getRedirectURI()); } std::string HttpResponse::getRedirectURI() const { return httpHeader->getFirst("Location"); } bool HttpResponse::isTransferEncodingSpecified() const { return httpHeader->defined("Transfer-Encoding"); } std::string HttpResponse::getTransferEncoding() const { return httpHeader->getFirst("Transfer-Encoding"); } TransferEncodingHandle HttpResponse::getTransferDecoder() const { if(isTransferEncodingSpecified()) { if(getTransferEncoding() == "chunked") { return SharedHandle(new ChunkedEncoding()); } } return SharedHandle(); } uint64_t HttpResponse::getContentLength() const { if(httpHeader.isNull()) { return 0; } else { return httpHeader->getRange()->getContentLength(); } } uint64_t HttpResponse::getEntityLength() const { if(httpHeader.isNull()) { return 0; } else { return httpHeader->getRange()->getEntityLength(); } } std::string HttpResponse::getContentType() const { if(httpHeader.isNull()) { return ""; } else { return httpHeader->getFirst("Content-Type"); } } void HttpResponse::setHttpHeader(const SharedHandle& httpHeader) { this->httpHeader = httpHeader; } SharedHandle HttpResponse::getHttpHeader() const { return httpHeader; } void HttpResponse::setHttpRequest(const SharedHandle& httpRequest) { this->httpRequest = httpRequest; } SharedHandle HttpResponse::getHttpRequest() const { return httpRequest; } // TODO return std::string const std::string& HttpResponse::getResponseStatus() const { return httpHeader->getResponseStatus(); } } // namespace aria2