Skip to content

Commit 6813d57

Browse files
committed
squashing write-stream changes
1 parent a610bbd commit 6813d57

9 files changed

Lines changed: 123 additions & 57 deletions

File tree

lib/handlers/patch.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module.exports = handler
22

3-
var debug = require('../debug').handlers
3+
var Busboy = require('busboy')
4+
var each = require('async').each
5+
var debug = require('debug')('ldnode:post')
46
var header = require('../header')
57
var patch = require('./patch')
68
var error = require('../http-error')
@@ -12,52 +14,80 @@ function handler (req, res, next) {
1214
// Handle SPARQL(-update?) query
1315
if (contentType === 'application/sparql' ||
1416
contentType === 'application/sparql-update') {
15-
debug('POST -- Handling sparql query via PATCH')
17+
debug('switching to sparql query')
1618
return patch(req, res, next)
1719
}
1820

21+
// Handle container path
1922
var containerPath = req.path
20-
debug('POST -- On parent: ' + containerPath)
21-
22-
// Not a container
2323
if (containerPath[containerPath.length - 1] !== '/') {
2424
containerPath += '/'
2525
}
2626

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

33+
// Check if container is a directory
3634
if (!stats.isDirectory()) {
37-
debug('POST -- Path is not a container')
38-
res.set('Allow', 'GET,HEAD,PUT,DELETE')
35+
debug('path is not a container, 405!')
3936
return next(error(405, 'Requested resource is not a container'))
4037
}
4138

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-
}
39+
// Dispatch to the right handler
40+
if (contentType === 'multipart/form-data') {
41+
multi(req, res, next)
42+
} else {
43+
one(req, res, next)
44+
}
45+
})
46+
47+
function multi () {
48+
debug('receving multiple files')
49+
var busboy = new Busboy({ headers: req.headers })
50+
var files = []
5051

51-
ldp.put(req.hostname, resourcePath + meta, req.text, function (err) {
52+
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
53+
debug('one file received via multipart: ' + filename)
54+
files.push({stream: file, name: filename})
55+
})
56+
busboy.on('finish', function () {
57+
each(
58+
files,
59+
function (file, callback) {
60+
ldp.post(
61+
req.hostname,
62+
containerPath,
63+
file.filename,
64+
file.stream,
65+
false,
66+
callback)
67+
}, function (err) {
68+
debug('done storing files' + (err ? 'with error' + err.message : 'with no error'))
69+
res.sendStatus(err ? 500 : 200)
70+
})
71+
})
72+
}
73+
74+
function one () {
75+
debug('receving one file')
76+
var linkHeader = header.parseMetadataFromHeader(req.get('Link'))
77+
ldp.post(
78+
req.hostname,
79+
containerPath,
80+
req.get('Slug'),
81+
req,
82+
linkHeader.isBasicContainer,
83+
function (err, resourcePath) {
5284
if (err) {
53-
return next(err)
85+
next(err)
5486
}
55-
5687
header.addLinks(res, linkHeader)
5788
res.set('Location', resourcePath)
5889
res.sendStatus(201)
59-
return next()
6090
})
61-
})
62-
})
91+
}
6392
}
93+

lib/handlers/put.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ 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 || '')
@@ -51,10 +52,11 @@ IdentityProvider.prototype.putGraph = function (uri, graph) {
5152
var self = this
5253
return function (callback) {
5354
var content = $rdf.serialize(content, graph, uri, 'text/turtle')
55+
var stream = stringToStream(content)
5456
var parsed = url.parse(uri)
5557
var host = parsed.hostname
5658
var path = parsed.path
57-
return self.store.put(host, path, content, callback)
59+
return self.store.put(host, path, stream, callback)
5860
}
5961
}
6062

lib/ldp-middleware.js

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

33
var express = require('express')
4-
var getRawBody = require('raw-body')
54
var header = require('./header')
65
var acl = require('./acl')
76
var login = require('./login')
@@ -20,19 +19,6 @@ function LdpMiddleware (corsSettings) {
2019
if (corsSettings) {
2120
router.use(corsSettings)
2221
}
23-
router.use('/*', function (req, res, next) {
24-
getRawBody(req, {
25-
length: req.headers['content-length'],
26-
encoding: 'utf-8' // typer.parse(req.headers['content-type']).parameters.charset
27-
},
28-
function (err, string) {
29-
if (err) {
30-
return next(err)
31-
}
32-
req.text = string
33-
next()
34-
})
35-
})
3622

3723
router.use('/*', login.loginHandler)
3824
router.get('/*', acl.allow('Read'), get)

lib/ldp.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,30 @@ LDP.prototype.listContainer = function (filename, uri, containerData, contentTyp
311311
})
312312
}
313313

