• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MetadataRequestHandler(net::URLRequest * request)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 
~MetadataRequestHandler()53 MetadataRequestHandler::~MetadataRequestHandler() {
54 }
55 
Factory(net::URLRequest * request,const std::string & scheme)56 net::URLRequestJob* MetadataRequestHandler::Factory(net::URLRequest* request,
57                                                const std::string& scheme) {
58   return new MetadataRequestHandler(request);
59 }
60 
Start()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 
Kill()69 void MetadataRequestHandler::Kill() {
70 }
71 
ReadRawData(net::IOBuffer * buf,int buf_size,int * bytes_read)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 
GetMimeType(std::string * mime_type) const121 bool MetadataRequestHandler::GetMimeType(std::string* mime_type) const {
122   *mime_type = "application/json";
123   return true;
124 }
125 
StartAsync()126 void MetadataRequestHandler::StartAsync() {
127   NotifyHeadersComplete();
128 }
129 
130 }  // namespace
131 
RegisterMetadataURLRequestHandler()132 void RegisterMetadataURLRequestHandler() {
133 #if defined(OS_CHROMEOS)
134   net::URLRequest::RegisterProtocolFactory(chrome::kMetadataScheme,
135                                            &MetadataRequestHandler::Factory);
136 #endif
137 }
138