Commit 91430c35 authored by asanka's avatar asanka Committed by Commit bot

[net] Subtract timestamps to determine if uploading file changed.

UploadFileElementReader relies on checking the modified time of files
being uploaded to determine if a sliced file was modified during upload.
Clients of the net stack (in particular Blink) currently pass around the
expected modified time in a manner which cause the timestamp to lose
precision (E.g. converting to and from a double time_t).

As a result the expected timestamp and the current timestamp as returned
by GetFileInfo() will not match exactly. Current code attempted to
compensate for this by converting both timestamps to (integer) time_t.
However, since the conversion rounds down, this check would only succeed
if the loss of precision of the expected timestamp also caused it to
round down. This is not always the case. (E.g. (epoch + 10.999999) will
become 10 when converted to time_t, but the expected timestamp may have
rounded up to (epoch + 11.0) in the meantime.)

This patch compares the timestamps by checking if the magnitude of the
difference is less than one second.

BUG=426465
CQ_EXTRA_TRYBOTS=tryserver.blink:linux_blink_rel,linux_blink_dbg,mac_blink_rel,win_blink_rel
R=mmenke

Committed: https://crrev.com/b77c8ffae588001875fb50ead987a147ca882bdb
Cr-Commit-Position: refs/heads/master@{#314397}

Reverted: https://crrev.com/7ccf4fab5d4473e431f1a289056033eea0b3dd43
Cr-Commit-Position: refs/heads/master@{#314451}

Review URL: https://codereview.chromium.org/868253012

Cr-Commit-Position: refs/heads/master@{#314634}
parent 6b039c37
...@@ -174,12 +174,15 @@ void UploadFileElementReader::OnGetFileInfoCompleted( ...@@ -174,12 +174,15 @@ void UploadFileElementReader::OnGetFileInfoCompleted(
} }
// If the underlying file has been changed and the expected file modification // If the underlying file has been changed and the expected file modification
// time is set, treat it as error. Note that the expected modification time // time is set, treat it as error. Note that |expected_modification_time_| may
// from WebKit is based on time_t precision. So we have to convert both to // have gone through multiple conversion steps involving loss of precision
// time_t to compare. This check is used for sliced files. // (including conversion to time_t). Therefore the check below only verifies
// that the timestamps are within one second of each other. This check is used
// for sliced files.
if (!expected_modification_time_.is_null() && if (!expected_modification_time_.is_null() &&
expected_modification_time_.ToTimeT() != (expected_modification_time_ - file_info->last_modified)
file_info->last_modified.ToTimeT()) { .magnitude()
.InSeconds() != 0) {
callback.Run(ERR_UPLOAD_FILE_CHANGED); callback.Run(ERR_UPLOAD_FILE_CHANGED);
return; return;
} }
......
...@@ -210,25 +210,33 @@ TEST_F(UploadFileElementReaderTest, FileChanged) { ...@@ -210,25 +210,33 @@ TEST_F(UploadFileElementReaderTest, FileChanged) {
// Expect one second before the actual modification time to simulate change. // Expect one second before the actual modification time to simulate change.
const base::Time expected_modification_time = const base::Time expected_modification_time =
info.last_modified - base::TimeDelta::FromSeconds(1); info.last_modified - base::TimeDelta::FromSeconds(1);
reader_.reset( reader_.reset(new UploadFileElementReader(
new UploadFileElementReader(base::MessageLoopProxy::current().get(), base::MessageLoopProxy::current().get(), temp_file_path_, 0, kuint64max,
temp_file_path_, expected_modification_time));
0,
kuint64max,
expected_modification_time));
TestCompletionCallback init_callback; TestCompletionCallback init_callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult()); EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult());
} }
TEST_F(UploadFileElementReaderTest, InexactExpectedTimeStamp) {
base::File::Info info;
ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info));
const base::Time expected_modification_time =
info.last_modified - base::TimeDelta::FromMilliseconds(900);
reader_.reset(new UploadFileElementReader(
base::MessageLoopProxy::current().get(), temp_file_path_, 0, kuint64max,
expected_modification_time));
TestCompletionCallback init_callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(OK, init_callback.WaitForResult());
}
TEST_F(UploadFileElementReaderTest, WrongPath) { TEST_F(UploadFileElementReaderTest, WrongPath) {
const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path")); const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path"));
reader_.reset( reader_.reset(
new UploadFileElementReader(base::MessageLoopProxy::current().get(), new UploadFileElementReader(base::MessageLoopProxy::current().get(),
wrong_path, wrong_path, 0, kuint64max, base::Time()));
0,
kuint64max,
base::Time()));
TestCompletionCallback init_callback; TestCompletionCallback init_callback;
ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
EXPECT_EQ(ERR_FILE_NOT_FOUND, init_callback.WaitForResult()); EXPECT_EQ(ERR_FILE_NOT_FOUND, init_callback.WaitForResult());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment