fix(proxy/api/ndJsonStream): send header for empty iterables

Introduced by ed987e161
This commit is contained in:
Julien Fontanet 2021-10-29 17:04:36 +02:00
parent 4dc4b635f2
commit 84fdd3fe4b
2 changed files with 38 additions and 31 deletions

View File

@ -15,24 +15,29 @@ import { createLogger } from '@xen-orchestra/log'
const { debug, warn } = createLogger('xo:proxy:api')
const ndJsonStream = asyncIteratorToStream(async function*(responseId, iterable) {
let headerSent = false
try {
for await (const data of iterable) {
if (!headerSent) {
let cursor, iterator
try {
const getIterator = iterable[Symbol.iterator] ?? iterable[Symbol.asyncIterator]
iterator = getIterator.call(iterable)
cursor = await iterator.next()
yield format.response(responseId, { $responseType: 'ndjson' }) + '\n'
headerSent = true
} catch (error) {
yield format.error(responseId, error)
throw error
}
while (!cursor.done) {
try {
yield JSON.stringify(data) + '\n'
yield JSON.stringify(cursor.value) + '\n'
} catch (error) {
warn('ndJsonStream, item error', { error })
}
cursor = await iterator.next()
}
} catch (error) {
warn('ndJsonStream, fatal error', { error })
if (!headerSent) {
yield format.error(responseId, error)
}
}
})
@ -47,7 +52,7 @@ export default class Api {
ctx.req.setTimeout(0)
const profile = await app.authentication.findProfile({
authenticationToken: ctx.cookies.get('authenticationToken'),
authenticationToken: ctx.cookies.get('authenticationToken')
})
if (profile === undefined) {
ctx.status = 401
@ -126,14 +131,14 @@ export default class Api {
}
}.bind(this),
{
description: 'returns the signatures of all available API methods',
},
description: 'returns the signatures of all available API methods'
}
],
getServerVersion: [
() => appVersion,
{
description: 'returns the version of xo-server',
},
description: 'returns the version of xo-server'
}
],
listMethods: [
function*() {
@ -143,8 +148,8 @@ export default class Api {
}
}.bind(this),
{
description: 'returns the name of all available API methods',
},
description: 'returns the name of all available API methods'
}
],
methodSignature: [
({ method: name }) => {
@ -159,10 +164,10 @@ export default class Api {
{
description: 'returns the signature of an API method',
params: {
method: { type: 'string' },
},
},
],
method: { type: 'string' }
}
}
]
},
test: {
range: [
@ -184,11 +189,11 @@ export default class Api {
params: {
start: { optional: true, type: 'number' },
step: { optional: true, type: 'number' },
stop: { type: 'number' },
},
},
],
},
stop: { type: 'number' }
}
}
]
}
})
}
@ -215,7 +220,7 @@ export default class Api {
return required
}),
type: 'object',
type: 'object'
})
const m = params => {

View File

@ -27,3 +27,5 @@
> - major: if the change breaks compatibility
>
> In case of conflict, the highest (lowest in previous list) `$version` wins.
- @xen-orchestra/proxy patch