Skip to content

Commit 3a5081e

Browse files
committed
add Qiniu auth
1 parent 384a77a commit 3a5081e

File tree

10 files changed

+701
-40
lines changed

10 files changed

+701
-40
lines changed

src/Qiniu/Http/HttpManager.cs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Specialized;
34
using System.Text;
45
using System.IO;
56
using System.Net;
@@ -60,13 +61,26 @@ public static string CreateFormDataBoundary()
6061
}
6162

6263
/// <summary>
63-
/// HTTP-GET方法
64+
/// HTTP-GET 方法(不包含 headers)
6465
/// </summary>
65-
/// <param name="url">请求目标URL</param>
66-
/// <param name="token">令牌(凭证)[可选->设置为null]</param>
66+
/// <param name="url">请求目标 URL</param>
67+
/// <param name="token">令牌(凭证)[可选 -> 设置为 null]</param>
6768
/// <param name="binaryMode">是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)</param>
6869
/// <returns>HTTP-GET的响应结果</returns>
6970
public HttpResult Get(string url, string token, bool binaryMode = false)
71+
{
72+
return Get(url, null, token, binaryMode);
73+
}
74+
75+
/// <summary>
76+
/// HTTP-GET 方法
77+
/// </summary>
78+
/// <param name="url">请求目标URL</param>
79+
/// <param name="headers">请求 Headers[可选 -> 设置为 null]</param>
80+
/// <param name="token">令牌(凭证)[可选 -> 设置为 null]</param>
81+
/// <param name="binaryMode">是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)</param>
82+
/// <returns>HTTP-GET的响应结果</returns>
83+
public HttpResult Get(string url, StringDictionary headers, string token, bool binaryMode = false)
7084
{
7185
HttpResult result = new HttpResult();
7286

@@ -76,6 +90,18 @@ public HttpResult Get(string url, string token, bool binaryMode = false)
7690
{
7791
wReq = WebRequest.Create(url) as HttpWebRequest;
7892
wReq.Method = "GET";
93+
if (headers != null)
94+
{
95+
foreach (string fieldName in headers.Keys)
96+
{
97+
wReq.Headers.Add(fieldName, headers[fieldName]);
98+
}
99+
100+
if (headers.ContainsKey("Content-Type"))
101+
{
102+
wReq.ContentType = headers["Content-Type"];
103+
}
104+
}
79105
if (!string.IsNullOrEmpty(token))
80106
{
81107
wReq.Headers.Add("Authorization", token);
@@ -165,13 +191,25 @@ public HttpResult Get(string url, string token, bool binaryMode = false)
165191
}
166192

167193
/// <summary>
168-
/// HTTP-POST方法(不包含body数据)
194+
/// HTTP-POST 方法(不包含 headers,不包含 body 数据)
169195
/// </summary>
170-
/// <param name="url">请求目标URL</param>
171-
/// <param name="token">令牌(凭证)[可选]</param>
196+
/// <param name="url">请求目标 URL</param>
197+
/// <param name="token">令牌(凭证)[可选 -> 设置为 null]</param>
172198
/// <param name="binaryMode">是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)</param>
173-
/// <returns>HTTP-POST的响应结果</returns>
199+
/// <returns>HTTP-POST 的响应结果</returns>
174200
public HttpResult Post(string url, string token, bool binaryMode = false)
201+
{
202+
return Post(url, null, token, binaryMode);
203+
}
204+
205+
/// <summary>
206+
/// HTTP-POST 方法(不包含 body 数据)
207+
/// </summary>
208+
/// <param name="url">请求目标 URL</param>
209+
/// <param name="token">令牌(凭证)[可选 -> 设置为 null]</param>
210+
/// <param name="binaryMode">是否以二进制模式读取响应内容(默认:否,即表示以文本方式读取)</param>
211+
/// <returns>HTTP-POST 的响应结果</returns>
212+
public HttpResult Post(string url, StringDictionary headers, string token, bool binaryMode = false)
175213
{
176214
HttpResult result = new HttpResult();
177215

@@ -181,6 +219,18 @@ public HttpResult Post(string url, string token, bool binaryMode = false)
181219
{
182220
wReq = WebRequest.Create(url) as HttpWebRequest;
183221
wReq.Method = "POST";
222+
if (headers != null)
223+
{
224+
foreach (string fieldName in headers.Keys)
225+
{
226+
wReq.Headers.Add(fieldName, headers[fieldName]);
227+
}
228+
229+
if (headers.ContainsKey("Content-Type"))
230+
{
231+
wReq.ContentType = headers["Content-Type"];
232+
}
233+
}
184234
if (!string.IsNullOrEmpty(token))
185235
{
186236
wReq.Headers.Add("Authorization", token);

src/Qiniu/Storage/BucketManager.cs

Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using Qiniu.Http;
44
using Qiniu.Util;
55
using System.Collections.Generic;
6+
using System.Collections.Specialized;
7+
68
namespace Qiniu.Storage
79
{
810
/// <summary>
@@ -43,9 +45,13 @@ public StatResult Stat(string bucket, string key)
4345
{
4446
string statUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, bucket),
4547
StatOp(bucket, key));
46-
string token = auth.CreateManageToken(statUrl);
48+
StringDictionary headers = new StringDictionary
49+
{
50+
{"Content-Type", ContentType.WWW_FORM_URLENC}
51+
};
52+
string token = auth.CreateManageTokenV2("GET", statUrl, headers);
4753

48-
HttpResult hr = httpManager.Get(statUrl, token);
54+
HttpResult hr = httpManager.Get(statUrl, headers, token);
4955
result.Shadow(hr);
5056
}
5157
catch (QiniuException ex)
@@ -88,9 +94,13 @@ public BucketsResult Buckets(bool shared)
8894
sharedStr = "true";
8995
}
9096
string bucketsUrl = string.Format("{0}/buckets?shared={1}", rsHost, sharedStr);
91-
string token = auth.CreateManageToken(bucketsUrl);
97+
StringDictionary headers = new StringDictionary
98+
{
99+
{"Content-Type", ContentType.WWW_FORM_URLENC}
100+
};
101+
string token = auth.CreateManageTokenV2("GET", bucketsUrl, headers);
92102

93-
HttpResult hr = httpManager.Get(bucketsUrl, token);
103+
HttpResult hr = httpManager.Get(bucketsUrl, headers, token);
94104
result.Shadow(hr);
95105
}
96106
catch (QiniuException ex)
@@ -129,9 +139,13 @@ public HttpResult Delete(string bucket, string key)
129139
{
130140
string deleteUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, bucket),
131141
DeleteOp(bucket, key));
132-
string token = auth.CreateManageToken(deleteUrl);
142+
StringDictionary headers = new StringDictionary
143+
{
144+
{"Content-Type", ContentType.WWW_FORM_URLENC}
145+
};
146+
string token = auth.CreateManageTokenV2("POST", deleteUrl, headers);
133147

134-
result = httpManager.Post(deleteUrl, token);
148+
result = httpManager.Post(deleteUrl, headers, token);
135149
}
136150
catch (QiniuException ex)
137151
{
@@ -184,9 +198,13 @@ public HttpResult Copy(string srcBucket, string srcKey, string dstBucket, string
184198
{
185199
string copyUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, srcBucket),
186200
CopyOp(srcBucket, srcKey, dstBucket, dstKey, force));
187-
string token = auth.CreateManageToken(copyUrl);
201+
StringDictionary headers = new StringDictionary
202+
{
203+
{"Content-Type", ContentType.WWW_FORM_URLENC}
204+
};
205+
string token = auth.CreateManageTokenV2("POST", copyUrl, headers);
188206

189-
result = httpManager.Post(copyUrl, token);
207+
result = httpManager.Post(copyUrl, headers, token);
190208
}
191209
catch (QiniuException ex)
192210
{
@@ -239,9 +257,13 @@ public HttpResult Move(string srcBucket, string srcKey, string dstBucket, string
239257
{
240258
string moveUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, srcBucket),
241259
MoveOp(srcBucket, srcKey, dstBucket, dstKey, force));
242-
string token = auth.CreateManageToken(moveUrl);
260+
StringDictionary headers = new StringDictionary
261+
{
262+
{"Content-Type", ContentType.WWW_FORM_URLENC}
263+
};
264+
string token = auth.CreateManageTokenV2("POST", moveUrl, headers);
243265

244-
result = httpManager.Post(moveUrl, token);
266+
result = httpManager.Post(moveUrl, headers, token);
245267
}
246268
catch (QiniuException ex)
247269
{
@@ -279,8 +301,12 @@ public HttpResult ChangeMime(string bucket, string key, string mimeType)
279301
{
280302
string chgmUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, bucket),
281303
ChangeMimeOp(bucket, key, mimeType));
282-
string token = auth.CreateManageToken(chgmUrl);
283-
result = httpManager.Post(chgmUrl, token);
304+
StringDictionary headers = new StringDictionary
305+
{
306+
{"Content-Type", ContentType.WWW_FORM_URLENC}
307+
};
308+
string token = auth.CreateManageTokenV2("POST", chgmUrl, headers);
309+
result = httpManager.Post(chgmUrl, headers, token);
284310
}
285311
catch (QiniuException ex)
286312
{
@@ -318,8 +344,12 @@ public HttpResult ChangeType(string bucket, string key, int fileType)
318344
{
319345
string chtypeUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, bucket),
320346
ChangeTypeOp(bucket, key, fileType));
321-
string token = auth.CreateManageToken(chtypeUrl);
322-
result = httpManager.Post(chtypeUrl, token);
347+
StringDictionary headers = new StringDictionary
348+
{
349+
{"Content-Type", ContentType.WWW_FORM_URLENC}
350+
};
351+
string token = auth.CreateManageTokenV2("POST", chtypeUrl, headers);
352+
result = httpManager.Post(chtypeUrl, headers, token);
323353
}
324354
catch (QiniuException ex)
325355
{
@@ -351,8 +381,12 @@ public HttpResult RestoreAr(string bucket, string key, int freezeAfterDays)
351381
string restoreUrl = string.Format("{0}{1}",
352382
this.config.RsHost(this.mac.AccessKey, bucket),
353383
RestoreArOp(bucket, key, freezeAfterDays));
354-
string token = auth.CreateManageToken(restoreUrl);
355-
result = httpManager.Post(restoreUrl, token);
384+
StringDictionary headers = new StringDictionary
385+
{
386+
{"Content-Type", ContentType.WWW_FORM_URLENC}
387+
};
388+
string token = auth.CreateManageTokenV2("POST", restoreUrl, headers);
389+
result = httpManager.Post(restoreUrl, headers, token);
356390
}
357391
catch (QiniuException ex)
358392
{
@@ -389,8 +423,15 @@ private BatchResult Batch(string batchOps)
389423
string scheme = this.config.UseHttps ? "https://" : "http://";
390424
string rsHost = string.Format("{0}{1}", scheme, Config.DefaultRsHost);
391425
string batchUrl = rsHost + "/batch";
426+
string token = auth.CreateManageTokenV2(
427+
"POST",
428+
batchUrl,
429+
new StringDictionary
430+
{
431+
{"Content-Type", ContentType.WWW_FORM_URLENC}
432+
},
433+
batchOps);
392434
byte[] data = Encoding.UTF8.GetBytes(batchOps);
393-
string token = auth.CreateManageToken(batchUrl, data);
394435

395436
HttpResult hr = httpManager.PostForm(batchUrl, data, token);
396437
result.Shadow(hr);
@@ -448,9 +489,13 @@ public FetchResult Fetch(string resUrl, string bucket, string key)
448489
{
449490
string fetchUrl = string.Format("{0}{1}", this.config.IovipHost(this.mac.AccessKey, bucket),
450491
FetchOp(resUrl, bucket, key));
451-
string token = auth.CreateManageToken(fetchUrl);
492+
StringDictionary headers = new StringDictionary
493+
{
494+
{"Content-Type", ContentType.WWW_FORM_URLENC}
495+
};
496+
string token = auth.CreateManageTokenV2("POST", fetchUrl, headers);
452497

453-
HttpResult httpResult = httpManager.Post(fetchUrl, token);
498+
HttpResult httpResult = httpManager.Post(fetchUrl, headers, token);
454499
result.Shadow(httpResult);
455500
}
456501
catch (QiniuException ex)
@@ -487,9 +532,13 @@ public HttpResult Prefetch(string bucket, string key)
487532
try
488533
{
489534
string prefetchUrl = this.config.IovipHost(this.mac.AccessKey, bucket) + PrefetchOp(bucket, key);
490-
string token = auth.CreateManageToken(prefetchUrl);
535+
StringDictionary headers = new StringDictionary
536+
{
537+
{"Content-Type", ContentType.WWW_FORM_URLENC}
538+
};
539+
string token = auth.CreateManageTokenV2("POST", prefetchUrl, headers);
491540

492-
result = httpManager.Post(prefetchUrl, token);
541+
result = httpManager.Post(prefetchUrl, headers, token);
493542
}
494543
catch (QiniuException ex)
495544
{
@@ -527,8 +576,15 @@ public DomainsResult Domains(string bucket)
527576
string rsHost = string.Format("{0}{1}", scheme, Config.DefaultApiHost);
528577
string domainsUrl = string.Format("{0}{1}", rsHost, "/v6/domain/list");
529578
string body = string.Format("tbl={0}", bucket);
579+
string token = auth.CreateManageTokenV2(
580+
"POST",
581+
domainsUrl,
582+
new StringDictionary
583+
{
584+
{"Content-Type", ContentType.WWW_FORM_URLENC}
585+
},
586+
body);
530587
byte[] data = Encoding.UTF8.GetBytes(body);
531-
string token = auth.CreateManageToken(domainsUrl, data);
532588

533589
HttpResult hr = httpManager.PostForm(domainsUrl, data, token);
534590
result.Shadow(hr);
@@ -615,9 +671,13 @@ public ListResult ListFiles(string bucket, string prefix, string marker, int lim
615671
}
616672

617673
string listUrl = string.Format("{0}{1}", this.config.RsfHost(this.mac.AccessKey, bucket), sb.ToString());
618-
string token = auth.CreateManageToken(listUrl);
674+
StringDictionary headers = new StringDictionary
675+
{
676+
{"Content-Type", ContentType.WWW_FORM_URLENC}
677+
};
678+
string token = auth.CreateManageTokenV2("POST", listUrl, headers);
619679

620-
HttpResult hr = httpManager.Post(listUrl, token);
680+
HttpResult hr = httpManager.Post(listUrl, headers, token);
621681
result.Shadow(hr);
622682
}
623683
catch (QiniuException ex)
@@ -656,8 +716,12 @@ public HttpResult DeleteAfterDays(string bucket, string key, int deleteAfterDays
656716
{
657717
string updateUrl = string.Format("{0}{1}", this.config.RsHost(this.mac.AccessKey, bucket),
658718
DeleteAfterDaysOp(bucket, key, deleteAfterDays));
659-
string token = auth.CreateManageToken(updateUrl);
660-
result = httpManager.Post(updateUrl, token);
719+
StringDictionary headers = new StringDictionary
720+
{
721+
{"Content-Type", ContentType.WWW_FORM_URLENC}
722+
};
723+
string token = auth.CreateManageTokenV2("POST", updateUrl, headers);
724+
result = httpManager.Post(updateUrl, headers, token);
661725
}
662726
catch (QiniuException ex)
663727
{

src/Qiniu/Storage/ResumeHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class ResumeHelper
1919
/// <returns>用于记录断点信息的文件名</returns>
2020
public static string GetDefaultRecordKey(string localFile, string key)
2121
{
22-
string tempDir = System.Environment.GetEnvironmentVariable("TEMP");
22+
string tempDir = System.IO.Path.GetTempPath();
2323
System.IO.FileInfo fileInfo = new System.IO.FileInfo(localFile);
2424
string uniqueKey = string.Format("{0}:{1}:{2}", localFile, key, fileInfo.LastWriteTime.ToFileTime());
2525
return Path.Combine(tempDir, "QiniuResume_" + Hashing.CalcMD5X(uniqueKey));

src/Qiniu/Util/Auth.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace Qiniu.Util
1+
using System.Collections.Specialized;
2+
3+
namespace Qiniu.Util
24
{
35
/// <summary>
46
/// Authentication/Authorization
@@ -107,6 +109,46 @@ public static string CreateManageToken(Mac mac, string url)
107109
return CreateManageToken(mac, url, null);
108110
}
109111

112+
/// <summary>
113+
/// 生成 Qiniu 管理凭证
114+
/// </summary>
115+
/// <param name="method">请求的方法</param>
116+
/// <param name="url">请求的 URL</param>
117+
/// <param name="headers">请求的 Headers</param>
118+
/// <param name="body">请求体(可选),要求 UTF-8 编码</param>
119+
/// <returns>生成的管理凭证</returns>
120+
public string CreateManageTokenV2(string method, string url, StringDictionary headers, string body = "")
121+
{
122+
return string.Format("Qiniu {0}", signature.SignRequestV2(method, url, headers, body));
123+
}
124+
125+
/// <summary>
126+
/// 生成 Qiniu 管理凭证-不包含 header
127+
/// </summary>
128+
/// <param name="method">请求的方法</param>
129+
/// <param name="url">请求的 URL</param>
130+
/// <param name="body">请求体(可选),要求 UTF-8 编码</param>
131+
/// <returns>生成的管理凭证</returns>
132+
public string CreateManageTokenV2(string method, string url, string body = "")
133+
{
134+
return CreateManageTokenV2(method, url, null, body);
135+
}
136+
137+
/// <summary>
138+
/// 生成 Qiniu 管理凭证-使用外部 mac
139+
/// </summary>
140+
/// <param name="mac">外部传入的 mac</param>
141+
/// <param name="method">请求的方法</param>
142+
/// <param name="url">请求的 URL</param>
143+
/// <param name="headers">请求的 Headers</param>
144+
/// <param name="body">请求体(可选),要求 UTF-8 编码</param>
145+
/// <returns>生成的管理凭证</returns>
146+
public static string CreateManageTokenV2(Mac mac, string method, string url, StringDictionary headers, string body = "")
147+
{
148+
Signature sign = new Signature(mac);
149+
return string.Format("Qiniu {0}", sign.SignRequestV2(method, url, headers, body));
150+
}
151+
110152
/// <summary>
111153
/// 生成上传凭证
112154
/// </summary>

0 commit comments

Comments
 (0)