Skip to content
This repository was archived by the owner on Apr 29, 2020. It is now read-only.

Commit 4155796

Browse files
committed
refactor: pass mode and mtime in headers
1 parent 93ec9c0 commit 4155796

File tree

2 files changed

+44
-33
lines changed

2 files changed

+44
-33
lines changed

src/parser.js

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,55 +45,51 @@ const ignore = async (stream) => {
4545
}
4646

4747
async function * parseEntry (stream, options) {
48-
let entry = {}
49-
5048
for await (const part of stream) {
51-
let type
49+
if (!part.headers['content-type']) {
50+
throw new Error('No content-type in multipart part')
51+
}
5252

53-
if (part.headers['content-type']) {
54-
type = Content.type(part.headers['content-type'])
53+
const type = Content.type(part.headers['content-type'])
5554

56-
if (type.boundary) {
57-
// recursively parse nested multiparts
58-
yield * parser(part.body, {
59-
...options,
60-
boundary: type.boundary
61-
})
55+
if (type.boundary) {
56+
// recursively parse nested multiparts
57+
yield * parser(part.body, {
58+
...options,
59+
boundary: type.boundary
60+
})
6261

63-
continue
64-
}
62+
continue
6563
}
6664

6765
if (!part.headers['content-disposition']) {
6866
throw new Error('No content disposition in multipart part')
6967
}
7068

71-
const disposition = parseDisposition(part.headers['content-disposition'])
69+
const entry = {}
7270

73-
if (disposition.name.includes('mtime')) {
74-
entry.mtime = parseInt((await collect(part.body)).toString('utf8'), 10)
71+
if (part.headers.mtime) {
72+
entry.mtime = parseInt(part.headers.mtime, 10)
7573
}
7674

77-
if (disposition.name.includes('mode')) {
78-
entry.mode = parseInt((await collect(part.body)).toString('utf8'), 10)
75+
if (part.headers.mode) {
76+
entry.mode = parseInt(part.headers.mode, 8)
7977
}
8078

81-
if (type) {
82-
if (isDirectory(type.mime)) {
83-
entry.type = 'directory'
84-
} else if (type.mime === applicationSymlink) {
85-
entry.type = 'symlink'
86-
} else {
87-
entry.type = 'file'
88-
}
79+
if (isDirectory(type.mime)) {
80+
entry.type = 'directory'
81+
} else if (type.mime === applicationSymlink) {
82+
entry.type = 'symlink'
83+
} else {
84+
entry.type = 'file'
85+
}
8986

90-
entry.name = decodeURIComponent(disposition.filename)
91-
entry.body = part.body
87+
const disposition = parseDisposition(part.headers['content-disposition'])
9288

93-
yield entry
89+
entry.name = decodeURIComponent(disposition.filename)
90+
entry.body = part.body
9491

95-
entry = {}
96-
}
92+
yield entry
9793
}
9894
}
9995

test/parser.spec.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,28 @@ describe('parser', () => {
111111

112112
it('parses regular multipart requests correctly', (done) => {
113113
const formData = {
114-
mtime: fileMtime,
115-
mode: fileMode,
116114
file: fs.createReadStream(filePath)
117115
}
118116

119117
request.post({ url: `http://localhost:${PORT}`, formData: formData }, (err) => done(err))
120118
})
119+
120+
it('parses multipart requests with metatdata correctly', (done) => {
121+
const r = request.post({ url: `http://localhost:${PORT}` }, (err) => done(err))
122+
123+
// request uses an old version of form-data so this is clunky
124+
const CRLF = '\r\n'
125+
const form = r.form()
126+
form.append('file', fileContent, {
127+
header: [
128+
`--${form.getBoundary()}`,
129+
'content-type: application/octet-stream',
130+
'content-disposition: form-data; filename="file.txt"; name="file"',
131+
`mtime: ${fileMtime}`,
132+
`mode: ${fileMode}`
133+
].join(CRLF) + CRLF
134+
})
135+
})
121136
})
122137

123138
describe('directory', () => {

0 commit comments

Comments
 (0)