디스코urs 파일 업로드의 새로운 시대

지난 몇 달간 Discourse 코어에서 업로드와 관련된 많은 커밋이 이루어졌다는 점을 눈치채셨을 것입니다. 이는 Discourse 코어 내에서 코드베이스의 jQuery file upload 사용법을 대체하려는 전반적인 노력의 일환이었으며, 이는 더 넓은 차원에서 코드베이스의 jQuery 자체 사용법을 대체하려는 노력의 일부이기도 합니다. jQuery file uploader는 매우 오래된 프로젝트로, 거의 처음부터 Discourse 코어의 일부였습니다. 저는 다른 프로젝트에서도 제 경력 내내 이 라이브러리를 사용해 온 것 같습니다. 하지만 이제 이 ‘믿을 만한老将(노장)’을 은퇴시킬 때입니다:

우리는 jQuery file upload(그리고 곧 또 다른 라이브러리인 resumable.js도)를 대체하여 Uppy라는 라이브러리를 도입했습니다. Uppy는 훨씬 더 현대적인 업로드 라이브러리로, 플러그인으로 쉽게 확장할 수 있으며 우리가 적용하는 다양한 워크플로우를 모두 처리할 수 있습니다. 특히, 이를 통해 Discourse 클라이언트에서 API를 통해 대용량 파일을 전송해야 하는 대신 S3로 직접 다중 부분(multipart) 업로드를 수행할 수 있게 되었습니다.

현재 컴포저(Composer)는 모든 업로드에 Uppy를 사용하며, 앱의 다른 많은 부분(아바타 업로드, 프로필 배경 업로드 등)에서도 이를 활용하고 있습니다. 마지막으로 남은 몇몇 부분도 향후 몇 주 내에 Uppy로 전환될 예정입니다. 대부분의 사용자에게는 거의 눈에 띄지 않는 변경일 것이지만, 플러그인 및 테마 컴포넌트 개발자들은 몇 가지 변경 사항을 적용해야 합니다.

플러그인 API

프리프로세서(Preprocessors)

모든 업로드 프리프로세서는 이제 Uppy 플러그인으로 작성되어야 합니다. 이러한 플러그인은 작성하기가 비교적 간단하며, 단순한 프로미스 기반 워크플로우를 사용합니다. 업로드 프리프로세서는 Uppy가 파일을 S3 또는 /uploads.json 엔드포인트로 업로드하기 전에 파일을 수정하거나 메타데이터를 추가할 수 있습니다. 자체 프리프로세서를 작성할 때 참고할 수 있는 코어 내의 여러 프리프로세서가 이미 존재합니다:

컴포저용 업로드 프리프로세서는 플러그인 API를 통해 api.addComposerUploadPreProcessor로 등록됩니다:

업로드 핸들러(Upload Handlers)

업로드 핸들러는 Uppy 플러그인으로 작성되지 않으며, 이전과 동일한 방식으로 동작하지만 약간의 변경 사항이 있습니다. 이제 파일이 업로드 핸들러에 등록된 확장자와 일치하면, 일치하는 모든 파일이 한 번에 전송됩니다. 이전에는 업로드 핸들러에 한 번에 하나의 파일만 전송되었지만, 이제 대신 배열로 전송됩니다:

업로드 핸들러에 의해 처리된 파일은 Uppy 업로드 파이프라인에서 추가로 처리되지 않습니다. 프리프로세서는 업로드 핸들러가 호출되기 전에 실행됩니다.

S3 다중 부분 직접 업로드

앞서 언급했듯이, Uppy 사용은 UI에서 S3로 직접 다중 부분 업로드를 수행할 수 있게 해줍니다. 이 기능을 활성화하려면 enable_direct_s3_uploads 사이트 설정을 true로 설정해야 합니다.

우리가 호스팅을 제공하는 경우, 해당 S3 버킷에는 이미 관련 권한이 적용되어 있습니다. 하지만 자체 호스팅(self-hosting)을 사용하는 경우, 이 기능이 작동하려면 버킷에 여러 권한과 CORS 규칙을 설정해야 합니다.

