Skip to content

Commit

Permalink
feat(app-server): add cache-control & etag of http request for gridfs…
Browse files Browse the repository at this point in the history
… files;
  • Loading branch information
maslow committed Aug 16, 2021
1 parent acc2e8e commit acc3c44
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 5 deletions.
7 changes: 7 additions & 0 deletions packages/app-server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ export default class Config {
return process.env['FILE_SYSTEM_DRIVER'] ?? 'gridfs'
}

/**
* value of HTTP header Cache-Control: max-age=120 while download file
*/
static get FILE_SYSTEM_HTTP_CACHE_CONTROL(): string {
return process.env['FILE_SYSTEM_HTTP_CACHE_CONTROL']
}

/**
* the `temp path`
*/
Expand Down
1 change: 1 addition & 0 deletions packages/app-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ server.all('*', function (_req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type')
res.header('Access-Control-Allow-Methods', '*')
res.header('X-Powered-By', 'LaF Server')
next()
})

Expand Down
30 changes: 26 additions & 4 deletions packages/app-server/src/router/file/gridfs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as fs from 'fs'
import * as express from 'express'
import { GridFSBucket } from 'mongodb'
import { Globals } from '../../lib/globals'
import { checkFileOperationToken, FS_OPERATION } from './utils'
import { checkFileOperationToken, FS_OPERATION, generateETag } from './utils'
import Config from '../../config'


export const GridFSHandlers = {
Expand Down Expand Up @@ -37,7 +38,14 @@ async function handleUploadFile(req: express.Request, res: express.Response) {
const bucket = new GridFSBucket(Globals.accessor.db, { bucketName: bucket_name })

const stream = bucket.openUploadStream(file.filename, {
metadata: { original_name: file.originalname, created_by: auth?.uid, bucket: bucket_name, created_at: Date.now() },
metadata: {
original_name: file.originalname,
created_by: auth?.uid,
bucket: bucket_name,
created_at: Date.now(),
contentType: file.mimetype
},
// @deprecated: this field will be deprecated in future, use metadata instead. keep it now for history reasons
contentType: file.mimetype
})

Expand Down Expand Up @@ -91,8 +99,22 @@ async function handleDownloadFile(req: express.Request, res: express.Response) {
return res.status(404).send('Not Found')
}

if (file?.contentType) {
res.contentType(file.contentType)
const contentType = file?.metadata?.contentType || file?.contentType
if (contentType) {
res.contentType(contentType)
}

if (Config.FILE_SYSTEM_HTTP_CACHE_CONTROL) {
res.set('Cache-Control', Config.FILE_SYSTEM_HTTP_CACHE_CONTROL)
}
res.set('Last-Modified', file.uploadDate.toUTCString())

// process cache policy with ETag & If-None-Match
const ETag = generateETag(file.length, file.uploadDate.toString(), file.filename)
res.set('ETag', ETag)
if (req.header('If-None-Match') === ETag) {
res.status(304).send('Not Modified')
return
}

res.set('x-bucket', bucket_name)
Expand Down
13 changes: 12 additions & 1 deletion packages/app-server/src/router/file/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import assert = require("assert")
import { parseToken } from "../../lib/utils/token"

import * as crypto from 'crypto'

/**
* file operations
Expand Down Expand Up @@ -65,4 +65,15 @@ export function checkFileOperationToken(bucket: string, token: string, operation
}

return [0, null]
}


/**
* generate http ETag of a file
* @param file_size the size of file in bytes
* @param update_date the update date time of file
* @param filename file name
*/
export function generateETag(file_size: number, update_date: string, filename: string) {
return crypto.createHash('md5').update(`${filename}#${file_size}#${update_date}`).digest('hex')
}

0 comments on commit acc3c44

Please sign in to comment.