| 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 |