Skip to content

Commit 8a25a28

Browse files
committed
add RetryDomainsMiddleware
1 parent 83b8c57 commit 8a25a28

File tree

8 files changed

+747
-100
lines changed

8 files changed

+747
-100
lines changed

src/Qiniu/Http/HttpCode.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public enum HttpCode
5151
/// 镜像回源失败
5252
/// </summary>
5353
PREFETCH_FAILED = 478,
54+
55+
/// <summary>
56+
/// 接口未实现
57+
/// </summary>
58+
NOT_IMPLEMENTED = 501,
5459

5560
/// <summary>
5661
/// 错误网关
@@ -67,6 +72,11 @@ public enum HttpCode
6772
/// </summary>
6873
SERVER_TIME_EXCEED = 504,
6974

75+
/// <summary>
76+
/// 超出带宽限制
77+
/// </summary>
78+
BANDWIDTH_LIMIT_EXCEEDED = 509,
79+
7080
/// <summary>
7181
/// 单个资源访问频率过高
7282
/// </summary>
@@ -88,15 +98,25 @@ public enum HttpCode
8898
CONTENT_MODIFIED = 608,
8999

90100
/// <summary>
91-
/// 文件不存在
101+
/// 文件不存在/指定资源不存在或已被删除
92102
/// </summary>
93103
FILE_NOT_EXIST = 612,
94104

95105
/// <summary>
96-
/// 文件已存在
106+
/// 文件已存在/目标资源已存在
97107
/// </summary>
98108
FILE_EXISTS = 614,
99109

110+
/// <summary>
111+
/// 当前操作无法在共享空间执行(被共享的用户进行操作时)
112+
/// </summary>
113+
INVALID_SHARE_BUCKET = 616,
114+
115+
/// <summary>
116+
/// 当前操作无法在共享空间执行(所有者进行操作时)
117+
/// </summary>
118+
BUCKET_IS_SHARING = 618,
119+
100120
/// <summary>
101121
/// 空间数量已达上限
102122
/// </summary>
@@ -107,6 +127,11 @@ public enum HttpCode
107127
/// </summary>
108128
BUCKET_NOT_EXIST = 631,
109129

130+
/// <summary>
131+
/// 共享空间达到上限
132+
/// </summary>
133+
EXCEED_SHARED_BUCKETS_LIMIT = 632,
134+
110135
/// <summary>
111136
/// 列举资源(list)使用了非法的marker
112137
/// </summary>

src/Qiniu/Http/HttpManager.cs

Lines changed: 73 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class HttpManager
2424
public HttpManager(bool allowAutoRedirect = false)
2525
{
2626
this.allowAutoRedirect = allowAutoRedirect;
27-
userAgent = GetUserAgent();
27+
userAgent = GetUserAgent();
2828
}
2929

3030
/// <summary>
@@ -45,7 +45,7 @@ public static string GetUserAgent()
4545
/// <returns>客户端标识UA</returns>
4646
public void SetUserAgent(string userAgent)
4747
{
48-
if(!string.IsNullOrEmpty(userAgent))
48+
if (!string.IsNullOrEmpty(userAgent))
4949
{
5050
this.userAgent = userAgent;
5151
}
@@ -61,64 +61,46 @@ public static string CreateFormDataBoundary()
6161
return string.Format("-------{0}Boundary{1}", QiniuCSharpSDK.ALIAS, Hashing.CalcMD5X(now));
6262
}
6363

