11
11
#include "reader.h"
12
12
#include "recorder_utils.h"
13
13
#include "private/region.h"
14
+ #include "private/code.h"
14
15
#include <curl/curl.h>
15
16
16
17
/*============================================================================*/
@@ -58,20 +59,27 @@ CURL *Qiniu_Client_reset(Qiniu_Client *self);
58
59
59
60
Qiniu_Error Qiniu_callex (CURL * curl , Qiniu_Buffer * resp , Qiniu_Json * * ret , Qiniu_Bool simpleError , Qiniu_Buffer * resph );
60
61
61
- static Qiniu_Error Get_Qiniu_UpHost (Qiniu_Client * client , const char * accessKey , const char * bucketName , Qiniu_Io_PutExtra * extra , const char * * upHost )
62
+ static Qiniu_Error Get_Qiniu_UpHosts (Qiniu_Client * client , const char * accessKey , const char * bucketName , Qiniu_Io_PutExtra * extra , const char * const * * upHosts , size_t * upHostsCount )
62
63
{
63
64
if (extra && extra -> ipCount != 0 )
64
65
{
65
66
Qiniu_Count oldIndex = Qiniu_Count_Inc (& extra -> ipIndex );
66
- * upHost = extra -> upIps [abs (oldIndex % extra -> ipCount )];
67
+ * upHosts = & extra -> upIps [labs (oldIndex % extra -> ipCount )];
68
+ * upHostsCount = 1 ;
67
69
}
68
70
else if (extra && extra -> upHost != NULL )
69
71
{
70
- * upHost = extra -> upHost ;
72
+ * upHosts = & extra -> upHost ;
73
+ * upHostsCount = 1 ;
74
+ }
75
+ else if (extra && extra -> upHosts != NULL && extra -> upHostsCount != 0 )
76
+ {
77
+ * upHosts = extra -> upHosts ;
78
+ * upHostsCount = extra -> upHostsCount ;
71
79
}
72
80
else
73
81
{
74
- Qiniu_Error err = _Qiniu_Region_Get_Up_Host (client , accessKey , bucketName , upHost );
82
+ Qiniu_Error err = _Qiniu_Region_Get_Up_Hosts (client , accessKey , bucketName , upHosts , upHostsCount );
75
83
if (err .code != Qiniu_OK .code )
76
84
{
77
85
return err ;
@@ -150,48 +158,61 @@ static Qiniu_Error Qiniu_Io_call(
150
158
{
151
159
int retCode = 0 ;
152
160
Qiniu_Error err ;
153
- struct curl_slist * headers = NULL ;
154
- const char * upHost = NULL ;
161
+ struct curl_slist * headers ;
162
+ const char * const * upHosts ;
163
+ const char * defaultUpHosts [] = {QINIU_UP_HOST };
164
+ size_t upHostsCount ;
155
165
156
- err = Qiniu_Client_config (self );
166
+ headers = curl_slist_append (NULL , "Expect:" );
167
+ err = Get_Qiniu_UpHosts (self , accessKey , bucketName , extra , & upHosts , & upHostsCount );
157
168
if (err .code != Qiniu_OK .code )
158
169
{
159
170
return err ;
160
171
}
161
- err = Get_Qiniu_UpHost (self , accessKey , bucketName , extra , & upHost );
162
- if (err .code != Qiniu_OK .code )
172
+ if (upHostsCount == 0 )
163
173
{
164
- return err ;
174
+ upHosts = defaultUpHosts ;
175
+ upHostsCount = 1 ;
165
176
}
166
177
167
- headers = curl_slist_append (NULL , "Expect:" );
168
-
169
- CURL * curl = Qiniu_Client_reset (self );
170
- curl_easy_setopt (curl , CURLOPT_URL , upHost );
171
- curl_easy_setopt (curl , CURLOPT_HTTPPOST , formpost );
172
- curl_easy_setopt (curl , CURLOPT_HTTPHEADER , headers );
173
-
174
- //// For aborting uploading file.
175
- if (extra -> upAbortCallback )
178
+ for (size_t retries = 0 ; retries < upHostsCount && retries <= self -> retriesMax ; retries ++ )
176
179
{
177
- curl_easy_setopt (curl , CURLOPT_READFUNCTION , Qiniu_Rd_Reader_Callback );
178
- } // if
180
+ CURL * curl = Qiniu_Client_reset (self );
181
+ err = Qiniu_Client_config (self );
182
+ if (err .code != Qiniu_OK .code )
183
+ {
184
+ return err ;
185
+ }
186
+ curl_easy_setopt (curl , CURLOPT_URL , upHosts [retries ]);
187
+ curl_easy_setopt (curl , CURLOPT_HTTPPOST , formpost );
188
+ curl_easy_setopt (curl , CURLOPT_HTTPHEADER , headers );
179
189
180
- err = Qiniu_callex (curl , & self -> b , & self -> root , Qiniu_False , & self -> respHeader );
181
- if (err .code == Qiniu_OK .code && ret != NULL )
182
- {
183
- if (extra -> callbackRetParser != NULL )
190
+ //// For aborting uploading file.
191
+ if (extra -> upAbortCallback )
184
192
{
185
- err = (* extra -> callbackRetParser )(extra -> callbackRet , self -> root );
193
+ curl_easy_setopt (curl , CURLOPT_READFUNCTION , Qiniu_Rd_Reader_Callback );
194
+ } // if
195
+
196
+ err = Qiniu_callex (curl , & self -> b , & self -> root , Qiniu_False , & self -> respHeader );
197
+ if (err .code == Qiniu_OK .code )
198
+ {
199
+ if (extra -> callbackRetParser != NULL )
200
+ {
201
+ err = (* extra -> callbackRetParser )(extra -> callbackRet , self -> root );
202
+ }
203
+ else if (ret != NULL )
204
+ {
205
+ ret -> hash = Qiniu_Json_GetString (self -> root , "hash" , NULL );
206
+ ret -> key = Qiniu_Json_GetString (self -> root , "key" , NULL );
207
+ ret -> persistentId = Qiniu_Json_GetString (self -> root , "persistentId" , NULL );
208
+ }
209
+ break ;
186
210
}
187
- else
211
+ else if ( _Qiniu_Should_Retry ( err . code ) == QINIU_DONT_RETRY )
188
212
{
189
- ret -> hash = Qiniu_Json_GetString (self -> root , "hash" , NULL );
190
- ret -> key = Qiniu_Json_GetString (self -> root , "key" , NULL );
191
- ret -> persistentId = Qiniu_Json_GetString (self -> root , "persistentId" , NULL );
213
+ break ;
192
214
}
193
215
}
194
-
195
216
curl_formfree (formpost );
196
217
curl_slist_free_all (headers );
197
218
return err ;
@@ -313,7 +334,6 @@ Qiniu_Error Qiniu_Io_PutBuffer(
313
334
CURLFORM_BUFFER , key , CURLFORM_BUFFERPTR , buf , CURLFORM_BUFFERLENGTH , fsize , CURLFORM_END );
314
335
err = Qiniu_Io_call (self , accessKey , bucketName , ret , form .formpost , extra );
315
336
316
- error :
317
337
Qiniu_Free ((void * )accessKey );
318
338
Qiniu_Free ((void * )bucketName );
319
339
return err ;
@@ -327,42 +347,56 @@ static Qiniu_Error Qiniu_Io_call_with_callback(
327
347
{
328
348
int retCode = 0 ;
329
349
Qiniu_Error err ;
330
- struct curl_slist * headers = NULL ;
331
- const char * upHost ;
350
+ struct curl_slist * headers ;
351
+ const char * const * upHosts ;
352
+ const char * defaultUpHosts [] = {QINIU_UP_HOST };
353
+ size_t upHostsCount ;
332
354
333
- CURL * curl = Qiniu_Client_reset ( self );
334
- err = Qiniu_Client_config (self );
355
+ headers = curl_slist_append ( NULL , "Expect:" );
356
+ err = Get_Qiniu_UpHosts (self , accessKey , bucketName , extra , & upHosts , & upHostsCount );
335
357
if (err .code != Qiniu_OK .code )
336
358
{
337
359
return err ;
338
360
}
339
- err = Get_Qiniu_UpHost (self , accessKey , bucketName , extra , & upHost );
340
- if (err .code != Qiniu_OK .code )
361
+ if (upHostsCount == 0 )
341
362
{
342
- return err ;
363
+ upHosts = defaultUpHosts ;
364
+ upHostsCount = 1 ;
343
365
}
344
366
345
- headers = curl_slist_append (NULL , "Expect:" );
367
+ for (size_t retries = 0 ; retries < upHostsCount && retries <= self -> retriesMax ; retries ++ )
368
+ {
369
+ CURL * curl = Qiniu_Client_reset (self );
370
+ err = Qiniu_Client_config (self );
371
+ if (err .code != Qiniu_OK .code )
372
+ {
373
+ return err ;
374
+ }
346
375
347
- curl_easy_setopt (curl , CURLOPT_URL , upHost );
348
- curl_easy_setopt (curl , CURLOPT_HTTPPOST , formpost );
349
- curl_easy_setopt (curl , CURLOPT_HTTPHEADER , headers );
350
- curl_easy_setopt (curl , CURLOPT_READFUNCTION , rdr );
376
+ curl_easy_setopt (curl , CURLOPT_URL , upHosts [ retries ] );
377
+ curl_easy_setopt (curl , CURLOPT_HTTPPOST , formpost );
378
+ curl_easy_setopt (curl , CURLOPT_HTTPHEADER , headers );
379
+ curl_easy_setopt (curl , CURLOPT_READFUNCTION , rdr );
351
380
352
- err = Qiniu_callex (curl , & self -> b , & self -> root , Qiniu_False , & self -> respHeader );
353
- if (err .code == Qiniu_OK .code && ret != NULL )
354
- {
355
- if (extra -> callbackRetParser != NULL )
381
+ err = Qiniu_callex (curl , & self -> b , & self -> root , Qiniu_False , & self -> respHeader );
382
+ if (err .code == Qiniu_OK .code )
356
383
{
357
- err = (* extra -> callbackRetParser )(extra -> callbackRet , self -> root );
384
+ if (extra -> callbackRetParser != NULL )
385
+ {
386
+ err = (* extra -> callbackRetParser )(extra -> callbackRet , self -> root );
387
+ }
388
+ else if (ret != NULL )
389
+ {
390
+ ret -> hash = Qiniu_Json_GetString (self -> root , "hash" , NULL );
391
+ ret -> key = Qiniu_Json_GetString (self -> root , "key" , NULL );
392
+ }
393
+ break ;
358
394
}
359
- else
395
+ else if ( _Qiniu_Should_Retry ( err . code ) == QINIU_DONT_RETRY )
360
396
{
361
- ret -> hash = Qiniu_Json_GetString (self -> root , "hash" , NULL );
362
- ret -> key = Qiniu_Json_GetString (self -> root , "key" , NULL );
397
+ break ;
363
398
}
364
399
}
365
-
366
400
curl_formfree (formpost );
367
401
curl_slist_free_all (headers );
368
402
return err ;
@@ -408,7 +442,6 @@ Qiniu_Error Qiniu_Io_PutStream(
408
442
CURLFORM_END );
409
443
410
444
err = Qiniu_Io_call_with_callback (self , accessKey , bucketName , ret , form .formpost , rdr , extra );
411
- error :
412
445
Qiniu_Free ((void * )accessKey );
413
446
Qiniu_Free ((void * )bucketName );
414
447
return err ;
0 commit comments