Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: native_client_sdk/src/libraries/nacl_io/mount_http.cc

Issue 16232016: [NaCl SDK] nacl_io: big refactor to return error value (errno). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge master, fix windows Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/libraries/nacl_io/mount_http.cc
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_http.cc b/native_client_sdk/src/libraries/nacl_io/mount_http.cc
index 9e6155f145bf87ff998d39a06cb8a5578f929a8e..7b4316e8428e7c52a8f18a212ced961b698fe5c6 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_http.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_http.cc
@@ -4,30 +4,30 @@
*/
#include "nacl_io/mount_http.h"
+
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
-#include <ppapi/c/pp_errors.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+
#include <vector>
+
+#include <ppapi/c/pp_errors.h>
+
#include "nacl_io/mount_node_dir.h"
+#include "nacl_io/mount_node_http.h"
#include "nacl_io/osinttypes.h"
#include "sdk_util/auto_lock.h"
-#if defined(WIN32)
-#define snprintf _snprintf
-#endif
-
-
namespace {
-typedef std::vector<char *> StringList_t;
-size_t SplitString(char *str, const char *delim, StringList_t* list) {
- char *item = strtok(str, delim);
+typedef std::vector<char*> StringList_t;
+size_t SplitString(char* str, const char* delim, StringList_t* list) {
+ char* item = strtok(str, delim);
list->clear();
while (item) {
@@ -38,13 +38,7 @@ size_t SplitString(char *str, const char *delim, StringList_t* list) {
return list->size();
}
-
-// If we're attempting to read a partial request, but the server returns a full
-// request, we need to read all of the data up to the start of our partial
-// request into a dummy buffer. This is the maximum size of that buffer.
-const size_t MAX_READ_BUFFER_SIZE = 64 * 1024;
-const int32_t STATUSCODE_OK = 200;
-const int32_t STATUSCODE_PARTIAL_CONTENT = 206;
+} // namespace
std::string NormalizeHeaderKey(const std::string& s) {
// Capitalize the first letter and any letter following a hyphen:
@@ -60,557 +54,64 @@ std::string NormalizeHeaderKey(const std::string& s) {
return result;
}
-StringMap_t ParseHeaders(const char* headers, int32_t headers_length) {
- enum State {
- FINDING_KEY,
- SKIPPING_WHITESPACE,
- FINDING_VALUE,
- };
-
- StringMap_t result;
- std::string key;
- std::string value;
-
- State state = FINDING_KEY;
- const char* start = headers;
- for (int i = 0; i < headers_length; ++i) {
- switch (state) {
- case FINDING_KEY:
- if (headers[i] == ':') {
- // Found key.
- key.assign(start, &headers[i] - start);
- key = NormalizeHeaderKey(key);
- state = SKIPPING_WHITESPACE;
- }
- break;
-
- case SKIPPING_WHITESPACE:
- if (headers[i] == ' ') {
- // Found whitespace, keep going...
- break;
- }
-
- // Found a non-whitespace, mark this as the start of the value.
- start = &headers[i];
- state = FINDING_VALUE;
- // Fallthrough to start processing value without incrementing i.
-
- case FINDING_VALUE:
- if (headers[i] == '\n') {
- // Found value.
- value.assign(start, &headers[i] - start);
- result[key] = value;
- start = &headers[i + 1];
- state = FINDING_KEY;
- }
- break;
- }
- }
-
- return result;
-}
-
-bool ParseContentLength(const StringMap_t& headers, size_t* content_length) {
- StringMap_t::const_iterator iter = headers.find("Content-Length");
- if (iter == headers.end())
- return false;
-
- *content_length = strtoul(iter->second.c_str(), NULL, 10);
- return true;
-}
-
-bool ParseContentRange(const StringMap_t& headers, size_t* read_start,
- size_t* read_end, size_t* entity_length) {
- StringMap_t::const_iterator iter = headers.find("Content-Range");
- if (iter == headers.end())
- return false;
-
- // The key should look like "bytes ##-##/##" or "bytes ##-##/*". The last
- // value is the entity length, which can potentially be * (i.e. unknown).
- int read_start_int;
- int read_end_int;
- int entity_length_int;
- int result = sscanf(iter->second.c_str(), "bytes %"SCNuS"-%"SCNuS"/%"SCNuS,
- &read_start_int, &read_end_int, &entity_length_int);
-
- // The Content-Range header specifies an inclusive range: e.g. the first ten
- // bytes is "bytes 0-9/*". Convert it to a half-open range by incrementing
- // read_end.
- if (result == 2) {
- *read_start = read_start_int;
- *read_end = read_end_int + 1;
- *entity_length = 0;
- return true;
- } else if (result == 3) {
- *read_start = read_start_int;
- *read_end = read_end_int + 1;
- *entity_length = entity_length_int;
- return true;
- }
-
- return false;
-}
-
-} // namespace
-
-
-class MountNodeHttp : public MountNode {
- public:
- virtual int FSync();
- virtual int GetDents(size_t offs, struct dirent* pdir, size_t count);
- virtual int GetStat(struct stat* stat);
- virtual int Read(size_t offs, void* buf, size_t count);
- virtual int FTruncate(off_t size);
- virtual int Write(size_t offs, const void* buf, size_t count);
- virtual size_t GetSize();
-
- void SetCachedSize(off_t size);
-
- protected:
- MountNodeHttp(Mount* mount, const std::string& url, bool cache_content);
-
- private:
- bool OpenUrl(const char* method,
- StringMap_t* request_headers,
- PP_Resource* out_loader,
- PP_Resource* out_request,
- PP_Resource* out_response,
- int32_t* out_statuscode,
- StringMap_t* out_response_headers);
-
- int DownloadToCache();
- int ReadPartialFromCache(size_t offs, void* buf, size_t count);
- int DownloadPartial(size_t offs, void* buf, size_t count);
- int DownloadToBuffer(PP_Resource loader, void* buf, size_t count);
-
- std::string url_;
- std::vector<char> buffer_;
-
- bool cache_content_;
- bool has_cached_size_;
- std::vector<char> cached_data_;
-
- friend class MountHttp;
-};
-
-void MountNodeHttp::SetCachedSize(off_t size) {
- has_cached_size_ = true;
- stat_.st_size = size;
-}
-
-int MountNodeHttp::FSync() {
- errno = ENOSYS;
- return -1;
-}
-
-int MountNodeHttp::GetDents(size_t offs, struct dirent* pdir, size_t count) {
- errno = ENOSYS;
- return -1;
-}
-
-int MountNodeHttp::GetStat(struct stat* stat) {
- AutoLock lock(&lock_);
-
- // Assume we need to 'HEAD' if we do not know the size, otherwise, assume
- // that the information is constant. We can add a timeout if needed.
- MountHttp* mount = static_cast<MountHttp*>(mount_);
- if (stat_.st_size == 0 || !mount->cache_stat_) {
- StringMap_t headers;
- PP_Resource loader;
- PP_Resource request;
- PP_Resource response;
- int32_t statuscode;
- StringMap_t response_headers;
- if (!OpenUrl("HEAD", &headers, &loader, &request, &response, &statuscode,
- &response_headers)) {
- // errno is already set by OpenUrl.
- return -1;
- }
-
- ScopedResource scoped_loader(mount_->ppapi(), loader);
- ScopedResource scoped_request(mount_->ppapi(), request);
- ScopedResource scoped_response(mount_->ppapi(), response);
-
-
- size_t entity_length;
- if (ParseContentLength(response_headers, &entity_length)) {
- SetCachedSize(static_cast<off_t>(entity_length));
- } else if (cache_content_ && !has_cached_size_) {
- DownloadToCache();
- } else {
- // Don't use SetCachedSize here -- it is actually unknown.
- stat_.st_size = 0;
- }
-
- stat_.st_atime = 0; // TODO(binji): Use "Last-Modified".
- stat_.st_mtime = 0;
- stat_.st_ctime = 0;
- }
-
- // Fill the stat structure if provided
- if (stat) {
- memcpy(stat, &stat_, sizeof(stat_));
- }
- return 0;
-}
-
-int MountNodeHttp::Read(size_t offs, void* buf, size_t count) {
- AutoLock lock(&lock_);
- if (cache_content_) {
- if (cached_data_.empty()) {
- if (DownloadToCache() < 0)
- return -1;
- }
-
- return ReadPartialFromCache(offs, buf, count);
- }
-
- return DownloadPartial(offs, buf, count);
-}
-
-int MountNodeHttp::FTruncate(off_t size) {
- errno = ENOSYS;
- return -1;
-}
-
-int MountNodeHttp::Write(size_t offs, const void* buf, size_t count) {
- // TODO(binji): support POST?
- errno = ENOSYS;
- return -1;
-}
-
-size_t MountNodeHttp::GetSize() {
- // TODO(binji): This value should be cached properly; i.e. obey the caching
- // headers returned by the server.
- AutoLock lock(&lock_);
- if (!has_cached_size_) {
- // Even if DownloadToCache fails, the best result we can return is what
- // was written to stat_.st_size.
- if (cache_content_)
- DownloadToCache();
- }
-
- return stat_.st_size;
-}
-
-MountNodeHttp::MountNodeHttp(Mount* mount, const std::string& url,
- bool cache_content)
- : MountNode(mount),
- url_(url),
- cache_content_(cache_content),
- has_cached_size_(false) {
-}
-
-bool MountNodeHttp::OpenUrl(const char* method,
- StringMap_t* request_headers,
- PP_Resource* out_loader,
- PP_Resource* out_request,
- PP_Resource* out_response,
- int32_t* out_statuscode,
- StringMap_t* out_response_headers) {
- // Assume lock_ is already held.
-
- PepperInterface* ppapi = mount_->ppapi();
-
- MountHttp* mount_http = static_cast<MountHttp*>(mount_);
- ScopedResource request(ppapi,
- mount_http->MakeUrlRequestInfo(url_, method,
- request_headers));
- if (!request.pp_resource()) {
- errno = EINVAL;
- return false;
- }
-
- URLLoaderInterface* loader_interface = ppapi->GetURLLoaderInterface();
- URLResponseInfoInterface* response_interface =
- ppapi->GetURLResponseInfoInterface();
- VarInterface* var_interface = ppapi->GetVarInterface();
-
- ScopedResource loader(ppapi, loader_interface->Create(ppapi->GetInstance()));
- if (!loader.pp_resource()) {
- errno = EINVAL;
- return false;
- }
-
- int32_t result = loader_interface->Open(
- loader.pp_resource(), request.pp_resource(), PP_BlockUntilComplete());
- if (result != PP_OK) {
- errno = PPErrorToErrno(result);
- return false;
- }
-
- ScopedResource response(
- ppapi,
- loader_interface->GetResponseInfo(loader.pp_resource()));
- if (!response.pp_resource()) {
- errno = EINVAL;
- return false;
- }
-
- // Get response statuscode.
- PP_Var statuscode = response_interface->GetProperty(
- response.pp_resource(),
- PP_URLRESPONSEPROPERTY_STATUSCODE);
-
- if (statuscode.type != PP_VARTYPE_INT32) {
- errno = EINVAL;
- return false;
- }
-
- *out_statuscode = statuscode.value.as_int;
-
- // Only accept OK or Partial Content.
- if (*out_statuscode != STATUSCODE_OK &&
- *out_statuscode != STATUSCODE_PARTIAL_CONTENT) {
- errno = EINVAL;
- return false;
- }
-
- // Get response headers.
- PP_Var response_headers_var = response_interface->GetProperty(
- response.pp_resource(),
- PP_URLRESPONSEPROPERTY_HEADERS);
-
- uint32_t response_headers_length;
- const char* response_headers_str = var_interface->VarToUtf8(
- response_headers_var,
- &response_headers_length);
-
- *out_loader = loader.Release();
- *out_request = request.Release();
- *out_response = response.Release();
- *out_response_headers = ParseHeaders(response_headers_str,
- response_headers_length);
-
- return true;
-}
-
-int MountNodeHttp::DownloadToCache() {
- StringMap_t headers;
- PP_Resource loader;
- PP_Resource request;
- PP_Resource response;
- int32_t statuscode;
- StringMap_t response_headers;
- if (!OpenUrl("GET", &headers, &loader, &request, &response, &statuscode,
- &response_headers)) {
- // errno is already set by OpenUrl.
- return -1;
- }
-
- PepperInterface* ppapi = mount_->ppapi();
- ScopedResource scoped_loader(ppapi, loader);
- ScopedResource scoped_request(ppapi, request);
- ScopedResource scoped_response(ppapi, response);
-
- size_t content_length = 0;
- if (ParseContentLength(response_headers, &content_length)) {
- cached_data_.resize(content_length);
- int real_size = DownloadToBuffer(loader, cached_data_.data(),
- content_length);
- if (real_size < 0)
- return -1;
-
- SetCachedSize(real_size);
- cached_data_.resize(real_size);
- return real_size;
- }
-
- // We don't know how big the file is. Read in chunks.
- cached_data_.resize(MAX_READ_BUFFER_SIZE);
- size_t total_bytes_read = 0;
- size_t bytes_to_read = MAX_READ_BUFFER_SIZE;
- while (true) {
- char* buf = cached_data_.data() + total_bytes_read;
- int bytes_read = DownloadToBuffer(loader, buf, bytes_to_read);
- if (bytes_read < 0)
- return -1;
-
- total_bytes_read += bytes_read;
-
- if (bytes_read < bytes_to_read) {
- SetCachedSize(total_bytes_read);
- cached_data_.resize(total_bytes_read);
- return total_bytes_read;
- }
-
- cached_data_.resize(total_bytes_read + bytes_to_read);
- }
-}
-
-int MountNodeHttp::ReadPartialFromCache(size_t offs, void* buf, size_t count) {
- if (offs > cached_data_.size()) {
- errno = EINVAL;
- return -1;
- }
-
- count = std::min(count, cached_data_.size() - offs);
- memcpy(buf, &cached_data_.data()[offs], count);
- return count;
-}
-
-int MountNodeHttp::DownloadPartial(size_t offs, void* buf, size_t count) {
- StringMap_t headers;
-
- char buffer[100];
- // Range request is inclusive: 0-99 returns 100 bytes.
- snprintf(&buffer[0], sizeof(buffer), "bytes=%"PRIuS"-%"PRIuS,
- offs, offs + count - 1);
- headers["Range"] = buffer;
-
- PP_Resource loader;
- PP_Resource request;
- PP_Resource response;
- int32_t statuscode;
- StringMap_t response_headers;
- if (!OpenUrl("GET", &headers, &loader, &request, &response, &statuscode,
- &response_headers)) {
- // errno is already set by OpenUrl.
- return -1;
- }
-
- PepperInterface* ppapi = mount_->ppapi();
- ScopedResource scoped_loader(ppapi, loader);
- ScopedResource scoped_request(ppapi, request);
- ScopedResource scoped_response(ppapi, response);
-
- size_t read_start = 0;
- if (statuscode == STATUSCODE_OK) {
- // No partial result, read everything starting from the part we care about.
- size_t content_length;
- if (ParseContentLength(response_headers, &content_length)) {
- if (offs >= content_length) {
- errno = EINVAL;
- return 0;
- }
+Error MountHttp::Open(const Path& path, int mode, MountNode** out_node) {
+ *out_node = NULL;
- // Clamp count, if trying to read past the end of the file.
- if (offs + count > content_length) {
- count = content_length - offs;
- }
- }
- } else if (statuscode == STATUSCODE_PARTIAL_CONTENT) {
- // Determine from the headers where we are reading.
- size_t read_end;
- size_t entity_length;
- if (ParseContentRange(response_headers, &read_start, &read_end,
- &entity_length)) {
- if (read_start > offs || read_start > read_end) {
- // If this error occurs, the server is returning bogus values.
- errno = EINVAL;
- return -1;
- }
+ assert(url_root_.empty() || url_root_[url_root_.length() - 1] == '/');
- // Clamp count, if trying to read past the end of the file.
- count = std::min(read_end - read_start, count);
- } else {
- // Partial Content without Content-Range. Assume that the server gave us
- // exactly what we asked for. This can happen even when the server
- // returns 200 -- the cache may return 206 in this case, but not modify
- // the headers.
- read_start = offs;
- }
+ NodeMap_t::iterator iter = node_cache_.find(path.Join());
+ if (iter != node_cache_.end()) {
+ *out_node = iter->second;
+ return 0;
}
- if (read_start < offs) {
- // We aren't yet at the location where we want to start reading. Read into
- // our dummy buffer until then.
- size_t bytes_to_read = offs - read_start;
- if (buffer_.size() < bytes_to_read)
- buffer_.resize(std::min(bytes_to_read, MAX_READ_BUFFER_SIZE));
-
- while (bytes_to_read > 0) {
- int32_t bytes_read = DownloadToBuffer(loader, buffer_.data(),
- buffer_.size());
- if (bytes_read < 0)
- return -1;
+ // If we can't find the node in the cache, create it
+ std::string url = url_root_ + (path.IsAbsolute() ? path.Range(1, path.Size())
+ : path.Join());
- bytes_to_read -= bytes_read;
- }
+ MountNodeHttp* node = new MountNodeHttp(this, url, cache_content_);
+ Error error = node->Init(mode);
+ if (error) {
+ node->Release();
+ return error;
}
- return DownloadToBuffer(loader, buf, count);
-}
-
-int MountNodeHttp::DownloadToBuffer(PP_Resource loader, void* buf,
- size_t count) {
- PepperInterface* ppapi = mount_->ppapi();
- URLLoaderInterface* loader_interface = ppapi->GetURLLoaderInterface();
-
- char* out_buffer = static_cast<char*>(buf);
- size_t bytes_to_read = count;
- while (bytes_to_read > 0) {
- int32_t bytes_read = loader_interface->ReadResponseBody(
- loader, out_buffer, bytes_to_read, PP_BlockUntilComplete());
-
- if (bytes_read == 0) {
- // This is not an error -- it may just be that we were trying to read
- // more data than exists.
- return count - bytes_to_read;
- }
-
- if (bytes_read < 0) {
- errno = PPErrorToErrno(bytes_read);
- return -1;
- }
-
- assert(bytes_read <= bytes_to_read);
- bytes_to_read -= bytes_read;
- out_buffer += bytes_read;
+ error = node->GetStat(NULL);
+ if (error) {
+ node->Release();
+ return error;
}
- return count;
-}
-
-MountNode *MountHttp::Open(const Path& path, int mode) {
- assert(url_root_.empty() || url_root_[url_root_.length() - 1] == '/');
-
- NodeMap_t::iterator iter = node_cache_.find(path.Join());
- if (iter != node_cache_.end()) {
- return iter->second;
+ MountNodeDir* parent;
+ error = FindOrCreateDir(path.Parent(), &parent);
+ if (error) {
+ node->Release();
+ return error;
}
- // If we can't find the node in the cache, create it
- std::string url = url_root_ + (path.IsAbsolute() ?
- path.Range(1, path.Size()) :
- path.Join());
-
- MountNodeHttp* node = new MountNodeHttp(this, url, cache_content_);
- if (!node->Init(mode) || (0 != node->GetStat(NULL))) {
+ error = parent->AddChild(path.Basename(), node);
+ if (error) {
node->Release();
- return NULL;
+ return error;
}
- MountNodeDir* parent = FindOrCreateDir(path.Parent());
node_cache_[path.Join()] = node;
- parent->AddChild(path.Basename(), node);
- return node;
-}
-int MountHttp::Unlink(const Path& path) {
- errno = ENOSYS;
- return -1;
+ *out_node = node;
+ return 0;
}
-int MountHttp::Mkdir(const Path& path, int permissions) {
- errno = ENOSYS;
- return -1;
-}
+Error MountHttp::Unlink(const Path& path) { return ENOSYS; }
-int MountHttp::Rmdir(const Path& path) {
- errno = ENOSYS;
- return -1;
-}
+Error MountHttp::Mkdir(const Path& path, int permissions) { return ENOSYS; }
-int MountHttp::Remove(const Path& path) {
- errno = ENOSYS;
- return -1;
-}
+Error MountHttp::Rmdir(const Path& path) { return ENOSYS; }
+
+Error MountHttp::Remove(const Path& path) { return ENOSYS; }
-PP_Resource MountHttp::MakeUrlRequestInfo(
- const std::string& url,
- const char* method,
- StringMap_t* additional_headers) {
+PP_Resource MountHttp::MakeUrlRequestInfo(const std::string& url,
+ const char* method,
+ StringMap_t* additional_headers) {
URLRequestInfoInterface* interface = ppapi_->GetURLRequestInfoInterface();
VarInterface* var_interface = ppapi_->GetVarInterface();
@@ -618,21 +119,23 @@ PP_Resource MountHttp::MakeUrlRequestInfo(
if (!request_info)
return 0;
- interface->SetProperty(
- request_info, PP_URLREQUESTPROPERTY_URL,
- var_interface->VarFromUtf8(url.c_str(), url.length()));
- interface->SetProperty(request_info, PP_URLREQUESTPROPERTY_METHOD,
+ interface->SetProperty(request_info,
+ PP_URLREQUESTPROPERTY_URL,
+ var_interface->VarFromUtf8(url.c_str(), url.length()));
+ interface->SetProperty(request_info,
+ PP_URLREQUESTPROPERTY_METHOD,
var_interface->VarFromUtf8(method, strlen(method)));
interface->SetProperty(request_info,
PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS,
PP_MakeBool(allow_cors_ ? PP_TRUE : PP_FALSE));
- interface->SetProperty(request_info, PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS,
+ interface->SetProperty(request_info,
+ PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS,
PP_MakeBool(allow_credentials_ ? PP_TRUE : PP_FALSE));
// Merge the mount headers with the request headers. If the field is already
// set it |additional_headers|, don't use the one from headers_.
for (StringMap_t::iterator iter = headers_.begin(); iter != headers_.end();
- ++iter) {
+ ++iter) {
const std::string& key = NormalizeHeaderKey(iter->first);
if (additional_headers->find(key) == additional_headers->end()) {
additional_headers->insert(std::make_pair(key, iter->second));
@@ -642,12 +145,14 @@ PP_Resource MountHttp::MakeUrlRequestInfo(
// Join the headers into one string.
std::string headers;
for (StringMap_t::iterator iter = additional_headers->begin();
- iter != additional_headers->end(); ++iter) {
+ iter != additional_headers->end();
+ ++iter) {
headers += iter->first + ": " + iter->second + '\n';
}
interface->SetProperty(
- request_info, PP_URLREQUESTPROPERTY_HEADERS,
+ request_info,
+ PP_URLREQUESTPROPERTY_HEADERS,
var_interface->VarFromUtf8(headers.c_str(), headers.length()));
return request_info;
@@ -657,12 +162,12 @@ MountHttp::MountHttp()
: allow_cors_(false),
allow_credentials_(false),
cache_stat_(true),
- cache_content_(true) {
-}
+ cache_content_(true) {}
-bool MountHttp::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
- if (!Mount::Init(dev, args, ppapi))
- return false;
+Error MountHttp::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
+ Error error = Mount::Init(dev, args, ppapi);
+ if (error)
+ return error;
// Parse mount args.
for (StringMap_t::iterator iter = args.begin(); iter != args.end(); ++iter) {
@@ -674,11 +179,18 @@ bool MountHttp::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
url_root_ += '/';
}
} else if (iter->first == "manifest") {
- char *text = LoadManifest(iter->second);
- if (text != NULL) {
- ParseManifest(text);
+ char* text;
+ error = LoadManifest(iter->second, &text);
+ if (error)
+ return error;
+
+ error = ParseManifest(text);
+ if (error) {
delete[] text;
+ return error;
}
+
+ delete[] text;
} else if (iter->first == "allow_cross_origin_requests") {
allow_cors_ = iter->second == "true";
} else if (iter->first == "allow_credentials") {
@@ -693,34 +205,53 @@ bool MountHttp::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
}
}
- return true;
+ return 0;
}
-void MountHttp::Destroy() {
-}
+void MountHttp::Destroy() {}
+
+Error MountHttp::FindOrCreateDir(const Path& path, MountNodeDir** out_node) {
+ *out_node = NULL;
-MountNodeDir* MountHttp::FindOrCreateDir(const Path& path) {
std::string strpath = path.Join();
NodeMap_t::iterator iter = node_cache_.find(strpath);
if (iter != node_cache_.end()) {
- return static_cast<MountNodeDir*>(iter->second);
+ *out_node = static_cast<MountNodeDir*>(iter->second);
+ return 0;
}
- // If the node does not exist, create it, and add it to the node cache
+ // If the node does not exist, create it.
MountNodeDir* node = new MountNodeDir(this);
- node->Init(S_IREAD);
- node_cache_[strpath] = node;
+ Error error = node->Init(S_IREAD);
+ if (error) {
+ node->Release();
+ return error;
+ }
// If not the root node, find the parent node and add it to the parent
if (!path.Top()) {
- MountNodeDir* parent = FindOrCreateDir(path.Parent());
- parent->AddChild(path.Basename(), node);
+ MountNodeDir* parent;
+ error = FindOrCreateDir(path.Parent(), &parent);
+ if (error) {
+ node->Release();
+ return error;
+ }
+
+ error = parent->AddChild(path.Basename(), node);
+ if (error) {
+ node->Release();
+ return error;
+ }
}
- return node;
+ // Add it to the node cache.
+ node_cache_[strpath] = node;
+
+ *out_node = node;
+ return 0;
}
-bool MountHttp::ParseManifest(char *text) {
+Error MountHttp::ParseManifest(char* text) {
StringList_t lines;
SplitString(text, "\n", &lines);
@@ -741,62 +272,102 @@ bool MountHttp::ParseManifest(char *text) {
// Ignore EXEC bit
int mode = S_IFREG;
switch (modestr[0]) {
- case '-': mode = S_IFREG; break;
- case 'c': mode = S_IFCHR; break;
+ case '-':
+ mode = S_IFREG;
+ break;
+ case 'c':
+ mode = S_IFCHR;
+ break;
default:
fprintf(stderr, "Unable to parse type %s for %s.\n", modestr, name);
- return false;
+ return EINVAL;
}
switch (modestr[1]) {
- case '-': break;
- case 'r': mode |= S_IREAD; break;
+ case '-':
+ break;
+ case 'r':
+ mode |= S_IREAD;
+ break;
default:
fprintf(stderr, "Unable to parse read %s for %s.\n", modestr, name);
- return false;
+ return EINVAL;
}
switch (modestr[2]) {
- case '-': break;
- case 'w': mode |= S_IWRITE; break;
+ case '-':
+ break;
+ case 'w':
+ mode |= S_IWRITE;
+ break;
default:
fprintf(stderr, "Unable to parse write %s for %s.\n", modestr, name);
- return false;
+ return EINVAL;
}
Path path(name);
- std::string url = url_root_ + (path.IsAbsolute() ?
- path.Range(1, path.Size()) :
- path.Join());
+ std::string url =
+ url_root_ +
+ (path.IsAbsolute() ? path.Range(1, path.Size()) : path.Join());
MountNodeHttp* node = new MountNodeHttp(this, url, cache_content_);
- node->Init(mode);
+ Error error = node->Init(mode);
+ if (error) {
+ node->Release();
+ return error;
+ }
+
node->SetCachedSize(atoi(lenstr));
- MountNodeDir* dir_node = FindOrCreateDir(path.Parent());
- dir_node->AddChild(path.Basename(), node);
+ MountNodeDir* dir_node;
+ error = FindOrCreateDir(path.Parent(), &dir_node);
+ if (error) {
+ node->Release();
+ return error;
+ }
+
+ error = dir_node->AddChild(path.Basename(), node);
+ if (error) {
+ node->Release();
+ return error;
+ }
std::string pname = path.Join();
node_cache_[pname] = node;
}
}
- return true;
+ return 0;
}
-char *MountHttp::LoadManifest(const std::string& manifest_name) {
+Error MountHttp::LoadManifest(const std::string& manifest_name,
+ char** out_manifest) {
Path manifest_path(manifest_name);
- MountNode* manifest_node = Open(manifest_path, O_RDONLY);
+ MountNode* manifest_node = NULL;
+ *out_manifest = NULL;
- if (manifest_node) {
- char *text = new char[manifest_node->GetSize() + 1];
- off_t len = manifest_node->Read(0, text, manifest_node->GetSize());
+ int error = Open(manifest_path, O_RDONLY, &manifest_node);
+ if (error)
+ return error;
+
+ size_t size;
+ error = manifest_node->GetSize(&size);
+ if (error) {
manifest_node->Release();
+ return error;
+ }
- text[len] = 0;
- return text;
+ char* text = new char[size + 1];
+ int len;
+ error = manifest_node->Read(0, text, size, &len);
+ if (error) {
+ manifest_node->Release();
+ return error;
}
- fprintf(stderr, "Could not open manifest: %s\n", manifest_name.c_str());
- return NULL;
+ manifest_node->Release();
+ text[len] = 0;
+
+ *out_manifest = text;
+ return 0;
}
« no previous file with comments | « native_client_sdk/src/libraries/nacl_io/mount_http.h ('k') | native_client_sdk/src/libraries/nacl_io/mount_mem.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698