From edf94b54520a7a793fe13953635447487bb97821 Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:12:23 +0900 Subject: [PATCH] =?UTF-8?q?enhance(backend):=20head=E3=82=BF=E3=82=B0?= =?UTF-8?q?=E5=86=85=E3=81=ABrel=3Dalternate=E3=81=AE=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E3=81=AE=E3=81=82=E3=82=8Blink=E3=82=BF=E3=82=B0=E3=81=8C?= =?UTF-8?q?=E3=81=82=E3=82=8B=E5=A0=B4=E5=90=88=E3=80=81=E8=A8=98=E8=BF=B0?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=81=9FURL=E3=82=92=E5=8F=82=E7=85=A7?= =?UTF-8?q?=E3=81=97=E3=81=A6=E7=85=A7=E4=BC=9A=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20(#14371)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cherry picked from commit 9fbc1b7f7b71cf0eafadd728a6b66cb95a0c35d8 Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> Co-authored-by: taichan <40626578+tai-cha@users.noreply.github.com> --- .../src/core/activitypub/ApRequestService.ts | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index b008a3ec592e..b553708a8c08 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -6,6 +6,7 @@ import * as crypto from 'node:crypto'; import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; +import { JSDOM } from 'jsdom'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import type { MiUser } from '@/models/User.js'; @@ -179,7 +180,8 @@ export class ApRequestService { * @param url URL to fetch */ @bindThis - public async signedGet(url: string, user: { id: MiUser['id'] }): Promise { + public async signedGet(url: string, user: { id: MiUser['id'] }, followAlternate?: boolean): Promise { + const _followAlternate = followAlternate ?? true; const keypair = await this.userKeypairService.getUserKeypair(user.id); const req = ApRequestCreator.createSignedGet({ @@ -197,9 +199,25 @@ export class ApRequestService { headers: req.request.headers, }, { throwErrorWhenResponseNotOk: true, - validators: [validateContentTypeSetAsActivityPub], }); + //#region リクエスト先がhtmlかつactivity+jsonへのalternate linkタグがあるとき + if (res.headers.get('Content-type')?.startsWith('text/html;') && _followAlternate) { + const html = await res.text(); + const fragment = JSDOM.fragment(html); + + const alternate = fragment.querySelector('head > link[rel="alternate"][type="application/activity+json"]'); + if (alternate) { + const href = alternate.getAttribute('href'); + if (href) { + return await this.signedGet(href, user, false); + } + } + } + //#endregion + + validateContentTypeSetAsActivityPub(res); + return await res.json(); } }