From ae23f42fe820cdb3079b6e11a05d904d58283213 Mon Sep 17 00:00:00 2001 From: Jeremy Barnes Date: Sun, 21 Sep 2014 22:30:57 -0400 Subject: [PATCH 1/2] Fix Url::path() not returning file path for file:// URLs (TRIVIAL) --- types/url.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/url.cc b/types/url.cc index 662e63fc..c65e0083 100644 --- a/types/url.cc +++ b/types/url.cc @@ -167,7 +167,9 @@ std::string Url:: path() const { - return url->path(); + if (url->scheme() == "file") + return url->host() + url->path(); + else return url->path(); } std::string From ac385ebf242b4efd75f5aa48e65478637b33adf4 Mon Sep 17 00:00:00 2001 From: Jeremy Barnes Date: Sun, 21 Sep 2014 22:35:54 -0400 Subject: [PATCH 2/2] Implement tryGetUriInfo without a try/catch (TRIVIAL) --- service/fs_utils.cc | 36 ++++++++++++++++++++++++------------ service/fs_utils.h | 1 + service/s3.cc | 7 +++++++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/service/fs_utils.cc b/service/fs_utils.cc index 774e0c50..2e9db258 100644 --- a/service/fs_utils.cc +++ b/service/fs_utils.cc @@ -81,6 +81,20 @@ struct LocalUrlFsHandler : public UrlFsHandler { return extractInfo(stats); } + virtual FsObjectInfo tryGetInfo(const Url & url) const + { + struct stat stats; + string path = url.path(); + + // cerr << "fs info on path: " + path + "\n"; + int res = ::stat(path.c_str(), &stats); + if (res == -1) { + return FsObjectInfo(); + } + + return extractInfo(stats); + } + virtual void makeDirectory(const Url & url) const { boost::system::error_code ec; @@ -174,6 +188,9 @@ struct AtInit { /* ensures that local filenames are represented as urls */ Url makeUrl(const string & urlStr) { + if (urlStr.empty()) + throw ML::Exception("can't makeUrl on empty url"); + /* scheme is specified */ if (urlStr.find("://") != string::npos) { return Url(urlStr); @@ -232,24 +249,19 @@ void registerUrlFsHandler(const std::string & scheme, } FsObjectInfo -getUriObjectInfo(const std::string & url) +tryGetUriObjectInfo(const std::string & url) { Url realUrl = makeUrl(url); - return findFsHandler(realUrl.scheme())->getInfo(realUrl); + return findFsHandler(realUrl.scheme())->tryGetInfo(realUrl); } FsObjectInfo -tryGetUriObjectInfo(const std::string & url) +getUriObjectInfo(const std::string & url) { - JML_TRACE_EXCEPTIONS(false); - try { - return getUriObjectInfo(url); - } - catch (...) { - return FsObjectInfo(); - } + Url realUrl = makeUrl(url); + return findFsHandler(realUrl.scheme())->getInfo(realUrl); } - + size_t getUriSize(const std::string & url) { @@ -270,7 +282,7 @@ makeUriDirectory(const std::string & url) string dirUrl(url); size_t slashIdx = dirUrl.rfind('/'); if (slashIdx == string::npos) { - throw ML::Exception("makeUriDirectory cannot work on filenames"); + throw ML::Exception("makeUriDirectory cannot work on filenames: instead of " + url + " you should probably write file://" + url); } dirUrl.resize(slashIdx); diff --git a/service/fs_utils.h b/service/fs_utils.h index abbf4a55..e092d348 100644 --- a/service/fs_utils.h +++ b/service/fs_utils.h @@ -71,6 +71,7 @@ OnUriObject; struct UrlFsHandler { virtual FsObjectInfo getInfo(const Url & url) const = 0; + virtual FsObjectInfo tryGetInfo(const Url & url) const = 0; virtual size_t getSize(const Url & url) const; virtual std::string getEtag(const Url & url) const; diff --git a/service/s3.cc b/service/s3.cc index 7faa508c..93bfd3fe 100644 --- a/service/s3.cc +++ b/service/s3.cc @@ -60,6 +60,13 @@ struct S3UrlFsHandler : public UrlFsHandler { return api->getObjectInfo(bucket, url.path().substr(1)); } + virtual FsObjectInfo tryGetInfo(const Url & url) const + { + string bucket = url.host(); + auto api = getS3ApiForBucket(bucket); + return api->tryGetObjectInfo(bucket, url.path().substr(1)); + } + virtual void makeDirectory(const Url & url) const { }