/* */ #include "HttpDownloadCommand.h" #include "RequestGroup.h" #include "DownloadEngine.h" #include "Request.h" #include "HttpRequestCommand.h" #include "HttpConnection.h" #include "HttpRequest.h" #include "Segment.h" #include "Socket.h" #include "prefs.h" #include "Option.h" #include "HttpResponse.h" #include "HttpHeader.h" #include "Range.h" #include "DownloadContext.h" namespace aria2 { HttpDownloadCommand::HttpDownloadCommand (int cuid, const RequestHandle& req, const SharedHandle& fileEntry, RequestGroup* requestGroup, const SharedHandle& httpResponse, const HttpConnectionHandle& httpConnection, DownloadEngine* e, const SocketHandle& socket) :DownloadCommand(cuid, req, fileEntry, requestGroup, e, socket), _httpResponse(httpResponse), _httpConnection(httpConnection) {} HttpDownloadCommand::~HttpDownloadCommand() {} bool HttpDownloadCommand::prepareForNextSegment() { bool downloadFinished = _requestGroup->downloadFinished(); if(req->isPipeliningEnabled() && !downloadFinished) { HttpRequestCommand* command = new HttpRequestCommand(cuid, req, _fileEntry, _requestGroup, _httpConnection, e, socket); // Set proxy request here. aria2 sends the HTTP request specialized for // proxy. if(resolveProxyMethod(req->getProtocol()) == V_GET) { command->setProxyRequest(createProxyRequest()); } e->commands.push_back(command); return true; } else { if(req->isPipeliningEnabled() || (req->isKeepAliveEnabled() && ((!_transferEncodingDecoder.isNull() && _requestGroup->downloadFinished()) || _fileEntry->getLastOffset() == _segments.front()->getPositionToWrite()))) { e->poolSocket(req, isProxyDefined(), socket); } // The request was sent assuming that server supported pipelining, but // it turned out that server didn't support it. // We detect this situation by comparing the end byte in range header // of the response with the end byte of segment. // If it is the same, HTTP negotiation is necessary for the next request. if(!req->isPipeliningEnabled() && req->isPipeliningHint() && !downloadFinished) { const SharedHandle& segment = _segments.front(); off_t lastOffset =_fileEntry->gtoloff (std::min(static_cast(segment->getPosition()+segment->getLength()), _fileEntry->getLastOffset())); if(lastOffset == _httpResponse->getHttpHeader()->getRange()->getEndByte()+1) { return prepareForRetry(0); } } return DownloadCommand::prepareForNextSegment(); } } } // namespace aria2