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 length_received_(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 length_received) { |
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 length_received_ += length_received; |
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 // FIXME(vsevik): rename once renamed in webkit | 144 // FIXME(vsevik): rename once renamed in webkit |
142 client_->didReceiveData2(loader_, | 145 client_->didReceiveData2(loader_, |
143 data_.data(), | 146 data_.data(), |
144 static_cast<int>(data_length), -1); | 147 static_cast<int>(data_length), |
| 148 length_received_); |
| 149 length_received_ = 0; |
145 } | 150 } |
146 } | 151 } |
147 size_t boundary_end_pos = boundary_pos + boundary_.length(); | 152 size_t boundary_end_pos = boundary_pos + boundary_.length(); |
148 if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { | 153 if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { |
149 // This was the last boundary so we can stop processing. | 154 // This was the last boundary so we can stop processing. |
150 stop_sending_ = true; | 155 stop_sending_ = true; |
151 data_.clear(); | 156 data_.clear(); |
152 return; | 157 return; |
153 } | 158 } |
154 | 159 |
(...skipping 11 matching lines...) Expand all Loading... |
166 // At this point, we should send over any data we have, but keep enough data | 171 // 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. | 172 // buffered to handle a boundary that may have been truncated. |
168 if (!processing_headers_ && data_.length() > boundary_.length()) { | 173 if (!processing_headers_ && data_.length() > boundary_.length()) { |
169 // If the last character is a new line character, go ahead and just send | 174 // 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. | 175 // everything we have buffered. This matches an optimization in Gecko. |
171 int send_length = data_.length() - boundary_.length(); | 176 int send_length = data_.length() - boundary_.length(); |
172 if (data_[data_.length() - 1] == '\n') | 177 if (data_[data_.length() - 1] == '\n') |
173 send_length = data_.length(); | 178 send_length = data_.length(); |
174 // FIXME(vsevik): rename didReceiveData2 once renamed in webkit | 179 // FIXME(vsevik): rename didReceiveData2 once renamed in webkit |
175 if (client_) | 180 if (client_) |
176 client_->didReceiveData2(loader_, data_.data(), send_length, -1); | 181 client_->didReceiveData2(loader_, data_.data(), send_length, |
| 182 length_received_); |
177 data_ = data_.substr(send_length); | 183 data_ = data_.substr(send_length); |
| 184 length_received_ = 0; |
178 } | 185 } |
179 } | 186 } |
180 | 187 |
181 void MultipartResponseDelegate::OnCompletedRequest() { | 188 void MultipartResponseDelegate::OnCompletedRequest() { |
182 // 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 |
183 // it to WebCore. | 190 // it to WebCore. |
184 if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) { | 191 if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) { |
185 // FIXME(vsevik): rename didReceiveData2 once renamed in webkit | 192 // FIXME(vsevik): rename didReceiveData2 once renamed in webkit |
186 client_->didReceiveData2(loader_, | 193 client_->didReceiveData2(loader_, |
187 data_.data(), | 194 data_.data(), |
188 static_cast<int>(data_.length()), -1); | 195 static_cast<int>(data_.length()), |
| 196 length_received_); |
| 197 length_received_ = 0; |
189 } | 198 } |
190 } | 199 } |
191 | 200 |
192 int MultipartResponseDelegate::PushOverLine(const std::string& data, | 201 int MultipartResponseDelegate::PushOverLine(const std::string& data, |
193 size_t pos) { | 202 size_t pos) { |
194 int offset = 0; | 203 int offset = 0; |
195 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { | 204 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { |
196 ++offset; | 205 ++offset; |
197 if (pos + 1 < data.length() && data[pos + 1] == '\n') | 206 if (pos + 1 < data.length() && data[pos + 1] == '\n') |
198 ++offset; | 207 ++offset; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) | 394 if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) |
386 return false; | 395 return false; |
387 if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) | 396 if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) |
388 return false; | 397 return false; |
389 if (!base::StringToInt(byte_range_instance_size, content_range_instance_size)) | 398 if (!base::StringToInt(byte_range_instance_size, content_range_instance_size)) |
390 return false; | 399 return false; |
391 return true; | 400 return true; |
392 } | 401 } |
393 | 402 |
394 } // namespace webkit_glue | 403 } // namespace webkit_glue |
OLD | NEW |