propagateupload: Save the mtime given by the server in the reply to GET

There could be a race condition if the file was updated on the server
between the discovery and the propagate phase. By taking the mtime from
the server, we make sure that we do not have a race.

This is tested by t6.pl with BIG3.file because the script was modifying
the file between the two phases
This commit is contained in:
Olivier Goffart 2015-02-06 10:20:10 +01:00
parent 9e945eb471
commit 5ec793e045
4 changed files with 18 additions and 3 deletions

View file

@ -125,6 +125,10 @@ while(readdir $dh) {
closedir $dh;
assert( $seen == 1, "No conflict file created on precondition failed!" );
unlink($script);
$ENV{'OWNCLOUD_POST_UPDATE_SCRIPT'} = "";
assertLocalAndRemoteDir( '', 1);
# Set a custom chunk size in environment.
my $ChunkSize = 1*1024*1024;

View file

@ -37,7 +37,7 @@ GETFileJob::GETFileJob(AccountPtr account, const QString& path, QFile *device,
_device(device), _headers(headers), _expectedEtagForResume(expectedEtagForResume)
, _resumeStart(resumeStart) , _errorStatus(SyncFileItem::NoStatus)
, _bandwidthLimited(false), _bandwidthChoked(false), _bandwidthQuota(0), _bandwidthManager(0)
, _hasEmittedFinishedSignal(false)
, _hasEmittedFinishedSignal(false), _lastModified()
{
}
@ -49,7 +49,7 @@ GETFileJob::GETFileJob(AccountPtr account, const QUrl& url, QFile *device,
_device(device), _headers(headers), _expectedEtagForResume(expectedEtagForResume)
, _resumeStart(resumeStart), _errorStatus(SyncFileItem::NoStatus), _directDownloadUrl(url)
, _bandwidthLimited(false), _bandwidthChoked(false), _bandwidthQuota(0), _bandwidthManager(0)
, _hasEmittedFinishedSignal(false)
, _hasEmittedFinishedSignal(false), _lastModified()
{
}
@ -160,6 +160,10 @@ void GETFileJob::slotMetaDataChanged()
}
}
auto lastModified = reply()->header(QNetworkRequest::LastModifiedHeader);
if (!lastModified.isNull()) {
_lastModified = Utility::qDateTimeToTime_t(lastModified.toDateTime());
}
}
void GETFileJob::setBandwidthManager(BandwidthManager *bwm)
@ -410,6 +414,11 @@ void PropagateDownloadFileQNAM::slotGetFinished()
// (If it was really empty by the server, the GETFileJob will have errored
_item._etag = parseEtag(job->etag());
}
if (job->lastModified()) {
// It is possible that the file was modified on the server since we did the discovery phase
// so make sure we have the up-to-date time
_item._modtime = job->lastModified();
}
_item._requestDuration = job->duration();
_item._responseTimeStamp = job->responseTimestamp();

View file

@ -36,6 +36,7 @@ class GETFileJob : public AbstractNetworkJob {
qint64 _bandwidthQuota;
QPointer<BandwidthManager> _bandwidthManager;
bool _hasEmittedFinishedSignal;
time_t _lastModified;
public:
// DOES NOT take owncership of the device.
@ -86,6 +87,7 @@ public:
QByteArray &etag() { return _etag; }
quint64 resumeStart() { return _resumeStart; }
time_t lastModified() { return _lastModified; }
signals:

View file

@ -726,7 +726,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
qDebug() << "OOO => Post Update Script: " << script;
QProcess::execute(script.toUtf8());
#else
qDebug() << "**** Attention: POST_UPDATE_SCRIPT installed, but not executed because compiled with NDEBUG";
qWarning() << "**** Attention: POST_UPDATE_SCRIPT installed, but not executed because compiled with NDEBUG";
#endif
}