requestEnd: Now properly supports ctx.headers and properly sends all headers to res with status code using writeHead
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
FileResponse: Initial development started to serve files
This commit is contained in:
parent
acb099868b
commit
cfd56f83ae
3 changed files with 80 additions and 38 deletions
32
flaska.mjs
32
flaska.mjs
|
@ -277,15 +277,22 @@ export function FormidableHandler(formidable, org = {}) {
|
||||||
|
|
||||||
export class HttpError extends Error {
|
export class HttpError extends Error {
|
||||||
constructor(statusCode, message, body = null) {
|
constructor(statusCode, message, body = null) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
||||||
Error.captureStackTrace(this, HttpError);
|
Error.captureStackTrace(this, HttpError);
|
||||||
|
|
||||||
let proto = Object.getPrototypeOf(this);
|
let proto = Object.getPrototypeOf(this);
|
||||||
proto.name = 'HttpError';
|
proto.name = 'HttpError';
|
||||||
|
|
||||||
this.status = statusCode
|
this.status = statusCode
|
||||||
this.body = body
|
this.body = body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FileResponse {
|
||||||
|
constructor(filepath, stat) {
|
||||||
|
this.filepath = filepath
|
||||||
|
this.stat = stat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,6 +837,7 @@ ctx.state.nonce = nonce;
|
||||||
|
|
||||||
ctx.res.statusCode = ctx.status
|
ctx.res.statusCode = ctx.status
|
||||||
if (statuses.empty[ctx.status]) {
|
if (statuses.empty[ctx.status]) {
|
||||||
|
ctx.res.writeHead(ctx.status, ctx.headers)
|
||||||
return ctx.res.end()
|
return ctx.res.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,20 +853,24 @@ ctx.state.nonce = nonce;
|
||||||
ctx.type = found[found.length - 1]
|
ctx.type = found[found.length - 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.res.setHeader('Content-Type', ctx.type || 'application/octet-stream')
|
ctx.headers['Content-Type'] = ctx.type || 'application/octet-stream'
|
||||||
|
|
||||||
|
ctx.res.writeHead(ctx.status, ctx.headers)
|
||||||
return this.stream.pipeline(body, ctx.res, function() { })
|
return this.stream.pipeline(body, ctx.res, function() { })
|
||||||
}
|
}
|
||||||
if (typeof(body) === 'object') {
|
if (typeof(body) === 'object') {
|
||||||
body = JSON.stringify(body)
|
body = JSON.stringify(body)
|
||||||
length = Buffer.byteLength(body)
|
length = Buffer.byteLength(body)
|
||||||
ctx.res.setHeader('Content-Type', 'application/json; charset=utf-8')
|
ctx.headers['Content-Type'] = 'application/json; charset=utf-8'
|
||||||
} else {
|
} else {
|
||||||
body = body.toString()
|
body = body.toString()
|
||||||
length = Buffer.byteLength(body)
|
length = Buffer.byteLength(body)
|
||||||
ctx.res.setHeader('Content-Type', ctx.type || 'text/plain; charset=utf-8')
|
ctx.headers['Content-Type'] = ctx.type || 'text/plain; charset=utf-8'
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.res.setHeader('Content-Length', length)
|
ctx.headers['Content-Length'] = length
|
||||||
|
|
||||||
|
ctx.res.writeHead(ctx.status, ctx.headers)
|
||||||
ctx.res.end(body)
|
ctx.res.end(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
test/fileResponse.test.mjs
Normal file
19
test/fileResponse.test.mjs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { Eltro as t, assert, stub } from 'eltro'
|
||||||
|
import { FileResponse } from '../flaska.mjs'
|
||||||
|
|
||||||
|
t.test('should add path and stat', function() {
|
||||||
|
const assertPath = 'some/path/here'
|
||||||
|
const assertStat = { a: 1 }
|
||||||
|
|
||||||
|
let fileRes = new FileResponse(assertPath, assertStat)
|
||||||
|
|
||||||
|
assert.strictEqual(fileRes.filepath, assertPath)
|
||||||
|
assert.strictEqual(fileRes.stat, assertStat)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.describe('CreateReader()', function() {
|
||||||
|
t.test('should return fileReader for file with correct seeking', function() {
|
||||||
|
const stubCreateReadStream = stub()
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
|
@ -17,13 +17,13 @@ t.describe('#requestEnd()', function() {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.body, assertBody)
|
assert.strictEqual(ctx.body, assertBody)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.callCount, 2)
|
assert.strictEqual(ctx.headers['Content-Type'], 'application/json; charset=utf-8')
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], 'application/json; charset=utf-8')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[0], 'Content-Length')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[1], assertBodyLength)
|
|
||||||
assert.ok(body)
|
assert.ok(body)
|
||||||
assert.strictEqual(body, '{"a":1}')
|
assert.strictEqual(body, '{"a":1}')
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -72,13 +72,13 @@ t.describe('#requestEnd()', function() {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.body, assertBody)
|
assert.strictEqual(ctx.body, assertBody)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.callCount, 2)
|
assert.strictEqual(ctx.headers['Content-Type'], 'application/json; charset=utf-8')
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], 'application/json; charset=utf-8')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[0], 'Content-Length')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[1], assertBodyLength)
|
|
||||||
assert.ok(body)
|
assert.ok(body)
|
||||||
assert.strictEqual(body, '{"a":1}')
|
assert.strictEqual(body, '{"a":1}')
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -101,13 +101,13 @@ t.describe('#requestEnd()', function() {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.body, assertBody)
|
assert.strictEqual(ctx.body, assertBody)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.callCount, 2)
|
assert.strictEqual(ctx.headers['Content-Type'], 'text/plain; charset=utf-8')
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], 'text/plain; charset=utf-8')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[0], 'Content-Length')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[1], assertBodyLength)
|
|
||||||
assert.ok(body)
|
assert.ok(body)
|
||||||
assert.strictEqual(body, assertBody)
|
assert.strictEqual(body, assertBody)
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -130,13 +130,13 @@ t.describe('#requestEnd()', function() {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.body, assertBody)
|
assert.strictEqual(ctx.body, assertBody)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.callCount, 2)
|
assert.strictEqual(ctx.headers['Content-Type'], 'text/plain; charset=utf-8')
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], 'text/plain; charset=utf-8')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[0], 'Content-Length')
|
|
||||||
assert.strictEqual(ctx.res.setHeader.secondCall[1], assertBodyLength)
|
|
||||||
assert.ok(body)
|
assert.ok(body)
|
||||||
assert.strictEqual(body, assertBody.toString())
|
assert.strictEqual(body, assertBody.toString())
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -157,9 +157,11 @@ t.describe('#requestEnd()', function() {
|
||||||
try {
|
try {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Type'], assertType)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], assertType)
|
|
||||||
assert.strictEqual(body, assertBody)
|
assert.strictEqual(body, assertBody)
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -182,11 +184,13 @@ t.describe('#requestEnd()', function() {
|
||||||
try {
|
try {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Type'], assertType)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], assertType)
|
|
||||||
assert.strictEqual(source, assertBody)
|
assert.strictEqual(source, assertBody)
|
||||||
assert.strictEqual(target, ctx.res)
|
assert.strictEqual(target, ctx.res)
|
||||||
assert.strictEqual(typeof(callback), 'function')
|
assert.strictEqual(typeof(callback), 'function')
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -205,10 +209,12 @@ t.describe('#requestEnd()', function() {
|
||||||
let onFinish = function(source, target) {
|
let onFinish = function(source, target) {
|
||||||
try {
|
try {
|
||||||
assert.strictEqual(ctx.res.statusCode, 200)
|
assert.strictEqual(ctx.res.statusCode, 200)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Type'], 'application/octet-stream')
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], 'application/octet-stream')
|
|
||||||
assert.strictEqual(source, ctx.body)
|
assert.strictEqual(source, ctx.body)
|
||||||
assert.strictEqual(target, ctx.res)
|
assert.strictEqual(target, ctx.res)
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -232,10 +238,12 @@ t.describe('#requestEnd()', function() {
|
||||||
let onFinish = function(source, target) {
|
let onFinish = function(source, target) {
|
||||||
try {
|
try {
|
||||||
assert.strictEqual(ctx.res.statusCode, 200)
|
assert.strictEqual(ctx.res.statusCode, 200)
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[0], 'Content-Type')
|
assert.strictEqual(ctx.headers['Content-Type'], test[1])
|
||||||
assert.strictEqual(ctx.res.setHeader.firstCall[1], test[1])
|
|
||||||
assert.strictEqual(source, ctx.body)
|
assert.strictEqual(source, ctx.body)
|
||||||
assert.strictEqual(target, ctx.res)
|
assert.strictEqual(target, ctx.res)
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
}
|
}
|
||||||
|
@ -271,6 +279,9 @@ t.describe('#requestEnd()', function() {
|
||||||
assert.strictEqual(ctx.status, assertStatus)
|
assert.strictEqual(ctx.status, assertStatus)
|
||||||
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
assert.strictEqual(ctx.res.statusCode, assertStatus)
|
||||||
assert.strictEqual(ctx.res.setHeader.callCount, 0)
|
assert.strictEqual(ctx.res.setHeader.callCount, 0)
|
||||||
|
assert.ok(ctx.res.writeHead.called)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||||
|
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||||
assert.notOk(body)
|
assert.notOk(body)
|
||||||
cb()
|
cb()
|
||||||
} catch (err) { cb(err) }
|
} catch (err) { cb(err) }
|
||||||
|
|
Loading…
Reference in a new issue