OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/base/upload_file_element_reader.h" | |
6 | |
7 #include "base/file_util.h" | |
8 #include "base/threading/thread_restrictions.h" | |
9 #include "net/base/file_stream.h" | |
10 #include "net/base/net_errors.h" | |
11 | |
12 namespace net { | |
13 | |
14 namespace { | |
15 | |
16 // In tests, this value is used to override the return value of | |
17 // UploadFileElementReader::GetContentLength() when set to non-zero. | |
18 uint64 overriding_content_length = 0; | |
19 | |
20 } // namespace | |
21 | |
22 UploadFileElementReader::UploadFileElementReader( | |
23 const FilePath& path, | |
24 uint64 range_offset, | |
25 uint64 range_length, | |
26 const base::Time& expected_modification_time) | |
27 : path_(path), | |
28 range_offset_(range_offset), | |
29 range_length_(range_length), | |
30 expected_modification_time_(expected_modification_time), | |
31 content_length_(0), | |
32 bytes_remaining_(0) { | |
33 } | |
34 | |
35 UploadFileElementReader::~UploadFileElementReader() { | |
36 // Temporarily allow until fix: http://crbug.com/72001. | |
37 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
38 if (file_stream_.get()) | |
39 file_stream_->CloseSync(); | |
40 } | |
41 | |
42 int UploadFileElementReader::InitSync() { | |
43 // Temporarily allow until fix: http://crbug.com/72001. | |
44 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
45 | |
46 scoped_ptr<FileStream> file_stream(new FileStream(NULL)); | |
47 int64 rv = file_stream->OpenSync( | |
48 path_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); | |
49 if (rv != OK) { | |
50 // If the file can't be opened, we'll just upload an empty file. | |
51 DLOG(WARNING) << "Failed to open \"" << path_.value() | |
52 << "\" for reading: " << rv; | |
53 file_stream.reset(); | |
54 } | |
55 if (file_stream.get() && range_offset_) { | |
56 rv = file_stream->SeekSync(FROM_BEGIN, range_offset_); | |
57 if (rv < 0) { | |
58 DLOG(WARNING) << "Failed to seek \"" << path_.value() | |
59 << "\" to offset: " << range_offset_ << " (" << rv | |
60 << ")"; | |
61 file_stream->CloseSync(); | |
62 file_stream.reset(); | |
63 } | |
64 } | |
65 file_stream_.reset(file_stream.release()); | |
66 | |
67 int64 length = 0; | |
68 if (file_stream_.get() && | |
69 file_util::GetFileSize(path_, &length) && | |
70 range_offset_ < static_cast<uint64>(length)) { | |
71 // Compensate for the offset. | |
72 length = std::min(length - range_offset_, range_length_); | |
73 } | |
74 content_length_ = length; | |
75 bytes_remaining_ = GetContentLength(); | |
76 | |
77 // If the underlying file has been changed and the expected file | |
78 // modification time is set, treat it as error. Note that the expected | |
79 // modification time from WebKit is based on time_t precision. So we | |
willchan no longer on Chromium
2012/09/06 01:06:01
I don't fully understand this comment. Is this mov
hashimoto
2012/09/06 01:55:39
This comment is moved from UploadDataStream::Init(
| |
80 // have to convert both to time_t to compare. This check is used for | |
81 // sliced files. | |
82 if (!expected_modification_time_.is_null()) { | |
83 base::PlatformFileInfo info; | |
84 if (file_util::GetFileInfo(path_, &info) && | |
85 expected_modification_time_.ToTimeT() != | |
86 info.last_modified.ToTimeT()) { | |
87 return ERR_UPLOAD_FILE_CHANGED; | |
88 } | |
89 } | |
90 | |
91 return OK; | |
92 } | |
93 | |
94 uint64 UploadFileElementReader::GetContentLength() const { | |
95 if (overriding_content_length) | |
96 return overriding_content_length; | |
97 return content_length_; | |
98 } | |
99 | |
100 uint64 UploadFileElementReader::BytesRemaining() const { | |
101 return bytes_remaining_; | |
102 } | |
103 | |
104 int UploadFileElementReader::ReadSync(char* buf, int buf_length) { | |
105 // Temporarily allow until fix: http://crbug.com/72001. | |
106 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
107 DCHECK_LT(0, buf_length); | |
108 | |
109 const uint64 num_bytes_to_read = | |
110 static_cast<int>(std::min(BytesRemaining(), | |
111 static_cast<uint64>(buf_length))); | |
112 if (num_bytes_to_read > 0) { | |
113 int num_bytes_consumed = 0; | |
114 // file_stream_ is NULL if the target file is | |
115 // missing or not readable. | |
116 if (file_stream_.get()) { | |
117 num_bytes_consumed = | |
118 file_stream_->ReadSync(buf, num_bytes_to_read); | |
119 } | |
120 if (num_bytes_consumed <= 0) { | |
121 // If there's less data to read than we initially observed, then | |
122 // pad with zero. Otherwise the server will hang waiting for the | |
123 // rest of the data. | |
124 memset(buf, 0, num_bytes_to_read); | |
125 } | |
126 } | |
127 DCHECK_GE(bytes_remaining_, num_bytes_to_read); | |
128 bytes_remaining_ -= num_bytes_to_read; | |
129 return num_bytes_to_read; | |
130 } | |
131 | |
132 UploadFileElementReader::ScopedOverridingContentLengthForTests:: | |
133 ScopedOverridingContentLengthForTests(uint64 value) { | |
134 overriding_content_length = value; | |
135 } | |
136 | |
137 UploadFileElementReader::ScopedOverridingContentLengthForTests:: | |
138 ~ScopedOverridingContentLengthForTests() { | |
139 overriding_content_length = 0; | |
140 } | |
141 | |
142 } // namespace net | |
OLD | NEW |