fix: Take host into account when extracting identifier

This commit is contained in:
Joachim Van Herwegen 2020-07-10 14:17:10 +02:00
parent 792323797d
commit cff9790b6e
4 changed files with 34 additions and 11 deletions

View File

@ -1,6 +1,8 @@
import { format } from 'url';
import { HttpRequest } from '../../server/HttpRequest'; import { HttpRequest } from '../../server/HttpRequest';
import { ResourceIdentifier } from '../representation/ResourceIdentifier'; import { ResourceIdentifier } from '../representation/ResourceIdentifier';
import { TargetExtractor } from './TargetExtractor'; import { TargetExtractor } from './TargetExtractor';
import { TLSSocket } from 'tls';
/** /**
* Extracts an identifier from an incoming {@link HttpRequest}. * Extracts an identifier from an incoming {@link HttpRequest}.
@ -14,6 +16,13 @@ export class SimpleTargetExtractor extends TargetExtractor {
} }
public async handle(input: HttpRequest): Promise<ResourceIdentifier> { public async handle(input: HttpRequest): Promise<ResourceIdentifier> {
return { path: input.url }; const isHttps = input.connection && (input.connection as TLSSocket).encrypted;
const url = format({
protocol: `http${isHttps ? 's' : ''}`,
host: input.headers.host,
pathname: input.url,
});
return { path: url };
} }
} }

View File

@ -18,6 +18,7 @@ import { SimpleResponseWriter } from '../../src/ldp/http/SimpleResponseWriter';
import { SimpleTargetExtractor } from '../../src/ldp/http/SimpleTargetExtractor'; import { SimpleTargetExtractor } from '../../src/ldp/http/SimpleTargetExtractor';
import streamifyArray from 'streamify-array'; import streamifyArray from 'streamify-array';
import { createResponse, MockResponse } from 'node-mocks-http'; import { createResponse, MockResponse } from 'node-mocks-http';
import * as url from 'url';
describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
let handler: AuthenticatedLdpHandler; let handler: AuthenticatedLdpHandler;
@ -54,11 +55,13 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
it('can add, read and delete data based on incoming requests.', async(): Promise<void> => { it('can add, read and delete data based on incoming requests.', async(): Promise<void> => {
// POST // POST
let requestUrl = new url.URL('http://test.com/');
let request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest; let request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest;
request.url = 'http://test.com/'; request.url = requestUrl.pathname;
request.method = 'POST'; request.method = 'POST';
request.headers = { request.headers = {
'content-type': 'text/turtle', 'content-type': 'text/turtle',
host: requestUrl.host,
}; };
let response: MockResponse<any> = createResponse({ eventEmitter: EventEmitter }); let response: MockResponse<any> = createResponse({ eventEmitter: EventEmitter });
@ -69,7 +72,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
expect(response.statusCode).toBe(200); expect(response.statusCode).toBe(200);
expect(response._getData()).toHaveLength(0); expect(response._getData()).toHaveLength(0);
id = response._getHeaders().location; id = response._getHeaders().location;
expect(id).toContain(request.url); expect(id).toContain(url.format(requestUrl));
resolve(); resolve();
}); });
}); });
@ -78,11 +81,13 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
await endPromise; await endPromise;
// GET // GET
requestUrl = new url.URL(id);
request = {} as HttpRequest; request = {} as HttpRequest;
request.url = id; request.url = requestUrl.pathname;
request.method = 'GET'; request.method = 'GET';
request.headers = { request.headers = {
accept: 'text/turtle', accept: 'text/turtle',
host: requestUrl.host,
}; };
response = createResponse({ eventEmitter: EventEmitter }); response = createResponse({ eventEmitter: EventEmitter });
@ -91,7 +96,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
expect(response._isEndCalled()).toBeTruthy(); expect(response._isEndCalled()).toBeTruthy();
expect(response.statusCode).toBe(200); expect(response.statusCode).toBe(200);
expect(response._getData()).toContain('<http://test.com/s> <http://test.com/p> <http://test.com/o>.'); expect(response._getData()).toContain('<http://test.com/s> <http://test.com/p> <http://test.com/o>.');
expect(response._getHeaders().location).toBe(request.url); expect(response._getHeaders().location).toBe(url.format(requestUrl));
resolve(); resolve();
}); });
}); });
@ -101,9 +106,11 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
// DELETE // DELETE
request = {} as HttpRequest; request = {} as HttpRequest;
request.url = id; request.url = requestUrl.pathname;
request.method = 'DELETE'; request.method = 'DELETE';
request.headers = {}; request.headers = {
host: requestUrl.host,
};
response = createResponse({ eventEmitter: EventEmitter }); response = createResponse({ eventEmitter: EventEmitter });
endPromise = new Promise((resolve): void => { endPromise = new Promise((resolve): void => {
@ -111,7 +118,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
expect(response._isEndCalled()).toBeTruthy(); expect(response._isEndCalled()).toBeTruthy();
expect(response.statusCode).toBe(200); expect(response.statusCode).toBe(200);
expect(response._getData()).toHaveLength(0); expect(response._getData()).toHaveLength(0);
expect(response._getHeaders().location).toBe(request.url); expect(response._getHeaders().location).toBe(url.format(requestUrl));
resolve(); resolve();
}); });
}); });
@ -121,10 +128,11 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
// GET // GET
request = {} as HttpRequest; request = {} as HttpRequest;
request.url = id; request.url = requestUrl.pathname;
request.method = 'GET'; request.method = 'GET';
request.headers = { request.headers = {
accept: 'text/turtle', accept: 'text/turtle',
host: requestUrl.host,
}; };
response = createResponse({ eventEmitter: EventEmitter }); response = createResponse({ eventEmitter: EventEmitter });

View File

@ -17,11 +17,12 @@ describe('A SimpleRequestParser with simple input parsers', (): void => {
it('can parse an incoming request.', async(): Promise<void> => { it('can parse an incoming request.', async(): Promise<void> => {
const request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest; const request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest;
request.method = 'POST'; request.method = 'POST';
request.url = 'http://test.com/'; request.url = '/';
request.headers = { request.headers = {
accept: 'text/turtle; q=0.8', accept: 'text/turtle; q=0.8',
'accept-language': 'en-gb, en;q=0.5', 'accept-language': 'en-gb, en;q=0.5',
'content-type': 'text/turtle', 'content-type': 'text/turtle',
host: 'test.com',
}; };
const result = await requestParser.handle(request); const result = await requestParser.handle(request);

View File

@ -12,6 +12,11 @@ describe('A SimpleTargetExtractor', (): void => {
}); });
it('returns the input URL.', async(): Promise<void> => { it('returns the input URL.', async(): Promise<void> => {
await expect(extractor.handle({ url: 'url' } as any)).resolves.toEqual({ path: 'url' }); await expect(extractor.handle({ url: 'url', headers: { host: 'test.com' }} as any)).resolves.toEqual({ path: 'http://test.com/url' });
});
it('uses https protocol if the connection is secure.', async(): Promise<void> => {
await expect(extractor.handle({ url: 'url', headers: { host: 'test.com' }, connection: { encrypted: true } as any } as any))
.resolves.toEqual({ path: 'https://test.com/url' });
}); });
}); });