Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: net/base/upload_data_stream.cc

Issue 1250002: Report unreadable files as size zero when uploading. (Closed)
Patch Set: Address comments Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/base/upload_data_stream.h ('k') | net/base/upload_data_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/upload_data_stream.h" 5 #include "net/base/upload_data_stream.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
11 11
12 namespace net { 12 namespace net {
13 13
14 UploadDataStream* UploadDataStream::Create(const UploadData* data, 14 UploadDataStream* UploadDataStream::Create(UploadData* data, int* error_code) {
15 int* error_code) {
16 scoped_ptr<UploadDataStream> stream(new UploadDataStream(data)); 15 scoped_ptr<UploadDataStream> stream(new UploadDataStream(data));
17 int rv = stream->FillBuf(); 16 int rv = stream->FillBuf();
18 if (error_code) 17 if (error_code)
19 *error_code = rv; 18 *error_code = rv;
20 if (rv != OK) 19 if (rv != OK)
21 return NULL; 20 return NULL;
22 21
23 return stream.release(); 22 return stream.release();
24 } 23 }
25 24
26 UploadDataStream::UploadDataStream(const UploadData* data) 25 UploadDataStream::UploadDataStream(UploadData* data)
27 : data_(data), 26 : data_(data),
28 buf_(new IOBuffer(kBufSize)), 27 buf_(new IOBuffer(kBufSize)),
29 buf_len_(0), 28 buf_len_(0),
30 next_element_(data->elements().begin()), 29 next_element_(data->elements()->begin()),
31 next_element_offset_(0), 30 next_element_offset_(0),
32 next_element_remaining_(0), 31 next_element_remaining_(0),
33 total_size_(data->GetContentLength()), 32 total_size_(data->GetContentLength()),
34 current_position_(0), 33 current_position_(0),
35 eof_(false) { 34 eof_(false) {
36 } 35 }
37 36
38 UploadDataStream::~UploadDataStream() { 37 UploadDataStream::~UploadDataStream() {
39 } 38 }
40 39
41 void UploadDataStream::DidConsume(size_t num_bytes) { 40 void UploadDataStream::DidConsume(size_t num_bytes) {
42 DCHECK_LE(num_bytes, buf_len_); 41 DCHECK_LE(num_bytes, buf_len_);
43 DCHECK(!eof_); 42 DCHECK(!eof_);
44 43
45 buf_len_ -= num_bytes; 44 buf_len_ -= num_bytes;
46 if (buf_len_) 45 if (buf_len_)
47 memmove(buf_->data(), buf_->data() + num_bytes, buf_len_); 46 memmove(buf_->data(), buf_->data() + num_bytes, buf_len_);
48 47
49 FillBuf(); 48 FillBuf();
50 49
51 current_position_ += num_bytes; 50 current_position_ += num_bytes;
52 } 51 }
53 52
54 int UploadDataStream::FillBuf() { 53 int UploadDataStream::FillBuf() {
55 std::vector<UploadData::Element>::const_iterator end = 54 std::vector<UploadData::Element>::iterator end =
56 data_->elements().end(); 55 data_->elements()->end();
57 56
58 while (buf_len_ < kBufSize && next_element_ != end) { 57 while (buf_len_ < kBufSize && next_element_ != end) {
59 bool advance_to_next_element = false; 58 bool advance_to_next_element = false;
60 59
61 const UploadData::Element& element = *next_element_; 60 UploadData::Element& element = *next_element_;
62 61
63 size_t size_remaining = kBufSize - buf_len_; 62 size_t size_remaining = kBufSize - buf_len_;
64 if (element.type() == UploadData::TYPE_BYTES) { 63 if (element.type() == UploadData::TYPE_BYTES) {
65 const std::vector<char>& d = element.bytes(); 64 const std::vector<char>& d = element.bytes();
66 size_t count = d.size() - next_element_offset_; 65 size_t count = d.size() - next_element_offset_;
67 66
68 size_t bytes_copied = std::min(count, size_remaining); 67 size_t bytes_copied = std::min(count, size_remaining);
69 68
70 memcpy(buf_->data() + buf_len_, &d[next_element_offset_], bytes_copied); 69 memcpy(buf_->data() + buf_len_, &d[next_element_offset_], bytes_copied);
71 buf_len_ += bytes_copied; 70 buf_len_ += bytes_copied;
72 71
73 if (bytes_copied == count) { 72 if (bytes_copied == count) {
74 advance_to_next_element = true; 73 advance_to_next_element = true;
75 } else { 74 } else {
76 next_element_offset_ += bytes_copied; 75 next_element_offset_ += bytes_copied;
77 } 76 }
78 } else { 77 } else {
79 DCHECK(element.type() == UploadData::TYPE_FILE); 78 DCHECK(element.type() == UploadData::TYPE_FILE);
80 79
81 // If the underlying file has been changed, treat it as error. 80 if (!next_element_remaining_) {
82 // Note that the expected modification time from WebKit is based on 81 // If the underlying file has been changed, treat it as error.
83 // time_t precision. So we have to convert both to time_t to compare. 82 // Note that the expected modification time from WebKit is based on
84 if (!element.expected_file_modification_time().is_null()) { 83 // time_t precision. So we have to convert both to time_t to compare.
85 file_util::FileInfo info; 84 if (!element.expected_file_modification_time().is_null()) {
86 if (file_util::GetFileInfo(element.file_path(), &info) && 85 file_util::FileInfo info;
87 element.expected_file_modification_time().ToTimeT() != 86 if (file_util::GetFileInfo(element.file_path(), &info) &&
88 info.last_modified.ToTimeT()) { 87 element.expected_file_modification_time().ToTimeT() !=
89 return ERR_UPLOAD_FILE_CHANGED; 88 info.last_modified.ToTimeT()) {
90 } 89 return ERR_UPLOAD_FILE_CHANGED;
91 }
92
93 if (!next_element_stream_.IsOpen()) {
94 int flags = base::PLATFORM_FILE_OPEN |
95 base::PLATFORM_FILE_READ;
96 int rv = next_element_stream_.Open(element.file_path(), flags);
97 // If the file does not exist, that's technically okay.. we'll just
98 // upload an empty file. This is for consistency with Mozilla.
99 DLOG_IF(WARNING, rv != OK) << "Failed to open \""
100 << element.file_path().value()
101 << "\" for reading: " << rv;
102
103 next_element_remaining_ = 0; // Default to reading nothing.
104 if (rv == OK) {
105 uint64 offset = element.file_range_offset();
106 if (offset && next_element_stream_.Seek(FROM_BEGIN, offset) < 0) {
107 DLOG(WARNING) << "Failed to seek \"" << element.file_path().value()
108 << "\" to offset: " << offset;
109 } else {
110 next_element_remaining_ = element.file_range_length();
111 } 90 }
112 } 91 }
92 next_element_remaining_ = element.GetContentLength();
93 next_element_stream_.reset(element.NewFileStreamForReading());
113 } 94 }
114 95
115 int rv = 0; 96 int rv = 0;
116 int count = static_cast<int>(std::min( 97 int count =
117 static_cast<uint64>(size_remaining), next_element_remaining_)); 98 static_cast<int>(std::min(next_element_remaining_,
118 if (count > 0 && 99 static_cast<uint64>(size_remaining)));
119 (rv = next_element_stream_.Read(buf_->data() + buf_len_, 100 if (count > 0) {
120 count, NULL)) > 0) { 101 if (next_element_stream_.get())
102 rv = next_element_stream_->Read(buf_->data() + buf_len_, count, NULL);
103 if (rv <= 0) {
104 // If there's less data to read than we initially observed, then
105 // pad with zero. Otherwise the server will hang waiting for the
106 // rest of the data.
107 memset(buf_->data() + buf_len_, 0, count);
108 rv = count;
109 }
121 buf_len_ += rv; 110 buf_len_ += rv;
111 }
112
113 if (static_cast<int>(next_element_remaining_) == rv) {
114 advance_to_next_element = true;
115 } else {
122 next_element_remaining_ -= rv; 116 next_element_remaining_ -= rv;
123 } else {
124 advance_to_next_element = true;
125 } 117 }
126 } 118 }
127 119
128 if (advance_to_next_element) { 120 if (advance_to_next_element) {
129 ++next_element_; 121 ++next_element_;
130 next_element_offset_ = 0; 122 next_element_offset_ = 0;
131 next_element_stream_.Close(); 123 next_element_remaining_ = 0;
124 next_element_stream_.reset();
132 } 125 }
133 } 126 }
134 127
135 if (next_element_ == end && !buf_len_) 128 if (next_element_ == end && !buf_len_)
136 eof_ = true; 129 eof_ = true;
137 130
138 return OK; 131 return OK;
139 } 132 }
140 133
141 } // namespace net 134 } // namespace net
OLDNEW
« no previous file with comments | « net/base/upload_data_stream.h ('k') | net/base/upload_data_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698