// 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;
+ if (read_start)
+ *read_start = read_start_int;
+ if (read_end)
+ *read_end = read_end_int + 1;
+ if (entity_length)
+ *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;
+ if (read_start)
+ *read_start = read_start_int;
+ if (read_end)
+ *read_end = read_end_int + 1;
+ if (entity_length)
+ *entity_length = entity_length_int;
return true;
}
bool cache_content)
: Node(filesystem),
url_(url),
+ buffer_(NULL),
+ buffer_len_(0),
cache_content_(cache_content),
has_cached_size_(false) {
}
ScopedResource response(filesystem_->ppapi());
int32_t statuscode;
StringMap_t response_headers;
- Error error = OpenUrl("HEAD",
+ const char* method = "HEAD";
+
+ if (filesystem->is_blob_url_) {
+ // Blob URLs do not support HEAD requests, but do give the content length
+ // in their response headers. We issue a single-byte GET request to
+ // retrieve the content length.
+ method = "GET";
+ headers["Range"] = "bytes=0-0";
+ }
+
+ Error error = OpenUrl(method,
&headers,
&loader,
&request,
return error;
off_t entity_length;
- if (ParseContentLength(response_headers, &entity_length)) {
+ if (ParseContentRange(response_headers, NULL, NULL, &entity_length)) {
+ SetCachedSize(static_cast<off_t>(entity_length));
+ } else if (ParseContentLength(response_headers, &entity_length)) {
SetCachedSize(static_cast<off_t>(entity_length));
} else if (cache_content_) {
// The server didn't give a content length; download the data to memory
*out_bytes = 0;
const int kBytesToRead = MAX_READ_BUFFER_SIZE;
- buffer_.resize(kBytesToRead);
+ buffer_ = (char*)realloc(buffer_, kBytesToRead);
+ assert(buffer_);
+ if (!buffer_) {
+ buffer_len_ = 0;
+ return ENOMEM;
+ }
+ buffer_len_ = kBytesToRead;
while (true) {
int bytes_read;
Error error =
- ReadResponseToBuffer(loader, buffer_.data(), kBytesToRead, &bytes_read);
+ ReadResponseToBuffer(loader, buffer_, kBytesToRead, &bytes_read);
if (error)
return error;
int* out_bytes) {
*out_bytes = 0;
- if (buffer_.size() < static_cast<size_t>(count))
- buffer_.resize(std::min(count, MAX_READ_BUFFER_SIZE));
+ if (buffer_len_ < count) {
+ int new_len = std::min(count, MAX_READ_BUFFER_SIZE);
+ buffer_ = (char*)realloc(buffer_, new_len);
+ assert(buffer_);
+ if (!buffer_) {
+ buffer_len_ = 0;
+ return ENOMEM;
+ }
+ buffer_len_ = new_len;
+ }
int bytes_left = count;
while (bytes_left > 0) {
- int bytes_to_read =
- std::min(static_cast<size_t>(bytes_left), buffer_.size());
+ int bytes_to_read = std::min(bytes_left, buffer_len_);
int bytes_read;
Error error = ReadResponseToBuffer(
- loader, buffer_.data(), bytes_to_read, &bytes_read);
+ loader, buffer_, bytes_to_read, &bytes_read);
if (error)
return error;