Skip to content

Commit 513d861

Browse files
Flesh out LdpGetOperation.from()
1 parent 239ac2b commit 513d861

3 files changed

Lines changed: 62 additions & 31 deletions

File tree

lib/api/ldp/api.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class LdpHttpHandler {
5757
*/
5858
async handleRequest (req, res, next) {
5959
try {
60-
const operation = this.operationFrom({req, store: this.store})
60+
const operation = this.operationFrom(req)
6161

6262
// check that operation is permitted (throws error if not)
6363
const permissions = await this.acl.allow(operation)
@@ -75,6 +75,13 @@ class LdpHttpHandler {
7575
}
7676
}
7777

78+
/**
79+
* LdpOperation factory method
80+
*
81+
* @param req {IncomingRequest}
82+
*
83+
* @returns {Promise<LdpOperation>}
84+
*/
7885
async operationFrom (req) {
7986
const options = this.parseOperation(req)
8087

@@ -83,23 +90,22 @@ class LdpHttpHandler {
8390
throw new HttpError(405, 'Method not supported')
8491
}
8592

86-
return new Operation(options)
93+
return Operation.from(options)
8794
}
8895

8996
/**
90-
* LdpOperation factory method
91-
*
9297
* @param req {IncomingRequest}
9398
*
94-
* @returns {Promise<LdpOperation>}
99+
* @returns {object} Operation constructor params object
95100
*/
96-
async parseOperation (req) {
101+
parseOperation (req) {
97102
const { method, headers, session: { authentication } } = req
98103

99104
const target = this.host.parseTargetUrl(req)
100105
const bodyStream = req // TODO: create a lazy parser here
101106

102-
return {method, headers, target, bodyStream, authentication}
107+
// Note: store is needed for LdpGetOperation factory
108+
return {method, headers, target, bodyStream, authentication, store: this.store}
103109
}
104110
}
105111

lib/api/ldp/ldp-operation.js

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const url = require('url')
44
const glob = require('glob')
5-
const HttpError = require('standard-http-error')
5+
// const HttpError = require('standard-http-error')
66

77
const BY_METHOD = {
88
'head': LdpHeadOperation,
@@ -39,24 +39,19 @@ class LdpOperation {
3939
}
4040

4141
/**
42-
* Taken from utils.getBaseUri()
42+
* General construction method, overridden where needed (such as in
43+
* LdpGetOperation).
4344
*
44-
* @param req {IncomingRequest}
45-
* @param host {SolidHost}
45+
* @param options {object}
4646
*
47-
* @returns {URL}
47+
* @returns {LdpOperation}
4848
*/
49-
static parseTargetUrl ({req, host}) {
50-
const protocol = host.serverUri.replace(/:.*/, '')
51-
52-
return url.format({
53-
protocol: protocol || req.protocol,
54-
host: req.get('host'),
55-
pathname: url.resolve(req.baseUrl, req.path),
56-
query: req.query
57-
})
49+
static from (options) {
50+
const Operation = this
51+
return new Operation(options)
5852
}
5953

54+
6055
writeCommonHeaders ({res}) {
6156
// set headers in common to all LDP responses
6257
}
@@ -81,28 +76,40 @@ class LdpHeadOperation extends LdpOperation {
8176
* - Need to also support similar use case if index.ttl exists
8277
* - "Glob pattern request" if glob magic chars are detected (ie `*`)
8378
* - Otherwise, plain Get request
79+
*
80+
* @return {LdpGlobOperation|LdpListContainerOperation|LdpGetOperation}
8481
*/
8582
class LdpGetOperation extends LdpOperation {
86-
static from ({headers, target, bodyStream, authentication, store}) {
83+
static from (options) {
84+
const { store, target } = options
8785
const targetUrl = url.format(target)
8886

8987
if (glob.hasMagic(targetUrl)) {
90-
// this is a Ldp Glob operation, return that
88+
return new LdpGlobOperation(options)
9189
}
9290

93-
// check to see if target is a container (based on Link: type rel)
94-
// ...
95-
// if it is a container, check to see if index.html exists
96-
const indexFile = url.resolve(targetUrl, '/index.html')
97-
if (store.exists(indexFile)) {
98-
// this is an implicit Get operation to the index file
99-
// return it
91+
const isContainer = targetUrl.endsWith('/')
92+
93+
if (isContainer) {
94+
// if it is a container, check to see if index.html exists
95+
const indexFile = url.resolve(targetUrl, '/index.html')
96+
97+
if (store.exists(indexFile)) {
98+
return new LdpGetOperation({target: indexFile, ...options})
99+
}
100+
101+
return new LdpListContainerOperation(options)
100102
}
101103

102-
// return plain get operation
104+
// plain get operation
105+
return new LdpGetOperation(options)
103106
}
104107
}
105108

109+
class LdpListContainerOperation extends LdpGetOperation {}
110+
111+
class LdpGlobOperation extends LdpGetOperation {}
112+
106113
/**
107114
* Creates a resource or container, and any necessary containers above it in
108115
* the hierarchy. Idempotent.

lib/models/solid-host.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ class SolidHost {
111111

112112
return cookieDomain
113113
}
114+
115+
/**
116+
* Taken from utils.getBaseUri()
117+
*
118+
* @param req {IncomingRequest}
119+
*
120+
* @returns {URL}
121+
*/
122+
parseTargetUrl (req) {
123+
const protocol = this.serverUri.replace(/:.*/, '')
124+
125+
return url.format({
126+
protocol: protocol || req.protocol,
127+
host: req.get('host'),
128+
pathname: url.resolve(req.baseUrl, req.path),
129+
query: req.query
130+
})
131+
}
114132
}
115133

116134
function getHostName (url) {

0 commit comments

Comments
 (0)