Skip to content

Commit

Permalink
fix: cancel stream reader on request abort (#158)
Browse files Browse the repository at this point in the history
We need to cancel the reader on request abort, otherwise we leak
resources.
  • Loading branch information
achingbrain authored Jul 9, 2024
1 parent 43af7c5 commit 5819965
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
"libp2p": "^1.3.1",
"multiformats": "^13.1.0",
"pino-pretty": "^11.0.0",
"private-ip": "^3.0.2"
"private-ip": "^3.0.2",
"race-signal": "^1.0.2"
},
"devDependencies": {
"@playwright/test": "^1.43.0",
Expand Down
13 changes: 9 additions & 4 deletions src/helia-http-gateway.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { raceSignal } from 'race-signal'
import { USE_SUBDOMAINS } from './constants.js'
import { dnsLinkLabelEncoder, isInlinedDnsLink } from './dns-link-labels.js'
import { getFullUrlFromFastifyRequest, getRequestAwareSignal } from './helia-server.js'
import { getIpnsAddressDetails } from './ipns-address-utils.js'
import type { VerifiedFetch } from '@helia/verified-fetch'
import type { ComponentLogger } from '@libp2p/interface'
import type { AbortOptions } from '@multiformats/multiaddr'
import type { FastifyReply, FastifyRequest, RouteOptions } from 'fastify'
import type { Helia } from 'helia'

Expand Down Expand Up @@ -91,10 +93,12 @@ export function httpGateway (opts: HeliaHTTPGatewayOptions): RouteOptions[] {
// internally, otherwise let the client making the request do it
const resp = await opts.fetch(url, { signal, redirect: USE_SUBDOMAINS ? 'manual' : 'follow' })

await convertVerifiedFetchResponseToFastifyReply(url, resp, reply)
await convertVerifiedFetchResponseToFastifyReply(url, resp, reply, {
signal
})
}

async function convertVerifiedFetchResponseToFastifyReply (url: string, verifiedFetchResponse: Response, reply: FastifyReply): Promise<void> {
async function convertVerifiedFetchResponseToFastifyReply (url: string, verifiedFetchResponse: Response, reply: FastifyReply, options: AbortOptions): Promise<void> {
if (!verifiedFetchResponse.ok) {
log('verified-fetch response for %s not ok: ', url, verifiedFetchResponse.status)
await reply.code(verifiedFetchResponse.status).send(verifiedFetchResponse.statusText)
Expand Down Expand Up @@ -123,14 +127,15 @@ export function httpGateway (opts: HeliaHTTPGatewayOptions): RouteOptions[] {
try {
let done = false
while (!done) {
const { done: _done, value } = await reader.read()
const { done: _done, value } = await raceSignal(reader.read(), options.signal)
if (value != null) {
reply.raw.write(Buffer.from(value))
}
done = _done
}
} catch (err) {
log.error('error reading response:', err)
log.error('error reading response for %s', url, err)
await reader.cancel(err)
} finally {
log.error('reading response for %s ended', url)
reply.raw.end()
Expand Down

0 comments on commit 5819965

Please sign in to comment.