期限切れ/未保存リモートファイルのローカルプロキシ (#5655)

* Media Proxy を実装

* サンプルを追加

* https://github.com/syuilo/misskey/pull/5649#discussion_r359967471 の修正

* https://github.com/syuilo/misskey/pull/5649#discussion_r359967966 の修正

* https://github.com/syuilo/misskey/pull/5649#discussion_r359968219 の修正

* 期限切れ/未保存リモートファイルのローカルプロキシ

* 設定

* 説明

* comment out

* fix

Co-authored-by: 和風ドレッシング <37681609+CookieRamen@users.noreply.github.com>
This commit is contained in:
MeiMei
2019-12-31 17:23:47 +09:00
committed by GitHub
parent 307fc18138
commit b0bb5d8dfc
11 changed files with 151 additions and 12 deletions

View File

@ -115,6 +115,11 @@ export class Meta {
})
public cacheRemoteFiles: boolean;
@Column('boolean', {
default: false,
})
public proxyRemoteFiles: boolean;
@Column('varchar', {
length: 128,
nullable: true

View File

@ -7,6 +7,9 @@ import { ensure } from '../../prelude/ensure';
import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '../../misc/schema';
import config from '../../config';
import { query, appendQuery } from '../../prelude/url';
import { Meta } from '../entities/meta';
import { fetchMeta } from '../../misc/fetch-meta';
export type PackedDriveFile = SchemaType<typeof packedDriveFileSchema>;
@ -22,12 +25,39 @@ export class DriveFileRepository extends Repository<DriveFile> {
);
}
public getPublicUrl(file: DriveFile, thumbnail = false): string | null {
let url = thumbnail ? (file.thumbnailUrl || file.webpublicUrl || null) : (file.webpublicUrl || file.url);
if (file.src !== null && file.userHost !== null && config.mediaProxy !== null) {
url = `${config.mediaProxy}/${thumbnail ? 'thumbnail' : ''}?url=${file.src}`;
public getPublicUrl(file: DriveFile, thumbnail = false, meta?: Meta): string | null {
// リモートかつメディアプロキシ
if (file.uri != null && file.userHost != null && config.mediaProxy != null) {
return appendQuery(config.mediaProxy, query({
url: file.uri,
thumbnail: thumbnail ? '1' : undefined
}));
}
return url;
// リモートかつ期限切れはローカルプロキシを試みる
if (file.uri != null && file.isLink && meta && meta.proxyRemoteFiles) {
const key = thumbnail ? file.thumbnailAccessKey : file.webpublicAccessKey;
if (key && !key.match('/')) { // 古いものはここにオブジェクトストレージキーが入ってるので除外
let ext = '';
if (file.name) {
[ext] = (file.name.match(/\.(\w+)$/) || ['']);
}
if (ext === '') {
if (file.type === 'image/jpeg') ext = '.jpg';
if (file.type === 'image/png') ext = '.png';
if (file.type === 'image/webp') ext = '.webp';
if (file.type === 'image/apng') ext = '.apng';
if (file.type === 'image/vnd.mozilla.apng') ext = '.apng';
}
return `/files/${key}/${key}${ext}`;
}
}
return thumbnail ? (file.thumbnailUrl || file.webpublicUrl || null) : (file.webpublicUrl || file.url);
}
public async clacDriveUsageOf(user: User['id'] | User): Promise<number> {
@ -87,6 +117,8 @@ export class DriveFileRepository extends Repository<DriveFile> {
const file = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
const meta = await fetchMeta();
return await awaitAll({
id: file.id,
createdAt: file.createdAt.toISOString(),
@ -96,8 +128,8 @@ export class DriveFileRepository extends Repository<DriveFile> {
size: file.size,
isSensitive: file.isSensitive,
properties: file.properties,
url: opts.self ? file.url : this.getPublicUrl(file, false),
thumbnailUrl: this.getPublicUrl(file, true),
url: opts.self ? file.url : this.getPublicUrl(file, false, meta),
thumbnailUrl: this.getPublicUrl(file, true, meta),
folderId: file.folderId,
folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, {
detail: true