Skip to content

Commit

Permalink
feat: add onRequest callback to server (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoboucas authored Nov 16, 2023
1 parent 0fb9ab6 commit 35629fd
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
25 changes: 25 additions & 0 deletions src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,14 @@ test('Reads and writes from the file system', async () => {
}

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

const { port: port1 } = await server1.start()
const store1 = getStore({
edgeURL: `http://localhost:${port1}`,
Expand Down Expand Up @@ -110,6 +113,28 @@ test('Reads and writes from the file system', async () => {
expect(list3.directories).toEqual([])
}

expect(server1Ops).toEqual([
'list',
'set',
'get',
'set',
'get',
'list',
'set',
'get',
'get',
'get',
'getMetadata',
'getMetadata',
'get',
'getMetadata',
'delete',
'get',
'getMetadata',
'get',
'list',
])

await server1.stop()
await fs.rm(directory1.path, { force: true, recursive: true })

Expand Down
45 changes: 39 additions & 6 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,20 @@ import { dirname, join, relative, resolve, sep } from 'node:path'

import { ListResponse } from './backend/list.ts'
import { decodeMetadata, encodeMetadata, METADATA_HEADER_INTERNAL } from './metadata.ts'
import { HTTPMethod } from './types.ts'
import { isNodeError, Logger } from './util.ts'

const API_URL_PATH = /\/api\/v1\/sites\/(?<site_id>[^/]+)\/blobs\/?(?<key>[^?]*)/
const DEFAULT_STORE = 'production'

export enum Operation {
DELETE = 'delete',
GET = 'get',
GET_METADATA = 'getMetadata',
LIST = 'list',
SET = 'set',
}

interface BlobsServerOptions {
/**
* Whether debug-level information should be logged, such as internal errors
Expand All @@ -28,6 +37,11 @@ interface BlobsServerOptions {
*/
logger?: Logger

/**
* Callback function to be called on every request.
*/
onRequest?: (parameters: { type: Operation }) => void

/**
* Port to run the server on. Defaults to a random port.
*/
Expand All @@ -45,16 +59,22 @@ export class BlobsServer {
private debug: boolean
private directory: string
private logger: Logger
private onRequest: (parameters: { type: Operation }) => void
private port: number
private server?: http.Server
private token?: string
private tokenHash: string

constructor({ debug, directory, logger, port, token }: BlobsServerOptions) {
constructor({ debug, directory, logger, onRequest, port, token }: BlobsServerOptions) {
this.address = ''
this.debug = debug === true
this.directory = directory
this.logger = logger ?? console.log
this.onRequest =
onRequest ??
(() => {
// no-op
})
this.port = port || 0
this.token = token
this.tokenHash = createHmac('sha256', Math.random.toString())
Expand Down Expand Up @@ -124,6 +144,8 @@ export class BlobsServer {
return this.list({ dataPath, metadataPath, rootPath, req, res, url })
}

this.onRequest({ type: Operation.GET })

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

try {
Expand Down Expand Up @@ -193,6 +215,8 @@ 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 Down Expand Up @@ -295,17 +319,26 @@ export class BlobsServer {
return this.sendResponse(req, res, 403)
}

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

return this.delete(req, res)
}

case 'GET':
case HTTPMethod.GET: {
return this.get(req, res)
}

case HTTPMethod.PUT: {
this.onRequest({ type: Operation.SET })

case 'PUT':
return this.put(req, res)
}

case HTTPMethod.HEAD: {
this.onRequest({ type: Operation.GET_METADATA })

case 'HEAD': {
return this.head(req, res)
}

Expand Down

0 comments on commit 35629fd

Please sign in to comment.