(payload, res, reply)
| 738 | } |
| 739 | |
| 740 | function sendWebStream (payload, res, reply) { |
| 741 | if (payload.locked) { |
| 742 | throw new FST_ERR_REP_READABLE_STREAM_LOCKED() |
| 743 | } |
| 744 | |
| 745 | let sourceOpen = true |
| 746 | let errorLogged = false |
| 747 | let waitingDrain = false |
| 748 | const reader = payload.getReader() |
| 749 | |
| 750 | eos(res, function (err) { |
| 751 | if (sourceOpen) { |
| 752 | if (err != null && res.headersSent && !errorLogged) { |
| 753 | errorLogged = true |
| 754 | logStreamError(reply.log, err, res) |
| 755 | } |
| 756 | reader.cancel().catch(noop) |
| 757 | } |
| 758 | }) |
| 759 | |
| 760 | if (!res.headersSent) { |
| 761 | for (const key in reply[kReplyHeaders]) { |
| 762 | res.setHeader(key, reply[kReplyHeaders][key]) |
| 763 | } |
| 764 | } else { |
| 765 | reply.log.warn('response will send, but you shouldn\'t use res.writeHead in stream mode') |
| 766 | } |
| 767 | |
| 768 | function onRead (result) { |
| 769 | if (result.done) { |
| 770 | sourceOpen = false |
| 771 | sendTrailer(null, res, reply) |
| 772 | return |
| 773 | } |
| 774 | /* c8 ignore next 5 - race condition: eos handler typically fires first */ |
| 775 | if (res.destroyed) { |
| 776 | sourceOpen = false |
| 777 | reader.cancel().catch(noop) |
| 778 | return |
| 779 | } |
| 780 | const shouldContinue = res.write(result.value) |
| 781 | if (shouldContinue === false) { |
| 782 | waitingDrain = true |
| 783 | res.once('drain', onDrain) |
| 784 | return |
| 785 | } |
| 786 | reader.read().then(onRead, onReadError) |
| 787 | } |
| 788 | |
| 789 | function onDrain () { |
| 790 | if (!waitingDrain || !sourceOpen || res.destroyed) { |
| 791 | return |
| 792 | } |
| 793 | waitingDrain = false |
| 794 | reader.read().then(onRead, onReadError) |
| 795 | } |
| 796 | |
| 797 | function onReadError (err) { |
no test coverage detected