Skip to content

Commit

Permalink
fix: directory url normalization is more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
SgtPooki committed Jan 31, 2025
1 parent 0d2feab commit c3572a2
Showing 1 changed file with 30 additions and 16 deletions.
46 changes: 30 additions & 16 deletions packages/verified-fetch/src/plugins/plugin-handle-dag-pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,28 @@ export class DagPbPlugin implements FetchHandlerPlugin {
return cid.code === dagPbCode
}

/**
* @see https://specs.ipfs.tech/http-gateways/path-gateway/#use-in-directory-url-normalization
*/
getRedirectUrl (context: PluginContext, pluginOptions: PluginOptions): string | null {
const { resource, path } = context
const redirectCheckNeeded = path === '' ? !resource.toString().endsWith('/') : !path.endsWith('/')
if (redirectCheckNeeded) {
try {
const url = new URL(resource.toString())
// make sure we append slash to end of the path
url.pathname = `${url.pathname}/`
return url.toString()
} catch (err: any) {
// resource is likely a CID
return `${resource.toString()}/`
}
}
return null
}

async handle (context: PluginContext, pluginOptions: PluginOptions): Promise<Response> {
const { cid, query } = context
const { cid } = context
const { logger, options, getBlockstore, handleServerTiming, withServerTiming = false, contentTypeParser, helia } = pluginOptions
const log = logger.forComponent('dag-pb-plugin')
const session = options?.session ?? true
Expand All @@ -46,27 +66,21 @@ export class DagPbPlugin implements FetchHandlerPlugin {

if (terminalElement?.type === 'directory') {
const dirCid = terminalElement.cid
// let redirectCheckNeeded = false
// if (query.format != null) {
const redirectCheckNeeded = path === '' ? !resource.toString().endsWith('/') : !path.endsWith('/')
// }
log.trace('path: %s, resource: %s, redirectCheckNeeded: %s', path, resource.toString(), redirectCheckNeeded)

// https://specs.ipfs.tech/http-gateways/path-gateway/#use-in-directory-url-normalization
if (redirectCheckNeeded) {
const redirectUrl = this.getRedirectUrl(context, pluginOptions)

if (redirectUrl != null) {
log.trace('directory url normalization spec requires redirect...')
if (options?.redirect === 'error') {
log('could not redirect to %s/ as redirect option was set to "error"', resource)
log('could not redirect to %s as redirect option was set to "error"', redirectUrl)
throw new TypeError('Failed to fetch')

Check warning on line 75 in packages/verified-fetch/src/plugins/plugin-handle-dag-pb.ts

View check run for this annotation

Codecov / codecov/patch

packages/verified-fetch/src/plugins/plugin-handle-dag-pb.ts#L74-L75

Added lines #L74 - L75 were not covered by tests
} else if (options?.redirect === 'manual') {
log('returning 301 permanent redirect to %s/', resource)
const url = new URL(resource.toString())
// make sure we append slash to end of the path
url.pathname = `${url.pathname}/`
return movedPermanentlyResponse(resource, url.toString())
log('returning 301 permanent redirect to %s', redirectUrl)
return movedPermanentlyResponse(resource, redirectUrl)
}
log('following redirect to %s', redirectUrl)

// fall-through simulates following the redirect?
resource = `${resource}/`
resource = redirectUrl
redirected = true
}

Expand Down

0 comments on commit c3572a2

Please sign in to comment.