Skip to content

Commit 094a28f

Browse files
committed
merge with master
2 parents 7757fce + 1bf360d commit 094a28f

17 files changed

Lines changed: 516 additions & 553 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ You can run `ldnode` as a [command-line tool](https://github.com/linkeddata/ldno
1818
- [x] WebID+TLS Authentication
1919
- [x] Real-time live updates (using WebSockets)
2020
- [x] Identity provider for WebID+TLS
21+
- [ ] Group members in ACL
2122

2223
## Command Line Usage
2324

bin/ldnode.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ function bin (argv) {
135135
try {
136136
app = ldnode.createServer(argv)
137137
} catch (e) {
138+
if (e.code === 'EACCES') {
139+
console.log('You need root privileges to start on this port')
140+
return 1
141+
}
142+
if (e.code === 'EADDRINUSE') {
143+
console.log('The port ' + argv.port + ' is already in use')
144+
return 1
145+
}
138146
console.log(e.message)
139147
console.log(e.stack)
140148
return 1

lib/handlers/delete.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
exports.handler = handler
1+
module.exports = handler
22

33
var debug = require('../debug').handlers
44

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
exports.handler = errorPageHandler
1+
module.exports = handler
22

33
var debug = require('../debug').server
44
var fs = require('fs')
55

6-
function errorPageHandler (err, req, res, next) {
6+
function handler (err, req, res, next) {
77
debug('Error page because of ' + err.message)
88

99
var ldp = req.app.locals.ldp

lib/handlers/get.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
exports.handler = get
1+
module.exports = handler
22

33
var fs = require('fs')
44
var glob = require('glob')
@@ -26,7 +26,7 @@ var RDFs = [
2626
'application/x-turtle'
2727
]
2828

29-
function get (req, res, next) {
29+
function handler (req, res, next) {
3030
var ldp = req.app.locals.ldp
3131
var includeBody = req.method === 'GET'
3232
var negotiator = new Negotiator(req)
@@ -74,7 +74,7 @@ function get (req, res, next) {
7474
// If request accepts the content-type we found
7575
if (negotiator.mediaType([contentType])) {
7676
debug('GET -- ' + req.originalUrl + ' no translation ' + contentType)
77-
res.setHeader('content-type', contentType)
77+
res.setHeader('Content-Type', contentType)
7878
return stream.pipe(res)
7979
}
8080

lib/handlers/patch.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
exports.handler = handler
1+
module.exports = handler
22

33
var mime = require('mime')
44
mime.default_type = 'text/turtle'
@@ -9,6 +9,18 @@ var utils = require('../utils.js')
99
var error = require('../http-error')
1010

1111
function handler (req, res, next) {
12+
req.setEncoding('utf8')
13+
req.text = ''
14+
req.on('data', function (chunk) {
15+
req.text += chunk
16+
})
17+
18+
req.on('end', function () {
19+
patchHandler(req, res, next)
20+
})
21+
}
22+
23+
function patchHandler (req, res, next) {
1224
var ldp = req.app.locals.ldp
1325
debug('PATCH -- ' + req.originalUrl)
1426
debug('PATCH -- text length: ' + (req.text ? req.text.length : 'undefined2'))

lib/handlers/post.js

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,99 @@
1-
exports.handler = handler
1+
module.exports = handler
22

3-
var debug = require('../debug').handlers
4-
var header = require('../header.js')
5-
var patch = require('./patch.js')
3+
var Busboy = require('busboy')
4+
var debug = require('debug')('ldnode:post')
5+
var header = require('../header')
6+
var patch = require('./patch')
67
var error = require('../http-error')
78

89
function handler (req, res, next) {
910
var ldp = req.app.locals.ldp
1011
var contentType = req.get('content-type')
11-
12+
debug('content-type is ', contentType)
1213
// Handle SPARQL(-update?) query
1314
if (contentType === 'application/sparql' ||
1415
contentType === 'application/sparql-update') {
15-
debug('POST -- Handling sparql query via PATCH')
16-
return patch.handler(req, res, next)
16+
debug('switching to sparql query')
17+
return patch(req, res, next)
1718
}
1819

20+
// Handle container path
1921
var containerPath = req.path
20-
debug('POST -- On parent: ' + containerPath)
21-
22-
// Not a container
2322
if (containerPath[containerPath.length - 1] !== '/') {
2423
containerPath += '/'
2524
}
2625

27-
debug('POST -- Content Type: ' + contentType)
28-
29-
var linkHeader = header.parseMetadataFromHeader(req.get('Link'))
30-
26+
// Check if container exists
3127
ldp.exists(req.hostname, containerPath, function (err, stats) {
3228
if (err) {
3329
return next(error(err, 'Container not valid'))
3430
}
3531

32+
// Check if container is a directory
3633
if (!stats.isDirectory()) {
37-
debug('POST -- Path is not a container')
38-
res.set('Allow', 'GET,HEAD,PUT,DELETE')
34+
debug('path is not a container, 405!')
3935
return next(error(405, 'Requested resource is not a container'))
4036
}
4137

42-
// TODO: possibly package this in ldp.post
43-
ldp.getAvailablePath(req.hostname, containerPath, req.get('Slug'), function (resourcePath) {
44-
debug('POST -- Will create at: ' + resourcePath)
45-
var meta = ''
46-
if (linkHeader.isBasicContainer) {
47-
resourcePath += '/'
48-
meta = ldp.suffixMeta
49-
}
38+
// Dispatch to the right handler
39+
if (req.is('multipart/form-data')) {
40+
multi(req, res, next)
41+
} else {
42+
one(req, res, next)
43+
}
44+
})
45+
46+
function multi () {
47+
debug('receving multiple files')
48+
49+
var busboy = new Busboy({ headers: req.headers })
50+
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
51+
debug('one file received via multipart: ' + filename)
52+
ldp.post(
53+
req.hostname,
54+
containerPath,
55+
filename,
56+
file,
57+
false,
58+
function (err) {
59+
if (err) {
60+
busboy.emit('error', err)
61+
}
62+
})
63+
})
64+
busboy.on('error', function (err) {
65+
debug('error receiving the file: ' + err.message)
66+
next(error(500, 'Error receiving the file'))
67+
})
68+
69+
// Handled by backpressure of streams!
70+
busboy.on('finish', function () {
71+
debug('done storing files')
72+
res.sendStatus(200)
73+
next()
74+
})
75+
req.pipe(busboy)
76+
}
5077

51-
ldp.put(req.hostname, resourcePath + meta, req.text, function (err) {
78+
function one () {
79+
debug('receving one file')
80+
var linkHeader = header.parseMetadataFromHeader(req.get('Link'))
81+
ldp.post(
82+
req.hostname,
83+
containerPath,
84+
req.get('Slug'),
85+
req,
86+
linkHeader.isBasicContainer,
87+
function (err, resourcePath) {
5288
if (err) {
5389
return next(err)
5490
}
55-
91+
debug('file stored on ' + resourcePath)
5692
header.addLinks(res, linkHeader)
5793
res.set('Location', resourcePath)
5894
res.sendStatus(201)
59-
return next()
95+
next()
6096
})
61-
})
62-
})
97+
}
6398
}
99+

lib/handlers/put.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
exports.handler = handler
1+
module.exports = handler
22

3-
var debug = require('../debug').handlers
3+
var debug = require('debug')('ldnode:put')
44

55
function handler (req, res, next) {
66
var ldp = req.app.locals.ldp
7-
debug('PUT -- originalUrl: ' + req.originalUrl)
7+
debug(req.originalUrl)
88
res.header('MS-Author-Via', 'SPARQL')
99

10-
ldp.put(req.hostname, req.path, req.text, function (err) {
10+
ldp.put(req.hostname, req.path, req, function (err) {
1111
if (err) {
12-
debug('PUT -- Write error: ' + err.message)
12+
debug('error putting the file:' + err.message)
1313
err.message = 'Can\'t write file: ' + err.message
1414
return next(err)
1515
}
1616

17-
debug('PUT -- Write Ok. Bytes written: ' + req.text.length)
17+
debug('succeded putting the file')
1818

1919
res.sendStatus(201)
2020
return next()
2121
})
2222
}
23+

lib/identity-provider.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ var waterfall = async.waterfall
1111
var debug = require('./debug').idp
1212
var express = require('express')
1313
var bodyParser = require('body-parser')
14-
var errorHandler = require('./handlers/error')
14+
var errorHandler = require('./handlers/error-pages')
1515
var url = require('url')
1616
var uriAbs = require('./utils').uriAbs
1717
var forge = require('node-forge')
1818
var asn1 = forge.asn1
1919
var pki = forge.pki
2020
var parse = require('./utils').parse
21+
var stringToStream = require('./utils').stringToStream
2122

2223
function defaultBuildURI (account, host, port) {
2324
var hostAndPort = (host || 'localhost') + (port || '')
@@ -52,10 +53,11 @@ IdentityProvider.prototype.putGraph = function (uri, graph) {
5253
var self = this
5354
return function (callback) {
5455
var content = $rdf.serialize(content, graph, uri, 'text/turtle')
56+
var stream = stringToStream(content)
5557
var parsed = url.parse(uri)
5658
var host = parsed.hostname
5759
var path = parsed.path
58-
return self.store.put(host, path, content, callback)
60+
return self.store.put(host, path, stream, callback)
5961
}
6062
}
6163

@@ -476,6 +478,6 @@ IdentityProvider.prototype.middleware = function (corsSettings) {
476478
var host = uriAbs(req)
477479
res.redirect('https://solid.github.io/solid-signup/?domain=' + host + '&acc=accounts/new&crt=accounts/cert')
478480
})
479-
router.use(errorHandler.handler)
481+
router.use(errorHandler)
480482
return router
481483
}

lib/ldp-middleware.js

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
module.exports = LdpMiddleware
22

33
var express = require('express')
4-
var getRawBody = require('raw-body')
5-
var responseTime = require('response-time')
64
var header = require('./header')
75
var acl = require('./acl')
86
var login = require('./login')
9-
var getHandler = require('./handlers/get.js')
10-
var postHandler = require('./handlers/post.js')
11-
var putHandler = require('./handlers/put.js')
12-
var deleteHandler = require('./handlers/delete.js')
13-
var patchHandler = require('./handlers/patch.js')
14-
var errorHandler = require('./handlers/error.js')
7+
var get = require('./handlers/get')
8+
var post = require('./handlers/post')
9+
var put = require('./handlers/put')
10+
var del = require('./handlers/delete')
11+
var patch = require('./handlers/patch')
12+
var errorPages = require('./handlers/error-pages')
1513

1614
function LdpMiddleware (corsSettings) {
1715
var router = express.Router('/')
@@ -21,45 +19,20 @@ function LdpMiddleware (corsSettings) {
2119
if (corsSettings) {
2220
router.use(corsSettings)
2321
}
24-
router.use('/*', function (req, res, next) {
25-
getRawBody(req, {
26-
length: req.headers['content-length'],
27-
encoding: 'utf-8' // typer.parse(req.headers['content-type']).parameters.charset
28-
},
29-
function (err, string) {
30-
if (err) {
31-
return next(err)
32-
}
33-
req.text = string
34-
next()
35-
})
36-
})
3722

3823
router.use('/*', login.loginHandler)
24+
router.get('/*', acl.allow('Read'), get)
25+
router.post('/*', acl.allow('Append'), post)
26+
router.patch('/*', acl.allow('Append'), patch)
27+
router.put('/*', acl.allow('Append'), put)
28+
router.delete('/*', acl.allow('Write'), del)
3929

40-
// ACL handlers
41-
router.get('/*', acl.allow('Read'))
42-
router.head('/*', acl.allow('Read'))
43-
router.post('/*', acl.allow('Append'))
44-
router.patch('/*', acl.allow('Append'))
45-
router.put('/*', acl.allow('Append'))
46-
router.delete('/*', acl.allow('Write'))
30+
// Errors
31+
router.use(errorPages)
4732

48-
// Convert json-ld and nquads to turtle
4933
// TODO: in the process of being deprecated
34+
// Convert json-ld and nquads to turtle
5035
// router.use('/*', parse.parseHandler)
5136

52-
// Add response time
53-
router.use(responseTime())
54-
55-
// HTTP methods handlers
56-
router.get('/*', getHandler.handler)
57-
router.put('/*', putHandler.handler)
58-
router.delete('/*', deleteHandler.handler)
59-
router.post('/*', postHandler.handler)
60-
router.patch('/*', patchHandler.handler)
61-
62-
// Error handling
63-
router.use(errorHandler.handler)
6437
return router
6538
}

0 commit comments

Comments
 (0)