From 5a16f3d6d8f0c382148f247ff533db95cd08179d Mon Sep 17 00:00:00 2001 From: Kadi Kraman Date: Tue, 21 Jan 2025 10:51:32 +0000 Subject: [PATCH] [eas-cli] Detect valid JSON files during hosting upload (#2829) * Use application/json as content type for valid JSON without an extension * Add changelog * Pull getContentTypeAsync to a separate function --- CHANGELOG.md | 1 + packages/eas-cli/src/worker/upload.ts | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8c8654033..e5a7f45cda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This is the log of notable changes to EAS CLI and related packages. - Allow filtering by `--fingerprint_hash` in `eas build:list` command. ([#2818](https://github.com/expo/eas-cli/pull/2818) by [@szdziedzic](https://github.com/szdziedzic)) ### ๐Ÿ› Bug fixes +- Ensure that the AASA file is served with content type application/json ([#2829](https://github.com/expo/eas-cli/pull/2829) by [@kadikraman](https://github.com/kadikraman)) ### ๐Ÿงน Chores - Fix logs typos in the `eas deploy` command. ([#2822](https://github.com/expo/eas-cli/pull/2822) by [@kadikraman](https://github.com/kadikraman)) diff --git a/packages/eas-cli/src/worker/upload.ts b/packages/eas-cli/src/worker/upload.ts index 63f41207a9..5a5c89a68b 100644 --- a/packages/eas-cli/src/worker/upload.ts +++ b/packages/eas-cli/src/worker/upload.ts @@ -4,6 +4,7 @@ import mime from 'mime'; import { Gzip } from 'minizlib'; import fetch, { Headers, HeadersInit, RequestInit, Response } from 'node-fetch'; import fs, { createReadStream } from 'node:fs'; +import { readFile } from 'node:fs/promises'; import path from 'node:path'; import promiseRetry from 'promise-retry'; @@ -28,6 +29,24 @@ const isCompressible = (contentType: string | null, size: number): boolean => { } }; +const getContentTypeAsync = async (filePath: string): Promise => { + let contentType = mime.getType(path.basename(filePath)); + + if (!contentType) { + const fileContent = await readFile(filePath, 'utf-8'); + try { + // check if file is valid JSON without an extension, e.g. for the apple app site association file + const parsedData = JSON.parse(fileContent); + + if (parsedData) { + contentType = 'application/json'; + } + } catch {} + } + + return contentType; +}; + export interface UploadParams extends Omit { filePath: string; compress?: boolean; @@ -70,14 +89,15 @@ export async function uploadAsync(params: UploadParams): Promise { headers: headersInit, ...requestInit } = params; - const stat = await fs.promises.stat(params.filePath); + const stat = await fs.promises.stat(filePath); if (stat.size > MAX_UPLOAD_SIZE) { throw new Error( - `Upload of "${params.filePath}" aborted: File size is greater than the upload limit (>500MB)` + `Upload of "${filePath}" aborted: File size is greater than the upload limit (>500MB)` ); } - const contentType = mime.getType(path.basename(params.filePath)); + const contentType = await getContentTypeAsync(filePath); + return await promiseRetry( async retry => { const headers = new Headers(headersInit);