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_util.h" | 8 #include "base/string_util.h" |
9 #include "net/base/net_util.h" | 9 #include "net/base/net_util.h" |
10 #include "net/http/http_util.h" | 10 #include "net/http/http_util.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 processing_headers_ = false; | 118 processing_headers_ = false; |
119 } else { | 119 } else { |
120 // Get more data before trying again. | 120 // Get more data before trying again. |
121 return; | 121 return; |
122 } | 122 } |
123 } | 123 } |
124 DCHECK(!processing_headers_); | 124 DCHECK(!processing_headers_); |
125 | 125 |
126 size_t boundary_pos; | 126 size_t boundary_pos; |
127 while ((boundary_pos = FindBoundary()) != std::string::npos) { | 127 while ((boundary_pos = FindBoundary()) != std::string::npos) { |
128 if (boundary_pos > 0) { | 128 if (boundary_pos > 0 && client_) { |
129 // Send the last data chunk. | 129 // Send the last data chunk. |
130 client_->didReceiveData(loader_, | 130 client_->didReceiveData(loader_, |
131 data_.data(), | 131 data_.data(), |
132 static_cast<int>(boundary_pos)); | 132 static_cast<int>(boundary_pos)); |
133 } | 133 } |
134 size_t boundary_end_pos = boundary_pos + boundary_.length(); | 134 size_t boundary_end_pos = boundary_pos + boundary_.length(); |
135 if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { | 135 if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { |
136 // This was the last boundary so we can stop processing. | 136 // This was the last boundary so we can stop processing. |
137 stop_sending_ = true; | 137 stop_sending_ = true; |
138 data_.clear(); | 138 data_.clear(); |
(...skipping 12 matching lines...) Expand all Loading... |
151 } | 151 } |
152 | 152 |
153 // At this point, we should send over any data we have, but keep enough data | 153 // At this point, we should send over any data we have, but keep enough data |
154 // buffered to handle a boundary that may have been truncated. | 154 // buffered to handle a boundary that may have been truncated. |
155 if (!processing_headers_ && data_.length() > boundary_.length()) { | 155 if (!processing_headers_ && data_.length() > boundary_.length()) { |
156 // If the last character is a new line character, go ahead and just send | 156 // If the last character is a new line character, go ahead and just send |
157 // everything we have buffered. This matches an optimization in Gecko. | 157 // everything we have buffered. This matches an optimization in Gecko. |
158 int send_length = data_.length() - boundary_.length(); | 158 int send_length = data_.length() - boundary_.length(); |
159 if (data_[data_.length() - 1] == '\n') | 159 if (data_[data_.length() - 1] == '\n') |
160 send_length = data_.length(); | 160 send_length = data_.length(); |
161 client_->didReceiveData(loader_, data_.data(), send_length); | 161 if (client_) |
| 162 client_->didReceiveData(loader_, data_.data(), send_length); |
162 data_ = data_.substr(send_length); | 163 data_ = data_.substr(send_length); |
163 } | 164 } |
164 } | 165 } |
165 | 166 |
166 void MultipartResponseDelegate::OnCompletedRequest() { | 167 void MultipartResponseDelegate::OnCompletedRequest() { |
167 // If we have any pending data and we're not in a header, go ahead and send | 168 // If we have any pending data and we're not in a header, go ahead and send |
168 // it to WebCore. | 169 // it to WebCore. |
169 if (!processing_headers_ && !data_.empty()) { | 170 if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) { |
170 client_->didReceiveData(loader_, | 171 client_->didReceiveData(loader_, |
171 data_.data(), | 172 data_.data(), |
172 static_cast<int>(data_.length())); | 173 static_cast<int>(data_.length())); |
173 } | 174 } |
174 } | 175 } |
175 | 176 |
176 int MultipartResponseDelegate::PushOverLine(const std::string& data, | 177 int MultipartResponseDelegate::PushOverLine(const std::string& data, |
177 size_t pos) { | 178 size_t pos) { |
178 int offset = 0; | 179 int offset = 0; |
179 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { | 180 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 WebString::fromUTF8(value)); | 241 WebString::fromUTF8(value)); |
241 } | 242 } |
242 } | 243 } |
243 // To avoid recording every multipart load as a separate visit in | 244 // To avoid recording every multipart load as a separate visit in |
244 // the history database, we want to keep track of whether the response | 245 // the history database, we want to keep track of whether the response |
245 // is part of a multipart payload. We do want to record the first visit, | 246 // is part of a multipart payload. We do want to record the first visit, |
246 // so we only set isMultipartPayload to true after the first visit. | 247 // so we only set isMultipartPayload to true after the first visit. |
247 response.setIsMultipartPayload(has_sent_first_response_); | 248 response.setIsMultipartPayload(has_sent_first_response_); |
248 has_sent_first_response_ = true; | 249 has_sent_first_response_ = true; |
249 // Send the response! | 250 // Send the response! |
250 client_->didReceiveResponse(loader_, response); | 251 if (client_) |
| 252 client_->didReceiveResponse(loader_, response); |
251 | 253 |
252 return true; | 254 return true; |
253 } | 255 } |
254 | 256 |
255 // Boundaries are supposed to be preceeded with --, but it looks like gecko | 257 // Boundaries are supposed to be preceeded with --, but it looks like gecko |
256 // doesn't require the dashes to exist. See nsMultiMixedConv::FindToken. | 258 // doesn't require the dashes to exist. See nsMultiMixedConv::FindToken. |
257 size_t MultipartResponseDelegate::FindBoundary() { | 259 size_t MultipartResponseDelegate::FindBoundary() { |
258 size_t boundary_pos = data_.find(boundary_); | 260 size_t boundary_pos = data_.find(boundary_); |
259 if (boundary_pos != std::string::npos) { | 261 if (boundary_pos != std::string::npos) { |
260 // Back up over -- for backwards compat | 262 // Back up over -- for backwards compat |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 byte_range_upper_bound_characters); | 353 byte_range_upper_bound_characters); |
352 | 354 |
353 if (!StringToInt(byte_range_lower_bound, content_range_lower_bound)) | 355 if (!StringToInt(byte_range_lower_bound, content_range_lower_bound)) |
354 return false; | 356 return false; |
355 if (!StringToInt(byte_range_upper_bound, content_range_upper_bound)) | 357 if (!StringToInt(byte_range_upper_bound, content_range_upper_bound)) |
356 return false; | 358 return false; |
357 return true; | 359 return true; |
358 } | 360 } |
359 | 361 |
360 } // namespace webkit_glue | 362 } // namespace webkit_glue |
OLD | NEW |