libzypp 17.32.5
metalink_p.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
9
14
15#include "metalink_p.h"
16#include "final_p.h"
17
18 #include <iostream>
19#include <fstream>
20
21namespace zyppng {
22
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 ) {
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 {
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 ) {
88 } else {
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
123
125 }
126
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
138 dig.create( _fileChecksumType );
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();
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}
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
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:38
Wrapper class for stat/lstat.
Definition PathInfo.h:222
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
void reuseBlocks(FILE *wfp, const std::string &filename)
std::string getChecksumType() const
size_t numBlocks() const
return the number of blocks in the blocklist
std::string fileChecksumType() const
WeakPtr parent() const
Definition base.cc:26
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:364
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
void setFinished() override
zypp::media::MediaBlockList _blockList
Definition metalink_p.h:62
std::string _fileChecksumType
Definition metalink_p.h:63
std::shared_ptr< FinishedState > transitionToFinished()
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