diff --git a/src/ldp/http/SimpleTargetExtractor.ts b/src/ldp/http/SimpleTargetExtractor.ts index 27903e6ca..60320305f 100644 --- a/src/ldp/http/SimpleTargetExtractor.ts +++ b/src/ldp/http/SimpleTargetExtractor.ts @@ -1,6 +1,8 @@ +import { format } from 'url'; import { HttpRequest } from '../../server/HttpRequest'; import { ResourceIdentifier } from '../representation/ResourceIdentifier'; import { TargetExtractor } from './TargetExtractor'; +import { TLSSocket } from 'tls'; /** * Extracts an identifier from an incoming {@link HttpRequest}. @@ -14,6 +16,13 @@ export class SimpleTargetExtractor extends TargetExtractor { } public async handle(input: HttpRequest): Promise { - 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 }; } } diff --git a/test/integration/AuthenticatedLdpHandler.test.ts b/test/integration/AuthenticatedLdpHandler.test.ts index 25069ac72..233bcf5d6 100644 --- a/test/integration/AuthenticatedLdpHandler.test.ts +++ b/test/integration/AuthenticatedLdpHandler.test.ts @@ -18,6 +18,7 @@ import { SimpleResponseWriter } from '../../src/ldp/http/SimpleResponseWriter'; import { SimpleTargetExtractor } from '../../src/ldp/http/SimpleTargetExtractor'; import streamifyArray from 'streamify-array'; import { createResponse, MockResponse } from 'node-mocks-http'; +import * as url from 'url'; describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { 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 => { // POST + let requestUrl = new url.URL('http://test.com/'); let request = streamifyArray([ ' .' ]) as HttpRequest; - request.url = 'http://test.com/'; + request.url = requestUrl.pathname; request.method = 'POST'; request.headers = { 'content-type': 'text/turtle', + host: requestUrl.host, }; let response: MockResponse = createResponse({ eventEmitter: EventEmitter }); @@ -69,7 +72,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { expect(response.statusCode).toBe(200); expect(response._getData()).toHaveLength(0); id = response._getHeaders().location; - expect(id).toContain(request.url); + expect(id).toContain(url.format(requestUrl)); resolve(); }); }); @@ -78,11 +81,13 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { await endPromise; // GET + requestUrl = new url.URL(id); request = {} as HttpRequest; - request.url = id; + request.url = requestUrl.pathname; request.method = 'GET'; request.headers = { accept: 'text/turtle', + host: requestUrl.host, }; response = createResponse({ eventEmitter: EventEmitter }); @@ -91,7 +96,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { expect(response._isEndCalled()).toBeTruthy(); expect(response.statusCode).toBe(200); expect(response._getData()).toContain(' .'); - expect(response._getHeaders().location).toBe(request.url); + expect(response._getHeaders().location).toBe(url.format(requestUrl)); resolve(); }); }); @@ -101,9 +106,11 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { // DELETE request = {} as HttpRequest; - request.url = id; + request.url = requestUrl.pathname; request.method = 'DELETE'; - request.headers = {}; + request.headers = { + host: requestUrl.host, + }; response = createResponse({ eventEmitter: EventEmitter }); endPromise = new Promise((resolve): void => { @@ -111,7 +118,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { expect(response._isEndCalled()).toBeTruthy(); expect(response.statusCode).toBe(200); expect(response._getData()).toHaveLength(0); - expect(response._getHeaders().location).toBe(request.url); + expect(response._getHeaders().location).toBe(url.format(requestUrl)); resolve(); }); }); @@ -121,10 +128,11 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => { // GET request = {} as HttpRequest; - request.url = id; + request.url = requestUrl.pathname; request.method = 'GET'; request.headers = { accept: 'text/turtle', + host: requestUrl.host, }; response = createResponse({ eventEmitter: EventEmitter }); diff --git a/test/integration/RequestParser.test.ts b/test/integration/RequestParser.test.ts index d631b511f..dcc156cdf 100644 --- a/test/integration/RequestParser.test.ts +++ b/test/integration/RequestParser.test.ts @@ -17,11 +17,12 @@ describe('A SimpleRequestParser with simple input parsers', (): void => { it('can parse an incoming request.', async(): Promise => { const request = streamifyArray([ ' .' ]) as HttpRequest; request.method = 'POST'; - request.url = 'http://test.com/'; + request.url = '/'; request.headers = { accept: 'text/turtle; q=0.8', 'accept-language': 'en-gb, en;q=0.5', 'content-type': 'text/turtle', + host: 'test.com', }; const result = await requestParser.handle(request); diff --git a/test/unit/ldp/http/SimpleTargetExtractor.test.ts b/test/unit/ldp/http/SimpleTargetExtractor.test.ts index de9406277..112db596e 100644 --- a/test/unit/ldp/http/SimpleTargetExtractor.test.ts +++ b/test/unit/ldp/http/SimpleTargetExtractor.test.ts @@ -12,6 +12,11 @@ describe('A SimpleTargetExtractor', (): void => { }); it('returns the input URL.', async(): Promise => { - 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 => { + await expect(extractor.handle({ url: 'url', headers: { host: 'test.com' }, connection: { encrypted: true } as any } as any)) + .resolves.toEqual({ path: 'https://test.com/url' }); }); });