Home | History | Annotate | Download | only in blob
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "webkit/browser/blob/blob_url_request_job_factory.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "base/strings/string_util.h"
     11 #include "net/base/request_priority.h"
     12 #include "net/url_request/url_request_context.h"
     13 #include "net/url_request/url_request_job_factory.h"
     14 #include "webkit/browser/blob/blob_data_handle.h"
     15 #include "webkit/browser/blob/blob_storage_context.h"
     16 #include "webkit/browser/blob/blob_url_request_job.h"
     17 #include "webkit/browser/fileapi/file_system_context.h"
     18 
     19 namespace webkit_blob {
     20 
     21 namespace {
     22 
     23 int kUserDataKey;  // The value is not important, the addr is a key.
     24 
     25 BlobDataHandle* GetRequestedBlobDataHandle(net::URLRequest* request) {
     26   return static_cast<BlobDataHandle*>(request->GetUserData(&kUserDataKey));
     27 }
     28 
     29 }  // namespace
     30 
     31 // static
     32 scoped_ptr<net::URLRequest> BlobProtocolHandler::CreateBlobRequest(
     33     scoped_ptr<BlobDataHandle> blob_data_handle,
     34     const net::URLRequestContext* request_context,
     35     net::URLRequest::Delegate* request_delegate) {
     36   const GURL kBlobUrl("blob://see_user_data/");
     37   scoped_ptr<net::URLRequest> request = request_context->CreateRequest(
     38       kBlobUrl, net::DEFAULT_PRIORITY, request_delegate);
     39   SetRequestedBlobDataHandle(request.get(), blob_data_handle.Pass());
     40   return request.Pass();
     41 }
     42 
     43 // static
     44 void BlobProtocolHandler::SetRequestedBlobDataHandle(
     45     net::URLRequest* request,
     46     scoped_ptr<BlobDataHandle> blob_data_handle) {
     47   request->SetUserData(&kUserDataKey, blob_data_handle.release());
     48 }
     49 
     50 BlobProtocolHandler::BlobProtocolHandler(
     51     BlobStorageContext* context,
     52     fileapi::FileSystemContext* file_system_context,
     53     base::MessageLoopProxy* loop_proxy)
     54     : file_system_context_(file_system_context),
     55       file_loop_proxy_(loop_proxy) {
     56   if (context)
     57     context_ = context->AsWeakPtr();
     58 }
     59 
     60 BlobProtocolHandler::~BlobProtocolHandler() {
     61 }
     62 
     63 net::URLRequestJob* BlobProtocolHandler::MaybeCreateJob(
     64     net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
     65   return new webkit_blob::BlobURLRequestJob(
     66       request, network_delegate, LookupBlobData(request),
     67       file_system_context_, file_loop_proxy_);
     68 }
     69 
     70 scoped_refptr<webkit_blob::BlobData>
     71 BlobProtocolHandler::LookupBlobData(net::URLRequest* request) const {
     72   BlobDataHandle* blob_data_handle = GetRequestedBlobDataHandle(request);
     73   if (blob_data_handle)
     74     return blob_data_handle->data();
     75   if (!context_.get())
     76     return NULL;
     77 
     78   // Support looking up based on uuid, the FeedbackExtensionAPI relies on this.
     79   // TODO(michaeln): Replace this use case and others like it with a BlobReader
     80   // impl that does not depend on urlfetching to perform this function.
     81   const std::string kPrefix("blob:uuid/");
     82   if (!StartsWithASCII(request->url().spec(), kPrefix, true))
     83     return NULL;
     84   std::string uuid = request->url().spec().substr(kPrefix.length());
     85   scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(uuid);
     86   return handle.get() ? handle->data() : NULL;
     87 }
     88 
     89 }  // namespace webkit_blob
     90