diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 2de2198..6150290 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -28,7 +28,7 @@ export type DownloadableMessage = { mediaKey?: Uint8Array, directPath?: string, export type MediaConnInfo = { auth: string ttl: number - hosts: { hostname: string }[] + hosts: { hostname: string, maxContentLengthBytes: number }[] fetchDate: Date } diff --git a/src/Types/Socket.ts b/src/Types/Socket.ts index b9d8f42..8b2c403 100644 --- a/src/Types/Socket.ts +++ b/src/Types/Socket.ts @@ -3,6 +3,7 @@ import type { Agent } from "https" import type { Logger } from "pino" import type { URL } from "url" import type NodeCache from 'node-cache' +import { MediaConnInfo } from "./Message" export type WAVersion = [number, number, number] export type WABrowserDescription = [string, string, string] @@ -35,5 +36,5 @@ export type CommonSocketConfig = { /** provide a cache to store media, so does not have to be re-uploaded */ mediaCache?: NodeCache - customUploadHosts: string[] + customUploadHosts: MediaConnInfo['hosts'] } diff --git a/src/Types/index.ts b/src/Types/index.ts index 5e91fa3..9dbc635 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -19,8 +19,6 @@ export type SocketConfig = CommonSocketConfig & { userDevicesCache?: NodeCache /** map to store the retry counts for failed messages */ msgRetryCounterMap?: { [msgId: string]: number } - /** custom domains to push media via */ - customUploadHosts: string[] /** * fetch a message from your store * implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 61c31f0..ab4a0c6 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -467,7 +467,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C let uploadInfo = await refreshMediaConn(false) let urls: { mediaUrl: string, directPath: string } - const hosts = [ ...customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] + const hosts = [ ...customUploadHosts, ...uploadInfo.hosts ] let chunks: Buffer[] = [] for await(const chunk of stream) { @@ -476,11 +476,17 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C let reqBody = Buffer.concat(chunks) - for (let hostname of hosts) { + for (let { hostname, maxContentLengthBytes } of hosts) { + logger.debug(`uploading to "${hostname}"`) + const auth = encodeURIComponent(uploadInfo.auth) // the auth token const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` let result: any try { + if(maxContentLengthBytes && reqBody.length > maxContentLengthBytes) { + throw new Boom(`Body too large for "${hostname}"`, { statusCode: 413 }) + } + const body = await axios.post( url, reqBody, @@ -509,8 +515,12 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) } } catch (error) { - const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) + if(axios.isAxiosError(error)) { + result = error.response?.data + } + + const isLast = hostname === hosts[uploadInfo.hosts.length-1]?.hostname + logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) } } // clear buffer just to be sure we're releasing the memory