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 541022: Fix the case where the browser livelocks if we cannot open a file. (Closed)
Patch Set: Uploading checkpoint. This is known to cause all uploads on Windows to be zero bytes long. 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') | no next file » | 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/logging.h" 7 #include "base/logging.h"
8 #include "net/base/io_buffer.h" 8 #include "net/base/io_buffer.h"
9 #include "net/base/net_errors.h" 9 #include "net/base/net_errors.h"
10 10
11 namespace net { 11 namespace net {
12 12
13 UploadDataStream::UploadDataStream(const UploadData* data) 13 UploadDataStream::UploadDataStream(UploadData* data)
14 : data_(data), 14 : data_(data),
15 buf_(new IOBuffer(kBufSize)), 15 buf_(new IOBuffer(kBufSize)),
16 buf_len_(0), 16 buf_len_(0),
17 next_element_(data->elements().begin()), 17 next_element_(data->elements().begin()),
18 next_element_offset_(0), 18 next_element_offset_(0),
19 next_element_remaining_(0), 19 next_element_remaining_(0),
20 total_size_(data->GetContentLength()), 20 total_size_(data->GetContentLength()),
21 current_position_(0), 21 current_position_(0),
22 eof_(false) { 22 eof_(false) {
23 FillBuf(); 23 FillBuf();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 buf_len_ += bytes_copied; 60 buf_len_ += bytes_copied;
61 61
62 if (bytes_copied == count) { 62 if (bytes_copied == count) {
63 advance_to_next_element = true; 63 advance_to_next_element = true;
64 } else { 64 } else {
65 next_element_offset_ += bytes_copied; 65 next_element_offset_ += bytes_copied;
66 } 66 }
67 } else { 67 } else {
68 DCHECK(element.type() == UploadData::TYPE_FILE); 68 DCHECK(element.type() == UploadData::TYPE_FILE);
69 69
70 if (!next_element_stream_.IsOpen()) { 70 if (element.file_range_length() == 0) {
71 int flags = base::PLATFORM_FILE_OPEN | 71 // If we failed to open the file, then the length is set to zero. The
72 base::PLATFORM_FILE_READ; 72 // length used when calculating the POST size was also zero. This
73 int rv = next_element_stream_.Open(element.file_path(), flags); 73 // matches the behaviour of Mozilla.
74 // If the file does not exist, that's technically okay.. we'll just 74 next_element_remaining_ = 0;
75 // upload an empty file. This is for consistency with Mozilla. 75 } else {
76 DLOG_IF(WARNING, rv != OK) << "Failed to open \"" 76 if (!next_element_stream_.IsOpen()) {
77 << element.file_path().value() 77 // We ignore the return value of Open becuase we've already checked
78 << "\" for reading: " << rv; 78 // !IsOpen, above.
79 int flags = base::PLATFORM_FILE_READ |
80 base::PLATFORM_FILE_WRITE;
81 next_element_stream_.Open(element.platform_file(), flags);
79 82
80 next_element_remaining_ = 0; // Default to reading nothing.
81 if (rv == OK) {
82 uint64 offset = element.file_range_offset(); 83 uint64 offset = element.file_range_offset();
83 if (offset && next_element_stream_.Seek(FROM_BEGIN, offset) < 0) { 84 if (offset && next_element_stream_.Seek(FROM_BEGIN, offset) < 0) {
84 DLOG(WARNING) << "Failed to seek \"" << element.file_path().value() 85 DLOG(WARNING) << "Failed to seek \"" << element.file_path().value()
85 << "\" to offset: " << offset; 86 << "\" to offset: " << offset;
86 } else { 87 } else {
87 next_element_remaining_ = element.file_range_length(); 88 next_element_remaining_ = element.file_range_length();
88 } 89 }
89 } 90 }
90 } 91 }
91 92
92 int rv = 0; 93 int rv = 0;
93 int count = static_cast<int>(std::min( 94 if (next_element_remaining_ > 0) {
94 static_cast<uint64>(size_remaining), next_element_remaining_)); 95 int count =
95 if (count > 0 && 96 static_cast<int>(std::min(next_element_remaining_,
96 (rv = next_element_stream_.Read(buf_->data() + buf_len_, 97 static_cast<uint64>(size_remaining)));
97 count, NULL)) > 0) { 98 rv = next_element_stream_.Read(buf_->data() + buf_len_, count, NULL);
99 if (rv < 1) {
100 // If the file was truncated between the time that we opened it and
101 // now, or if we got an error on reading, then we pad with NULs.
102 memset(buf_->data() + buf_len_, 0, count);
103 rv = count;
104 }
105
98 buf_len_ += rv; 106 buf_len_ += rv;
99 next_element_remaining_ -= rv; 107 next_element_remaining_ -= rv;
100 } else { 108 } else {
101 advance_to_next_element = true; 109 advance_to_next_element = true;
102 } 110 }
103 } 111 }
104 112
105 if (advance_to_next_element) { 113 if (advance_to_next_element) {
106 ++next_element_; 114 ++next_element_;
107 next_element_offset_ = 0; 115 next_element_offset_ = 0;
108 next_element_stream_.Close(); 116 next_element_stream_.Release();
109 } 117 }
110 } 118 }
111 119
112 if (next_element_ == end && !buf_len_) 120 if (next_element_ == end && !buf_len_) {
113 eof_ = true; 121 eof_ = true;
122 data_->CloseFiles();
123 }
114 } 124 }
115 125
116 } // namespace net 126 } // namespace net
OLDNEW
« no previous file with comments | « net/base/upload_data_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698