314-
LDP.prototype.put = function (host, resourcePath, contents, callback) {
314+
LDP.prototype.post = function (hostname, containerPath, slug, stream, container, callback) {
315+
var ldp = this
316+
317+
debug.handlers('POST -- On parent: ' + containerPath)
318+
319+
// TODO: possibly package this in ldp.post
320+
ldp.getAvailablePath(hostname, containerPath, slug, function (resourcePath) {
321+
debug.handlers('POST -- Will create at: ' + resourcePath)
322+
var meta = ''
323+
324+
if (container) {
325+
resourcePath += '/'
326+
meta = ldp.suffixMeta
327+
}
328+
329+
ldp.put(hostname, resourcePath + meta, stream, function (err) {
330+
if (err) callback(err)
331+
332+
callback(null, resourcePath)
333+
})
334+
})
335+
}
336+
337+
LDP.prototype.put = function (host, resourcePath, stream, callback) {
315338
var ldp = this
316339
var root = !ldp.idp ? ldp.root : ldp.root + host + '/'
317340
var filePath = utils.uriToFilename(resourcePath, root, host)
@@ -326,13 +349,12 @@ LDP.prototype.put = function (host, resourcePath, contents, callback) {
326349
debug.handlers('PUT -- Error creating directory: ' + err)
327350
return callback(error(err))
328351
}
329-
return fs.writeFile(filePath, contents, function (err) {
330-
if (err) {
331-
debug.handlers('PUT -- Error writing file: ' + err)
332-
return callback(error(err))
333-
}
334-
// Success!
335-
return callback(null)
352+
var file = stream.pipe(fs.createWriteStream(filePath))
353+
file.on('error', function () {
354+
callback(error(500))
355+
})
356+
file.on('finish', function () {
357+
callback(null)
336358
})
337359
})
338360
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"dependencies": {
2727
"async": "^1.3.0",
2828
"body-parser": "^1.14.2",
29+
"busboy": "^0.2.12",
2930
"cors": "^2.7.1",
3031
"debug": "^2.2.0",
3132
"express": "^4.13.3",

test/http.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,15 @@ describe('HTTP APIs', function () {
351351
.set('slug', 'loans')
352352
.set('link', '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"')
353353
.send(postRequest2Body)
354-
.expect(201, done)
354+
.expect(201)
355+
.end(function (err) {
356+
if (err) return done(err)
357+
var stats = fs.statSync(__dirname + '/resources/loans/')
358+
if (!stats.isDirectory()) {
359+
return done(new Error('Cannot read file just created'))
360+
}
361+
done()
362+
})
355363
})
356364
it('should be able to access container', function (done) {
357365
server.get('/loans')

test/ldp.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var assert = require('chai').assert
22
var $rdf = require('rdflib')
33
var ns = require('../lib/vocab/ns.js').ns
44
var LDP = require('../lib/ldp')
5+
var stringToStream = require('../lib/utils').stringToStream
56

67
// Helper functions for the FS
78
var rm = require('./test-utils').rm
@@ -68,7 +69,8 @@ describe('LDP', function () {
6869

6970
describe('put', function () {
7071
it('should write a file in an existing dir', function (done) {
71-
ldp.put('localhost', '/resources/testPut.txt', 'hello world', function (err) {
72+
var stream = stringToStream('hello world')
73+
ldp.put('localhost', '/resources/testPut.txt', stream, function (err) {
7274
assert.notOk(err)
7375
var found = read('testPut.txt')
7476
rm('testPut.txt')
@@ -78,7 +80,8 @@ describe('LDP', function () {
7880
})
7981

8082
it('should fail if a trailing `/` is passed', function (done) {
81-
ldp.put('localhost', '/resources/', 'hello world', function (err) {
83+
var stream = stringToStream('hello world')
84+
ldp.put('localhost', '/resources/', stream, function (err) {
8285
assert.equal(err.status, 409)
8386
done()
8487
})
@@ -87,7 +90,8 @@ describe('LDP', function () {
8790

8891
describe('delete', function () {
8992
it('should delete a file in an existing dir', function (done) {
90-
ldp.put('localhost', '/resources/testPut.txt', 'hello world', function (err) {
93+
var stream = stringToStream('hello world')
94+
ldp.put('localhost', '/resources/testPut.txt', stream, function (err) {
9195
assert.notOk(err)
9296
fs.stat(ldp.root + '/resources/testPut.txt', function (err) {
9397
if (err) {

0 commit comments

Comments
 (0)