| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/buffered_resource_handler.h" | 5 #include "content/browser/renderer_host/buffered_resource_handler.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 std::string mime_type; | 157 std::string mime_type; |
| 158 request_->GetMimeType(&mime_type); | 158 request_->GetMimeType(&mime_type); |
| 159 | 159 |
| 160 std::string content_type_options; | 160 std::string content_type_options; |
| 161 request_->GetResponseHeaderByName("x-content-type-options", | 161 request_->GetResponseHeaderByName("x-content-type-options", |
| 162 &content_type_options); | 162 &content_type_options); |
| 163 | 163 |
| 164 const bool sniffing_blocked = | 164 const bool sniffing_blocked = |
| 165 LowerCaseEqualsASCII(content_type_options, "nosniff"); | 165 LowerCaseEqualsASCII(content_type_options, "nosniff"); |
| 166 const bool not_modified_status = | 166 const bool not_modified_status = |
| 167 response_->headers && response_->headers->response_code() == 304; | 167 (response_->head.headers && |
| 168 response_->head.headers->response_code() == 304); |
| 168 const bool we_would_like_to_sniff = not_modified_status ? | 169 const bool we_would_like_to_sniff = not_modified_status ? |
| 169 false : net::ShouldSniffMimeType(request_->url(), mime_type); | 170 false : net::ShouldSniffMimeType(request_->url(), mime_type); |
| 170 | 171 |
| 171 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type); | 172 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type); |
| 172 | 173 |
| 173 if (!sniffing_blocked && we_would_like_to_sniff) { | 174 if (!sniffing_blocked && we_would_like_to_sniff) { |
| 174 // We're going to look at the data before deciding what the content type | 175 // We're going to look at the data before deciding what the content type |
| 175 // is. That means we need to delay sending the ResponseStarted message | 176 // is. That means we need to delay sending the ResponseStarted message |
| 176 // over the IPC channel. | 177 // over the IPC channel. |
| 177 sniff_content_ = true; | 178 sniff_content_ = true; |
| 178 VLOG(1) << "To buffer: " << request_->url().spec(); | 179 VLOG(1) << "To buffer: " << request_->url().spec(); |
| 179 return true; | 180 return true; |
| 180 } | 181 } |
| 181 | 182 |
| 182 if (sniffing_blocked && mime_type.empty() && !not_modified_status) { | 183 if (sniffing_blocked && mime_type.empty() && !not_modified_status) { |
| 183 // Ugg. The server told us not to sniff the content but didn't give us a | 184 // Ugg. The server told us not to sniff the content but didn't give us a |
| 184 // mime type. What's a browser to do? Turns out, we're supposed to treat | 185 // mime type. What's a browser to do? Turns out, we're supposed to treat |
| 185 // the response as "text/plain". This is the most secure option. | 186 // the response as "text/plain". This is the most secure option. |
| 186 mime_type.assign("text/plain"); | 187 mime_type.assign("text/plain"); |
| 187 response_->mime_type.assign(mime_type); | 188 response_->head.mime_type.assign(mime_type); |
| 188 } | 189 } |
| 189 | 190 |
| 190 if (!not_modified_status && ShouldWaitForPlugins()) { | 191 if (!not_modified_status && ShouldWaitForPlugins()) { |
| 191 wait_for_plugins_ = true; | 192 wait_for_plugins_ = true; |
| 192 return true; | 193 return true; |
| 193 } | 194 } |
| 194 | 195 |
| 195 return false; | 196 return false; |
| 196 } | 197 } |
| 197 | 198 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 224 // SniffMimeType() returns false if there is not enough data to determine | 225 // SniffMimeType() returns false if there is not enough data to determine |
| 225 // the mime type. However, even if it returns false, it returns a new type | 226 // the mime type. However, even if it returns false, it returns a new type |
| 226 // that is probably better than the current one. | 227 // that is probably better than the current one. |
| 227 DCHECK_LT(bytes_read_, net::kMaxBytesToSniff); | 228 DCHECK_LT(bytes_read_, net::kMaxBytesToSniff); |
| 228 if (!finished_) { | 229 if (!finished_) { |
| 229 buffering_ = true; | 230 buffering_ = true; |
| 230 return true; | 231 return true; |
| 231 } | 232 } |
| 232 } | 233 } |
| 233 sniff_content_ = false; | 234 sniff_content_ = false; |
| 234 response_->mime_type.assign(new_type); | 235 response_->head.mime_type.assign(new_type); |
| 235 | 236 |
| 236 // We just sniffed the mime type, maybe there is a doctype to process. | 237 // We just sniffed the mime type, maybe there is a doctype to process. |
| 237 if (ShouldWaitForPlugins()) | 238 if (ShouldWaitForPlugins()) |
| 238 wait_for_plugins_ = true; | 239 wait_for_plugins_ = true; |
| 239 } | 240 } |
| 240 | 241 |
| 241 buffering_ = false; | 242 buffering_ = false; |
| 242 | 243 |
| 243 if (wait_for_plugins_) | 244 if (wait_for_plugins_) |
| 244 return true; | 245 return true; |
| 245 | 246 |
| 246 return false; | 247 return false; |
| 247 } | 248 } |
| 248 | 249 |
| 249 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, | 250 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, |
| 250 bool* defer) { | 251 bool* defer) { |
| 251 ResourceRequestInfoImpl* info = | 252 ResourceRequestInfoImpl* info = |
| 252 ResourceRequestInfoImpl::ForRequest(request_); | 253 ResourceRequestInfoImpl::ForRequest(request_); |
| 253 std::string mime_type; | 254 std::string mime_type; |
| 254 request_->GetMimeType(&mime_type); | 255 request_->GetMimeType(&mime_type); |
| 255 | 256 |
| 256 if (mime_type == "application/x-x509-user-cert") { | 257 if (mime_type == "application/x-x509-user-cert") { |
| 257 // Let X.509 certs be handled by the X509UserCertResourceHandler. | 258 // Let X.509 certs be handled by the X509UserCertResourceHandler. |
| 258 | 259 |
| 259 // This is entirely similar to how DownloadResourceHandler works except we | 260 // This is entirely similar to how DownloadResourceHandler works except we |
| 260 // are doing it for an X.509 client certificates. | 261 // are doing it for an X.509 client certificates. |
| 261 // TODO(darin): This does not belong here! | 262 // TODO(darin): This does not belong here! |
| 262 | 263 |
| 263 if (response_->headers && // Can be NULL if FTP. | 264 if (response_->head.headers && // Can be NULL if FTP. |
| 264 response_->headers->response_code() / 100 != 2) { | 265 response_->head.headers->response_code() / 100 != 2) { |
| 265 // The response code indicates that this is an error page, but we are | 266 // The response code indicates that this is an error page, but we are |
| 266 // expecting an X.509 user certificate. We follow Firefox here and show | 267 // expecting an X.509 user certificate. We follow Firefox here and show |
| 267 // our own error page instead of handling the error page as a | 268 // our own error page instead of handling the error page as a |
| 268 // certificate. | 269 // certificate. |
| 269 // TODO(abarth): We should abstract the response_code test, but this kind | 270 // TODO(abarth): We should abstract the response_code test, but this kind |
| 270 // of check is scattered throughout our codebase. | 271 // of check is scattered throughout our codebase. |
| 271 request_->CancelWithError(net::ERR_FILE_NOT_FOUND); | 272 request_->CancelWithError(net::ERR_FILE_NOT_FOUND); |
| 272 return false; | 273 return false; |
| 273 } | 274 } |
| 274 | 275 |
| 275 scoped_ptr<ResourceHandler> handler( | 276 scoped_ptr<ResourceHandler> handler( |
| 276 new X509UserCertResourceHandler(request_, | 277 new X509UserCertResourceHandler(request_, |
| 277 info->GetChildID(), | 278 info->GetChildID(), |
| 278 info->GetRouteID())); | 279 info->GetRouteID())); |
| 279 | 280 |
| 280 return UseAlternateResourceHandler(request_id, handler.Pass(), defer); | 281 return UseAlternateResourceHandler(request_id, handler.Pass(), defer); |
| 281 } | 282 } |
| 282 | 283 |
| 283 if (info->allow_download() && ShouldDownload(NULL)) { | 284 if (info->allow_download() && ShouldDownload(NULL)) { |
| 284 // Forward the data to the download thread. | 285 // Forward the data to the download thread. |
| 285 | 286 if (response_->head.headers && // Can be NULL if FTP. |
| 286 if (response_->headers && // Can be NULL if FTP. | 287 response_->head.headers->response_code() / 100 != 2) { |
| 287 response_->headers->response_code() / 100 != 2) { | |
| 288 // The response code indicates that this is an error page, but we don't | 288 // The response code indicates that this is an error page, but we don't |
| 289 // know how to display the content. We follow Firefox here and show our | 289 // know how to display the content. We follow Firefox here and show our |
| 290 // own error page instead of triggering a download. | 290 // own error page instead of triggering a download. |
| 291 // TODO(abarth): We should abstract the response_code test, but this kind | 291 // TODO(abarth): We should abstract the response_code test, but this kind |
| 292 // of check is scattered throughout our codebase. | 292 // of check is scattered throughout our codebase. |
| 293 request_->CancelWithError(net::ERR_FILE_NOT_FOUND); | 293 request_->CancelWithError(net::ERR_FILE_NOT_FOUND); |
| 294 return false; | 294 return false; |
| 295 } | 295 } |
| 296 | 296 |
| 297 info->set_is_download(true); | 297 info->set_is_download(true); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 321 PluginServiceImpl::GetInstance()->GetPlugins( | 321 PluginServiceImpl::GetInstance()->GetPlugins( |
| 322 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, AsWeakPtr())); | 322 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, AsWeakPtr())); |
| 323 return true; | 323 return true; |
| 324 } | 324 } |
| 325 | 325 |
| 326 // This test mirrors the decision that WebKit makes in | 326 // This test mirrors the decision that WebKit makes in |
| 327 // WebFrameLoaderClient::dispatchDecidePolicyForMIMEType. | 327 // WebFrameLoaderClient::dispatchDecidePolicyForMIMEType. |
| 328 bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) { | 328 bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) { |
| 329 if (need_plugin_list) | 329 if (need_plugin_list) |
| 330 *need_plugin_list = false; | 330 *need_plugin_list = false; |
| 331 std::string type = StringToLowerASCII(response_->mime_type); | 331 std::string type = StringToLowerASCII(response_->head.mime_type); |
| 332 | 332 |
| 333 // First, examine Content-Disposition. | 333 // First, examine Content-Disposition. |
| 334 std::string disposition; | 334 std::string disposition; |
| 335 request_->GetResponseHeaderByName("content-disposition", &disposition); | 335 request_->GetResponseHeaderByName("content-disposition", &disposition); |
| 336 if (!disposition.empty()) { | 336 if (!disposition.empty()) { |
| 337 net::HttpContentDisposition parsed_disposition(disposition, std::string()); | 337 net::HttpContentDisposition parsed_disposition(disposition, std::string()); |
| 338 if (parsed_disposition.is_attachment()) | 338 if (parsed_disposition.is_attachment()) |
| 339 return true; | 339 return true; |
| 340 } | 340 } |
| 341 | 341 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 | 440 |
| 441 bool defer = false; | 441 bool defer = false; |
| 442 if (!CompleteResponseStarted(request_id, &defer)) { | 442 if (!CompleteResponseStarted(request_id, &defer)) { |
| 443 controller()->Cancel(); | 443 controller()->Cancel(); |
| 444 } else if (!defer && needs_resume) { | 444 } else if (!defer && needs_resume) { |
| 445 controller()->Resume(); | 445 controller()->Resume(); |
| 446 } | 446 } |
| 447 } | 447 } |
| 448 | 448 |
| 449 } // namespace content | 449 } // namespace content |
| OLD | NEW |