libzypp 17.31.23
metalink_p.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
9
13#include <zypp-core/fs/PathInfo.h>
14
15#include "metalink_p.h"
16#include "final_p.h"
17
18 #include <iostream>
19#include <fstream>
20
21namespace zyppng {
22
23 DlMetalinkState::DlMetalinkState(zypp::media::MediaBlockList &&blockList, std::vector<Url> &&mirrors, DownloadPrivate &parent)
24 : RangeDownloaderBaseState( std::move(mirrors), parent )
25 , _blockList( std::move(blockList) )
26 {
27 MIL << "About to enter DlMetalinkState for url " << parent._spec.url() << std::endl;
28 }
29
31 {
32 auto &sm = stateMachine();
33 const auto &spec = sm._spec;
34
35 _fileSize = sm._spec.expectedFileSize();
36
37 //first we try to reuse blocks from the deltafile , if we have one
38 if ( !spec.deltaFile().empty() ) {
39 zypp::PathInfo dFileInfo ( spec.deltaFile() );
40 if ( dFileInfo.isFile() && dFileInfo.isR() ) {
41 FILE *f = fopen( spec.targetPath().asString().c_str(), "w+b" );
42 if ( !f ) {
43 setFailed( NetworkRequestErrorPrivate::customError( NetworkRequestError::InternalError, zypp::str::Format("Failed to open target file.(errno %1%)" ) % errno ) );
44 return;
45 }
46
47 try {
48 _blockList.reuseBlocks ( f, spec.deltaFile().asString() );
49 } catch ( ... ) { }
50
51 fclose( f );
52 } else {
53 DBG << "Delta XFER: Delta file: " << spec.deltaFile() << " does not exist or is not readable." << std::endl;
54 }
55 } else {
56 DBG << "Delta XFER: No delta file given, can not reuse blocks." << std::endl;
57 }
58
59 // setup the base downloader
60 _error = {};
61 _ranges.clear();
62 _failedRanges.clear();
64
68 }
69
70 const size_t fLen = _blockList.getFilesize();
71 if ( _fileSize > 0 ) {
72 // check if the file size as reported by zchunk is equal to the one we expect
73 if ( _fileSize != fLen ) {
76 zypp::str::Format("Metalink file reports a different filesize than what was expected ( Meta: %1% != Exp: %2%).") % fLen % _fileSize )
77 );
78 }
79 } else {
80 _fileSize = fLen;
81 }
82
83 const auto maxConns = sm._requestDispatcher->maximumConcurrentConnections();
84 if ( sm._spec.preferredChunkSize() == 0 ) {
85 const auto autoBlkSize = makeBlksize( _fileSize );
86 if ( maxConns == -1 ) {
87 _preferredChunkSize = autoBlkSize;
88 } else {
89 _preferredChunkSize = _fileSize / maxConns;
90 if ( _preferredChunkSize < autoBlkSize )
91 _preferredChunkSize = autoBlkSize;
94 }
95 } else {
96 // spec chunk size overrules the automatic one
97 _preferredChunkSize = sm._spec.preferredChunkSize();
98 }
99
100 MIL << "Downloading " << sm._spec.url() << " with " << _preferredChunkSize << " chunk size over " << maxConns << std::endl;
101
102 // remember how many bytes we need to download
103 size_t bytesToDl = 0;
104 // do we need to pad the digest when calculating the checksum for blocks
105 const auto &chksumPad = _blockList.checksumPad ();
106 for ( size_t i = 0; i < _blockList.numBlocks(); i++ ) {
107 const auto &mediaBlock = _blockList.getBlock( i );
108 const auto &blockSum = _blockList.getChecksum ( i );
109 _ranges.push_back(
110 Block{
111 .start = mediaBlock.off,
112 .len = mediaBlock.size,
113 .chksumtype = _blockList.getChecksumType(),
114 .chksumVec = blockSum,
115 .chksumCompareLen = blockSum.size( ),
116 .chksumPad = chksumPad > 0 ? chksumPad : std::optional<size_t>()
117 } );
118
119 bytesToDl += mediaBlock.size;
120 }
121 // substract the length of the blocks we have to download from the overall file size
122 _downloadedMultiByteCount = fLen - bytesToDl;
123
125 }
126
128 {
130 }
131
133 {
134 if ( _fileChecksumType.size() && _fileChksumVec ) {
135 //TODO move this into a external application so we do not need to block on it
136 //need to check file digest
137 zypp::Digest dig;
139
140 std::ifstream istrm( stateMachine()._spec.targetPath().asString(), std::ios::binary);
141 if ( !istrm.is_open() ) {
142 setFailed( "Failed to verify file digest (Could not open target file)." );
143 return;
144 }
145 if ( !dig.update( istrm ) ) {
146 setFailed( "Failed to verify file digest (Could not read target file)." );
147 return;
148 }
149
150 const auto &calculatedChksum = dig.digestVector();
151 if ( *_fileChksumVec != calculatedChksum ) {
152 setFailed( "Failed to verify file digest (Checksum did not match)." );
153 return;
154 }
155 }
157 }
158
159 std::shared_ptr<FinishedState> DlMetalinkState::transitionToFinished()
160 {
161 return std::make_shared<FinishedState>( std::move(_error), stateMachine() );
162 }
163
164}
Store and operate with byte count.
Definition: ByteCount.h:31
static const Unit M
1024^2 Byte
Definition: ByteCount.h:48
Compute Message Digests (MD5, SHA1 etc)
Definition: Digest.h:37
UByteArray digestVector()
get vector of unsigned char representation of the digest
Definition: Digest.cc:261
bool update(const char *bytes, size_t len)
feed data into digest computation algorithm
Definition: Digest.cc:279
bool create(const std::string &name)
initialize creation of a new message digest
Definition: Digest.cc:173
Wrapper class for stat/lstat.
Definition: PathInfo.h:221
void reuseBlocks(FILE *wfp, std::string filename)
const UByteArray & getFileChecksum()
const MediaBlock & getBlock(size_t blkno) const
return the offset/size of a block with number blkno
UByteArray getChecksum(size_t blkno) const
std::string getChecksumType() const
size_t numBlocks() const
return the number of blocks in the blocklist
std::string fileChecksumType() const
DownloadSpec _spec
Definition: base_p.h:98
const Url & url() const
Definition: downloadspec.cc:50
static zyppng::NetworkRequestError customError(NetworkRequestError::Type t, std::string &&errorMsg="", std::map< std::string, boost::any > &&extraInfo={})
The NetworkRequestError class Represents a error that occured in.
Definition: Arch.h:361
Convenient building of std::string with boost::format.
Definition: String.h:253
DlMetalinkState(zypp::media::MediaBlockList &&blockList, std::vector< Url > &&mirrors, DownloadPrivate &parent)
Definition: metalink_p.cc:23
virtual void setFinished() override
Definition: metalink_p.cc:132
zypp::media::MediaBlockList _blockList
Definition: metalink_p.h:62
std::string _fileChecksumType
Definition: metalink_p.h:63
std::shared_ptr< FinishedState > transitionToFinished()
Definition: metalink_p.cc:159
std::optional< std::vector< unsigned char > > _fileChksumVec
Definition: metalink_p.h:64
static zypp::ByteCount makeBlksize(size_t filesize)
void cancelAll(const NetworkRequestError &err)
void setFailed(NetworkRequestError &&err)
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96