fix(clouddrop): cap concurrent TCP connections at 50 via undici Agent
Defensive guard to stay under server's cd_conn 100/IP limit even with aggressive parallel uploads and keep-alive pooling.
This commit is contained in:
parent
84f117584c
commit
ff8b0799e0
@ -1,7 +1,7 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const { request } = require('undici');
|
||||
const { request, Agent } = require('undici');
|
||||
|
||||
const BASE_URL = 'https://clouddrop.cc';
|
||||
const API_BASE = `${BASE_URL}/api/cloud`;
|
||||
@ -15,6 +15,16 @@ const COMPLETE_TIMEOUT = 5 * 60_000;
|
||||
const SHARE_TIMEOUT = 30_000;
|
||||
const SIMPLE_UPLOAD_TIMEOUT = 30 * 60_000;
|
||||
|
||||
// Cap concurrent TCP connections to clouddrop.cc at 50 to stay well under
|
||||
// the server's per-IP limit of 100 concurrent connections (cd_conn).
|
||||
// Shared across all ClouddropUploader instances via module-level agent.
|
||||
const clouddropAgent = new Agent({
|
||||
connections: 50,
|
||||
pipelining: 1,
|
||||
keepAliveTimeout: 30_000,
|
||||
keepAliveMaxTimeout: 60_000
|
||||
});
|
||||
|
||||
/**
|
||||
* Clouddrop.cc uploader — uses API Key (Bearer) authentication.
|
||||
* Files > 16 MB use the chunked protocol, smaller files use simple upload.
|
||||
@ -115,6 +125,7 @@ class ClouddropUploader {
|
||||
|
||||
const res = await request(`${API_BASE}/upload?mode=rename`, {
|
||||
method: 'POST',
|
||||
dispatcher: clouddropAgent,
|
||||
body: generate(),
|
||||
signal,
|
||||
headers: this._headers({
|
||||
@ -138,6 +149,7 @@ class ClouddropUploader {
|
||||
// 1. Init session
|
||||
const initRes = await request(`${API_BASE}/upload/init`, {
|
||||
method: 'POST',
|
||||
dispatcher: clouddropAgent,
|
||||
signal,
|
||||
headers: this._headers({ 'Content-Type': 'application/json' }),
|
||||
body: JSON.stringify({ filename: fileName, size: fileSize, parentId: null }),
|
||||
@ -167,6 +179,7 @@ class ClouddropUploader {
|
||||
|
||||
const chunkRes = await request(`${API_BASE}/upload/${sessionId}/chunk/${i}`, {
|
||||
method: 'PUT',
|
||||
dispatcher: clouddropAgent,
|
||||
signal,
|
||||
body: buf,
|
||||
headers: this._headers({
|
||||
@ -188,6 +201,7 @@ class ClouddropUploader {
|
||||
// 3. Complete session
|
||||
const completeRes = await request(`${API_BASE}/upload/${sessionId}/complete`, {
|
||||
method: 'POST',
|
||||
dispatcher: clouddropAgent,
|
||||
signal,
|
||||
headers: this._headers({ 'Content-Type': 'application/json' }),
|
||||
body: '{}',
|
||||
@ -206,6 +220,7 @@ class ClouddropUploader {
|
||||
async _createShareLink(fileId, signal) {
|
||||
const res = await request(`${API_BASE}/share-link`, {
|
||||
method: 'POST',
|
||||
dispatcher: clouddropAgent,
|
||||
signal,
|
||||
headers: this._headers({ 'Content-Type': 'application/json' }),
|
||||
body: JSON.stringify({ fileId, expiry: 'never' }),
|
||||
@ -223,6 +238,7 @@ class ClouddropUploader {
|
||||
if (!this.apiKey) throw new Error('Clouddrop: API-Key fehlt');
|
||||
const res = await request(`${API_BASE}/files?limit=1`, {
|
||||
method: 'GET',
|
||||
dispatcher: clouddropAgent,
|
||||
signal,
|
||||
headers: this._headers(),
|
||||
headersTimeout: 15_000,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user