diff --git a/src/ldp/http/Patch.ts b/src/ldp/http/Patch.ts index 47724298d..1df19e0be 100644 --- a/src/ldp/http/Patch.ts +++ b/src/ldp/http/Patch.ts @@ -4,8 +4,4 @@ import { Representation } from '../representation/Representation'; * Represents the changes needed for a PATCH request. */ export interface Patch extends Representation { - /** - * The raw body of the PATCH request. - */ - raw: string; } diff --git a/src/ldp/http/SimpleSparqlUpdateBodyParser.ts b/src/ldp/http/SimpleSparqlUpdateBodyParser.ts index 22b73919f..013204187 100644 --- a/src/ldp/http/SimpleSparqlUpdateBodyParser.ts +++ b/src/ldp/http/SimpleSparqlUpdateBodyParser.ts @@ -1,6 +1,7 @@ import { BodyParser } from './BodyParser'; +import { DATA_TYPE_BINARY } from '../../util/ContentTypes'; import { HttpRequest } from '../../server/HttpRequest'; -import { Readable } from 'stream'; +import { PassThrough } from 'stream'; import { readableToString } from '../../util/Util'; import { SparqlUpdatePatch } from './SparqlUpdatePatch'; import { translate } from 'sparqlalgebrajs'; @@ -23,17 +24,21 @@ export class SimpleSparqlUpdateBodyParser extends BodyParser { public async handle(input: HttpRequest): Promise { try { - const sparql = await readableToString(input); + // Note that readableObjectMode is only defined starting from Node 12 + // It is impossible to check if object mode is enabled in Node 10 (without accessing private variables) + const options = { objectMode: input.readableObjectMode }; + const toAlgebraStream = new PassThrough(options); + const dataCopy = new PassThrough(options); + input.pipe(toAlgebraStream); + input.pipe(dataCopy); + const sparql = await readableToString(toAlgebraStream); const algebra = translate(sparql, { quads: true }); // Prevent body from being requested again return { algebra, - dataType: 'sparql-algebra', - raw: sparql, - get data(): Readable { - throw new Error('Body already parsed'); - }, + dataType: DATA_TYPE_BINARY, + data: dataCopy, metadata: { raw: [], profiles: [], diff --git a/src/storage/patch/SimpleSparqlUpdatePatchHandler.ts b/src/storage/patch/SimpleSparqlUpdatePatchHandler.ts index 6b9ba8f23..e39cb7efc 100644 --- a/src/storage/patch/SimpleSparqlUpdatePatchHandler.ts +++ b/src/storage/patch/SimpleSparqlUpdatePatchHandler.ts @@ -28,7 +28,7 @@ export class SimpleSparqlUpdatePatchHandler extends PatchHandler { } public async canHandle(input: {identifier: ResourceIdentifier; patch: SparqlUpdatePatch}): Promise { - if (input.patch.dataType !== 'sparql-algebra' || !input.patch.algebra) { + if (typeof input.patch.algebra !== 'object') { throw new UnsupportedHttpError('Only SPARQL update patch requests are supported.'); } } diff --git a/test/integration/AuthenticatedLdpHandler.test.ts b/test/integration/AuthenticatedLdpHandler.test.ts index 8d942571c..13eaa54d3 100644 --- a/test/integration/AuthenticatedLdpHandler.test.ts +++ b/test/integration/AuthenticatedLdpHandler.test.ts @@ -120,8 +120,8 @@ describe('An AuthenticatedLdpHandler', (): void => { describe('with simple PATCH handlers', (): void => { const bodyParser: BodyParser = new CompositeAsyncHandler([ - new SimpleBodyParser(), new SimpleSparqlUpdateBodyParser(), + new SimpleBodyParser(), ]); const requestParser = new SimpleRequestParser({ targetExtractor: new SimpleTargetExtractor(), diff --git a/test/unit/ldp/http/SimpleSparqlUpdateBodyParser.test.ts b/test/unit/ldp/http/SimpleSparqlUpdateBodyParser.test.ts index e12375998..3981ae1fe 100644 --- a/test/unit/ldp/http/SimpleSparqlUpdateBodyParser.test.ts +++ b/test/unit/ldp/http/SimpleSparqlUpdateBodyParser.test.ts @@ -1,4 +1,6 @@ import { Algebra } from 'sparqlalgebrajs'; +import arrayifyStream from 'arrayify-stream'; +import { DATA_TYPE_BINARY } from '../../../../src/util/ContentTypes'; import { HttpRequest } from '../../../../src/server/HttpRequest'; import { SimpleSparqlUpdateBodyParser } from '../../../../src/ldp/http/SimpleSparqlUpdateBodyParser'; import streamifyArray from 'streamify-array'; @@ -32,13 +34,16 @@ describe('A SimpleSparqlUpdateBodyParser', (): void => { namedNode('http://test.com/p'), namedNode('http://test.com/o'), ) ]); - expect(result.dataType).toBe('sparql-algebra'); - expect(result.raw).toBe('DELETE DATA { }'); + expect(result.dataType).toBe(DATA_TYPE_BINARY); expect(result.metadata).toEqual({ raw: [], profiles: [], contentType: 'application/sparql-update', }); - expect((): any => result.data).toThrow('Body already parsed'); + + // Workaround for Node 10 not exposing objectMode + expect((await arrayifyStream(result.data)).join('')).toEqual( + 'DELETE DATA { }', + ); }); }); diff --git a/test/unit/storage/patch/SimpleSparqlUpdatePatchHandler.test.ts b/test/unit/storage/patch/SimpleSparqlUpdatePatchHandler.test.ts index 80b072999..e7bab4a5c 100644 --- a/test/unit/storage/patch/SimpleSparqlUpdatePatchHandler.test.ts +++ b/test/unit/storage/patch/SimpleSparqlUpdatePatchHandler.test.ts @@ -80,9 +80,9 @@ describe('A SimpleSparqlUpdatePatchHandler', (): void => { it('only accepts SPARQL updates.', async(): Promise => { const input = { identifier: { path: 'path' }, - patch: { dataType: 'sparql-algebra', algebra: {}} as SparqlUpdatePatch }; + patch: { algebra: {}} as SparqlUpdatePatch }; await expect(handler.canHandle(input)).resolves.toBeUndefined(); - input.patch.dataType = 'notAlgebra'; + delete input.patch.algebra; await expect(handler.canHandle(input)).rejects.toThrow(UnsupportedHttpError); });