Skip to content

Commit 1f1e4ea

Browse files
committed
fix resume upload v2 can't upload without key
1 parent 5ce8a57 commit 1f1e4ea

File tree

4 files changed

+134
-12
lines changed

4 files changed

+134
-12
lines changed

src/Qiniu/Storage/ResumableUploader.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ public HttpResult UploadFile(string localFile, string key, string token, PutExtr
7979
public HttpResult UploadStream(Stream stream, string key, string upToken, PutExtra putExtra)
8080
{
8181
HttpResult result = new HttpResult();
82-
string encodedObjectName = "";
83-
if (putExtra != null && putExtra.Version == "v2")
82+
string encodedObjectNameForV2 = "~";
83+
if (putExtra != null && putExtra.Version == "v2" && key != null)
8484
{
85-
encodedObjectName = Base64.GetEncodedObjectName(key);
85+
encodedObjectNameForV2 = Base64.UrlSafeBase64Encode(key);
8686
}
8787

8888
//check put extra
@@ -144,7 +144,7 @@ public HttpResult UploadStream(Stream stream, string key, string upToken, PutExt
144144
}
145145
else if (putExtra.Version == "v2")
146146
{
147-
HttpResult res = initReq(encodedObjectName, upToken);
147+
HttpResult res = initReq(encodedObjectNameForV2, upToken);
148148
Dictionary<string, string> responseBody = JsonConvert.DeserializeObject<Dictionary<string, string>>(res.Text);
149149
if (res.Code != 200)
150150
{
@@ -265,7 +265,7 @@ public HttpResult UploadStream(Stream stream, string key, string upToken, PutExt
265265
{
266266

267267
processMakeBlocks(blockDataDict, upToken, putExtra, resumeInfo, blockMakeResults, uploadedBytesDict, fileSize,
268-
encodedObjectName);
268+
encodedObjectNameForV2);
269269
//check mkblk results
270270
foreach (int blkIndex in blockMakeResults.Keys)
271271
{
@@ -290,7 +290,7 @@ public HttpResult UploadStream(Stream stream, string key, string upToken, PutExt
290290
if (blockDataDict.Count > 0)
291291
{
292292
processMakeBlocks(blockDataDict, upToken, putExtra, resumeInfo, blockMakeResults, uploadedBytesDict, fileSize,
293-
encodedObjectName);
293+
encodedObjectNameForV2);
294294
//check mkblk results
295295
foreach (int blkIndex in blockMakeResults.Keys)
296296
{
@@ -319,7 +319,7 @@ public HttpResult UploadStream(Stream stream, string key, string upToken, PutExt
319319
}
320320
else if (putExtra.Version == "v2")
321321
{
322-
hr = completeParts(key, resumeInfo, key, upToken, putExtra, encodedObjectName);
322+
hr = completeParts(key, resumeInfo, key, upToken, putExtra, encodedObjectNameForV2);
323323
} else {
324324
throw new Exception("Invalid Version, only supports v1 / v2");
325325
}
@@ -701,7 +701,7 @@ private HttpResult MakeFile(string fileName, long size, string key, string upTok
701701
}
702702

703703
/// <summary>
704-
/// 初始化上传任务
704+
/// 初始化上传任务,仅用于分片上传 V2
705705
/// </summary>
706706
/// <param name="upToken">上传凭证</param>
707707
/// <param name="encodedObjectName">Base64编码后的资源名</param>
@@ -754,7 +754,7 @@ private HttpResult initReq(string encodedObjectName, string upToken)
754754
}
755755

756756
/// <summary>
757-
/// 根据已上传的所有分片数据创建文件
757+
/// 根据已上传的所有分片数据创建文件,仅用于分片上传 V2
758758
/// </summary>
759759
/// <param name="fileName">源文件名</param>
760760
/// <param name="resumeInfo">分片上传记录信息</param>

src/Qiniu/Storage/ResumeBlocker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ResumeBlocker
1616
public object ProgressLock { set; get; }
1717
public Dictionary<string, long> UploadedBytesDict { set; get; }
1818
public long FileSize { set; get; }
19-
public string encodedObjectName { set; get; }
19+
public string encodedObjectName { set; get; } // 仅用于分片上传 V2
2020

2121
public ResumeBlocker(ManualResetEvent doneEvent, byte[] blockBuffer, long blockIndex, string uploadToken,
2222
PutExtra putExtra, ResumeInfo resumeInfo, Dictionary<long, HttpResult> blockMakeResults,

src/Qiniu/Util/Base64.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ public static byte[] UrlsafeBase64Decode(string text)
5050
}
5151

5252
/// <summary>
53-
/// 获取EncodedObjectName
53+
/// 获取EncodedObjectName,建议仅用于分片上传 V2
5454
/// </summary>
5555
/// <param name="key">待加密的字符串</param>
5656
/// <returns>已加密的字符串</returns>
5757
public static string GetEncodedObjectName(string key)
5858
{
5959
string encodedObjectName = "~";
60-
if (!string.IsNullOrEmpty(key))
60+
if (key != null)
6161
{
6262
encodedObjectName = UrlSafeBase64Encode(key);
6363
}

src/QiniuTests/Storage/ResumableUploaderTests.cs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,63 @@ public void UploadFileV2Test()
144144
System.IO.File.Delete(filePath);
145145
}
146146

147+
[Test]
148+
public void UploadFileV2WithoutKeyTest()
149+
{
150+
Mac mac = new Mac(AccessKey, SecretKey);
151+
152+
string tempPath = Path.GetTempPath();
153+
int rnd = new Random().Next(1, 100000);
154+
string filePath = tempPath + "resumeFile" + rnd.ToString();
155+
char[] testBody = new char[6 * 1024 * 1024];
156+
FileStream stream = new FileStream(filePath, FileMode.Create);
157+
StreamWriter sw = new StreamWriter(stream, System.Text.Encoding.Default);
158+
sw.Write(testBody);
159+
sw.Close();
160+
stream.Close();
161+
162+
PutPolicy putPolicy = new PutPolicy();
163+
putPolicy.Scope = Bucket;
164+
putPolicy.SetExpires(3600);
165+
putPolicy.DeleteAfterDays = 1;
166+
string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
167+
168+
Config config = new Config();
169+
config.Zone = Zone.ZONE_CN_East;
170+
config.UseHttps = true;
171+
config.UseCdnDomains = true;
172+
config.ChunkSize = ChunkUnit.U512K;
173+
PutExtra extra = new PutExtra();
174+
extra.MimeType = "application/json";
175+
extra.Version = "v2";
176+
extra.PartSize = 4 * 1024 * 1024;
177+
ResumableUploader target = new ResumableUploader(config);
178+
HttpResult result = target.UploadFile(filePath, null, token, extra);
179+
Console.WriteLine("chunk upload result: " + result.ToString());
180+
Assert.AreEqual((int)HttpCode.OK, result.Code);
181+
Dictionary<string, string> responseBody = JsonConvert.DeserializeObject<Dictionary<string, string>>(result.Text);
182+
Assert.AreEqual(responseBody["hash"], responseBody["key"]);
183+
184+
string downloadUrl = string.Format("http://{0}/{1}", Domain, responseBody["key"]);
185+
HttpWebRequest wReq = WebRequest.Create(downloadUrl) as HttpWebRequest;
186+
wReq.Method = "GET";
187+
HttpWebResponse wResp = wReq.GetResponse() as HttpWebResponse;
188+
Assert.AreEqual((int)HttpCode.OK, (int)wResp.StatusCode);
189+
Assert.AreEqual("application/json", wResp.Headers[HttpResponseHeader.ContentType]);
190+
191+
using (var md5_1 = MD5.Create()) {
192+
using (var md5_2 = MD5.Create()) {
193+
using (var fileStream = File.OpenRead(filePath)) {
194+
byte[] checksum1 = md5_1.ComputeHash(fileStream);
195+
byte[] checksum2 = md5_2.ComputeHash(wResp.GetResponseStream());
196+
Assert.AreEqual(checksum1, checksum2);
197+
}
198+
}
199+
}
200+
201+
File.Delete(filePath);
202+
}
203+
147204
[Test]
148205
public void ResumeUploadFileTest()
149206
{
@@ -264,6 +321,71 @@ public void ResumeUploadFileV2Test()
264321
System.IO.File.Delete(filePath);
265322
}
266323
}
324+
325+
[Test]
326+
public void ResumeUploadFileV2WithoutKeyTest()
327+
{
328+
Mac mac = new Mac(AccessKey, SecretKey);
329+
Config config = new Config();
330+
config.UseHttps = true;
331+
config.Zone = Zone.ZONE_CN_East;
332+
config.UseCdnDomains = true;
333+
config.ChunkSize = ChunkUnit.U512K;
334+
ResumableUploader target = new ResumableUploader(config);
335+
PutExtra extra = new PutExtra();
336+
extra.PartSize = 4 * 1024 * 1024;
337+
extra.Version = "v2";
338+
339+
int[] sizes = new int[5]{extra.PartSize/2, extra.PartSize, extra.PartSize+1, extra.PartSize*2, 10*1024*1024};
340+
foreach(int i in sizes)
341+
{
342+
char[] testBody = new char[i];
343+
Random rand = new Random();
344+
345+
string tempPath = Path.GetTempPath();
346+
int rnd = new Random().Next(1, 100000);
347+
string filePath = tempPath + "resumeFile" + rnd.ToString();
348+
FileStream stream = new FileStream(filePath, FileMode.Create);
349+
StreamWriter sw = new StreamWriter(stream, System.Text.Encoding.Default);
350+
sw.Write(testBody);
351+
sw.Close();
352+
stream.Close();
353+
Stream fs = File.OpenRead(filePath);
354+
355+
PutPolicy putPolicy = new PutPolicy();
356+
putPolicy.Scope = Bucket;
357+
putPolicy.SetExpires(3600);
358+
putPolicy.DeleteAfterDays = 1;
359+
string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
360+
361+
//设置断点续传进度记录文件
362+
extra.ResumeRecordFile = ResumeHelper.GetDefaultRecordKey(filePath, rand.Next().ToString());
363+
Console.WriteLine("record file:" + extra.ResumeRecordFile);
364+
HttpResult result = target.UploadStream(fs, null, token, extra);
365+
Console.WriteLine("resume upload: " + result.ToString());
366+
Assert.AreEqual((int)HttpCode.OK, result.Code);
367+
Dictionary<string, string> responseBody = JsonConvert.DeserializeObject<Dictionary<string, string>>(result.Text);
368+
Assert.AreEqual(responseBody["hash"], responseBody["key"]);
369+
370+
string downloadUrl = string.Format("http://{0}/{1}", Domain, responseBody["key"]);
371+
HttpWebRequest wReq = WebRequest.Create(downloadUrl) as HttpWebRequest;
372+
wReq.Method = "GET";
373+
HttpWebResponse wResp = wReq.GetResponse() as HttpWebResponse;
374+
Assert.AreEqual((int)HttpCode.OK, (int)wResp.StatusCode);
375+
376+
using (var md5_1 = MD5.Create()) {
377+
using (var md5_2 = MD5.Create()) {
378+
using (var fileStream = File.OpenRead(filePath)) {
379+
byte[] checksum1 = md5_1.ComputeHash(fileStream);
380+
byte[] checksum2 = md5_2.ComputeHash(wResp.GetResponseStream());
381+
Assert.AreEqual(checksum1, checksum2);
382+
}
383+
}
384+
}
385+
386+
File.Delete(filePath);
387+
}
388+
}
267389

268390
}
269391
}

0 commit comments

Comments
 (0)