desktop-cos.ts 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /** Shared Tencent COS client construction for Desktop update objects. */
  2. import COS from 'cos-nodejs-sdk-v5'
  3. /** Region of every Desktop update bucket, present or future deployment. */
  4. export const DESKTOP_COS_REGION = 'ap-beijing'
  5. /** Request-level inactivity deadline for COS transfers, in milliseconds. */
  6. const TRANSFER_TIMEOUT_MS = 900_000
  7. /** Credentials for one COS client; values are never written to retained records. */
  8. export interface DesktopCosCredentials {
  9. readonly secretId: string
  10. readonly secretKey: string
  11. }
  12. /** Request options the SDK exposes to `before-send` listeners. */
  13. interface CosRequestOptions {
  14. headers: Record<string, unknown>
  15. }
  16. /**
  17. * Create a COS client whose writes cannot be repeated by the SDK.
  18. *
  19. * The SDK retries a failed request only while the request body is not a stream, so every caller
  20. * supplies a stream with an explicit `ContentLength` and a precomputed `Content-MD5`. Host
  21. * switching, redirect following, and clock-offset correction stay off so an ambiguous write is
  22. * never sent to another endpoint. The SDK also injects an empty `Cache-Control` header when the
  23. * caller names none; that header is removed here so uploading leaves cache policy to deployment
  24. * infrastructure.
  25. * @param credentials SecretId and SecretKey for the selected deployment.
  26. * @returns A COS client that sends HTTPS requests to the region named by each call.
  27. */
  28. export function createDesktopCos(credentials: DesktopCosCredentials): COS {
  29. const cos = new COS({
  30. SecretId: credentials.secretId,
  31. SecretKey: credentials.secretKey,
  32. Protocol: 'https:',
  33. KeepAlive: false,
  34. FollowRedirect: false,
  35. AutoSwitchHost: false,
  36. CorrectClockSkew: false,
  37. ChunkRetryTimes: 0,
  38. Timeout: TRANSFER_TIMEOUT_MS,
  39. UploadCheckContentMd5: false,
  40. })
  41. cos.on('before-send', (options: CosRequestOptions) => {
  42. for (const name of Object.keys(options.headers)) {
  43. if (name.toLowerCase() === 'cache-control' && options.headers[name] === '') delete options.headers[name]
  44. }
  45. })
  46. return cos
  47. }