/* */ #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 namespace aria2 { HttpResponse::HttpResponse():cuid(0), status(0), httpRequest(0), httpHeader(0), logger(LogFactory::getInstance()) {} HttpResponse::~HttpResponse() {} void HttpResponse::validateResponse() const { if(status == 401) { throw new DlAbortEx(EX_AUTH_FAILED); } if(status == 404) { throw new DlAbortEx(MSG_RESOURCE_NOT_FOUND); } if(status >= 400) { throw new DlAbortEx(EX_BAD_STATUS, status); } if(status >= 300) { if(!httpHeader->defined("Location")) { throw new DlAbortEx(EX_LOCATION_HEADER_REQUIRED, status); } } else { if(!httpHeader->defined("Transfer-Encoding")) { // compare the received range against the requested range RangeHandle responseRange = httpHeader->getRange(); if(!httpRequest->isRangeSatisfied(responseRange)) { throw new DlAbortEx(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()); } } } } 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 { 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 new ChunkedEncoding(); } } return 0; } 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; } } // namespace aria2