0
# Configuration & Regions
1
2
Regional configuration and upload settings for optimal performance across different geographic locations, along with API management functions.
3
4
## Capabilities
5
6
### Regional Configuration
7
8
Qiniu Cloud Storage operates in multiple regions worldwide. Choose the appropriate region for optimal upload performance.
9
10
```typescript { .api }
11
const region = {
12
/** East China (Huadong) */
13
z0: 'z0',
14
/** North China (Huabei) */
15
z1: 'z1',
16
/** South China (Huanan) */
17
z2: 'z2',
18
/** North America */
19
na0: 'na0',
20
/** Southeast Asia */
21
as0: 'as0',
22
/** East China 2 (Huadong-Zhejiang 2) */
23
cnEast2: 'cn-east-2'
24
} as const;
25
```
26
27
**Usage Examples:**
28
29
```typescript
30
import { upload, region } from "qiniu-js";
31
32
// Upload to East China region (most common)
33
const subscription = upload(file, key, token, {
34
fname: file.name
35
}, {
36
region: region.z0,
37
useCdnDomain: true
38
});
39
40
// Upload to North America region for US users
41
const usUpload = upload(file, key, token, {
42
fname: file.name
43
}, {
44
region: region.na0,
45
upprotocol: 'https'
46
});
47
48
// Upload to Southeast Asia for Asian users
49
const asiaUpload = upload(file, key, token, {
50
fname: file.name
51
}, {
52
region: region.as0
53
});
54
55
// Dynamic region selection based on user location
56
function selectOptimalRegion(userCountry: string): string {
57
const regionMap: { [key: string]: string } = {
58
'US': region.na0,
59
'CA': region.na0,
60
'SG': region.as0,
61
'MY': region.as0,
62
'TH': region.as0,
63
'CN': region.z0,
64
'default': region.z0
65
};
66
67
return regionMap[userCountry] || regionMap['default'];
68
}
69
```
70
71
### Upload URL Management
72
73
Functions for managing upload endpoints and cleaning up failed uploads.
74
75
```typescript { .api }
76
/**
77
* Get the optimal upload URL for given configuration
78
* @param config - Upload URL configuration
79
* @param token - Upload token
80
* @returns Promise resolving to upload URL
81
*/
82
function getUploadUrl(config: UploadUrlConfig, token: string): Promise<string>;
83
84
/**
85
* Delete uploaded chunks from a failed or cancelled resumable upload
86
* @param token - Upload token
87
* @param key - Target file key
88
* @param uploadinfo - Upload session information
89
* @returns Promise for cleanup completion
90
*/
91
function deleteUploadedChunks(
92
token: string,
93
key: string | null | undefined,
94
uploadinfo: UploadInfo
95
): Promise<ResponseSuccess<void>>;
96
97
interface UploadUrlConfig {
98
/** Upload protocol */
99
upprotocol?: 'https' | 'http';
100
/** Custom upload host */
101
uphost?: string[];
102
/** Target region */
103
region?: string;
104
/** Use CDN domain */
105
useCdnDomain?: boolean;
106
}
107
108
interface UploadInfo {
109
/** Upload session ID */
110
id: string;
111
/** Upload endpoint URL */
112
url: string;
113
}
114
```
115
116
**Usage Examples:**
117
118
```typescript
119
import { getUploadUrl, deleteUploadedChunks } from "qiniu-js";
120
121
// Get upload URL for specific configuration
122
async function getCustomUploadUrl(token: string) {
123
try {
124
const uploadUrl = await getUploadUrl({
125
region: 'z0',
126
upprotocol: 'https',
127
useCdnDomain: true
128
}, token);
129
130
console.log('Upload URL:', uploadUrl);
131
return uploadUrl;
132
} catch (error) {
133
console.error('Failed to get upload URL:', error);
134
throw error;
135
}
136
}
137
138
// Clean up failed resumable upload
139
async function cleanupFailedUpload(token: string, key: string, uploadInfo: UploadInfo) {
140
try {
141
await deleteUploadedChunks(token, key, uploadInfo);
142
console.log('Cleanup completed for upload session:', uploadInfo.id);
143
} catch (error) {
144
console.error('Cleanup failed:', error);
145
}
146
}
147
148
// Advanced upload URL management
149
class UploadManager {
150
private uploadUrls: Map<string, string> = new Map();
151
152
async getOrCreateUploadUrl(region: string, token: string): Promise<string> {
153
const cacheKey = `${region}-${token.substring(0, 10)}`;
154
155
if (this.uploadUrls.has(cacheKey)) {
156
return this.uploadUrls.get(cacheKey)!;
157
}
158
159
const url = await getUploadUrl({
160
region,
161
upprotocol: 'https',
162
useCdnDomain: true
163
}, token);
164
165
this.uploadUrls.set(cacheKey, url);
166
return url;
167
}
168
169
clearCache() {
170
this.uploadUrls.clear();
171
}
172
}
173
```
174
175
## Regional Configuration Details
176
177
### Region Selection Guidelines
178
179
Choose the appropriate region based on your users' geographic location for optimal performance:
180
181
| Region | Code | Location | Best For |
182
|--------|------|----------|----------|
183
| East China | `z0` | Shanghai | China mainland users |
184
| North China | `z1` | Beijing | Northern China users |
185
| South China | `z2` | Guangzhou | Southern China users |
186
| North America | `na0` | USA | US and Canada users |
187
| Southeast Asia | `as0` | Singapore | Asian users outside China |
188
| East China 2 | `cnEast2` | Zhejiang | Backup for East China |
189
190
**Region Performance Example:**
191
192
```typescript
193
import { upload, region } from "qiniu-js";
194
195
// Measure upload performance across regions
196
async function benchmarkRegions(file: File, token: string): Promise<void> {
197
const regions = [region.z0, region.z1, region.z2, region.na0, region.as0];
198
const results: { region: string; time: number; speed: number }[] = [];
199
200
for (const reg of regions) {
201
const startTime = Date.now();
202
203
try {
204
await new Promise((resolve, reject) => {
205
upload(file, `benchmark-${reg}.test`, token, {}, { region: reg })
206
.subscribe({
207
complete: resolve,
208
error: reject
209
});
210
});
211
212
const duration = Date.now() - startTime;
213
const speed = (file.size / 1024) / (duration / 1000); // KB/s
214
215
results.push({
216
region: reg,
217
time: duration,
218
speed: Math.round(speed)
219
});
220
221
} catch (error) {
222
console.error(`Region ${reg} failed:`, error);
223
}
224
}
225
226
// Sort by speed
227
results.sort((a, b) => b.speed - a.speed);
228
console.log('Region performance results:', results);
229
}
230
```
231
232
### Upload Configuration Best Practices
233
234
Optimize upload settings for different scenarios.
235
236
```typescript
237
import { upload, region } from "qiniu-js";
238
239
// Configuration for different use cases
240
const configurations = {
241
// Fast uploads for small files
242
smallFiles: {
243
forceDirect: true,
244
useCdnDomain: true,
245
retryCount: 3,
246
region: region.z0
247
},
248
249
// Reliable uploads for large files
250
largeFiles: {
251
chunkSize: 8, // 8MB chunks
252
concurrentRequestLimit: 3,
253
retryCount: 5,
254
useCdnDomain: true,
255
region: region.z0
256
},
257
258
// Conservative settings for unstable networks
259
unstableNetwork: {
260
chunkSize: 2, // Smaller chunks
261
concurrentRequestLimit: 1,
262
retryCount: 10,
263
useCdnDomain: false, // Direct to origin
264
region: region.z0
265
},
266
267
// High-performance settings for stable networks
268
highPerformance: {
269
chunkSize: 16, // Large chunks
270
concurrentRequestLimit: 6,
271
retryCount: 3,
272
useCdnDomain: true,
273
region: region.z0
274
}
275
};
276
277
// Smart configuration selection
278
function selectConfiguration(file: File, networkQuality: 'fast' | 'normal' | 'slow') {
279
const fileSize = file.size;
280
const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
281
282
if (fileSize < 4 * 1024 * 1024) { // < 4MB
283
return configurations.smallFiles;
284
}
285
286
if (networkQuality === 'slow' || isMobile) {
287
return configurations.unstableNetwork;
288
}
289
290
if (networkQuality === 'fast' && fileSize > 100 * 1024 * 1024) { // > 100MB
291
return configurations.highPerformance;
292
}
293
294
return configurations.largeFiles;
295
}
296
297
// Usage with smart configuration
298
function smartUpload(file: File, key: string, token: string, networkQuality: 'fast' | 'normal' | 'slow' = 'normal') {
299
const config = selectConfiguration(file, networkQuality);
300
301
return upload(file, key, token, {
302
fname: file.name
303
}, config);
304
}
305
```
306
307
### Custom Host Configuration
308
309
Configure custom upload hosts for enterprise deployments.
310
311
```typescript
312
import { upload } from "qiniu-js";
313
314
// Custom host configuration
315
const enterpriseConfig = {
316
uphost: [
317
'upload.your-domain.com',
318
'upload-backup.your-domain.com'
319
],
320
upprotocol: 'https' as const,
321
useCdnDomain: false,
322
retryCount: 3
323
};
324
325
// Upload using custom hosts
326
const enterpriseUpload = upload(file, key, token, {
327
fname: file.name
328
}, enterpriseConfig);
329
330
// Fallback configuration with multiple hosts
331
const redundantConfig = {
332
uphost: [
333
'primary-upload.example.com',
334
'secondary-upload.example.com',
335
'tertiary-upload.example.com'
336
],
337
upprotocol: 'https' as const,
338
retryCount: 5 // Will try different hosts on failure
339
};
340
```
341
342
### Dynamic Configuration
343
344
Adapt configuration based on runtime conditions.
345
346
```typescript
347
import { upload, region } from "qiniu-js";
348
349
class DynamicUploadConfig {
350
private userLocation: string = 'unknown';
351
private networkSpeed: number = 0;
352
private deviceType: 'mobile' | 'desktop' = 'desktop';
353
354
constructor() {
355
this.detectEnvironment();
356
}
357
358
private detectEnvironment() {
359
// Detect device type
360
this.deviceType = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
361
? 'mobile' : 'desktop';
362
363
// Estimate network speed (simplified)
364
if ('connection' in navigator) {
365
const connection = (navigator as any).connection;
366
this.networkSpeed = connection.downlink || 1;
367
}
368
}
369
370
getOptimalConfig(fileSize: number) {
371
const config: any = {
372
useCdnDomain: true,
373
upprotocol: 'https'
374
};
375
376
// Region selection
377
config.region = this.selectRegion();
378
379
// Chunk size based on network and device
380
if (this.deviceType === 'mobile' || this.networkSpeed < 2) {
381
config.chunkSize = 2; // 2MB for mobile/slow networks
382
config.concurrentRequestLimit = 1;
383
} else if (this.networkSpeed > 10) {
384
config.chunkSize = 16; // 16MB for fast networks
385
config.concurrentRequestLimit = 6;
386
} else {
387
config.chunkSize = 8; // 8MB default
388
config.concurrentRequestLimit = 3;
389
}
390
391
// Retry logic
392
config.retryCount = this.deviceType === 'mobile' ? 5 : 3;
393
394
// Force direct for small files
395
if (fileSize < 4 * 1024 * 1024) {
396
config.forceDirect = true;
397
}
398
399
return config;
400
}
401
402
private selectRegion(): string {
403
// Simplified region selection
404
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
405
406
if (timezone.includes('America')) {
407
return region.na0;
408
} else if (timezone.includes('Asia') && !timezone.includes('China')) {
409
return region.as0;
410
} else {
411
return region.z0; // Default to East China
412
}
413
}
414
}
415
416
// Usage
417
const dynamicConfig = new DynamicUploadConfig();
418
419
function adaptiveUpload(file: File, key: string, token: string) {
420
const config = dynamicConfig.getOptimalConfig(file.size);
421
422
console.log('Using adaptive configuration:', config);
423
424
return upload(file, key, token, {
425
fname: file.name
426
}, config);
427
}
428
```