spec(MisskeyIO#922): 'https://'を省略するように (MisskeyIO#931)

This commit is contained in:
あわわわとーにゅ 2025-02-02 04:32:39 +09:00 committed by GitHub
parent a55ee2c03c
commit 155ce4094f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 30 additions and 18 deletions

View file

@ -12,7 +12,7 @@ import type { Packed } from '@/misc/json-schema.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiUser } from '@/models/User.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { appendQuery, query } from '@/misc/prelude/url.js';
import { appendQuery, omitHttps, query } from '@/misc/prelude/url.js';
import { deepClone } from '@/misc/clone.js';
import { bindThis } from '@/decorators.js';
import { isMimeImage } from '@/misc/is-mime-image.js';
@ -77,7 +77,7 @@ export class DriveFileEntityService {
@bindThis
private getProxiedUrl(url: string, mode?: 'static' | 'avatar'): string {
return appendQuery(
`${this.config.mediaProxy}/${mode ?? 'image'}/${encodeURIComponent(url)}`,
`${this.config.mediaProxy}/${mode ?? 'image'}/${encodeURIComponent(omitHttps(url))}`,
query({
...(mode ? { [mode]: '1' } : {}),
}),

View file

@ -14,10 +14,16 @@ export function query(obj: Record<string, unknown>): string {
.reduce((a, [k, v]) => (a[k] = v, a), {} as Record<string, any>);
return Object.entries(params)
.map((e) => `${e[0]}=${encodeURIComponent(e[1])}`)
.map((p) => `${p[0]}=${encodeURIComponent(p[1])}`)
.join('&');
}
export function appendQuery(url: string, query: string): string {
return `${url}${/\?/.test(url) ? url.endsWith('?') ? '' : '&' : '?'}${query}`;
}
export function omitHttps(url: string): string {
if (url.startsWith('https://')) return url.slice(8);
if (url.startsWith('https%3A%2F%2F')) return url.slice(14);
return url;
}

View file

@ -26,7 +26,7 @@ import { FileInfoService } from '@/core/FileInfoService.js';
import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js';
import { isMimeImage } from '@/misc/is-mime-image.js';
import { appendQuery, query } from '@/misc/prelude/url.js';
import { appendQuery, omitHttps, query } from '@/misc/prelude/url.js';
import { correctFilename } from '@/misc/correct-filename.js';
import { handleRequestRedirectToOmitSearch } from '@/misc/fastify-hook-handlers.js';
import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
@ -162,7 +162,7 @@ export class FileServerService {
reply.header('Cache-Control', 'max-age=31536000, immutable');
const url = appendQuery(
`${this.config.mediaProxy}/static/${encodeURIComponent(file.url)}`,
`${this.config.mediaProxy}/static/${encodeURIComponent(omitHttps(file.url))}`,
query({
static: '1',
}),
@ -185,7 +185,7 @@ export class FileServerService {
if (['image/svg+xml'].includes(file.mime)) {
reply.header('Cache-Control', 'max-age=31536000, immutable');
const url = `${this.config.mediaProxy}/svg/${encodeURIComponent(file.url)}`;
const url = `${this.config.mediaProxy}/svg/${encodeURIComponent(omitHttps(file.url))}`;
file.cleanup();
return await reply.redirect(url, 301);
@ -342,13 +342,13 @@ export class FileServerService {
reply.header('Cache-Control', 'public, max-age=259200'); // 3 days
const url = appendQuery(
`${this.config.mediaProxy}/redirect/${encodeURIComponent(request.params.url)}`,
const redirectUrl = appendQuery(
`${this.config.mediaProxy}/redirect/${encodeURIComponent(omitHttps(url))}`,
query(transformQuery as Record<string, string>),
);
return reply.redirect(
url,
redirectUrl,
301,
);
}

View file

@ -19,7 +19,7 @@ import { DI } from '@/di-symbols.js';
import type Logger from '@/logger.js';
import * as Acct from '@/misc/acct.js';
import { genIdenticon } from '@/misc/gen-identicon.js';
import { appendQuery, query } from '@/misc/prelude/url.js';
import { appendQuery, omitHttps, query } from '@/misc/prelude/url.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js';
@ -167,7 +167,7 @@ export class ServerService implements OnApplicationShutdown {
if ('badge' in request.query) {
url = appendQuery(
// || emoji.originalUrl してるのは後方互換性のためpublicUrlはstringなので??はだめ)
`${this.config.mediaProxy}/emoji/${encodeURIComponent(emoji.publicUrl || emoji.originalUrl)}`,
`${this.config.mediaProxy}/emoji/${encodeURIComponent(omitHttps(emoji.publicUrl || emoji.originalUrl))}`,
query({
badge: '1',
}),
@ -175,7 +175,7 @@ export class ServerService implements OnApplicationShutdown {
} else {
url = appendQuery(
// || emoji.originalUrl してるのは後方互換性のためpublicUrlはstringなので??はだめ)
`${this.config.mediaProxy}/emoji/${encodeURIComponent(emoji.publicUrl || emoji.originalUrl)}`,
`${this.config.mediaProxy}/emoji/${encodeURIComponent(omitHttps(emoji.publicUrl || emoji.originalUrl))}`,
query({
emoji: '1',
...('static' in request.query ? { static: '1' } : {}),

View file

@ -12,7 +12,7 @@ import type { Config } from '@/config.js';
import { MetaService } from '@/core/MetaService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import type Logger from '@/logger.js';
import { appendQuery, query } from '@/misc/prelude/url.js';
import { appendQuery, omitHttps, query } from '@/misc/prelude/url.js';
import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js';
import { ApiError } from '@/server/api/error.js';
@ -40,7 +40,7 @@ export class UrlPreviewService {
if (!RegExp(/^https?:\/\//).exec(url)) return url;
return appendQuery(
`${this.config.mediaProxy}/preview/${encodeURIComponent(url)}`,
`${this.config.mediaProxy}/preview/${encodeURIComponent(omitHttps(url))}`,
query({
preview: '1',
}),

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { appendQuery, query } from '@/scripts/url.js';
import { appendQuery, omitHttps, query } from '@/scripts/url.js';
import { url } from '@/config.js';
import { instance } from '@/instance.js';
@ -25,7 +25,7 @@ export function getProxiedImageUrl(imageUrl: string, type?: 'preview' | 'emoji'
}
return appendQuery(
`${mustOrigin ? localProxy : instance.mediaProxy}/${type === 'preview' ? 'preview' : 'image'}/${encodeURIComponent(imageUrl)}`,
`${mustOrigin ? localProxy : instance.mediaProxy}/${type === 'preview' ? 'preview' : 'image'}/${encodeURIComponent(omitHttps(imageUrl))}`,
query({
...(!noFallback ? { 'fallback': '1' } : {}),
...(type ? { [type]: '1' } : {}),
@ -55,7 +55,7 @@ export function getStaticImageUrl(baseUrl: string): string {
}
return appendQuery(
`${instance.mediaProxy}/static/${encodeURIComponent(u.href)}`,
`${instance.mediaProxy}/static/${encodeURIComponent(omitHttps(u.href))}`,
query({ static: '1' }),
);
}

View file

@ -8,7 +8,7 @@
* 2. undefinedの時はクエリを付けない
* new URLSearchParams(obj)
*/
export function query(obj: Record<string, any>): string {
export function query(obj: Record<string, unknown>): string {
const params = Object.entries(obj)
.filter(([, v]) => Array.isArray(v) ? v.length : v !== undefined)
.reduce((a, [k, v]) => (a[k] = v, a), {} as Record<string, any>);
@ -21,3 +21,9 @@ export function query(obj: Record<string, any>): string {
export function appendQuery(url: string, query: string): string {
return `${url}${/\?/.test(url) ? url.endsWith('?') ? '' : '&' : '?'}${query}`;
}
export function omitHttps(url: string): string {
if (url.startsWith('https://')) return url.slice(8);
if (url.startsWith('https%3A%2F%2F')) return url.slice(14);
return url;
}