mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Replace RedirectAllHttpHandler usage with RedirectingHttpHandler
This commit is contained in:
parent
89eeb52b01
commit
d2bc995272
@ -26,6 +26,7 @@ The following changes are relevant for v3 custom configs that replaced certain f
|
|||||||
### Interface changes
|
### Interface changes
|
||||||
These changes are relevant if you wrote custom modules for the server that depend on existing interfaces.
|
These changes are relevant if you wrote custom modules for the server that depend on existing interfaces.
|
||||||
- `YargsCliExtractor` was changed to now take as input an array of parameter objects.
|
- `YargsCliExtractor` was changed to now take as input an array of parameter objects.
|
||||||
|
- `RedirectAllHttpHandler` was removed and fully replaced by `RedirectingHttpHandler`.
|
||||||
|
|
||||||
## v4.0.0
|
## v4.0.0
|
||||||
### New features
|
### New features
|
||||||
|
@ -4,11 +4,17 @@
|
|||||||
{
|
{
|
||||||
"comment": "Redirects all request to the setup.",
|
"comment": "Redirects all request to the setup.",
|
||||||
"@id": "urn:solid-server:default:SetupRedirectHandler",
|
"@id": "urn:solid-server:default:SetupRedirectHandler",
|
||||||
"@type": "RedirectAllHttpHandler",
|
"@type": "RedirectingHttpHandler",
|
||||||
"args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
"redirects": [
|
||||||
"args_target": "/setup",
|
{
|
||||||
"args_targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
|
"RedirectingHttpHandler:_redirects_key": ".*",
|
||||||
"args_responseWriter": { "@id": "urn:solid-server:default:ResponseWriter" }
|
"RedirectingHttpHandler:_redirects_value": "/setup"
|
||||||
},
|
}
|
||||||
|
],
|
||||||
|
"baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" },
|
||||||
|
"targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" },
|
||||||
|
"responseWriter": { "@id": "urn:solid-server:default:ResponseWriter" },
|
||||||
|
"statusCode": 302
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,6 @@ export * from './server/HttpResponse';
|
|||||||
export * from './server/HttpServerFactory';
|
export * from './server/HttpServerFactory';
|
||||||
export * from './server/OperationHttpHandler';
|
export * from './server/OperationHttpHandler';
|
||||||
export * from './server/ParsingHttpHandler';
|
export * from './server/ParsingHttpHandler';
|
||||||
export * from './server/RedirectingHttpHandler';
|
|
||||||
export * from './server/WebSocketHandler';
|
export * from './server/WebSocketHandler';
|
||||||
export * from './server/WebSocketServerFactory';
|
export * from './server/WebSocketServerFactory';
|
||||||
|
|
||||||
@ -280,7 +279,7 @@ export * from './server/middleware/StaticAssetHandler';
|
|||||||
export * from './server/middleware/WebSocketAdvertiser';
|
export * from './server/middleware/WebSocketAdvertiser';
|
||||||
|
|
||||||
// Server/Util
|
// Server/Util
|
||||||
export * from './server/util/RedirectAllHttpHandler';
|
export * from './server/util/RedirectingHttpHandler';
|
||||||
export * from './server/util/RouterHandler';
|
export * from './server/util/RouterHandler';
|
||||||
|
|
||||||
// Storage/Accessors
|
// Storage/Accessors
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import type { TargetExtractor } from '../../http/input/identifier/TargetExtractor';
|
|
||||||
import { RedirectResponseDescription } from '../../http/output/response/RedirectResponseDescription';
|
|
||||||
import type { ResponseWriter } from '../../http/output/ResponseWriter';
|
|
||||||
import { FoundHttpError } from '../../util/errors/FoundHttpError';
|
|
||||||
import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError';
|
|
||||||
import { getRelativeUrl, joinUrl } from '../../util/PathUtil';
|
|
||||||
import type { HttpHandlerInput } from '../HttpHandler';
|
|
||||||
import { HttpHandler } from '../HttpHandler';
|
|
||||||
|
|
||||||
export interface RedirectAllHttpHandlerArgs {
|
|
||||||
baseUrl: string;
|
|
||||||
target: string;
|
|
||||||
targetExtractor: TargetExtractor;
|
|
||||||
responseWriter: ResponseWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will redirect all incoming requests to the given target.
|
|
||||||
* In case the incoming request already has the correct target,
|
|
||||||
* the `canHandle` call will reject the input.
|
|
||||||
*/
|
|
||||||
export class RedirectAllHttpHandler extends HttpHandler {
|
|
||||||
private readonly baseUrl: string;
|
|
||||||
private readonly target: string;
|
|
||||||
private readonly targetExtractor: TargetExtractor;
|
|
||||||
private readonly responseWriter: ResponseWriter;
|
|
||||||
|
|
||||||
public constructor(args: RedirectAllHttpHandlerArgs) {
|
|
||||||
super();
|
|
||||||
this.baseUrl = args.baseUrl;
|
|
||||||
this.target = args.target;
|
|
||||||
this.targetExtractor = args.targetExtractor;
|
|
||||||
this.responseWriter = args.responseWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async canHandle({ request }: HttpHandlerInput): Promise<void> {
|
|
||||||
const target = await getRelativeUrl(this.baseUrl, request, this.targetExtractor);
|
|
||||||
if (target === this.target) {
|
|
||||||
throw new NotImplementedHttpError('Target is already correct.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async handle({ response }: HttpHandlerInput): Promise<void> {
|
|
||||||
const result = new RedirectResponseDescription(new FoundHttpError(joinUrl(this.baseUrl, this.target)));
|
|
||||||
await this.responseWriter.handleSafe({ response, result });
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +1,18 @@
|
|||||||
import type { TargetExtractor } from '../http/input/identifier/TargetExtractor';
|
import type { TargetExtractor } from '../../http/input/identifier/TargetExtractor';
|
||||||
import { RedirectResponseDescription } from '../http/output/response/RedirectResponseDescription';
|
import { RedirectResponseDescription } from '../../http/output/response/RedirectResponseDescription';
|
||||||
import type { ResponseWriter } from '../http/output/ResponseWriter';
|
import type { ResponseWriter } from '../../http/output/ResponseWriter';
|
||||||
import { getLoggerFor } from '../logging/LogUtil';
|
import { getLoggerFor } from '../../logging/LogUtil';
|
||||||
import { FoundHttpError } from '../util/errors/FoundHttpError';
|
import { FoundHttpError } from '../../util/errors/FoundHttpError';
|
||||||
import { MovedPermanentlyHttpError } from '../util/errors/MovedPermanentlyHttpError';
|
import { MovedPermanentlyHttpError } from '../../util/errors/MovedPermanentlyHttpError';
|
||||||
import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError';
|
import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError';
|
||||||
import { PermanentRedirectHttpError } from '../util/errors/PermanentRedirectHttpError';
|
import { PermanentRedirectHttpError } from '../../util/errors/PermanentRedirectHttpError';
|
||||||
import type { RedirectHttpError } from '../util/errors/RedirectHttpError';
|
import type { RedirectHttpError } from '../../util/errors/RedirectHttpError';
|
||||||
import { SeeOtherHttpError } from '../util/errors/SeeOtherHttpError';
|
import { SeeOtherHttpError } from '../../util/errors/SeeOtherHttpError';
|
||||||
import { TemporaryRedirectHttpError } from '../util/errors/TemporaryRedirectHttpError';
|
import { TemporaryRedirectHttpError } from '../../util/errors/TemporaryRedirectHttpError';
|
||||||
import { getRelativeUrl, joinUrl } from '../util/PathUtil';
|
import { getRelativeUrl, joinUrl } from '../../util/PathUtil';
|
||||||
import type { HttpHandlerInput } from './HttpHandler';
|
import type { HttpHandlerInput } from '../HttpHandler';
|
||||||
import { HttpHandler } from './HttpHandler';
|
import { HttpHandler } from '../HttpHandler';
|
||||||
import type { HttpRequest } from './HttpRequest';
|
import type { HttpRequest } from '../HttpRequest';
|
||||||
|
|
||||||
const redirectErrorFactories: Record<301 | 302 | 303 | 307 | 308, (location: string) => RedirectHttpError> = {
|
const redirectErrorFactories: Record<301 | 302 | 303 | 307 | 308, (location: string) => RedirectHttpError> = {
|
||||||
301: (location: string): RedirectHttpError => new MovedPermanentlyHttpError(location),
|
301: (location: string): RedirectHttpError => new MovedPermanentlyHttpError(location),
|
@ -1,53 +0,0 @@
|
|||||||
import type { TargetExtractor } from '../../../../src/http/input/identifier/TargetExtractor';
|
|
||||||
import type { ResponseWriter } from '../../../../src/http/output/ResponseWriter';
|
|
||||||
import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier';
|
|
||||||
import type { HttpRequest } from '../../../../src/server/HttpRequest';
|
|
||||||
import type { HttpResponse } from '../../../../src/server/HttpResponse';
|
|
||||||
import { RedirectAllHttpHandler } from '../../../../src/server/util/RedirectAllHttpHandler';
|
|
||||||
import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError';
|
|
||||||
import { joinUrl } from '../../../../src/util/PathUtil';
|
|
||||||
import { SOLID_HTTP } from '../../../../src/util/Vocabularies';
|
|
||||||
|
|
||||||
describe('A RedirectAllHttpHandler', (): void => {
|
|
||||||
const baseUrl = 'http://test.com/';
|
|
||||||
const target = '/foo';
|
|
||||||
const absoluteTarget = 'http://test.com/foo';
|
|
||||||
let request: HttpRequest;
|
|
||||||
const response: HttpResponse = {} as any;
|
|
||||||
let targetExtractor: jest.Mocked<TargetExtractor>;
|
|
||||||
let responseWriter: jest.Mocked<ResponseWriter>;
|
|
||||||
let handler: RedirectAllHttpHandler;
|
|
||||||
|
|
||||||
beforeEach(async(): Promise<void> => {
|
|
||||||
request = { url: '/foo' } as any;
|
|
||||||
|
|
||||||
targetExtractor = {
|
|
||||||
handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url!) })),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
responseWriter = { handleSafe: jest.fn() } as any;
|
|
||||||
|
|
||||||
handler = new RedirectAllHttpHandler({ baseUrl, target, targetExtractor, responseWriter });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('rejects requests for the target.', async(): Promise<void> => {
|
|
||||||
request.url = target;
|
|
||||||
await expect(handler.canHandle({ request, response })).rejects.toThrow(NotImplementedHttpError);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('accepts all other requests.', async(): Promise<void> => {
|
|
||||||
request.url = '/otherPath';
|
|
||||||
await expect(handler.canHandle({ request, response })).resolves.toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('writes out a redirect response.', async(): Promise<void> => {
|
|
||||||
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
|
|
||||||
expect(responseWriter.handleSafe).toHaveBeenCalledTimes(1);
|
|
||||||
expect(responseWriter.handleSafe).toHaveBeenLastCalledWith({
|
|
||||||
response,
|
|
||||||
result: expect.objectContaining({ statusCode: 302 }),
|
|
||||||
});
|
|
||||||
const { metadata } = responseWriter.handleSafe.mock.calls[0][0].result;
|
|
||||||
expect(metadata?.get(SOLID_HTTP.terms.location)?.value).toBe(absoluteTarget);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,11 +1,11 @@
|
|||||||
import type { TargetExtractor } from '../../../src/http/input/identifier/TargetExtractor';
|
import type { TargetExtractor } from '../../../../src/http/input/identifier/TargetExtractor';
|
||||||
import type { ResponseWriter } from '../../../src/http/output/ResponseWriter';
|
import type { ResponseWriter } from '../../../../src/http/output/ResponseWriter';
|
||||||
import type { ResourceIdentifier } from '../../../src/http/representation/ResourceIdentifier';
|
import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier';
|
||||||
import type { HttpRequest } from '../../../src/server/HttpRequest';
|
import type { HttpRequest } from '../../../../src/server/HttpRequest';
|
||||||
import type { HttpResponse } from '../../../src/server/HttpResponse';
|
import type { HttpResponse } from '../../../../src/server/HttpResponse';
|
||||||
import { RedirectingHttpHandler } from '../../../src/server/RedirectingHttpHandler';
|
import { RedirectingHttpHandler } from '../../../../src/server/util/RedirectingHttpHandler';
|
||||||
import { joinUrl } from '../../../src/util/PathUtil';
|
import { joinUrl } from '../../../../src/util/PathUtil';
|
||||||
import { SOLID_HTTP } from '../../../src/util/Vocabularies';
|
import { SOLID_HTTP } from '../../../../src/util/Vocabularies';
|
||||||
|
|
||||||
describe('A RedirectingHttpHandler', (): void => {
|
describe('A RedirectingHttpHandler', (): void => {
|
||||||
const baseUrl = 'http://test.com/';
|
const baseUrl = 'http://test.com/';
|
Loading…
x
Reference in New Issue
Block a user