Discourseにおけるファイルアップロードの新時代

過去数ヶ月にわたり、Discourseコアのアップロードに関連する多くのコミットに気づいたかもしれません。これは、コードベースからのjQuery file uploadの使用を置き換えるためのコア内の全体的な取り組みの一環であり、さらに広範な、コードベースからのjQuery自体の使用を置き換えるための全体的な取り組みの一部です。jQuery file uploaderは非常に古いプロジェクトであり、ほぼ最初からDiscourseコアの一部でした。私も他のプロジェクトでキャリア全体でそれを使用してきたと思います。しかし、Ol’ Reliableを引退する時が来ました。

jQuery file upload(そしてまもなく別のライブラリであるresumable.jsも置き換えます)をUppyというライブラリに置き換えました。これは、プラグインで簡単に拡張でき、私たちが投げるさまざまなワークフローをすべて処理できる、はるかにモダンなアップロードライブラリです。重要なのは、これにより、大きなファイルをAPI経由で送信するのではなく、DiscourseクライアントからS3に直接マルチパートアップロードできるようになることです。

コンポーザーは現在すべてのアップロードにUppyを使用しており、アプリ内の他の多くの場所(アバターアップロード、プロファイル背景アップロードなど)でも使用されています。最後の数週間で、残りの部分も削除される予定です。これはほとんどのユーザーにとってはほとんど目に見えない変更になるはずですが、プラグインおよびテーマコンポーネントの作成者はいくつかの変更を行う必要があります。

プラグインAPI

事前処理プログラム

すべてのアップロード事前処理プログラムは、Uppyプラグインとして記述する必要があります。これらのプラグインは非常に簡単に記述でき、単純なPromiseベースのワークフローを使用します。アップロード事前処理プログラムは、UppyがファイルをS3または/uploads.jsonエンドポイントにアップロードする前に、ファイルを変更したり、メタデータを追加したりできます。すでにコアにいくつかの事前処理プログラムがあり、独自のものを記述する際の参考として使用できます。

コンポーザーのアップロード事前処理プログラムは、プラグインAPIを使用してapi.addComposerUploadPreProcessorを介して登録されます。

アップロードハンドラー

アップロードハンドラーはUppyプラグインとして記述されていません。それらは、マイナーな変更を加えて、これまでどおり機能します。ファイルがアップロードハンドラーに登録された拡張子に一致すると、一致するすべてのファイルが一度に送信されます。以前は一度に1つのファイルのみがアップロードハンドラーに送信されていましたが、現在は配列が送信されます。

アップロードハンドラーによって処理されたファイルは、Uppyのアップロードパイプラインでさらに処理されません。事前処理プログラムは、アップロードハンドラーが呼び出される前に実行されます。

S3マルチパート直接アップロード

先ほど、Uppyの使用により、UIからS3への直接マルチパートアップロードも可能になると述べました。この機能を有効にするには、enable_direct_s3_uploadsサイト設定をtrueに設定する必要があります。

当社でホストされている場合、関連するS3権限はすでにバケットに適用されています。ただし、セルフホストしている場合は、これが機能するためにバケットに設定する必要があるいくつかの権限とCORSルールがあります。

CORSルールについては、s3:ensure_cors_rules rakeタスクをrake s3:ensure_cors_rulesで実行するだけで済みます。これにより、Discourseインスタンスに設定されているS3認証情報に使用するアクセスキーとシークレットキーにS3:GetBucketCorsおよびS3:PutBucketCors権限が有効になっている限り、バケットに次のルールが追加されます。

{
  "AllowedHeaders": [
    "Authorization",
    "Content-Disposition",
    "Content-Type"
  ],
  "AllowedMethods": [
    "GET",
    "HEAD",
    "PUT"
  ],
  "AllowedOrigins": [
    "*"
  ],
  "ExposeHeaders": [
    "ETag"
  ],
  "MaxAgeSeconds": 3000
}

権限については、Discourseインスタンスに設定されているS3認証情報に使用するアクセスキーとシークレットキーに、次の権限が有効になっている必要があります。

{
    "Sid": "YourSid",
    "Effect": "Allow",
    "Action": [
        "s3:PutObjectVersionAcl",
        "s3:PutObjectAcl",
        "s3:PutObject",
        "s3:GetObjectAcl",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:CreateMultipartUpload",
        "s3:CompleteMultipartUpload",
        "s3:AbortMultipartUpload"
    ],
    "Resource": [
        "YOUR_RESOURCE"
    ]
}

これは数ヶ月にわたるプロセスであり、まだ完了していません!jQuery file uploaderとresumable.jsをDiscourseコアから完全に削除する準備ができたときに、このトピックで投稿します。ここに投稿した内容について質問があればお知らせください!

「いいね!」 49

5件の投稿が新しいトピックに分割されました: Uppy not working on Firefox 68

itsgoneitsdone

これらの2つのコミットにより、jQuery file uploaderとresumable.jsはDiscourseコアから削除されました。

既知のすべてのプラグインから、これらおよび古いUploadMixinへの参照をすべて削除するように最善を尽くしましたが、見落としたものや認識していないものがあるかもしれません。心配はいりません、移行プロセスは簡単です。ユースケースの99%は、非常に最小限の変更で、新しいUppyUploadMixinをそのまま置き換えることができます。例はこちらをご覧ください。

残りの1%については、Uppyのインスタンスを作成し、イベントに直接フックすることができます。例はこちらをご覧ください。

プラグインの変更についても、このトピックのOPで説明しました。次のリリースまでまだ数週間ありますので、問題が発生した場合はここにご報告ください。ワイルドな旅でした! :roller_coaster:

「いいね!」 14

ちなみに、APIドキュメントが新しいアップロードエンドポイントで更新されました。Discourse API Docs を参照してください。

(cc @mattdm、こちらにご興味があるかもしれません)

「いいね!」 6

ダイレクトS3アップロードを有効にした後、中国のユーザーから画像がアップロードできないという報告を受けています。アップロードは0%でスタックし、タイムアウトします。

最初に考えられるのは、S3が中国でブロックされているのではないかということですが、少なくとも完全にブロックされているわけではないことは事実です。中国のユーザーはS3に保存されている画像(この場合、バケットはeu-central-1リージョンにあります)を問題なく見ることができます。しかし、なぜかアップロードだけが機能しないようです。

GFW(Great Firewall)の背後にいないとデバッグが難しいですが、中国の一部のユーザーは、おそらく関連する違いとして、画像はデュアルスタックエンドポイントを使用してロードされているのに対し、アップロードは通常の(IPv4のみの)エンドポイント(bucket-name.s3.dualstack.eu-central-1.amazonaws.combucket-name.s3.eu-central-1.amazonaws.com)を使用していると述べています。いくつかのテストから、確かにそのようになっているようですが、それが意図されたものか、アップロードに必要なものかはわかりません。

さらに示唆的なのは、デュアルスタックホスト名から解決されたIPアドレスをホストファイル(非デュアルスタック名ホスト名用)に追加することで問題が完全に解決し、その変更だけでアップロードできるようになったと報告した人もいることです。

Discourseチームには、この問題をより詳しくデバッグできる中国在住の担当者がいるでしょうか?

「いいね!」 4

投稿が新しいトピックに分割されました: S3設定中にエラーが発生しました: アクションが存在しません