ATLAS Offline Software
VP1HttpGetFile_Private.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 // //
8 // Internal classes for VP1HttpGetFile //
9 // //
10 // Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11 // Initial version: June 2008 //
12 // //
14 
15 #include <QThread>
16 #include <QMutex>
17 #include <QTimer>
18 #include <QDateTime>
19 #include <QFileInfo>
20 #include <QFile>
21 #include <QDir>
22 #include <QUrl>
23 
24 //#include <QHttp> // Qt 4
25 //#include <QNetworkAccessManager> // TODO: use this to port to Qt5
26 
27 #include "VP1Gui/VP1MD5Sum.h"
28 
29 class VP1HttpGetFile_DownloadThread : public QThread {
30 
31  Q_OBJECT
32 
33 public:
34 
36  const QString& localtargetfile,
37  const QString& expectedMD5Sum,
38  const QString& data,
39  QObject * parent = 0);
41 
42  //For accessing the results:
43  bool errors() const { m_mutex.lock(); bool err=!m_errorString.isEmpty(); m_mutex.unlock(); return err; }
44  QString errorString() const { m_mutex.lock(); QString err = m_errorString; m_mutex.unlock(); return err; }
45 
46  const QString& urltofile() const { return m_urltofile; }
47  const QString& localtargetfile() const { return m_localtargetfile; }
48  const QString& expectedMD5Sum() const { return m_expectedMD5Sum; }
49  const QString& data() const { return m_data; }
50 
51 protected:
52  void run();
53 public Q_SLOTS:
54  void checkForStall();
55 private Q_SLOTS:
56  void done(bool);
58 private:
59  const QString m_urltofile;
60  const QString m_localtargetfile;
61  const QString m_expectedMD5Sum;
62  const QString m_data;
63  QString m_errorString;
64  mutable QMutex m_mutex;//Protects m_errors;
65 // QHttp * m_http; // Old Qt4 code --> TODO: need to be ported to Qt5!!
67  DOWNLOADFINISHSTATUS m_downloadFinishedStatus;//-1: not finished, 0: error, 1: no-error
68  unsigned m_lastChangeTime;
69  qint64 m_lastcheckedsize;//-2 never checked, -1 does not exists.
71  void endInFailure(const QString&, CLEANUPOPT );
72 };
73 
74 //Remember that we are also included from the qt moc file:
75 #ifdef VP1HttpGetFile_cxx
76 
77 //____________________________________________________________________
79  const QString& localtargetfile,
80  const QString& expectedMD5Sum,
81  const QString& data,
82  QObject * parent )
83  : QThread(parent),
84  m_urltofile(urltofile),
85  m_localtargetfile(localtargetfile),
86  m_expectedMD5Sum(expectedMD5Sum),
87  m_data(data),
88  m_errorString("Download not finished"),
89 // m_http(0),
90  m_downloadFinishedStatus(NOTFINISHED),
91  m_lastChangeTime(0),
92  m_lastcheckedsize(-2)
93 {
94 }
95 
96 //____________________________________________________________________
97 void VP1HttpGetFile_DownloadThread::endInFailure(const QString& err, CLEANUPOPT opt)
98 {
99  m_mutex.lock();
100 
103 
104  m_errorString = err.isEmpty() ? "Unspecified error" : err;
105  m_mutex.unlock();
106 }
107 
108 //____________________________________________________________________
110 {
111  // TODO: to be ported to Qt5!!
112 // if (!m_http)
113 // return;
114 // unsigned currentTime = QDateTime::currentDateTime().toTime_t();
115 // if (currentTime>m_lastChangeTime+10) {//10s
116 // m_downloadFinishedStatus = STALLEDERROR;
117 // quit();
118 // }
119 }
120 
121 //____________________________________________________________________
123 {
125  quit();
126 }
127 
128 //____________________________________________________________________
130 {
131  //We monitor that filesize of files downloaded is strictly
132  //increasing (and that a created file does not disappear):
133  QFileInfo fi(m_localtargetfile);
134  qint64 currentsize = fi.exists() ? fi.size() : -1;
135  if (currentsize < m_lastcheckedsize) {
137  quit();
138  }
139 
140  //For stall-detection:
141  if (currentsize > m_lastcheckedsize)
142  m_lastChangeTime = QDateTime::currentDateTime().toTime_t();
143 
144  m_lastcheckedsize = currentsize;
145 }
146 
147 //____________________________________________________________________
149 
150  // NOTE!! TODO: This has to be ported to Qt 5!!!
151  /*
153  // Input validation //
155 
156  //Input validation ==> MD5 sum
157 
158  if ( !m_expectedMD5Sum.isEmpty() && !VP1MD5Sum::validMD5Sum(m_expectedMD5Sum) ) {
159  endInFailure("Invalid target md5sum: "+m_expectedMD5Sum,CLEANUPLOCALFILE);
160  return;
161  }
162 
163  //Input validation ==> URL
164 
165  if (m_urltofile.isEmpty()) {
166  endInFailure("Empty URL",DONTTOUCHLOCALFILE);
167  return;
168  }
169 
170  QUrl url(m_urltofile.contains("://") ? m_urltofile : "http://" + m_urltofile);
171  if (!url.isValid()||url.host().isEmpty()) {
172  endInFailure("Invalid URL: "+m_urltofile,DONTTOUCHLOCALFILE);
173  return;
174  }
175  //Input validation ==> Target file
176 
177  //File can not exist already and we abort if we are already
178  //downloading a file to that location:
179  QFileInfo fi(m_localtargetfile);
180  if (fi.exists()) {
181  //In one case we might still end well: if we know the target
182  //checksum and if the file has it (this also does away with
183  //several problems of "simultaneous downloads started":
184  if (!m_expectedMD5Sum.isEmpty()&&VP1MD5Sum::sumMatches(m_localtargetfile,m_expectedMD5Sum))
185  return;
186  endInFailure ("Download target already exists: "+m_localtargetfile,DONTTOUCHLOCALFILE);
187  return;
188  }
189  if (!fi.dir().exists()) {
190  endInFailure("Directory ("+fi.dir().absolutePath()+") for download target does not exist: "+m_localtargetfile,DONTTOUCHLOCALFILE);
191  return;
192  }
193 
194  //Open target file:
195  QFile file(m_localtargetfile);
196  if (!file.open(QIODevice::WriteOnly)) {
197  endInFailure("Could not open file for write access: "+m_localtargetfile,DONTTOUCHLOCALFILE);
198  return;
199  }
200 
202  // HTTP request and event loop //
204 
205  m_http = new QHttp(0);
206 
207  connect(m_http,SIGNAL(done(bool)),this,SLOT(done(bool)));
208  connect(m_http,SIGNAL(dataReadProgress(int,int)),this,SLOT(dataReadProgress()));
209 
210  QHttpRequestHeader header("GET", url.path()+(url.hasQuery()?"?"+url.encodedQuery():QString("")));
211  // ^^^ Todo: We could support username/passwd part of url also.
212  header.setValue("Host", url.host());
213  header.setValue("User-Agent", "ATLASVP1");
214  m_http->setHost(url.host());
215  m_lastChangeTime = QDateTime::currentDateTime().toTime_t();
216 
217  //Go:
218  m_http->request(header,0,&file);
219  QTimer timer(0);
220  connect(&timer, SIGNAL(timeout()), this, SLOT(checkForStall()));
221  timer.start(1000);//1s
222  exec();
223  timer.stop();
224 
225  //Cleanup http:
226  m_http->blockSignals(true);
227  if (m_http->hasPendingRequests())
228  m_http->clearPendingRequests();
229  if (m_http->currentId()!=0)
230  m_http->abort();
231  delete m_http;
232  m_http = 0;
233 
234  file.close();
235 
236  //Errors?
237  if (m_downloadFinishedStatus!=NOERRORS) {
238  switch(m_downloadFinishedStatus) {
239  case HTTPERROR:
240  endInFailure("Download finished with error "+m_http->errorString(),CLEANUPLOCALFILE);
241  return;
242  case STALLEDERROR:
243  endInFailure("Download stalled",CLEANUPLOCALFILE);
244  return;
245  case SIZEDECREASEDERROR:
246  endInFailure("Aborted since file was either removed or decreased in size.",CLEANUPLOCALFILE);
247  return;
248  default:
249  endInFailure("Unexpected download status (SHOULD NEVER HAPPEN)",CLEANUPLOCALFILE);
250  return;
251  }
252  }
253 
255  // Checksum test //
257 
258  if (!m_expectedMD5Sum.isEmpty()) {
259  bool match = VP1MD5Sum::sumMatches(m_localtargetfile,m_expectedMD5Sum);
260  if (!match) {
261  endInFailure("Checksum did not match",CLEANUPLOCALFILE);
262  return;
263  }
264  }
265 
266  //All ok:
267 
268  m_mutex.lock();
269  m_errorString = "";
270  m_mutex.unlock();
271  */
272 
273 }
274 
275 #endif
VP1HttpGetFile_DownloadThread::~VP1HttpGetFile_DownloadThread
virtual ~VP1HttpGetFile_DownloadThread()
Definition: VP1HttpGetFile_Private.h:40
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
VP1HttpGetFile_DownloadThread::checkForStall
void checkForStall()
VP1HttpGetFile_DownloadThread::m_errorString
QString m_errorString
Definition: VP1HttpGetFile_Private.h:63
make_coralServer_rep.opt
opt
Definition: make_coralServer_rep.py:19
VP1HttpGetFile_DownloadThread::STALLEDERROR
@ STALLEDERROR
Definition: VP1HttpGetFile_Private.h:66
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
VP1HttpGetFile_DownloadThread::DONTTOUCHLOCALFILE
@ DONTTOUCHLOCALFILE
Definition: VP1HttpGetFile_Private.h:70
VP1HttpGetFile_DownloadThread::urltofile
const QString & urltofile() const
Definition: VP1HttpGetFile_Private.h:46
VP1HttpGetFile_DownloadThread::m_downloadFinishedStatus
DOWNLOADFINISHSTATUS m_downloadFinishedStatus
Definition: VP1HttpGetFile_Private.h:67
VP1HttpGetFile_DownloadThread::dataReadProgress
void dataReadProgress()
VP1HttpGetFile_DownloadThread::m_lastChangeTime
unsigned m_lastChangeTime
Definition: VP1HttpGetFile_Private.h:68
VP1HttpGetFile_DownloadThread::SIZEDECREASEDERROR
@ SIZEDECREASEDERROR
Definition: VP1HttpGetFile_Private.h:66
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
VP1HttpGetFile_DownloadThread::errors
bool errors() const
Definition: VP1HttpGetFile_Private.h:43
VP1HttpGetFile_DownloadThread::HTTPERROR
@ HTTPERROR
Definition: VP1HttpGetFile_Private.h:66
VP1HttpGetFile_DownloadThread::errorString
QString errorString() const
Definition: VP1HttpGetFile_Private.h:44
VP1HttpGetFile_DownloadThread::done
void done(bool)
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:182
test_pyathena.parent
parent
Definition: test_pyathena.py:15
VP1HttpGetFile_DownloadThread::m_data
const QString m_data
Definition: VP1HttpGetFile_Private.h:62
VP1HttpGetFile_DownloadThread::DOWNLOADFINISHSTATUS
DOWNLOADFINISHSTATUS
Definition: VP1HttpGetFile_Private.h:66
VP1HttpGetFile_DownloadThread::expectedMD5Sum
const QString & expectedMD5Sum() const
Definition: VP1HttpGetFile_Private.h:48
VP1HttpGetFile_DownloadThread::VP1HttpGetFile_DownloadThread
VP1HttpGetFile_DownloadThread(const QString &urltofile, const QString &localtargetfile, const QString &expectedMD5Sum, const QString &data, QObject *parent=0)
VP1HttpGetFile_DownloadThread::run
void run()
VP1HttpGetFile_DownloadThread::m_lastcheckedsize
qint64 m_lastcheckedsize
Definition: VP1HttpGetFile_Private.h:69
VP1HttpGetFile_DownloadThread::localtargetfile
const QString & localtargetfile() const
Definition: VP1HttpGetFile_Private.h:47
VP1HttpGetFile_DownloadThread::CLEANUPLOCALFILE
@ CLEANUPLOCALFILE
Definition: VP1HttpGetFile_Private.h:70
VP1HttpGetFile_DownloadThread::m_expectedMD5Sum
const QString m_expectedMD5Sum
Definition: VP1HttpGetFile_Private.h:61
VP1HttpGetFile_DownloadThread::NOERRORS
@ NOERRORS
Definition: VP1HttpGetFile_Private.h:66
checkFileSG.fi
fi
Definition: checkFileSG.py:65
VP1MD5Sum.h
VP1HttpGetFile_DownloadThread::m_urltofile
const QString m_urltofile
Definition: VP1HttpGetFile_Private.h:59
VP1HttpGetFile_DownloadThread
Definition: VP1HttpGetFile_Private.h:29
VP1HttpGetFile_DownloadThread::m_mutex
QMutex m_mutex
Definition: VP1HttpGetFile_Private.h:64
python.dummyaccess.exists
def exists(filename)
Definition: dummyaccess.py:9
VP1HttpGetFile_DownloadThread::CLEANUPOPT
CLEANUPOPT
Definition: VP1HttpGetFile_Private.h:70
VP1HttpGetFile_DownloadThread::data
const QString & data() const
Definition: VP1HttpGetFile_Private.h:49
error
Definition: IImpactPoint3dEstimator.h:70
VP1HttpGetFile_DownloadThread::endInFailure
void endInFailure(const QString &, CLEANUPOPT)
VP1HttpGetFile_DownloadThread::m_localtargetfile
const QString m_localtargetfile
Definition: VP1HttpGetFile_Private.h:60
VP1HttpGetFile_DownloadThread::NOTFINISHED
@ NOTFINISHED
Definition: VP1HttpGetFile_Private.h:66