feat: Create router rule based on matching the base URL

This commit is contained in:
Joachim Van Herwegen
2021-02-25 17:05:54 +01:00
parent b160121176
commit b78599182c
3 changed files with 88 additions and 0 deletions

View File

@@ -190,6 +190,7 @@ export * from './storage/patch/PatchHandler';
export * from './storage/patch/SparqlUpdatePatchHandler';
// Storage/Routing
export * from './storage/routing/BaseUrlRouterRule';
export * from './storage/routing/ConvertingRouterRule';
export * from './storage/routing/PreferenceSupport';
export * from './storage/routing/RegexRouterRule';

View File

@@ -0,0 +1,48 @@
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
import type { KeyValueStorage } from '../keyvalue/KeyValueStorage';
import type { ResourceStore } from '../ResourceStore';
import { RouterRule } from './RouterRule';
/**
* Routes requests based on their base url.
* Checks if any of the stored base URLs match the request identifier.
* If there are no matches the base store will be returned if one was configured.
*
* Part of the dynamic pod creation.
* Uses the identifiers that were added to the routing storage.
* @see {@link TemplatedPodGenerator}, {@link ConfigPodInitializer}, {@link ConfigPodManager}
*/
export class BaseUrlRouterRule extends RouterRule {
private readonly baseStore?: ResourceStore;
private readonly stores: KeyValueStorage<ResourceIdentifier, ResourceStore>;
public constructor(stores: KeyValueStorage<ResourceIdentifier, ResourceStore>, baseStore?: ResourceStore) {
super();
this.baseStore = baseStore;
this.stores = stores;
}
public async handle({ identifier }: { identifier: ResourceIdentifier }): Promise<ResourceStore> {
try {
return await this.findStore(identifier);
} catch (error: unknown) {
if (this.baseStore) {
return this.baseStore;
}
throw error;
}
}
/**
* Finds the store whose base url key is contained in the given identifier.
*/
private async findStore(identifier: ResourceIdentifier): Promise<ResourceStore> {
for await (const [ key, store ] of this.stores.entries()) {
if (identifier.path.startsWith(key.path)) {
return store;
}
}
throw new NotFoundHttpError();
}
}