Content-Disposition in ObjectStrage (#4524)
* Content-Disposition in ObjectStrage * encode filename
This commit is contained in:
		
							parent
							
								
									bd720491a9
								
							
						
					
					
						commit
						c2eec272e6
					
				
					 4 changed files with 23 additions and 10 deletions
				
			
		
							
								
								
									
										6
									
								
								src/misc/content-disposition.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/misc/content-disposition.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
const cd = require('content-disposition');
 | 
			
		||||
 | 
			
		||||
export function contentDisposition(type: 'inline' | 'attachment', filename: string): string {
 | 
			
		||||
	const fallback = filename.replace(/[^\w.-]/g, '_');
 | 
			
		||||
	return cd(filename, { type, fallback });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import DriveFile, { getDriveFileBucket } from '../../models/drive-file';
 | 
			
		|||
import DriveFileThumbnail, { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
 | 
			
		||||
import DriveFileWebpublic, { getDriveFileWebpublicBucket } from '../../models/drive-file-webpublic';
 | 
			
		||||
import { serverLogger } from '..';
 | 
			
		||||
import { contentDisposition } from '../../misc/content-disposition';
 | 
			
		||||
 | 
			
		||||
const assets = `${__dirname}/../../server/file/assets/`;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,12 +64,12 @@ export default async function(ctx: Koa.BaseContext) {
 | 
			
		|||
 | 
			
		||||
		if (thumb != null) {
 | 
			
		||||
			ctx.set('Content-Type', 'image/jpeg');
 | 
			
		||||
			ctx.set('Content-Disposition', `filename="${rename(file.filename, { suffix: '-thumb', extname: '.jpeg' })}"`);
 | 
			
		||||
			ctx.set('Content-Disposition', contentDisposition('inline', `${rename(file.filename, { suffix: '-thumb', extname: '.jpeg' })}"`));
 | 
			
		||||
			const bucket = await getDriveFileThumbnailBucket();
 | 
			
		||||
			ctx.body = bucket.openDownloadStream(thumb._id);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (file.contentType.startsWith('image/')) {
 | 
			
		||||
				ctx.set('Content-Disposition', `filename="${file.filename}"`);
 | 
			
		||||
				ctx.set('Content-Disposition', contentDisposition('inline', `${file.filename}"`));
 | 
			
		||||
				await sendRaw();
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.status = 404;
 | 
			
		||||
| 
						 | 
				
			
			@ -82,17 +83,17 @@ export default async function(ctx: Koa.BaseContext) {
 | 
			
		|||
 | 
			
		||||
		if (web != null) {
 | 
			
		||||
			ctx.set('Content-Type', file.contentType);
 | 
			
		||||
			ctx.set('Content-Disposition', `filename="${rename(file.filename, { suffix: '-web' })}"`);
 | 
			
		||||
			ctx.set('Content-Disposition', contentDisposition('inline', `${rename(file.filename, { suffix: '-web' })}"`));
 | 
			
		||||
 | 
			
		||||
			const bucket = await getDriveFileWebpublicBucket();
 | 
			
		||||
			ctx.body = bucket.openDownloadStream(web._id);
 | 
			
		||||
		} else {
 | 
			
		||||
			ctx.set('Content-Disposition', `filename="${file.filename}"`);
 | 
			
		||||
			ctx.set('Content-Disposition', contentDisposition('inline', `${file.filename}"`));
 | 
			
		||||
			await sendRaw();
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if ('download' in ctx.query) {
 | 
			
		||||
			ctx.set('Content-Disposition', `attachment; filename="${file.filename}`);
 | 
			
		||||
			ctx.set('Content-Disposition', contentDisposition('attachment', `${file.filename}`));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		await sendRaw();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@ import { driveLogger } from './logger';
 | 
			
		|||
import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
 | 
			
		||||
import Instance from '../../models/instance';
 | 
			
		||||
import checkSvg from '../../misc/check-svg';
 | 
			
		||||
import { contentDisposition } from '../../misc/content-disposition';
 | 
			
		||||
 | 
			
		||||
const logger = driveLogger.createSubLogger('register', 'yellow');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +70,7 @@ async function save(path: string, name: string, type: string, hash: string, size
 | 
			
		|||
		//#region Uploads
 | 
			
		||||
		logger.info(`uploading original: ${key}`);
 | 
			
		||||
		const uploads = [
 | 
			
		||||
			upload(key, fs.createReadStream(path), type)
 | 
			
		||||
			upload(key, fs.createReadStream(path), type, name)
 | 
			
		||||
		];
 | 
			
		||||
 | 
			
		||||
		if (alts.webpublic) {
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +78,7 @@ async function save(path: string, name: string, type: string, hash: string, size
 | 
			
		|||
			webpublicUrl = `${ baseUrl }/${ webpublicKey }`;
 | 
			
		||||
 | 
			
		||||
			logger.info(`uploading webpublic: ${webpublicKey}`);
 | 
			
		||||
			uploads.push(upload(webpublicKey, alts.webpublic.data, alts.webpublic.type));
 | 
			
		||||
			uploads.push(upload(webpublicKey, alts.webpublic.data, alts.webpublic.type, name));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (alts.thumbnail) {
 | 
			
		||||
| 
						 | 
				
			
			@ -198,13 +199,17 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 | 
			
		|||
/**
 | 
			
		||||
 * Upload to ObjectStorage
 | 
			
		||||
 */
 | 
			
		||||
async function upload(key: string, stream: fs.ReadStream | Buffer, type: string) {
 | 
			
		||||
async function upload(key: string, stream: fs.ReadStream | Buffer, type: string, filename?: string) {
 | 
			
		||||
	const minio = new Minio.Client(config.drive.config);
 | 
			
		||||
 | 
			
		||||
	await minio.putObject(config.drive.bucket, key, stream, null, {
 | 
			
		||||
	const metadata = {
 | 
			
		||||
		'Content-Type': type,
 | 
			
		||||
		'Cache-Control': 'max-age=31536000, immutable'
 | 
			
		||||
	});
 | 
			
		||||
	} as Minio.ItemBucketMetadata;
 | 
			
		||||
 | 
			
		||||
	if (filename) metadata['Content-Disposition'] = contentDisposition('inline', filename);
 | 
			
		||||
 | 
			
		||||
	await minio.putObject(config.drive.bucket, key, stream, null, metadata);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue