| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/net/metadata_url_request.h" |
| |
| #include "base/compiler_specific.h" |
| #include "base/file_path.h" |
| #include "base/message_loop.h" |
| #include "base/task.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/parsers/metadata_parser_manager.h" |
| #include "chrome/browser/parsers/metadata_parser.h" |
| #include "chrome/common/url_constants.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/net_util.h" |
| #include "net/url_request/url_request.h" |
| #include "net/url_request/url_request_job.h" |
| |
| namespace { |
| |
| class MetadataRequestHandler : public net::URLRequestJob { |
| public: |
| explicit MetadataRequestHandler(net::URLRequest* request); |
| |
| static net::URLRequestJob* Factory(net::URLRequest* request, |
| const std::string& scheme); |
| |
| // net::URLRequestJob implementation. |
| virtual void Start(); |
| virtual void Kill(); |
| virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); |
| virtual bool GetMimeType(std::string* mime_type) const; |
| |
| private: |
| ~MetadataRequestHandler(); |
| |
| void StartAsync(); |
| std::string result_; |
| bool parsed; |
| int data_offset_; |
| ScopedRunnableMethodFactory<MetadataRequestHandler> method_factory_; |
| DISALLOW_COPY_AND_ASSIGN(MetadataRequestHandler); |
| }; |
| |
| MetadataRequestHandler::MetadataRequestHandler(net::URLRequest* request) |
| : net::URLRequestJob(request), |
| data_offset_(0), |
| ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| parsed = false; |
| } |
| |
| MetadataRequestHandler::~MetadataRequestHandler() { |
| } |
| |
| net::URLRequestJob* MetadataRequestHandler::Factory(net::URLRequest* request, |
| const std::string& scheme) { |
| return new MetadataRequestHandler(request); |
| } |
| |
| void MetadataRequestHandler::Start() { |
| // Start reading asynchronously so that all error reporting and data |
| // callbacks happen as they would for network requests. |
| MessageLoop::current()->PostTask( |
| FROM_HERE, |
| method_factory_.NewRunnableMethod(&MetadataRequestHandler::StartAsync)); |
| } |
| |
| void MetadataRequestHandler::Kill() { |
| } |
| |
| bool MetadataRequestHandler::ReadRawData(net::IOBuffer* buf, int buf_size, |
| int *bytes_read) { |
| FilePath path; |
| |
| if (!request()->url().is_valid()) { |
| return false; |
| } |
| if (!net::FileURLToFilePath(request()->url(), &path)) { |
| return false; |
| } |
| if (!parsed) { |
| MetadataParserManager* manager = MetadataParserManager::GetInstance(); |
| scoped_ptr<MetadataParser> parser(manager->GetParserForFile(path)); |
| if (parser != NULL) { |
| result_ = "{\n"; |
| parser->Parse(); |
| MetadataPropertyIterator *iter = parser->GetPropertyIterator(); |
| while (!iter->IsEnd()) { |
| std::string key; |
| std::string value; |
| if (iter->GetNext(&key, &value)) { |
| result_ += "\""; |
| result_ += key; |
| result_ += "\":"; |
| result_ += "\""; |
| result_ += value; |
| result_ += "\",\n"; |
| } else { |
| break; |
| } |
| } |
| result_ += "}"; |
| delete iter; |
| } else { |
| result_ = "{}"; |
| } |
| parsed = true; |
| } |
| int remaining = static_cast<int>(result_.size()) - data_offset_; |
| if (buf_size > remaining) |
| buf_size = remaining; |
| if (buf_size > 0) { |
| memcpy(buf->data(), &result_[data_offset_], buf_size); |
| data_offset_ += buf_size; |
| } |
| *bytes_read = buf_size; |
| return true; |
| } |
| |
| bool MetadataRequestHandler::GetMimeType(std::string* mime_type) const { |
| *mime_type = "application/json"; |
| return true; |
| } |
| |
| void MetadataRequestHandler::StartAsync() { |
| NotifyHeadersComplete(); |
| } |
| |
| } // namespace |
| |
| void RegisterMetadataURLRequestHandler() { |
| #if defined(OS_CHROMEOS) |
| net::URLRequest::RegisterProtocolFactory(chrome::kMetadataScheme, |
| &MetadataRequestHandler::Factory); |
| #endif |
| } |