CORS 규칙의 경우, rake s3:ensure_cors_rules를 실행하여 s3:ensure_cors_rules rake 작업을 실행하기만 하면 됩니다. 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"
    ]
}

이는 수개월에 걸쳐 진행된 과정이며, 아직 완료되지 않았습니다! Discourse 코어에서 jQuery file uploader와 resumable.js를 완전히 제거하기 전에 이 토픽에 다시 게시하겠습니다. 여기에 게시한 내용에 대해 궁금한 점이 있다면 알려주세요!

49개의 좋아요

5개의 게시물이 새 주제로 분리되었습니다: Uppy not working on Firefox 68

itsgoneitsdone

이 두 커밋으로 jQuery file uploader와 resumable.js가 더 이상 Discourse 코어의 일부가 아닙니다:

알고 있는 모든 플러그인에서 이 라이브러리들과 이전 UploadMixin에 대한 참조를 모두 제거하기 위해 최선을 다했지만, 놓쳤거나 알지 못하는 부분이 있을 수 있습니다. 걱정하지 마세요, 마이그레이션 과정은 간단합니다. 사용 사례의 99%는 최소한의 변경 사항만으로 새로운 UppyUploadMixin을 드롭인 교체(drop-in replacement)로 사용할 수 있습니다. 예시를 확인하려면 아래를 참고하세요:

나머지 1%의 경우, Uppy 인스턴스를 생성하고 이벤트를 직접 연결하면 됩니다. 예시를 확인하려면 아래를 참고하세요:

또한 이 토픽의 OP(원본 글)에서 플러그인 변경 사항에 대해 다루었습니다. 다음 릴리스까지 아직 몇 주가 남았으므로, 문제가 발생하면 여기에 보고해 주세요. 정말 흥미진진한 여정이었습니다! :roller_coaster:

14개의 좋아요

다른 내용으로, API 문서에 새로운 업로드 엔드포인트가 추가되어 업데이트되었습니다. 확인하시려면 Discourse API Docs 으로 이동해 주세요.

(cc @mattdm, 이 내용이 관심 있으실 수 있습니다)

6개의 좋아요

직접 S3 업로드를 활성화한 이후, 중국에 있는 사용자들로부터 이미지 업로드가 불가능하다는 보고가 접수되고 있습니다. 업로드가 0%에서 멈추고 타임아웃이 발생합니다.

첫 번째로 떠오르는 생각은 S3가 중국에서 차단되어 있을 수 있다는 것입니다. 하지만 실제로는 그렇지 않다는 것을 잘 알고 있습니다. 적어도 완전히 차단된 것은 아닙니다. 중국에 있는 사용자는 S3에 저장된 이미지를 정상적으로 볼 수 있습니다(우리의 경우 버킷은 eu-central-1 리전에 위치해 있습니다). 하지만 어떤 이유인지, 업로드만 작동하지 않는 것 같습니다.

GFW(만리방화벽) 뒤에서 디버깅하지 않는 상황에서는 이를 파악하기가 어렵지만, 중국에 있는 일부 사용자는 아마도 관련이 있을 만한 차이점 중 하나로, 이미지는 듀얼 스택 엔드포인트를 통해 로드되지만 업로드는 일반(IPv4 전용) 엔드포인트(bucket-name.s3.dualstack.eu-central-1.amazonaws.com 대 bucket-name.s3.eu-central-1.amazonaws.com)를 사용한다는 점을 언급했습니다. 몇 가지 테스트를 해본 결과, 실제로 그렇게 되어 있는 것 같지만, 이것이 의도된 것인지 업로드에 필수적인 것인지는 확실하지 않습니다.

아마도 더 결정적인 증거는, 일부 사용자가 듀얼 스택 호스트네임에서 해석된 IP 주소를 hosts 파일에 추가(비듀얼 스택 이름의 호스트네임에 대해)했을 때 문제가 완전히 해결되었고, 그 변경만으로 업로드가 가능했다는 보고입니다.

Discourse 팀에 중국에 위치해 있어 이 문제를 더 잘 디버깅할 수 있는 사람이 있는지 모르겠습니다.

4개의 좋아요

게시물이 새 주제로 분리되었습니다: S3 설정 중 오류: 액션이 존재하지 않음