enhance(backend): ActivityPub Deliver queueでBodyを事前処理するように (misskey-dev#12916) (MisskeyIO#327)
Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> Co-authored-by: riku6460 <17585784+riku6460@users.noreply.github.com>
This commit is contained in:
parent
30f5203c5f
commit
402fcc5ded
|
@ -17,6 +17,7 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, Obj
|
||||||
import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js';
|
import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js';
|
||||||
import type httpSignature from '@peertube/http-signature';
|
import type httpSignature from '@peertube/http-signature';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
|
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueService {
|
export class QueueService {
|
||||||
|
@ -75,11 +76,15 @@ export class QueueService {
|
||||||
if (content == null) return null;
|
if (content == null) return null;
|
||||||
if (to == null) return null;
|
if (to == null) return null;
|
||||||
|
|
||||||
|
const contentBody = JSON.stringify(content);
|
||||||
|
const digest = ApRequestCreator.createDigest(contentBody);
|
||||||
|
|
||||||
const data: DeliverJobData = {
|
const data: DeliverJobData = {
|
||||||
user: {
|
user: {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
},
|
},
|
||||||
content,
|
content: contentBody,
|
||||||
|
digest,
|
||||||
to,
|
to,
|
||||||
isSharedInbox,
|
isSharedInbox,
|
||||||
};
|
};
|
||||||
|
@ -104,6 +109,8 @@ export class QueueService {
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map<string, boolean>) {
|
public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map<string, boolean>) {
|
||||||
if (content == null) return null;
|
if (content == null) return null;
|
||||||
|
const contentBody = JSON.stringify(content);
|
||||||
|
const digest = ApRequestCreator.createDigest(contentBody);
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
attempts: this.config.deliverJobMaxAttempts ?? 12,
|
attempts: this.config.deliverJobMaxAttempts ?? 12,
|
||||||
|
@ -118,7 +125,8 @@ export class QueueService {
|
||||||
name: d[0],
|
name: d[0],
|
||||||
data: {
|
data: {
|
||||||
user,
|
user,
|
||||||
content,
|
content: contentBody,
|
||||||
|
digest,
|
||||||
to: d[0],
|
to: d[0],
|
||||||
isSharedInbox: d[1],
|
isSharedInbox: d[1],
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,9 +34,9 @@ type PrivateKey = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ApRequestCreator {
|
export class ApRequestCreator {
|
||||||
static createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }): Signed {
|
static createSignedPost(args: { key: PrivateKey, url: string, body: string, digest?: string, additionalHeaders: Record<string, string> }): Signed {
|
||||||
const u = new URL(args.url);
|
const u = new URL(args.url);
|
||||||
const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`;
|
const digestHeader = args.digest ?? this.createDigest(args.body);
|
||||||
|
|
||||||
const request: Request = {
|
const request: Request = {
|
||||||
url: u.href,
|
url: u.href,
|
||||||
|
@ -59,6 +59,10 @@ export class ApRequestCreator {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static createDigest(body: string) {
|
||||||
|
return `SHA-256=${crypto.createHash('sha256').update(body).digest('base64')}`;
|
||||||
|
}
|
||||||
|
|
||||||
static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
|
static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
|
||||||
const u = new URL(args.url);
|
const u = new URL(args.url);
|
||||||
|
|
||||||
|
@ -145,8 +149,8 @@ export class ApRequestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown): Promise<void> {
|
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, digest?: string): Promise<void> {
|
||||||
const body = JSON.stringify(object);
|
const body = typeof object === 'string' ? object : JSON.stringify(object);
|
||||||
|
|
||||||
const keypair = await this.userKeypairService.getUserKeypair(user.id);
|
const keypair = await this.userKeypairService.getUserKeypair(user.id);
|
||||||
|
|
||||||
|
@ -157,6 +161,7 @@ export class ApRequestService {
|
||||||
},
|
},
|
||||||
url,
|
url,
|
||||||
body,
|
body,
|
||||||
|
digest,
|
||||||
additionalHeaders: {
|
additionalHeaders: {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -72,7 +72,7 @@ export class DeliverProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content);
|
await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content, job.data.digest);
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
this.federatedInstanceService.fetch(host).then(i => {
|
this.federatedInstanceService.fetch(host).then(i => {
|
||||||
|
|
|
@ -16,7 +16,9 @@ export type DeliverJobData = {
|
||||||
/** Actor */
|
/** Actor */
|
||||||
user: ThinUser;
|
user: ThinUser;
|
||||||
/** Activity */
|
/** Activity */
|
||||||
content: unknown;
|
content: string;
|
||||||
|
/** Digest header */
|
||||||
|
digest: string;
|
||||||
/** inbox URL to deliver */
|
/** inbox URL to deliver */
|
||||||
to: string;
|
to: string;
|
||||||
/** whether it is sharedInbox */
|
/** whether it is sharedInbox */
|
||||||
|
|
Loading…
Reference in a new issue