Skip to content

Commit

Permalink
tweak azure stream wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewhilton committed Oct 15, 2024
1 parent 6c0ff22 commit 37efa84
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 7 deletions.
1 change: 1 addition & 0 deletions classes/local/store/azure_blob_storage/client.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use tool_objectfs\local\store\object_client_base;

// TODO does this fail when the plugin is not installed ?
// e.g. when just using AWS?
use local_azureblobstorage\api;
use stdClass;
use Throwable;
Expand Down
89 changes: 82 additions & 7 deletions classes/local/store/azure_blob_storage/stream_wrapper.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace tool_objectfs\local\store\azure_blob_storage;

use GuzzleHttp\Psr7\CachingStream;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\Utils;
use local_azureblobstorage\api;
use Throwable;

/**
* Stream wrapper.
* Allows you to use built in file function e.g. readfile, copy, unlink, etc... with blob:// file urls.
*
* @package tool_objectfs
* @author Matthew Hilton <matthewhilton@catalyst-au.net>
* @copyright 2024 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class stream_wrapper {
/** @var resource|null Stream context (this is set by PHP) */
public $context;
Expand Down Expand Up @@ -107,13 +131,40 @@ private function open_read_stream() {
$params = $this->getOptions(true);

// TODO not sure if this is correct.
$promise = $client->get_blob($params['Key'])->wait();
$this->body = $promise->body;
$response = $client->get_blob($params['Key'])->wait();
$this->body = $response->getBody();

// TODO implement checking

// TODO implement CachingStream
// Wrap the body in a caching entity body if seeking is allowed.
if ($this->getOption('seekable') && !$this->body->isSeekable()) {
$this->body = new CachingStream($this->body);
}

return true;
}

/**
* Reads from the stream
* @param int $count bytes to read
* @return string
*/
public function stream_read($count) {
// If the file isn't readable, we need to return no content. Azure can emit XML here otherwise.
return $this->readable ? $this->body->read($count) : '';
}

/**
* Returns if stream is at end of file.
* @return bool
*/
public function stream_eof() {
return $this->body->eof();
}

public function unlink($path) {
$info = $this->getcontainerkey($path);
$this->getclient()->delete_blob($info['Key'])->wait();
return true;
}

Expand Down Expand Up @@ -381,12 +432,13 @@ public function url_stat($path, $flags) {

try {
$params = $this->withPath($path);
$properties = $this->getclient()->get_blob_properties($params['Key'])->wait();
$res = $this->getclient()->get_blob_properties($params['Key'])->wait();

$stat['size'] = $stat[7] = $bp->getContentLength();
$stat['size'] = $stat[7] = current($res->getHeader('Content-Length'));

// Set the modification time and last modified to the Last-Modified header.
$lastmodified = $bp->getLastModified()->getTimestamp();
// Convert from the
$lastmodified = strtotime(current($res->getHeader('Last-Modified')));

$stat['mtime'] = $stat[9] = $lastmodified;
$stat['ctime'] = $stat[10] = $lastmodified;
Expand All @@ -398,7 +450,7 @@ public function url_stat($path, $flags) {

// TODO better exception
} catch (Throwable $ex) {
// The specified blob does not exist.
// It's most likely the specified blob does not exist.
return false;
}
}
Expand All @@ -416,4 +468,27 @@ private function withpath($path) {
// TODO rewrite
return $this->getContainerKey($path) + $params;
}

/**
* Returns the size of the opened object body.
*
* @return int|null
*/
private function getsize() {
$size = $this->body->getSize();

return $size !== null ? $size : $this->size;
}

/**
* stream_stat
* @return array
*/
public function stream_stat() {
$stat = $this->getStatTemplate();
$stat[7] = $stat['size'] = $this->getSize();
$stat[2] = $stat['mode'] = $this->mode;

return $stat;
}
}

0 comments on commit 37efa84

Please sign in to comment.