Home | History | Annotate | Download | only in net
      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 "chrome/browser/net/metadata_url_request.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/file_path.h"
      9 #include "base/message_loop.h"
     10 #include "base/task.h"
     11 #include "build/build_config.h"
     12 #include "chrome/browser/parsers/metadata_parser_manager.h"
     13 #include "chrome/browser/parsers/metadata_parser.h"
     14 #include "chrome/common/url_constants.h"
     15 #include "net/base/io_buffer.h"
     16 #include "net/base/net_util.h"
     17 #include "net/url_request/url_request.h"
     18 #include "net/url_request/url_request_job.h"
     19 
     20 namespace {
     21 
     22 class MetadataRequestHandler : public net::URLRequestJob {
     23  public:
     24   explicit MetadataRequestHandler(net::URLRequest* request);
     25 
     26   static net::URLRequestJob* Factory(net::URLRequest* request,
     27                                      const std::string& scheme);
     28 
     29   // net::URLRequestJob implementation.
     30   virtual void Start();
     31   virtual void Kill();
     32   virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read);
     33   virtual bool GetMimeType(std::string* mime_type) const;
     34 
     35  private:
     36   ~MetadataRequestHandler();
     37 
     38   void StartAsync();
     39   std::string result_;
     40   bool parsed;
     41   int data_offset_;
     42   ScopedRunnableMethodFactory<MetadataRequestHandler> method_factory_;
     43   DISALLOW_COPY_AND_ASSIGN(MetadataRequestHandler);
     44 };
     45 
     46 MetadataRequestHandler::MetadataRequestHandler(net::URLRequest* request)
     47     : net::URLRequestJob(request),
     48       data_offset_(0),
     49       ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
     50   parsed = false;
     51 }
     52 
     53 MetadataRequestHandler::~MetadataRequestHandler() {
     54 }
     55 
     56 net::URLRequestJob* MetadataRequestHandler::Factory(net::URLRequest* request,
     57                                                const std::string& scheme) {
     58   return new MetadataRequestHandler(request);
     59 }
     60 
     61 void MetadataRequestHandler::Start() {
     62   // Start reading asynchronously so that all error reporting and data
     63   // callbacks happen as they would for network requests.
     64   MessageLoop::current()->PostTask(
     65       FROM_HERE,
     66       method_factory_.NewRunnableMethod(&MetadataRequestHandler::StartAsync));
     67 }
     68 
     69 void MetadataRequestHandler::Kill() {
     70 }
     71 
     72 bool MetadataRequestHandler::ReadRawData(net::IOBuffer* buf, int buf_size,
     73                                          int *bytes_read) {
     74   FilePath path;
     75 
     76   if (!request()->url().is_valid()) {
     77     return false;
     78   }
     79   if (!net::FileURLToFilePath(request()->url(), &path)) {
     80     return false;
     81   }
     82   if (!parsed) {
     83     MetadataParserManager* manager = MetadataParserManager::GetInstance();
     84     scoped_ptr<MetadataParser> parser(manager->GetParserForFile(path));
     85     if (parser != NULL) {
     86       result_ = "{\n";
     87       parser->Parse();
     88       MetadataPropertyIterator *iter = parser->GetPropertyIterator();
     89       while (!iter->IsEnd()) {
     90         std::string key;
     91         std::string value;
     92         if (iter->GetNext(&key, &value)) {
     93           result_ += "\"";
     94           result_ += key;
     95           result_ += "\":";
     96           result_ += "\"";
     97           result_ += value;
     98           result_ += "\",\n";
     99         } else {
    100           break;
    101         }
    102       }
    103       result_ += "}";
    104       delete iter;
    105     } else {
    106       result_ = "{}";
    107     }
    108     parsed = true;
    109   }
    110   int remaining = static_cast<int>(result_.size()) - data_offset_;
    111   if (buf_size > remaining)
    112     buf_size = remaining;
    113   if (buf_size > 0) {
    114     memcpy(buf->data(), &result_[data_offset_], buf_size);
    115     data_offset_ += buf_size;
    116   }
    117   *bytes_read = buf_size;
    118   return true;
    119 }
    120 
    121 bool MetadataRequestHandler::GetMimeType(std::string* mime_type) const {
    122   *mime_type = "application/json";
    123   return true;
    124 }
    125 
    126 void MetadataRequestHandler::StartAsync() {
    127   NotifyHeadersComplete();
    128 }
    129 
    130 }  // namespace
    131 
    132 void RegisterMetadataURLRequestHandler() {
    133 #if defined(OS_CHROMEOS)
    134   net::URLRequest::RegisterProtocolFactory(chrome::kMetadataScheme,
    135                                            &MetadataRequestHandler::Factory);
    136 #endif
    137 }
    138