@solid/community-server
Version:
Community Solid Server: an open and modular implementation of the Solid specifications
52 lines • 2.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.QuotaValidator = void 0;
const node_stream_1 = require("node:stream");
const Validator_1 = require("../../http/auxiliary/Validator");
const PayloadHttpError_1 = require("../../util/errors/PayloadHttpError");
const GuardedStream_1 = require("../../util/GuardedStream");
const StreamUtil_1 = require("../../util/StreamUtil");
/**
* The QuotaValidator validates data streams by making sure they would not exceed the limits of a QuotaStrategy.
*/
class QuotaValidator extends Validator_1.Validator {
strategy;
constructor(strategy) {
super();
this.strategy = strategy;
}
async handle({ representation, identifier }) {
const { data, metadata } = representation;
// 1. Get the available size
const availableSize = await this.strategy.getAvailableSpace(identifier);
// 2. Check if the estimated size is bigger then the available size
const estimatedSize = await this.strategy.estimateSize(metadata);
if (estimatedSize && availableSize.amount < estimatedSize.amount) {
return {
...representation,
data: (0, GuardedStream_1.guardStream)(new node_stream_1.Readable({
read() {
this.destroy(new PayloadHttpError_1.PayloadHttpError(`Quota exceeded: Advertised Content-Length is ${estimatedSize.amount} ${estimatedSize.unit} ` +
`and only ${availableSize.amount} ${availableSize.unit} is available`));
},
})),
};
}
// 3. Track if quota is exceeded during writing
const tracking = await this.strategy.createQuotaGuard(identifier);
// 4. Double check quota is not exceeded after write (concurrent writing possible)
const afterWrite = new node_stream_1.PassThrough({
// eslint-disable-next-line ts/no-misused-promises
flush: async (done) => {
const availableSpace = (await this.strategy.getAvailableSpace(identifier)).amount;
done(availableSpace < 0 ? new PayloadHttpError_1.PayloadHttpError('Quota exceeded after write completed') : undefined);
},
});
return {
...representation,
data: (0, StreamUtil_1.pipeSafely)((0, StreamUtil_1.pipeSafely)(data, tracking), afterWrite),
};
}
}
exports.QuotaValidator = QuotaValidator;
//# sourceMappingURL=QuotaValidator.js.map