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

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

Issue 6134003: Prototype of chunked transfer encoded POST. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 11 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 | Annotate | Revision Log
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.h" 5 #include "net/base/upload_data.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/file_stream.h" 9 #include "net/base/file_stream.h"
10 #include "base/string_util.h"
wtc 2011/01/20 00:29:47 Nit: list this header in alphabetical order.
10 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
11 12
12 namespace net { 13 namespace net {
13 14
14 UploadData::Element::Element() 15 UploadData::Element::Element()
15 : type_(TYPE_BYTES), 16 : type_(TYPE_BYTES),
16 file_range_offset_(0), 17 file_range_offset_(0),
17 file_range_length_(kuint64max), 18 file_range_length_(kuint64max),
18 override_content_length_(false), 19 override_content_length_(false),
19 content_length_computed_(false), 20 content_length_computed_(false),
20 content_length_(-1), 21 content_length_(-1),
21 file_stream_(NULL) { 22 file_stream_(NULL) {
22 } 23 }
23 24
24 UploadData::Element::~Element() { 25 UploadData::Element::~Element() {
25 // In the common case |file__stream_| will be null. 26 // In the common case |file__stream_| will be null.
26 delete file_stream_; 27 delete file_stream_;
27 } 28 }
28 29
29 uint64 UploadData::Element::GetContentLength() { 30 uint64 UploadData::Element::GetContentLength() {
30 if (override_content_length_ || content_length_computed_) 31 if (override_content_length_ || content_length_computed_)
31 return content_length_; 32 return content_length_;
32 33
33 if (type_ == TYPE_BYTES) 34 if (type_ == TYPE_BYTES || type_ == TYPE_CHUNK)
34 return static_cast<uint64>(bytes_.size()); 35 return static_cast<uint64>(bytes_.size());
35 else if (type_ == TYPE_BLOB) 36 else if (type_ == TYPE_BLOB)
36 // The blob reference will be resolved later. 37 // The blob reference will be resolved later.
37 return 0; 38 return 0;
38 39
39 DCHECK_EQ(TYPE_FILE, type_); 40 DCHECK_EQ(TYPE_FILE, type_);
40 DCHECK(!file_stream_); 41 DCHECK(!file_stream_);
41 42
42 // TODO(darin): This size calculation could be out of sync with the state of 43 // TODO(darin): This size calculation could be out of sync with the state of
43 // the file when we get around to reading it. We should probably find a way 44 // the file when we get around to reading it. We should probably find a way
(...skipping 14 matching lines...) Expand all
58 return 0; 59 return 0;
59 60
60 if (file_range_offset_ >= static_cast<uint64>(length)) 61 if (file_range_offset_ >= static_cast<uint64>(length))
61 return 0; // range is beyond eof 62 return 0; // range is beyond eof
62 63
63 // compensate for the offset and clip file_range_length_ to eof 64 // compensate for the offset and clip file_range_length_ to eof
64 content_length_ = std::min(length - file_range_offset_, file_range_length_); 65 content_length_ = std::min(length - file_range_offset_, file_range_length_);
65 return content_length_; 66 return content_length_;
66 } 67 }
67 68
69 void UploadData::Element::SetToChunk(const char* bytes, int bytes_len) {
70 std::string chunk_length = StringPrintf("%X\r\n", bytes_len);
71 bytes_.clear();
72 bytes_.insert(bytes_.end(), chunk_length.c_str(),
73 chunk_length.c_str() + chunk_length.length());
wtc 2011/01/20 00:29:47 Nit: c_str() => data()
74 bytes_.insert(bytes_.end(), bytes, bytes + bytes_len);
75 const char* crlf = "\r\n";
76 bytes_.insert(bytes_.end(), crlf, crlf + 2);
77 type_ = TYPE_CHUNK;
78 }
79
80 void UploadData::Element::SetToEndOfChunksMarker() {
81 bytes_.clear();
82 type_ = TYPE_CHUNK;
83 }
84
68 FileStream* UploadData::Element::NewFileStreamForReading() { 85 FileStream* UploadData::Element::NewFileStreamForReading() {
69 // In common usage GetContentLength() will call this first and store the 86 // In common usage GetContentLength() will call this first and store the
70 // result into |file_| and a subsequent call (from UploadDataStream) will 87 // result into |file_| and a subsequent call (from UploadDataStream) will
71 // get the cached open FileStream. 88 // get the cached open FileStream.
72 if (file_stream_) { 89 if (file_stream_) {
73 FileStream* file = file_stream_; 90 FileStream* file = file_stream_;
74 file_stream_ = NULL; 91 file_stream_ = NULL;
75 return file; 92 return file;
76 } 93 }
77 94
(...skipping 12 matching lines...) Expand all
90 DLOG(WARNING) << "Failed to seek \"" << file_path_.value() 107 DLOG(WARNING) << "Failed to seek \"" << file_path_.value()
91 << "\" to offset: " << file_range_offset_ << " (" << rv 108 << "\" to offset: " << file_range_offset_ << " (" << rv
92 << ")"; 109 << ")";
93 return NULL; 110 return NULL;
94 } 111 }
95 } 112 }
96 113
97 return file.release(); 114 return file.release();
98 } 115 }
99 116
100 UploadData::UploadData() : identifier_(0) { 117 UploadData::UploadData()
118 : identifier_(0),
119 chunk_callback_(NULL),
120 is_chunked_(false) {
101 } 121 }
102 122
103 void UploadData::AppendBytes(const char* bytes, int bytes_len) { 123 void UploadData::AppendBytes(const char* bytes, int bytes_len) {
124 DCHECK(!is_chunked_);
104 if (bytes_len > 0) { 125 if (bytes_len > 0) {
105 elements_.push_back(Element()); 126 elements_.push_back(Element());
106 elements_.back().SetToBytes(bytes, bytes_len); 127 elements_.back().SetToBytes(bytes, bytes_len);
107 } 128 }
108 } 129 }
109 130
110 void UploadData::AppendFile(const FilePath& file_path) { 131 void UploadData::AppendFile(const FilePath& file_path) {
132 DCHECK(!is_chunked_);
111 elements_.push_back(Element()); 133 elements_.push_back(Element());
112 elements_.back().SetToFilePath(file_path); 134 elements_.back().SetToFilePath(file_path);
113 } 135 }
114 136
115 void UploadData::AppendFileRange(const FilePath& file_path, 137 void UploadData::AppendFileRange(const FilePath& file_path,
116 uint64 offset, uint64 length, 138 uint64 offset, uint64 length,
117 const base::Time& expected_modification_time) { 139 const base::Time& expected_modification_time) {
140 DCHECK(!is_chunked_);
118 elements_.push_back(Element()); 141 elements_.push_back(Element());
119 elements_.back().SetToFilePathRange(file_path, offset, length, 142 elements_.back().SetToFilePathRange(file_path, offset, length,
120 expected_modification_time); 143 expected_modification_time);
121 } 144 }
122 145
123 void UploadData::AppendBlob(const GURL& blob_url) { 146 void UploadData::AppendBlob(const GURL& blob_url) {
147 DCHECK(!is_chunked_);
124 elements_.push_back(Element()); 148 elements_.push_back(Element());
125 elements_.back().SetToBlobUrl(blob_url); 149 elements_.back().SetToBlobUrl(blob_url);
126 } 150 }
127 151
152 void UploadData::AppendChunk(const char* bytes, int bytes_len) {
153 DCHECK(is_chunked_);
154 elements_.push_back(Element());
155 elements_.back().SetToChunk(bytes, bytes_len);
156 if (!bytes_len) {
vandebo (ex-Chrome) 2011/01/18 21:51:17 nit: This uses two Elements to represent the last
Satish 2011/01/20 18:02:36 I avoided doing that because it would take up unwa
vandebo (ex-Chrome) 2011/01/20 20:48:45 There are already several bools in the Element cla
157 // End of chunked stream is marked by a chunk with an empty |bytes_|.
wtc 2011/01/20 00:29:47 Nit: chunked stream => chunks
158 elements_.push_back(Element());
159 elements_.back().SetToEndOfChunksMarker();
160 }
161 if (chunk_callback_)
162 chunk_callback_->OnChunkAvailable();
163 }
164
165 void UploadData::set_chunk_callback(ChunkCallback* callback) {
166 DCHECK(!chunk_callback_);
wtc 2011/01/20 00:29:47 IMPORTANT: I believe this DCHECK is too strong. W
167 chunk_callback_ = callback;
168 }
169
128 uint64 UploadData::GetContentLength() { 170 uint64 UploadData::GetContentLength() {
171 DCHECK(!is_chunked_);
129 uint64 len = 0; 172 uint64 len = 0;
130 std::vector<Element>::iterator it = elements_.begin(); 173 std::vector<Element>::iterator it = elements_.begin();
131 for (; it != elements_.end(); ++it) 174 for (; it != elements_.end(); ++it)
132 len += (*it).GetContentLength(); 175 len += (*it).GetContentLength();
133 return len; 176 return len;
134 } 177 }
135 178
136 void UploadData::SetElements(const std::vector<Element>& elements) { 179 void UploadData::SetElements(const std::vector<Element>& elements) {
137 elements_ = elements; 180 elements_ = elements;
138 } 181 }
139 182
140 UploadData::~UploadData() { 183 UploadData::~UploadData() {
141 } 184 }
142 185
143 } // namespace net 186 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698