Skip to content

Commit

Permalink
feat: add url to server's onRequest callback (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoboucas authored Apr 1, 2024
1 parent 90a0412 commit 89f5ce4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
12 changes: 9 additions & 3 deletions src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ test('Reads and writes from the file system', async () => {
}

// Store #1: Edge access
const server1Ops: string[] = []
const server1Ops: { type: string; url: string }[] = []
const directory1 = await tmp.dir()
const server1 = new BlobsServer({
directory: directory1.path,
onRequest: ({ type }) => server1Ops.push(type),
onRequest: ({ type, url }) => server1Ops.push({ type, url }),
token,
})

Expand Down Expand Up @@ -113,7 +113,13 @@ test('Reads and writes from the file system', async () => {
expect(list3.directories).toEqual([])
}

expect(server1Ops).toEqual([
const urls = server1Ops.map(({ url }) => url)

expect(urls.every((url) => url.startsWith(`/${siteID}/`))).toBeTruthy()

const operations = server1Ops.map(({ type }) => type)

expect(operations).toEqual([
'list',
'set',
'get',
Expand Down
34 changes: 21 additions & 13 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export enum Operation {
SET = 'set',
}

export type OnRequestCallback = (parameters: { type: Operation; url: string }) => void

// TODO: Replace with `promises` import of `node:stream` once we can drop
// support for Node 14.
const pipeline = promisify(stream.pipeline)
Expand All @@ -49,7 +51,7 @@ interface BlobsServerOptions {
/**
* Callback function to be called on every request.
*/
onRequest?: (parameters: { type: Operation }) => void
onRequest?: OnRequestCallback

/**
* Port to run the server on. Defaults to a random port.
Expand All @@ -68,7 +70,7 @@ export class BlobsServer {
private debug: boolean
private directory: string
private logger: Logger
private onRequest: (parameters: { type: Operation }) => void
private onRequest?: OnRequestCallback
private port: number
private server?: http.Server
private token?: string
Expand All @@ -79,18 +81,24 @@ export class BlobsServer {
this.debug = debug === true
this.directory = directory
this.logger = logger ?? console.log
this.onRequest =
onRequest ??
(() => {
// no-op
})
this.onRequest = onRequest
this.port = port || 0
this.token = token
this.tokenHash = createHmac('sha256', Math.random.toString())
.update(token ?? Math.random.toString())
.digest('hex')
}

private dispatchOnRequestEvent(type: Operation, url: string | URL) {
if (!this.onRequest) {
return
}

const urlPath = url instanceof URL ? url.pathname + url.search : url

this.onRequest({ type, url: urlPath })
}

logDebug(...message: unknown[]) {
if (!this.debug) {
return
Expand Down Expand Up @@ -159,7 +167,7 @@ export class BlobsServer {
return this.listBlobs({ dataPath, metadataPath, rootPath, req, res, url })
}

this.onRequest({ type: Operation.GET })
this.dispatchOnRequestEvent(Operation.GET, url)

const headers: Record<string, string> = {}

Expand Down Expand Up @@ -230,8 +238,6 @@ export class BlobsServer {
res: http.ServerResponse
url: URL
}) {
this.onRequest({ type: Operation.LIST })

const { dataPath, rootPath, req, res, url } = options
const directories = url.searchParams.get('directories') === 'true'
const prefix = url.searchParams.get('prefix') ?? ''
Expand All @@ -240,6 +246,8 @@ export class BlobsServer {
directories: [],
}

this.dispatchOnRequestEvent(Operation.LIST, url)

try {
await BlobsServer.walk({ directories, path: dataPath, prefix, rootPath, result })
} catch (error) {
Expand Down Expand Up @@ -356,7 +364,7 @@ export class BlobsServer {

switch (req.method?.toLowerCase()) {
case HTTPMethod.DELETE: {
this.onRequest({ type: Operation.DELETE })
this.dispatchOnRequestEvent(Operation.DELETE, req.url)

return this.delete(req, res)
}
Expand All @@ -366,13 +374,13 @@ export class BlobsServer {
}

case HTTPMethod.PUT: {
this.onRequest({ type: Operation.SET })
this.dispatchOnRequestEvent(Operation.SET, req.url)

return this.put(req, res)
}

case HTTPMethod.HEAD: {
this.onRequest({ type: Operation.GET_METADATA })
this.dispatchOnRequestEvent(Operation.GET_METADATA, req.url)

return this.head(req, res)
}
Expand Down

0 comments on commit 89f5ce4

Please sign in to comment.