Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ur): do not parse body on root mu POST route, if request is an assignment #697 #703

Merged
merged 1 commit into from
May 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 47 additions & 25 deletions servers/ur/src/routes/mu.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,55 @@ export function mountMuRoutesWith ({ app, middleware }) {
return middleware({ processIdFromRequest: () => 'process' })(req, res, next)
})

/**
* Since the MU receives opaque data items, we have to unpack it, to know which MU
* to route to
*/
app.post('/', express.raw({ type: 'application/octet-stream', limit: '10mb' }), middleware({
processIdFromRequest: async (req) => {
const dataItem = new DataItem(Buffer.from(req.body))

if (!(await dataItem.isValid())) throw new InvalidDataItemError('A valid and signed data item must be provided as the body')
/**
* The processId is the target on a message data item
*/
if (isMessage(dataItem)) return dataItem.target
/**
* The processId is the dataItem itself on a process data item
*/
if (isProcess(dataItem)) return dataItem.id
app.post('/',
(req, res, next) => {
if (req.query.assign) {
/**
* This flag is used in subsequent steps to branch
* (see below)
*/
req.isAssignment = true
return next()
}

throw new InvalidDataItemError('Could not determine ao type of DataItem based on tag \'Type\'')
return express.raw({ type: 'application/octet-stream', limit: '10mb' })(req, res, next)
},
/**
* Since we consumed the request stream in order to parse the data item and
* determine the processId, we must provide a new request stream, to be sent
* as the body on proxied request
*/
restreamBody: (req) => Readable.from(req.body)
}))
middleware({
processIdFromRequest: async (req) => {
/**
* This request is an assignment, so there is no reason
* to consume the body in order to extract the processId
*
* as it is instead available as query parameter
*/
if (req.isAssignment) return req.query['process-id']

/**
* Since the MU receives opaque data items, the only place to extract the process id is
* the data item itself. So we first parse and validate the data item, then extract the process id
* based on the data item type.
*/
const dataItem = new DataItem(Buffer.from(req.body))

if (!(await dataItem.isValid())) throw new InvalidDataItemError('A valid and signed data item must be provided as the body')
/**
* The processId is the target on a message data item
*/
if (isMessage(dataItem)) return dataItem.target
/**
* The processId is the dataItem itself on a process data item
*/
if (isProcess(dataItem)) return dataItem.id

throw new InvalidDataItemError('Could not determine ao type of DataItem based on tag \'Type\'')
},
/**
* Since we consumed the request stream in order to parse the data item and
* determine the processId, we must provide a new request stream, to be sent
* as the body on proxied request
*/
restreamBody: (req) => Readable.from(req.body)
}))

app.post('/monitor/:processId', middleware({ processIdFromRequest: (req) => req.params.processId }))
app.delete('/monitor/:processId', middleware({ processIdFromRequest: (req) => req.params.processId }))
Expand Down