Repository: solid/community-server
Pull request #636 (2021-02-26 12:02:30)

Fix/sparql patch content type
See: https://github.com/solid/community-server/issues/637

RubenVerborgh: + integration test?

Patch:
diff --git a/src/ldp/http/SparqlUpdateBodyParser.ts b/src/ldp/http/SparqlUpdateBodyParser.ts
index 494ae9c3c..cf8d60f11 100644
--- a/src/ldp/http/SparqlUpdateBodyParser.ts
+++ b/src/ldp/http/SparqlUpdateBodyParser.ts
@@ -16,9 +16,8 @@ import type { SparqlUpdatePatch } from './SparqlUpdatePatch';
 export class SparqlUpdateBodyParser extends BodyParser {
   protected readonly logger = getLoggerFor(this);
 
-  public async canHandle({ request }: BodyParserArgs): Promise<void> {
-    const contentType = request.headers['content-type'];
-    if (contentType !== APPLICATION_SPARQL_UPDATE) {
+  public async canHandle({ metadata }: BodyParserArgs): Promise<void> {
+    if (metadata.contentType !== APPLICATION_SPARQL_UPDATE) {
       throw new UnsupportedMediaTypeHttpError('This parser only supports SPARQL UPDATE data.');
     }
   }


Test patch:
diff --git a/test/integration/LpdHandlerOperations.test.ts b/test/integration/LpdHandlerOperations.test.ts
index 185d1ccd2..829c20efd 100644
--- a/test/integration/LpdHandlerOperations.test.ts
+++ b/test/integration/LpdHandlerOperations.test.ts
@@ -107,6 +107,21 @@ describe('An integrated AuthenticatedLdpHandler', (): void => {
     expect(response.statusCode).toBe(205);
     expect(response._getData()).toHaveLength(0);
 
+    // PATCH using a content-type header with charset
+    requestUrl = new URL(id);
+    response = await performRequest(
+      handler,
+      requestUrl,
+      'PATCH',
+      { 'content-type': ' application/sparql-update ; charset=UTF-8', 'transfer-encoding': 'chunked' },
+      [ 'DELETE { <s1> <http://test.com/p1> <http://test.com/o1> }',
+        'INSERT {<s3> <http://test.com/p3> <http://test.com/o3>}',
+        'WHERE {}',
+      ],
+    );
+    expect(response.statusCode).toBe(205);
+    expect(response._getData()).toHaveLength(0);
+
     // GET
     response = await performRequest(handler, requestUrl, 'GET', { accept: 'text/turtle' }, []);
     expect(response.statusCode).toBe(200);
diff --git a/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts b/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts
index 35b8b63bc..3d53c73e6 100644
--- a/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts
+++ b/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts
@@ -21,9 +21,13 @@ describe('A SparqlUpdateBodyParser', (): void => {
 
   it('only accepts application/sparql-update content.', async(): Promise<void> => {
     await expect(bodyParser.canHandle(input)).rejects.toThrow(UnsupportedMediaTypeHttpError);
-    input.request.headers = { 'content-type': 'text/plain' };
+    input.metadata.contentType = 'text/plain';
     await expect(bodyParser.canHandle(input)).rejects.toThrow(UnsupportedMediaTypeHttpError);
-    input.request.headers = { 'content-type': 'application/sparql-update' };
+    input.metadata.contentType = 'application/sparql-update;charset=utf-8';
+    await expect(bodyParser.canHandle(input)).rejects.toThrow(UnsupportedMediaTypeHttpError);
+    input.metadata.contentType = 'application/sparql-update ; foo=bar';
+    await expect(bodyParser.canHandle(input)).rejects.toThrow(UnsupportedMediaTypeHttpError);
+    input.metadata.contentType = 'application/sparql-update';
     await expect(bodyParser.canHandle(input)).resolves.toBeUndefined();
   });