| 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/loader/mime_sniffing_resource_handler.h" | 5 #include "content/browser/loader/mime_sniffing_resource_handler.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 ResourceController* controller) { | 92 ResourceController* controller) { |
| 93 ResourceHandler::SetController(controller); | 93 ResourceHandler::SetController(controller); |
| 94 | 94 |
| 95 // Downstream handlers see the MimeSniffingResourceHandler as their | 95 // Downstream handlers see the MimeSniffingResourceHandler as their |
| 96 // ResourceController, which allows it to consume part or all of the resource | 96 // ResourceController, which allows it to consume part or all of the resource |
| 97 // response, and then later replay it to downstream handler. | 97 // response, and then later replay it to downstream handler. |
| 98 DCHECK(next_handler_.get()); | 98 DCHECK(next_handler_.get()); |
| 99 next_handler_->SetController(this); | 99 next_handler_->SetController(this); |
| 100 } | 100 } |
| 101 | 101 |
| 102 bool MimeSniffingResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 102 void MimeSniffingResourceHandler::OnWillStart(const GURL& url, |
| 103 bool* defer_or_cancel) { |
| 103 const char* accept_value = nullptr; | 104 const char* accept_value = nullptr; |
| 104 switch (GetRequestInfo()->GetResourceType()) { | 105 switch (GetRequestInfo()->GetResourceType()) { |
| 105 case RESOURCE_TYPE_MAIN_FRAME: | 106 case RESOURCE_TYPE_MAIN_FRAME: |
| 106 case RESOURCE_TYPE_SUB_FRAME: | 107 case RESOURCE_TYPE_SUB_FRAME: |
| 107 accept_value = kFrameAcceptHeader; | 108 accept_value = kFrameAcceptHeader; |
| 108 break; | 109 break; |
| 109 case RESOURCE_TYPE_STYLESHEET: | 110 case RESOURCE_TYPE_STYLESHEET: |
| 110 accept_value = kStylesheetAcceptHeader; | 111 accept_value = kStylesheetAcceptHeader; |
| 111 break; | 112 break; |
| 112 case RESOURCE_TYPE_FAVICON: | 113 case RESOURCE_TYPE_FAVICON: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 129 accept_value = kDefaultAcceptHeader; | 130 accept_value = kDefaultAcceptHeader; |
| 130 break; | 131 break; |
| 131 case RESOURCE_TYPE_LAST_TYPE: | 132 case RESOURCE_TYPE_LAST_TYPE: |
| 132 NOTREACHED(); | 133 NOTREACHED(); |
| 133 break; | 134 break; |
| 134 } | 135 } |
| 135 | 136 |
| 136 // The false parameter prevents overwriting an existing accept header value, | 137 // The false parameter prevents overwriting an existing accept header value, |
| 137 // which is needed because JS can manually set an accept header on an XHR. | 138 // which is needed because JS can manually set an accept header on an XHR. |
| 138 request()->SetExtraRequestHeaderByName(kAcceptHeader, accept_value, false); | 139 request()->SetExtraRequestHeaderByName(kAcceptHeader, accept_value, false); |
| 139 return next_handler_->OnWillStart(url, defer); | 140 next_handler_->OnWillStart(url, defer_or_cancel); |
| 140 } | 141 } |
| 141 | 142 |
| 142 bool MimeSniffingResourceHandler::OnResponseStarted(ResourceResponse* response, | 143 void MimeSniffingResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 143 bool* defer) { | 144 bool* defer_or_cancel) { |
| 144 DCHECK_EQ(STATE_STARTING, state_); | 145 DCHECK_EQ(STATE_STARTING, state_); |
| 145 response_ = response; | 146 response_ = response; |
| 146 | 147 |
| 147 state_ = STATE_BUFFERING; | 148 state_ = STATE_BUFFERING; |
| 148 // A 304 response should not contain a Content-Type header (RFC 7232 section | 149 // A 304 response should not contain a Content-Type header (RFC 7232 section |
| 149 // 4.1). The following code may incorrectly attempt to add a Content-Type to | 150 // 4.1). The following code may incorrectly attempt to add a Content-Type to |
| 150 // the response, and so must be skipped for 304 responses. | 151 // the response, and so must be skipped for 304 responses. |
| 151 if (!(response_->head.headers.get() && | 152 if (!(response_->head.headers.get() && |
| 152 response_->head.headers->response_code() == 304)) { | 153 response_->head.headers->response_code() == 304)) { |
| 153 if (ShouldSniffContent()) | 154 if (ShouldSniffContent()) |
| 154 return true; | 155 return; |
| 155 | 156 |
| 156 if (response_->head.mime_type.empty()) { | 157 if (response_->head.mime_type.empty()) { |
| 157 // Ugg. The server told us not to sniff the content but didn't give us a | 158 // Ugg. The server told us not to sniff the content but didn't give us a |
| 158 // mime type. What's a browser to do? Turns out, we're supposed to | 159 // mime type. What's a browser to do? Turns out, we're supposed to |
| 159 // treat the response as "text/plain". This is the most secure option. | 160 // treat the response as "text/plain". This is the most secure option. |
| 160 response_->head.mime_type.assign("text/plain"); | 161 response_->head.mime_type.assign("text/plain"); |
| 161 } | 162 } |
| 162 | 163 |
| 163 // Treat feed types as text/plain. | 164 // Treat feed types as text/plain. |
| 164 if (response_->head.mime_type == "application/rss+xml" || | 165 if (response_->head.mime_type == "application/rss+xml" || |
| 165 response_->head.mime_type == "application/atom+xml") { | 166 response_->head.mime_type == "application/atom+xml") { |
| 166 response_->head.mime_type.assign("text/plain"); | 167 response_->head.mime_type.assign("text/plain"); |
| 167 } | 168 } |
| 168 } | 169 } |
| 169 | 170 |
| 170 return ProcessState(defer); | 171 ProcessState(defer_or_cancel); |
| 171 } | 172 } |
| 172 | 173 |
| 173 bool MimeSniffingResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 174 bool MimeSniffingResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 174 int* buf_size, | 175 int* buf_size, |
| 175 int min_size) { | 176 int min_size) { |
| 176 if (state_ == STATE_STREAMING) | 177 if (state_ == STATE_STREAMING) |
| 177 return next_handler_->OnWillRead(buf, buf_size, min_size); | 178 return next_handler_->OnWillRead(buf, buf_size, min_size); |
| 178 | 179 |
| 179 DCHECK_EQ(-1, min_size); | 180 DCHECK_EQ(-1, min_size); |
| 180 | 181 |
| 181 if (read_buffer_.get()) { | 182 if (read_buffer_.get()) { |
| 182 CHECK_LT(bytes_read_, read_buffer_size_); | 183 CHECK_LT(bytes_read_, read_buffer_size_); |
| 183 *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_); | 184 *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_); |
| 184 *buf_size = read_buffer_size_ - bytes_read_; | 185 *buf_size = read_buffer_size_ - bytes_read_; |
| 185 } else { | 186 } else { |
| 186 if (!next_handler_->OnWillRead(buf, buf_size, min_size)) | 187 if (!next_handler_->OnWillRead(buf, buf_size, min_size)) |
| 187 return false; | 188 return false; |
| 188 | 189 |
| 189 read_buffer_ = *buf; | 190 read_buffer_ = *buf; |
| 190 read_buffer_size_ = *buf_size; | 191 read_buffer_size_ = *buf_size; |
| 191 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2); | 192 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2); |
| 192 } | 193 } |
| 193 return true; | 194 return true; |
| 194 } | 195 } |
| 195 | 196 |
| 196 bool MimeSniffingResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 197 void MimeSniffingResourceHandler::OnReadCompleted(int bytes_read, |
| 197 if (state_ == STATE_STREAMING) | 198 bool* defer_or_cancel) { |
| 198 return next_handler_->OnReadCompleted(bytes_read, defer); | 199 if (state_ == STATE_STREAMING) { |
| 200 next_handler_->OnReadCompleted(bytes_read, defer_or_cancel); |
| 201 return; |
| 202 } |
| 199 | 203 |
| 200 DCHECK_EQ(state_, STATE_BUFFERING); | 204 DCHECK_EQ(state_, STATE_BUFFERING); |
| 201 bytes_read_ += bytes_read; | 205 bytes_read_ += bytes_read; |
| 202 | 206 |
| 203 const std::string& type_hint = response_->head.mime_type; | 207 const std::string& type_hint = response_->head.mime_type; |
| 204 | 208 |
| 205 std::string new_type; | 209 std::string new_type; |
| 206 bool made_final_decision = | 210 bool made_final_decision = |
| 207 net::SniffMimeType(read_buffer_->data(), bytes_read_, request()->url(), | 211 net::SniffMimeType(read_buffer_->data(), bytes_read_, request()->url(), |
| 208 type_hint, &new_type); | 212 type_hint, &new_type); |
| 209 | 213 |
| 210 // SniffMimeType() returns false if there is not enough data to determine | 214 // SniffMimeType() returns false if there is not enough data to determine |
| 211 // the mime type. However, even if it returns false, it returns a new type | 215 // the mime type. However, even if it returns false, it returns a new type |
| 212 // that is probably better than the current one. | 216 // that is probably better than the current one. |
| 213 response_->head.mime_type.assign(new_type); | 217 response_->head.mime_type.assign(new_type); |
| 214 | 218 |
| 215 if (!made_final_decision && (bytes_read > 0)) | 219 if (!made_final_decision && (bytes_read > 0)) |
| 216 return true; | 220 return; |
| 217 | 221 |
| 218 return ProcessState(defer); | 222 ProcessState(defer_or_cancel); |
| 219 } | 223 } |
| 220 | 224 |
| 221 void MimeSniffingResourceHandler::OnResponseCompleted( | 225 void MimeSniffingResourceHandler::OnResponseCompleted( |
| 222 const net::URLRequestStatus& status, | 226 const net::URLRequestStatus& status, |
| 223 bool* defer) { | 227 bool* defer) { |
| 224 // Upon completion, act like a pass-through handler in case the downstream | 228 // Upon completion, act like a pass-through handler in case the downstream |
| 225 // handler defers OnResponseCompleted. | 229 // handler defers OnResponseCompleted. |
| 226 state_ = STATE_STREAMING; | 230 state_ = STATE_STREAMING; |
| 227 | 231 |
| 228 next_handler_->OnResponseCompleted(status, defer); | 232 next_handler_->OnResponseCompleted(status, defer); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 254 | 258 |
| 255 void MimeSniffingResourceHandler::CancelAndIgnore() { | 259 void MimeSniffingResourceHandler::CancelAndIgnore() { |
| 256 controller()->CancelAndIgnore(); | 260 controller()->CancelAndIgnore(); |
| 257 } | 261 } |
| 258 | 262 |
| 259 void MimeSniffingResourceHandler::CancelWithError(int error_code) { | 263 void MimeSniffingResourceHandler::CancelWithError(int error_code) { |
| 260 controller()->CancelWithError(error_code); | 264 controller()->CancelWithError(error_code); |
| 261 } | 265 } |
| 262 | 266 |
| 263 void MimeSniffingResourceHandler::AdvanceState() { | 267 void MimeSniffingResourceHandler::AdvanceState() { |
| 264 bool defer = false; | 268 bool defer_or_cancel = false; |
| 265 if (!ProcessState(&defer)) { | 269 ProcessState(&defer_or_cancel); |
| 266 Cancel(); | 270 if (!defer_or_cancel) { |
| 267 } else if (!defer) { | |
| 268 DCHECK_EQ(STATE_STREAMING, state_); | 271 DCHECK_EQ(STATE_STREAMING, state_); |
| 269 controller()->Resume(); | 272 controller()->Resume(); |
| 270 } | 273 } |
| 271 } | 274 } |
| 272 | 275 |
| 273 bool MimeSniffingResourceHandler::ProcessState(bool* defer) { | 276 void MimeSniffingResourceHandler::ProcessState(bool* defer_or_cancel) { |
| 274 bool return_value = true; | 277 while (!*defer_or_cancel && state_ != STATE_STREAMING) { |
| 275 while (!*defer && return_value && state_ != STATE_STREAMING) { | |
| 276 switch (state_) { | 278 switch (state_) { |
| 277 case STATE_BUFFERING: | 279 case STATE_BUFFERING: |
| 278 return_value = MaybeIntercept(defer); | 280 MaybeIntercept(defer_or_cancel); |
| 279 break; | 281 break; |
| 280 case STATE_INTERCEPTION_CHECK_DONE: | 282 case STATE_INTERCEPTION_CHECK_DONE: |
| 281 return_value = ReplayResponseReceived(defer); | 283 ReplayResponseReceived(defer_or_cancel); |
| 282 break; | 284 break; |
| 283 case STATE_REPLAYING_RESPONSE_RECEIVED: | 285 case STATE_REPLAYING_RESPONSE_RECEIVED: |
| 284 return_value = ReplayReadCompleted(defer); | 286 ReplayReadCompleted(defer_or_cancel); |
| 285 break; | 287 break; |
| 286 default: | 288 default: |
| 287 NOTREACHED(); | 289 NOTREACHED(); |
| 288 break; | 290 break; |
| 289 } | 291 } |
| 290 } | 292 } |
| 291 return return_value; | |
| 292 } | 293 } |
| 293 | 294 |
| 294 bool MimeSniffingResourceHandler::MaybeIntercept(bool* defer) { | 295 void MimeSniffingResourceHandler::MaybeIntercept(bool* defer_or_cancel) { |
| 295 DCHECK_EQ(STATE_BUFFERING, state_); | 296 DCHECK_EQ(STATE_BUFFERING, state_); |
| 296 // If a request that can be intercepted failed the check for interception | 297 // If a request that can be intercepted failed the check for interception |
| 297 // step, it should be canceled. | 298 // step, it should be canceled. |
| 298 if (!MaybeStartInterception(defer)) | 299 MaybeStartInterception(defer_or_cancel); |
| 299 return false; | |
| 300 | 300 |
| 301 if (!*defer) | 301 if (!*defer_or_cancel) |
| 302 state_ = STATE_INTERCEPTION_CHECK_DONE; | 302 state_ = STATE_INTERCEPTION_CHECK_DONE; |
| 303 | |
| 304 return true; | |
| 305 } | 303 } |
| 306 | 304 |
| 307 bool MimeSniffingResourceHandler::ReplayResponseReceived(bool* defer) { | 305 void MimeSniffingResourceHandler::ReplayResponseReceived( |
| 306 bool* defer_or_cancel) { |
| 308 DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_); | 307 DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_); |
| 309 state_ = STATE_REPLAYING_RESPONSE_RECEIVED; | 308 state_ = STATE_REPLAYING_RESPONSE_RECEIVED; |
| 310 return next_handler_->OnResponseStarted(response_.get(), defer); | 309 next_handler_->OnResponseStarted(response_.get(), defer_or_cancel); |
| 311 } | 310 } |
| 312 | 311 |
| 313 bool MimeSniffingResourceHandler::ReplayReadCompleted(bool* defer) { | 312 void MimeSniffingResourceHandler::ReplayReadCompleted(bool* defer_or_cancel) { |
| 314 DCHECK_EQ(STATE_REPLAYING_RESPONSE_RECEIVED, state_); | 313 DCHECK_EQ(STATE_REPLAYING_RESPONSE_RECEIVED, state_); |
| 315 | 314 |
| 316 state_ = STATE_STREAMING; | 315 state_ = STATE_STREAMING; |
| 317 | 316 |
| 318 if (!read_buffer_.get()) | 317 if (!read_buffer_.get()) |
| 319 return true; | 318 return; |
| 320 | 319 |
| 321 bool result = next_handler_->OnReadCompleted(bytes_read_, defer); | 320 next_handler_->OnReadCompleted(bytes_read_, defer_or_cancel); |
| 322 | 321 |
| 323 read_buffer_ = nullptr; | 322 read_buffer_ = nullptr; |
| 324 read_buffer_size_ = 0; | 323 read_buffer_size_ = 0; |
| 325 bytes_read_ = 0; | 324 bytes_read_ = 0; |
| 326 | |
| 327 return result; | |
| 328 } | 325 } |
| 329 | 326 |
| 330 bool MimeSniffingResourceHandler::ShouldSniffContent() { | 327 bool MimeSniffingResourceHandler::ShouldSniffContent() { |
| 331 if (request_context_type_ == REQUEST_CONTEXT_TYPE_FETCH) { | 328 if (request_context_type_ == REQUEST_CONTEXT_TYPE_FETCH) { |
| 332 // MIME sniffing should be disabled for a request initiated by fetch(). | 329 // MIME sniffing should be disabled for a request initiated by fetch(). |
| 333 return false; | 330 return false; |
| 334 } | 331 } |
| 335 | 332 |
| 336 const std::string& mime_type = response_->head.mime_type; | 333 const std::string& mime_type = response_->head.mime_type; |
| 337 | 334 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 348 // We're going to look at the data before deciding what the content type | 345 // We're going to look at the data before deciding what the content type |
| 349 // is. That means we need to delay sending the ResponseStarted message | 346 // is. That means we need to delay sending the ResponseStarted message |
| 350 // over the IPC channel. | 347 // over the IPC channel. |
| 351 VLOG(1) << "To buffer: " << request()->url().spec(); | 348 VLOG(1) << "To buffer: " << request()->url().spec(); |
| 352 return true; | 349 return true; |
| 353 } | 350 } |
| 354 | 351 |
| 355 return false; | 352 return false; |
| 356 } | 353 } |
| 357 | 354 |
| 358 bool MimeSniffingResourceHandler::MaybeStartInterception(bool* defer) { | 355 void MimeSniffingResourceHandler::MaybeStartInterception( |
| 356 bool* defer_or_cancel) { |
| 359 if (!CanBeIntercepted()) | 357 if (!CanBeIntercepted()) |
| 360 return true; | 358 return; |
| 361 | 359 |
| 362 DCHECK(!response_->head.mime_type.empty()); | 360 DCHECK(!response_->head.mime_type.empty()); |
| 363 | 361 |
| 364 ResourceRequestInfoImpl* info = GetRequestInfo(); | 362 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 365 const std::string& mime_type = response_->head.mime_type; | 363 const std::string& mime_type = response_->head.mime_type; |
| 366 | 364 |
| 367 // https://crbug.com/568184 - Temporary hack to track servers that aren't | 365 // https://crbug.com/568184 - Temporary hack to track servers that aren't |
| 368 // setting Content-Disposition when sending x-x509-user-cert and expecting | 366 // setting Content-Disposition when sending x-x509-user-cert and expecting |
| 369 // the browser to automatically install certificates; this is being | 367 // the browser to automatically install certificates; this is being |
| 370 // deprecated and will be removed upon full <keygen> removal. | 368 // deprecated and will be removed upon full <keygen> removal. |
| 371 if (mime_type == "application/x-x509-user-cert" && response_->head.headers) { | 369 if (mime_type == "application/x-x509-user-cert" && response_->head.headers) { |
| 372 UMA_HISTOGRAM_BOOLEAN( | 370 UMA_HISTOGRAM_BOOLEAN( |
| 373 "UserCert.ContentDisposition", | 371 "UserCert.ContentDisposition", |
| 374 response_->head.headers->HasHeader("Content-Disposition")); | 372 response_->head.headers->HasHeader("Content-Disposition")); |
| 375 } | 373 } |
| 376 | 374 |
| 377 // Allow requests for object/embed tags to be intercepted as streams. | 375 // Allow requests for object/embed tags to be intercepted as streams. |
| 378 if (info->GetResourceType() == content::RESOURCE_TYPE_OBJECT) { | 376 if (info->GetResourceType() == content::RESOURCE_TYPE_OBJECT) { |
| 379 DCHECK(!info->allow_download()); | 377 DCHECK(!info->allow_download()); |
| 380 | 378 |
| 381 bool handled_by_plugin; | 379 bool handled_by_plugin; |
| 382 if (!CheckForPluginHandler(defer, &handled_by_plugin)) | 380 CheckForPluginHandler(defer_or_cancel, &handled_by_plugin); |
| 383 return false; | 381 if (handled_by_plugin || *defer_or_cancel) |
| 384 if (handled_by_plugin || *defer) | 382 return; |
| 385 return true; | |
| 386 } | 383 } |
| 387 | 384 |
| 388 if (!info->allow_download()) | 385 if (!info->allow_download()) |
| 389 return true; | 386 return; |
| 390 | 387 |
| 391 // info->allow_download() == true implies | 388 // info->allow_download() == true implies |
| 392 // info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME or | 389 // info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME or |
| 393 // info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME. | 390 // info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME. |
| 394 DCHECK(info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME || | 391 DCHECK(info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME || |
| 395 info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME); | 392 info->GetResourceType() == RESOURCE_TYPE_SUB_FRAME); |
| 396 | 393 |
| 397 bool must_download = MustDownload(); | 394 bool must_download = MustDownload(); |
| 398 if (!must_download) { | 395 if (!must_download) { |
| 399 if (mime_util::IsSupportedMimeType(mime_type)) | 396 if (mime_util::IsSupportedMimeType(mime_type)) |
| 400 return true; | 397 return; |
| 401 | 398 |
| 402 bool handled_by_plugin; | 399 bool handled_by_plugin; |
| 403 if (!CheckForPluginHandler(defer, &handled_by_plugin)) | 400 CheckForPluginHandler(defer_or_cancel, &handled_by_plugin); |
| 404 return false; | 401 if (handled_by_plugin || *defer_or_cancel) |
| 405 if (handled_by_plugin || *defer) | 402 return; |
| 406 return true; | |
| 407 } | 403 } |
| 408 | 404 |
| 409 // This request is a download. | 405 // This request is a download. |
| 410 | 406 |
| 411 if (!CheckResponseIsNotProvisional()) | 407 if (!CheckResponseIsNotProvisional()) { |
| 412 return false; | 408 *defer_or_cancel = true; |
| 409 controller()->Cancel(); |
| 410 return; |
| 411 } |
| 413 | 412 |
| 414 info->set_is_download(true); | 413 info->set_is_download(true); |
| 415 std::unique_ptr<ResourceHandler> handler( | 414 std::unique_ptr<ResourceHandler> handler( |
| 416 host_->CreateResourceHandlerForDownload(request(), | 415 host_->CreateResourceHandlerForDownload(request(), |
| 417 true, // is_content_initiated | 416 true, // is_content_initiated |
| 418 must_download, | 417 must_download, |
| 419 false /* is_new_request */)); | 418 false /* is_new_request */)); |
| 420 intercepting_handler_->UseNewHandler(std::move(handler), std::string()); | 419 intercepting_handler_->UseNewHandler(std::move(handler), std::string()); |
| 421 return true; | |
| 422 } | 420 } |
| 423 | 421 |
| 424 bool MimeSniffingResourceHandler::CheckForPluginHandler( | 422 void MimeSniffingResourceHandler::CheckForPluginHandler( |
| 425 bool* defer, | 423 bool* defer_or_cancel, |
| 426 bool* handled_by_plugin) { | 424 bool* handled_by_plugin) { |
| 427 *handled_by_plugin = false; | 425 *handled_by_plugin = false; |
| 428 #if defined(ENABLE_PLUGINS) | 426 #if defined(ENABLE_PLUGINS) |
| 429 ResourceRequestInfoImpl* info = GetRequestInfo(); | 427 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 430 bool allow_wildcard = false; | 428 bool allow_wildcard = false; |
| 431 bool stale; | 429 bool stale; |
| 432 WebPluginInfo plugin; | 430 WebPluginInfo plugin; |
| 433 bool has_plugin = plugin_service_->GetPluginInfo( | 431 bool has_plugin = plugin_service_->GetPluginInfo( |
| 434 info->GetChildID(), info->GetRenderFrameID(), info->GetContext(), | 432 info->GetChildID(), info->GetRenderFrameID(), info->GetContext(), |
| 435 request()->url(), url::Origin(), response_->head.mime_type, | 433 request()->url(), url::Origin(), response_->head.mime_type, |
| 436 allow_wildcard, &stale, &plugin, NULL); | 434 allow_wildcard, &stale, &plugin, NULL); |
| 437 | 435 |
| 438 if (stale) { | 436 if (stale) { |
| 439 // Refresh the plugins asynchronously. | 437 // Refresh the plugins asynchronously. |
| 440 plugin_service_->GetPlugins( | 438 plugin_service_->GetPlugins( |
| 441 base::Bind(&MimeSniffingResourceHandler::OnPluginsLoaded, | 439 base::Bind(&MimeSniffingResourceHandler::OnPluginsLoaded, |
| 442 weak_ptr_factory_.GetWeakPtr())); | 440 weak_ptr_factory_.GetWeakPtr())); |
| 443 request()->LogBlockedBy("MimeSniffingResourceHandler"); | 441 request()->LogBlockedBy("MimeSniffingResourceHandler"); |
| 444 *defer = true; | 442 *defer_or_cancel = true; |
| 445 return true; | 443 return; |
| 446 } | 444 } |
| 447 | 445 |
| 448 if (has_plugin && plugin.type != WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) { | 446 if (has_plugin && plugin.type != WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN) { |
| 449 *handled_by_plugin = true; | 447 *handled_by_plugin = true; |
| 450 return true; | 448 return; |
| 451 } | 449 } |
| 452 | 450 |
| 453 // Attempt to intercept the request as a stream. | 451 // Attempt to intercept the request as a stream. |
| 454 base::FilePath plugin_path; | 452 base::FilePath plugin_path; |
| 455 if (has_plugin) | 453 if (has_plugin) |
| 456 plugin_path = plugin.path; | 454 plugin_path = plugin.path; |
| 457 std::string payload; | 455 std::string payload; |
| 458 std::unique_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream( | 456 std::unique_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream( |
| 459 plugin_path, request(), response_.get(), &payload)); | 457 plugin_path, request(), response_.get(), &payload)); |
| 460 if (handler) { | 458 if (handler) { |
| 461 if (!CheckResponseIsNotProvisional()) | 459 if (!CheckResponseIsNotProvisional()) { |
| 462 return false; | 460 controller()->Cancel(); |
| 461 *defer_or_cancel = true; |
| 462 return; |
| 463 } |
| 463 *handled_by_plugin = true; | 464 *handled_by_plugin = true; |
| 464 intercepting_handler_->UseNewHandler(std::move(handler), payload); | 465 intercepting_handler_->UseNewHandler(std::move(handler), payload); |
| 465 } | 466 } |
| 466 #endif | 467 #endif |
| 467 return true; | 468 return; |
| 468 } | 469 } |
| 469 | 470 |
| 470 bool MimeSniffingResourceHandler::CanBeIntercepted() { | 471 bool MimeSniffingResourceHandler::CanBeIntercepted() { |
| 471 if (response_->head.headers.get() && | 472 if (response_->head.headers.get() && |
| 472 response_->head.headers->response_code() == 304) { | 473 response_->head.headers->response_code() == 304) { |
| 473 return false; | 474 return false; |
| 474 } | 475 } |
| 475 | 476 |
| 476 return true; | 477 return true; |
| 477 } | 478 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 | 517 |
| 517 void MimeSniffingResourceHandler::OnPluginsLoaded( | 518 void MimeSniffingResourceHandler::OnPluginsLoaded( |
| 518 const std::vector<WebPluginInfo>& plugins) { | 519 const std::vector<WebPluginInfo>& plugins) { |
| 519 // No longer blocking on the plugins being loaded. | 520 // No longer blocking on the plugins being loaded. |
| 520 request()->LogUnblocked(); | 521 request()->LogUnblocked(); |
| 521 if (state_ == STATE_BUFFERING) | 522 if (state_ == STATE_BUFFERING) |
| 522 AdvanceState(); | 523 AdvanceState(); |
| 523 } | 524 } |
| 524 | 525 |
| 525 } // namespace content | 526 } // namespace content |
| OLD | NEW |