OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "webkit/glue/multipart_response_delegate.h" | 5 #include "webkit/glue/multipart_response_delegate.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/net_util.h" | 10 #include "net/base/net_util.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 } // namespace | 55 } // namespace |
56 | 56 |
57 MultipartResponseDelegate::MultipartResponseDelegate( | 57 MultipartResponseDelegate::MultipartResponseDelegate( |
58 WebURLLoaderClient* client, | 58 WebURLLoaderClient* client, |
59 WebURLLoader* loader, | 59 WebURLLoader* loader, |
60 const WebURLResponse& response, | 60 const WebURLResponse& response, |
61 const std::string& boundary) | 61 const std::string& boundary) |
62 : client_(client), | 62 : client_(client), |
63 loader_(loader), | 63 loader_(loader), |
64 original_response_(response), | 64 original_response_(response), |
65 raw_data_length_(0), | |
65 boundary_("--"), | 66 boundary_("--"), |
66 first_received_data_(true), | 67 first_received_data_(true), |
67 processing_headers_(false), | 68 processing_headers_(false), |
68 stop_sending_(false), | 69 stop_sending_(false), |
69 has_sent_first_response_(false) { | 70 has_sent_first_response_(false) { |
70 // Some servers report a boundary prefixed with "--". See bug 5786. | 71 // Some servers report a boundary prefixed with "--". See bug 5786. |
71 if (StartsWithASCII(boundary, "--", true)) { | 72 if (StartsWithASCII(boundary, "--", true)) { |
72 boundary_.assign(boundary); | 73 boundary_.assign(boundary); |
73 } else { | 74 } else { |
74 boundary_.append(boundary); | 75 boundary_.append(boundary); |
75 } | 76 } |
76 } | 77 } |
77 | 78 |
78 void MultipartResponseDelegate::OnReceivedData(const char* data, | 79 void MultipartResponseDelegate::OnReceivedData(const char* data, |
79 int data_len) { | 80 int data_len, |
81 int raw_data_length) { | |
80 // stop_sending_ means that we've already received the final boundary token. | 82 // stop_sending_ means that we've already received the final boundary token. |
81 // The server should stop sending us data at this point, but if it does, we | 83 // The server should stop sending us data at this point, but if it does, we |
82 // just throw it away. | 84 // just throw it away. |
83 if (stop_sending_) | 85 if (stop_sending_) |
84 return; | 86 return; |
85 | 87 |
86 data_.append(data, data_len); | 88 data_.append(data, data_len); |
89 raw_data_length_ += raw_data_length; | |
87 if (first_received_data_) { | 90 if (first_received_data_) { |
88 // Some servers don't send a boundary token before the first chunk of | 91 // Some servers don't send a boundary token before the first chunk of |
89 // data. We handle this case anyway (Gecko does too). | 92 // data. We handle this case anyway (Gecko does too). |
90 first_received_data_ = false; | 93 first_received_data_ = false; |
91 | 94 |
92 // Eat leading \r\n | 95 // Eat leading \r\n |
93 int pos = PushOverLine(data_, 0); | 96 int pos = PushOverLine(data_, 0); |
94 if (pos) | 97 if (pos) |
95 data_ = data_.substr(pos); | 98 data_ = data_.substr(pos); |
96 | 99 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 data_length--; | 137 data_length--; |
135 if (boundary_pos > 1 && data_[boundary_pos - 2] == '\r') { | 138 if (boundary_pos > 1 && data_[boundary_pos - 2] == '\r') { |
136 data_length--; | 139 data_length--; |
137 } | 140 } |
138 } | 141 } |
139 if (data_length > 0) { | 142 if (data_length > 0) { |
140 // Send the last data chunk. | 143 // Send the last data chunk. |
141 client_->didReceiveData(loader_, | 144 client_->didReceiveData(loader_, |
142 data_.data(), | 145 data_.data(), |
143 static_cast<int>(data_length), | 146 static_cast<int>(data_length), |
144 -1); | 147 raw_data_length_); |
148 raw_data_length_ = 0; | |
145 } | 149 } |
146 } | 150 } |
147 size_t boundary_end_pos = boundary_pos + boundary_.length(); | 151 size_t boundary_end_pos = boundary_pos + boundary_.length(); |
148 if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { | 152 if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { |
149 // This was the last boundary so we can stop processing. | 153 // This was the last boundary so we can stop processing. |
150 stop_sending_ = true; | 154 stop_sending_ = true; |
151 data_.clear(); | 155 data_.clear(); |
152 return; | 156 return; |
153 } | 157 } |
154 | 158 |
(...skipping 10 matching lines...) Expand all Loading... | |
165 | 169 |
166 // At this point, we should send over any data we have, but keep enough data | 170 // At this point, we should send over any data we have, but keep enough data |
167 // buffered to handle a boundary that may have been truncated. | 171 // buffered to handle a boundary that may have been truncated. |
168 if (!processing_headers_ && data_.length() > boundary_.length()) { | 172 if (!processing_headers_ && data_.length() > boundary_.length()) { |
169 // If the last character is a new line character, go ahead and just send | 173 // If the last character is a new line character, go ahead and just send |
170 // everything we have buffered. This matches an optimization in Gecko. | 174 // everything we have buffered. This matches an optimization in Gecko. |
171 int send_length = data_.length() - boundary_.length(); | 175 int send_length = data_.length() - boundary_.length(); |
172 if (data_[data_.length() - 1] == '\n') | 176 if (data_[data_.length() - 1] == '\n') |
173 send_length = data_.length(); | 177 send_length = data_.length(); |
174 if (client_) | 178 if (client_) |
175 client_->didReceiveData(loader_, data_.data(), send_length, -1); | 179 client_->didReceiveData(loader_, |
180 data_.data(), | |
181 send_length, | |
182 raw_data_length_); | |
176 data_ = data_.substr(send_length); | 183 data_ = data_.substr(send_length); |
184 raw_data_length_ = 0; | |
177 } | 185 } |
178 } | 186 } |
179 | 187 |
180 void MultipartResponseDelegate::OnCompletedRequest() { | 188 void MultipartResponseDelegate::OnCompletedRequest() { |
181 // If we have any pending data and we're not in a header, go ahead and send | 189 // If we have any pending data and we're not in a header, go ahead and send |
182 // it to WebCore. | 190 // it to WebCore. |
183 if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) { | 191 if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) { |
184 client_->didReceiveData(loader_, | 192 client_->didReceiveData(loader_, |
185 data_.data(), | 193 data_.data(), |
186 static_cast<int>(data_.length()), -1); | 194 static_cast<int>(data_.length()), |
195 raw_data_length_); | |
196 raw_data_length_ = 0; | |
darin (slow to review)
2011/04/08 15:47:18
it can sometimes be dangerous to assume that |this
vsevik
2011/04/08 16:23:48
Yes, I am sure. It is destroyed right after the On
| |
187 } | 197 } |
188 } | 198 } |
189 | 199 |
190 int MultipartResponseDelegate::PushOverLine(const std::string& data, | 200 int MultipartResponseDelegate::PushOverLine(const std::string& data, |
191 size_t pos) { | 201 size_t pos) { |
192 int offset = 0; | 202 int offset = 0; |
193 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { | 203 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { |
194 ++offset; | 204 ++offset; |
195 if (pos + 1 < data.length() && data[pos + 1] == '\n') | 205 if (pos + 1 < data.length() && data[pos + 1] == '\n') |
196 ++offset; | 206 ++offset; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) | 393 if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) |
384 return false; | 394 return false; |
385 if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) | 395 if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) |
386 return false; | 396 return false; |
387 if (!base::StringToInt(byte_range_instance_size, content_range_instance_size)) | 397 if (!base::StringToInt(byte_range_instance_size, content_range_instance_size)) |
388 return false; | 398 return false; |
389 return true; | 399 return true; |
390 } | 400 } |
391 | 401 |
392 } // namespace webkit_glue | 402 } // namespace webkit_glue |
OLD | NEW |