mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Prevent server from crashing if requested data can't be handled
This commit is contained in:
parent
ea788ba406
commit
ccd3f1738c
@ -98,7 +98,7 @@ export class AuthenticatedLdpHandler extends HttpHandler {
|
|||||||
|
|
||||||
const writeData = { response: input.response, description, error: err };
|
const writeData = { response: input.response, description, error: err };
|
||||||
|
|
||||||
return this.responseWriter.handleSafe(writeData);
|
await this.responseWriter.handleSafe(writeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,11 @@ export class SimpleResponseWriter extends ResponseWriter {
|
|||||||
if (!input.description && !input.error) {
|
if (!input.description && !input.error) {
|
||||||
throw new UnsupportedHttpError('Either a description or an error is required for output.');
|
throw new UnsupportedHttpError('Either a description or an error is required for output.');
|
||||||
}
|
}
|
||||||
|
if (input.description && input.description.body) {
|
||||||
|
if (input.description.body.dataType !== 'binary' && input.description.body.dataType !== 'string') {
|
||||||
|
throw new UnsupportedHttpError('Only string or binary results are supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handle(input: { response: HttpResponse; description?: ResponseDescription; error?: Error }): Promise<void> {
|
public async handle(input: { response: HttpResponse; description?: ResponseDescription; error?: Error }): Promise<void> {
|
||||||
|
@ -21,7 +21,13 @@ export class ExpressHttpServer {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
app.use(async(request, response): Promise<void> => {
|
app.use(async(request, response): Promise<void> => {
|
||||||
await this.handler.handleSafe({ request, response });
|
try {
|
||||||
|
await this.handler.handleSafe({ request, response });
|
||||||
|
} catch (error) {
|
||||||
|
const errMsg = `${error.name}: ${error.message}\n${error.stack}`;
|
||||||
|
process.stderr.write(errMsg);
|
||||||
|
response.status(500).send(errMsg);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return app.listen(port);
|
return app.listen(port);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ describe('An AuthenticatedLdpHandler', (): void => {
|
|||||||
it('can handle input.', async(): Promise<void> => {
|
it('can handle input.', async(): Promise<void> => {
|
||||||
const handler = new AuthenticatedLdpHandler(args);
|
const handler = new AuthenticatedLdpHandler(args);
|
||||||
|
|
||||||
await expect(handler.handle({ request: 'request' as any, response: 'response' as any })).resolves.toEqual('response');
|
await expect(handler.handle({ request: 'request' as any, response: 'response' as any })).resolves.toEqual(undefined);
|
||||||
expect(responseFn).toHaveBeenCalledTimes(1);
|
expect(responseFn).toHaveBeenCalledTimes(1);
|
||||||
expect(responseFn).toHaveBeenLastCalledWith({ response: 'response', description: 'operation' as any });
|
expect(responseFn).toHaveBeenLastCalledWith({ response: 'response', description: 'operation' as any });
|
||||||
});
|
});
|
||||||
@ -51,7 +51,7 @@ describe('An AuthenticatedLdpHandler', (): void => {
|
|||||||
args.requestParser = new StaticAsyncHandler(false, null);
|
args.requestParser = new StaticAsyncHandler(false, null);
|
||||||
const handler = new AuthenticatedLdpHandler(args);
|
const handler = new AuthenticatedLdpHandler(args);
|
||||||
|
|
||||||
await expect(handler.handle({ request: 'request' as any, response: null })).resolves.toEqual('response');
|
await expect(handler.handle({ request: 'request' as any, response: null })).resolves.toEqual(undefined);
|
||||||
expect(responseFn).toHaveBeenCalledTimes(1);
|
expect(responseFn).toHaveBeenCalledTimes(1);
|
||||||
expect(responseFn.mock.calls[0][0].error).toBeInstanceOf(Error);
|
expect(responseFn.mock.calls[0][0].error).toBeInstanceOf(Error);
|
||||||
});
|
});
|
||||||
|
@ -20,6 +20,12 @@ describe('A SimpleResponseWriter', (): void => {
|
|||||||
await expect(writer.canHandle({ response })).rejects.toThrow(UnsupportedHttpError);
|
await expect(writer.canHandle({ response })).rejects.toThrow(UnsupportedHttpError);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('requires the description body to be a string or binary stream if present.', async(): Promise<void> => {
|
||||||
|
await expect(writer.canHandle({ response, description: { body: { dataType: 'quad' }} as ResponseDescription })).rejects.toThrow(UnsupportedHttpError);
|
||||||
|
await expect(writer.canHandle({ response, description: { body: { dataType: 'string' }} as ResponseDescription })).resolves.toBeUndefined();
|
||||||
|
await expect(writer.canHandle({ response, description: { body: { dataType: 'binary' }} as ResponseDescription })).resolves.toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('responds with status code 200 and a location header if there is a description.', async(): Promise<void> => {
|
it('responds with status code 200 and a location header if there is a description.', async(): Promise<void> => {
|
||||||
await writer.handle({ response, description: { identifier: { path: 'path' }}});
|
await writer.handle({ response, description: { identifier: { path: 'path' }}});
|
||||||
expect(response._isEndCalled()).toBeTruthy();
|
expect(response._isEndCalled()).toBeTruthy();
|
||||||
|
@ -24,8 +24,9 @@ describe('ExpressHttpServer', (): void => {
|
|||||||
let server: Server;
|
let server: Server;
|
||||||
let canHandleJest: jest.Mock<Promise<void>, []>;
|
let canHandleJest: jest.Mock<Promise<void>, []>;
|
||||||
let handleJest: jest.Mock<Promise<void>, [any]>;
|
let handleJest: jest.Mock<Promise<void>, [any]>;
|
||||||
|
let handler: SimpleHttpHandler;
|
||||||
beforeEach(async(): Promise<void> => {
|
beforeEach(async(): Promise<void> => {
|
||||||
const handler = new SimpleHttpHandler();
|
handler = new SimpleHttpHandler();
|
||||||
canHandleJest = jest.fn(async(): Promise<void> => undefined);
|
canHandleJest = jest.fn(async(): Promise<void> => undefined);
|
||||||
handleJest = jest.fn(async(input): Promise<void> => handle(input));
|
handleJest = jest.fn(async(input): Promise<void> => handle(input));
|
||||||
|
|
||||||
@ -74,4 +75,12 @@ describe('ExpressHttpServer', (): void => {
|
|||||||
response: expect.objectContaining({}),
|
response: expect.objectContaining({}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('catches errors thrown by its handler.', async(): Promise<void> => {
|
||||||
|
handler.handle = async(): Promise<void> => {
|
||||||
|
throw new Error('dummyError');
|
||||||
|
};
|
||||||
|
const res = await request(server).get('/').expect(500);
|
||||||
|
expect(res.text).toContain('dummyError');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user