Skip to content

Commit

Permalink
feat: Support LDN inbox headers
Browse files Browse the repository at this point in the history
* chore: add inbox mapping to metadatawriter config

* fix: correct inbox link rel

* feat: make LinkTypeParser reuseable to fit all link headers

* feat: minor code optimization

* feat: cleaned up metadata parser config

* feat: further cleanup of metadata parser config

* feat: adapted LinkMetadataParser to take a list to be in line with LinkRelMetadataWriter implementation

* feat: minor changes to be in line with other classes and code improvements

Co-authored-by: Wouter Termont <woutermont@gmail.com>
  • Loading branch information
BelgianNoise and woutermont committed Aug 25, 2021
1 parent ff200e2 commit 759112b
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 13 deletions.
11 changes: 8 additions & 3 deletions config/ldp/metadata-parser/default.json
@@ -1,14 +1,19 @@
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
"import": [
"files-scs:config/ldp/metadata-parser/parsers/content-type.json",
"files-scs:config/ldp/metadata-parser/parsers/slug.json",
"files-scs:config/ldp/metadata-parser/parsers/link.json"
],
"@graph": [
{
"comment": "Converts request metadata (e.g. headers) to RDF metadata.",
"@id": "urn:solid-server:default:MetadataParser",
"@type": "ParallelHandler",
"handlers": [
{ "@type": "ContentTypeParser" },
{ "@type": "LinkTypeParser" },
{ "@type": "SlugParser" }
{ "@id": "urn:solid-server:default:ContentTypeParser" },
{ "@id": "urn:solid-server:default:SlugParser" },
{ "@id": "urn:solid-server:default:LinkRelParser" }
]
}
]
Expand Down
10 changes: 10 additions & 0 deletions config/ldp/metadata-parser/parsers/content-type.json
@@ -0,0 +1,10 @@
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
"@graph": [
{
"comment": "Converts content-type headers into RDF metadata.",
"@id": "urn:solid-server:default:ContentTypeParser",
"@type": "ContentTypeParser"
}
]
}
20 changes: 20 additions & 0 deletions config/ldp/metadata-parser/parsers/link.json
@@ -0,0 +1,20 @@
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
"@graph": [
{
"comment": "Converts link headers into RDF metadata.",
"@id": "urn:solid-server:default:LinkRelParser",
"@type": "LinkRelParser",
"linkRelMap": [
{
"LinkRelParser:_linkRelMap_key": "type",
"LinkRelParser:_linkRelMap_value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
},
{
"LinkRelParser:_linkRelMap_key": "http://www.w3.org/ns/ldp#inbox",
"LinkRelParser:_linkRelMap_value": "http://www.w3.org/ns/ldp#inbox"
}
]
}
]
}
10 changes: 10 additions & 0 deletions config/ldp/metadata-parser/parsers/slug.json
@@ -0,0 +1,10 @@
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
"@graph": [
{
"comment": "Converts slug headers into RDF metadata.",
"@id": "urn:solid-server:default:SlugParser",
"@type": "SlugParser"
}
]
}
4 changes: 4 additions & 0 deletions config/ldp/metadata-writer/writers/link-rel.json
Expand Up @@ -13,6 +13,10 @@
{
"LinkRelMetadataWriter:_linkRelMap_key": "http://www.w3.org/ns/auth/acl#accessControl",
"LinkRelMetadataWriter:_linkRelMap_value": "acl"
},
{
"LinkRelMetadataWriter:_linkRelMap_key": "http://www.w3.org/ns/ldp#inbox",
"LinkRelMetadataWriter:_linkRelMap_value": "http://www.w3.org/ns/ldp#inbox"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Expand Up @@ -97,7 +97,7 @@ export * from './ldp/http/conditions/ConditionsParser';
export * from './ldp/http/metadata/ConstantMetadataWriter';
export * from './ldp/http/metadata/ContentTypeParser';
export * from './ldp/http/metadata/LinkRelMetadataWriter';
export * from './ldp/http/metadata/LinkTypeParser';
export * from './ldp/http/metadata/LinkRelParser';
export * from './ldp/http/metadata/MappedMetadataWriter';
export * from './ldp/http/metadata/MetadataParser';
export * from './ldp/http/metadata/MetadataWriter';
Expand Down
@@ -1,17 +1,27 @@
import type { NamedNode } from '@rdfjs/types';
import { DataFactory } from 'n3';
import { getLoggerFor } from '../../../logging/LogUtil';
import type { HttpRequest } from '../../../server/HttpRequest';
import { parseParameters, splitAndClean, transformQuotedStrings } from '../../../util/HeaderUtil';
import { RDF } from '../../../util/Vocabularies';
import type { RepresentationMetadata } from '../../representation/RepresentationMetadata';
import { MetadataParser } from './MetadataParser';
import namedNode = DataFactory.namedNode;

/**
* Parses Link headers with "rel=type" parameters and adds them as RDF.type metadata.
* Parses Link headers with a specific `rel` value and adds them as metadata with the given predicate.
*/
export class LinkTypeParser extends MetadataParser {
export class LinkRelParser extends MetadataParser {
protected readonly logger = getLoggerFor(this);

private readonly linkRelMap: Record<string, NamedNode>;

public constructor(linkRelMap: Record<string, string>) {
super();
this.linkRelMap = Object.fromEntries(
Object.entries(linkRelMap).map(([ header, uri ]): [string, NamedNode] => [ header, namedNode(uri) ]),
);
}

public async handle(input: { request: HttpRequest; metadata: RepresentationMetadata }): Promise<void> {
const link = input.request.headers.link ?? [];
const entries: string[] = Array.isArray(link) ? link : [ link ];
Expand All @@ -29,8 +39,8 @@ export class LinkTypeParser extends MetadataParser {
continue;
}
for (const { name, value } of parseParameters(parameters, replacements)) {
if (name === 'rel' && value === 'type') {
metadata.add(RDF.type, DataFactory.namedNode(link.slice(1, -1)));
if (name === 'rel' && this.linkRelMap[value]) {
metadata.add(this.linkRelMap[value], namedNode(link.slice(1, -1)));
}
}
}
Expand Down
@@ -1,10 +1,10 @@
import { LinkTypeParser } from '../../../../../src/ldp/http/metadata/LinkTypeParser';
import { LinkRelParser } from '../../../../../src/ldp/http/metadata/LinkRelParser';
import { RepresentationMetadata } from '../../../../../src/ldp/representation/RepresentationMetadata';
import type { HttpRequest } from '../../../../../src/server/HttpRequest';
import { RDF } from '../../../../../src/util/Vocabularies';

describe('A LinkTypeParser', (): void => {
const parser = new LinkTypeParser();
describe('A LinkParser', (): void => {
const parser = new LinkRelParser({ type: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' });
let request: HttpRequest;
let metadata: RepresentationMetadata;

Expand All @@ -18,7 +18,7 @@ describe('A LinkTypeParser', (): void => {
expect(metadata.quads()).toHaveLength(0);
});

it('stores link headers with rel = type as metadata.', async(): Promise<void> => {
it('stores link headers with rel matching the given value as metadata.', async(): Promise<void> => {
request.headers.link = '<http://test.com/type>;rel="type"';
await expect(parser.handle({ request, metadata })).resolves.toBeUndefined();
expect(metadata.quads()).toHaveLength(1);
Expand Down

0 comments on commit 759112b

Please sign in to comment.