64-
public HttpWebRequest CreateHttpWebRequest(
64+
public HttpRequestOptions CreateHttpRequestOptions(
6565
string method,
6666
string url,
6767
StringDictionary headers,
6868
string token = null
6969
)
7070
{
71-
HttpWebRequest wReq = WebRequest.Create(url) as HttpWebRequest;
71+
HttpRequestOptions reqOpts = new HttpRequestOptions();
7272

73-
if (wReq == null)
74-
{
75-
StringBuilder msg = new StringBuilder();
76-
msg.AppendFormat("Failed to create HttpWebRequest with URL \"{0}\".", url);
77-
throw new InvalidOperationException(msg.ToString());
78-
}
79-
80-
wReq.Method = method;
73+
reqOpts.Method = method;
74+
reqOpts.Url = url;
8175

8276
if (headers != null)
8377
{
84-
foreach (string fieldName in headers.Keys)
85-
{
86-
if (!WebHeaderCollection.IsRestricted(fieldName))
87-
{
88-
wReq.Headers.Add(fieldName, headers[fieldName]);
89-
}
90-
}
91-
92-
if (headers.ContainsKey("Content-Type"))
93-
{
94-
wReq.ContentType = headers["Content-Type"];
95-
}
78+
reqOpts.Headers = headers;
9679
}
97-
80+
9881
if (!string.IsNullOrEmpty(token))
9982
{
100-
wReq.Headers.Add("Authorization", token);
83+
reqOpts.Headers.Add("Authorization", token);
10184
}
102-
103-
wReq.UserAgent = userAgent;
104-
wReq.AllowAutoRedirect = allowAutoRedirect;
105-
wReq.ServicePoint.Expect100Continue = false;
106-
107-
return wReq;
85+
86+
reqOpts.Headers.Add("User-Agent", userAgent);
87+
reqOpts.AllowAutoRedirect = allowAutoRedirect;
88+
89+
return reqOpts;
10890
}
10991

11092
public HttpResult CreateHttpResult(HttpWebResponse wResp, bool binaryMode = false)
11193
{
11294
HttpResult result = new HttpResult();
113-
95+
11496
if (wResp == null)
11597
{
11698
return result;
11799
}
118100

119101
result.Code = (int)wResp.StatusCode;
120102
result.RefCode = (int)wResp.StatusCode;
121-
103+
122104
getHeaders(ref result, wResp);
123105

124106
Stream respStream = wResp.GetResponseStream();
@@ -156,12 +138,14 @@ public HttpResult CreateHttpResult(HttpWebResponse wResp, bool binaryMode = fals
156138
return result;
157139
}
158140

159-
public HttpResult SendRequest(HttpWebRequest wReq, Boolean binaryMode = false)
141+
public HttpResult SendRequest(HttpRequestOptions reqOpts, Boolean binaryMode = false)
160142
{
161143
HttpResult result;
144+
HttpWebRequest wReq = null;
162145

163146
try
164147
{
148+
wReq = reqOpts.CreateHttpWebRequest();
165149
HttpWebResponse wResp = wReq.GetResponse() as HttpWebResponse;
166150

167151
result = CreateHttpResult(wResp, binaryMode);
@@ -178,7 +162,7 @@ public HttpResult SendRequest(HttpWebRequest wReq, Boolean binaryMode = false)
178162
"[{0}] [{1}] [HTTP-{2}] Error: ",
179163
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"),
180164
userAgent,
181-
wReq.Method
165+
reqOpts.Method
182166
);
183167
Exception e = ex;
184168
while (e != null)
@@ -203,23 +187,23 @@ public HttpResult SendRequest(HttpWebRequest wReq, Boolean binaryMode = false)
203187
return result;
204188
}
205189

206-
public HttpResult SendRequest(HttpWebRequest wReq, List<IMiddleware> middlewares, Boolean binaryMode = false)
190+
public HttpResult SendRequest(HttpRequestOptions reqOpts, List<IMiddleware> middlewares, Boolean binaryMode = false)
207191
{
208192
if (middlewares == null || middlewares.Count == 0)
209193
{
210-
return SendRequest(wReq, binaryMode);
194+
return SendRequest(reqOpts, binaryMode);
211195
}
212-
196+
213197
List<IMiddleware> reversedMiddlewares = new List<IMiddleware>(middlewares);
214198
reversedMiddlewares.Reverse();
215199
DNextSend composedHandle = reversedMiddlewares.Aggregate<IMiddleware, DNextSend>(
216200
req => SendRequest(req, binaryMode),
217201
(handle, middleware) => request => middleware.Send(request, handle)
218202
);
219203

220-
return composedHandle(wReq);
204+
return composedHandle(reqOpts);
221205
}
222-
206+
223207
/// <summary>
224208
/// HTTP-GET 方法(不包含 headers)
225209
/// </summary>
@@ -262,14 +246,25 @@ public HttpResult Get(string url, StringDictionary headers, Auth auth, bool bina
262246
/// <returns>HTTP-GET的响应结果</returns>
263247
public HttpResult Get(string url, StringDictionary headers, string token, bool binaryMode = false)
264248
{
265-
HttpWebRequest wReq = CreateHttpWebRequest("GET", url, headers, token);
266-
return SendRequest(wReq, binaryMode);
249+
return Get(url, headers, token, null, binaryMode);
267250
}
268251

269252
public HttpResult Get(string url, StringDictionary headers, string token, List<IMiddleware> middlewares, bool binaryMode = false)
270253
{
271-
HttpWebRequest wReq = CreateHttpWebRequest("GET", url, headers, token);
272-
return SendRequest(wReq, middlewares, binaryMode);
254+
if (headers == null)
255+
{
256+
headers = new StringDictionary{
257+
{"Content-Type", ContentType.WWW_FORM_URLENC}
258+
};
259+
}
260+
261+
if (!headers.ContainsKey("Content-Type"))
262+
{
263+
headers["Content-Type"] = ContentType.WWW_FORM_URLENC;
264+
}
265+
266+
HttpRequestOptions requestOptions = CreateHttpRequestOptions("GET", url, headers, token);
267+
return SendRequest(requestOptions, middlewares, binaryMode);
273268
}
274269

275270
/// <summary>
@@ -297,7 +292,7 @@ public HttpResult Post(string url, StringDictionary headers, Auth auth, bool bin
297292
{
298293
headers["Content-Type"] = ContentType.WWW_FORM_URLENC;
299294
}
300-
295+
301296
addAuthHeaders(ref headers, auth);
302297

303298
string token = auth.CreateManageTokenV2("POST", url, headers);
@@ -314,8 +309,8 @@ public HttpResult Post(string url, StringDictionary headers, Auth auth, bool bin
314309
/// <returns>HTTP-POST 的响应结果</returns>
315310
public HttpResult Post(string url, StringDictionary headers, string token, bool binaryMode = false)
316311
{
317-
HttpWebRequest wReq = CreateHttpWebRequest("POST", url, headers, token);
318-
return SendRequest(wReq, binaryMode);
312+
HttpRequestOptions reqOpts = CreateHttpRequestOptions("POST", url, headers, token);
313+
return SendRequest(reqOpts, binaryMode);
319314
}
320315

321316
/// <summary>
@@ -348,20 +343,16 @@ public HttpResult PostData(string url, byte[] data, string token, bool binaryMod
348343
/// <returns>HTTP-POST的响应结果</returns>
349344
public HttpResult PostData(string url, byte[] data, string mimeType, string token, bool binaryMode = false)
350345
{
351-
HttpWebRequest wReq = CreateHttpWebRequest("POST", url, null, token);
346+
HttpRequestOptions reqOpts = CreateHttpRequestOptions("POST", url, null, token);
352347

353-
wReq.ContentType = mimeType;
348+
reqOpts.Headers.Add("Content-Type", mimeType);
354349
if (data != null)
355350
{
356-
wReq.AllowWriteStreamBuffering = true;
357-
using (Stream sReq = wReq.GetRequestStream())
358-
{
359-
sReq.Write(data, 0, data.Length);
360-
sReq.Flush();
361-
}
351+
reqOpts.AllowWriteStreamBuffering = true;
352+
reqOpts.RequestData = data;
362353
}
363-
364-
return SendRequest(wReq, binaryMode);
354+
355+
return SendRequest(reqOpts, binaryMode);
365356
}
366357

367358
/// <summary>
@@ -416,7 +407,8 @@ public HttpResult PostForm(string url, Dictionary<string, string> kvData, string
416407
data = string.Join("&",
417408
kvData.Select(kvp => Uri.EscapeDataString(kvp.Key) + "=" + Uri.EscapeDataString(kvp.Value)));
418409
}
419-
return PostForm(url, data, token, binaryMode); }
410+
return PostForm(url, data, token, binaryMode);
411+
}
420412

421413
/// <summary>
422414
/// HTTP-POST方法(包含表单数据)
@@ -480,22 +472,18 @@ public HttpResult PostForm(string url, byte[] data, string token, bool binaryMod
480472
/// <returns>HTTP-POST的响应结果</returns>
481473
public HttpResult PostForm(string url, StringDictionary headers, byte[] data, string token, bool binaryMode = false)
482474
{
483-
484-
485-
HttpWebRequest wReq = CreateHttpWebRequest("POST", url, headers, token);
486-
487-
wReq.ContentType = ContentType.WWW_FORM_URLENC;
475+
HttpRequestOptions reqOpts = CreateHttpRequestOptions("POST", url, headers, token);
476+
if (!reqOpts.Headers.ContainsKey("Content-Type"))
477+
{
478+
reqOpts.Headers.Add("Content-Type", ContentType.WWW_FORM_URLENC);
479+
}
488480
if (data != null)
489481
{
490-
wReq.AllowWriteStreamBuffering = true;
491-
using (Stream sReq = wReq.GetRequestStream())
492-
{
493-
sReq.Write(data, 0, data.Length);
494-
sReq.Flush();
495-
}
482+
reqOpts.AllowWriteStreamBuffering = true;
483+
reqOpts.RequestData = data;
496484
}
497-
498-
return SendRequest(wReq, binaryMode);
485+
486+
return SendRequest(reqOpts, binaryMode);
499487
}
500488

501489
/// <summary>
@@ -509,21 +497,20 @@ public HttpResult PostForm(string url, StringDictionary headers, byte[] data, st
509497
/// <returns>HTTP-POST的响应结果</returns>
510498
public HttpResult PostMultipart(string url, byte[] data, string boundary, string token, bool binaryMode = false)
511499
{
512-
HttpWebRequest wReq = CreateHttpWebRequest("POST", url, null, token);
500+
HttpRequestOptions reqOpts = CreateHttpRequestOptions("POST", url, null, token);
513501

514-
wReq.ContentType = string.Format("{0}; boundary={1}", ContentType.MULTIPART_FORM_DATA, boundary);
502+
reqOpts.Headers.Add(
503+
"Content-Type",
504+
string.Format("{0}; boundary={1}", ContentType.MULTIPART_FORM_DATA, boundary)
505+
);
515506

516507
if (data != null)
517508
{
518-
wReq.AllowWriteStreamBuffering = true;
519-
using (Stream sReq = wReq.GetRequestStream())
520-
{
521-
sReq.Write(data, 0, data.Length);
522-
sReq.Flush();
523-
}
509+
reqOpts.AllowWriteStreamBuffering = true;
510+
reqOpts.RequestData = data;
524511
}
525512

526-
return SendRequest(wReq, binaryMode);
513+
return SendRequest(reqOpts, binaryMode);
527514
}
528515

529516
/// <summary>
@@ -543,20 +530,16 @@ public HttpResult PutDataWithHeaders(string url, byte[] data, Dictionary<string,
543530
headersDict.Add(kvp.Key, kvp.Value);
544531
}
545532

546-
HttpWebRequest wReq = CreateHttpWebRequest("PUT", url, headersDict);
533+
HttpRequestOptions wReq = CreateHttpRequestOptions("PUT", url, headersDict);
547534

548-
wReq.ContentType = ContentType.APPLICATION_OCTET_STREAM;
535+
wReq.Headers.Add("Content-Type", ContentType.APPLICATION_OCTET_STREAM);
549536

550537
if (data != null)
551538
{
552539
wReq.AllowWriteStreamBuffering = true;
553-
using (Stream sReq = wReq.GetRequestStream())
554-
{
555-
sReq.Write(data, 0, data.Length);
556-
sReq.Flush();
557-
}
540+
wReq.RequestData = data;
558541
}
559-
542+
560543
return SendRequest(wReq, binaryMode);
561544
}
562545

@@ -591,7 +574,7 @@ private void getHeaders(ref HttpResult hr, HttpWebResponse resp)
591574
hr.RefInfo.Add("ContentType", resp.ContentType);
592575
}
593576

594-
hr.RefInfo.Add("ContentLength", resp.ContentLength.ToString());
577+
hr.RefInfo.Add("ContentLength", resp.ContentLength.ToString());
595578

596579
var headers = resp.Headers;
597580
if (headers != null && headers.Count > 0)

0 commit comments

Comments
 (0)