/// <summary> /// 上传最后一块分块文件。同时,此函数可以用来一次上传整个文件 /// </summary> /// <returns></returns> private async Task <string> upload_LastBlock(string uuid, PartViewStream pvs, string uploadToken, string host, long iblock) { var flength = pvs.Length; //pvs.SetRange(0, pvs.Length - 1); var uploadUrl = host + $"/mkblk/{flength}/{iblock}"; HttpWebRequest req = WebRequest.CreateHttp(uploadUrl); req.Method = "POST"; req.Headers.Add("Qingzhen-Token", recentToken); req.Headers.Add("Authorization", uploadToken); req.ContentLength = pvs.Length; req.ContentType = "application/octet-stream"; req.Headers.Add("UploadBatch", uuid); var reqStream = await req.GetRequestStreamAsync(); await pvs.CopyToAsync(reqStream); reqStream.Close(); var resp = (HttpWebResponse)await req.GetResponseAsync(); var respStream = resp.GetResponseStream(); var sr = new StreamReader(respStream); var retjson = sr.ReadToEnd(); sr.Close(); resp.Close(); req.Abort(); Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); string ctx = json["ctx"].ToString(); return(ctx); }
async Task <string> postStream(string url, Dictionary <string, string> heads, Stream stm, long stmLen) { HttpWebRequest req = WebRequest.CreateHttp(url); req.Method = "POST"; foreach (var h in heads) { req.Headers.Add(h.Key, h.Value); } req.ContentLength = stmLen; req.ContentType = "application/octet-stream"; var reqStream = await req.GetRequestStreamAsync(); // CopyTo(reqSteam) 使用在这个请求里可能发生异常,故用自己写的BlockCopyTo await PartViewStream.StreamBlockCopyAsync(stm, reqStream); reqStream.Close(); HttpWebResponse resp = (HttpWebResponse)await req.GetResponseAsync(); var respStream = resp.GetResponseStream(); var sr = new StreamReader(respStream); var retjson = await sr.ReadToEndAsync(); sr.Close(); resp.Close(); req.Abort(); return(retjson); }
async Task <string> upload_firstChunk(string uuid, PartViewStream pvs, long iblock, string uploadToken, string host, string keyname) { var uploadUrl = host + $"/mkblk/{block_size}/{iblock}"; HttpWebRequest req = WebRequest.CreateHttp(uploadUrl); req.Method = "POST"; req.Headers.Add("Authorization", uploadToken); req.Headers.Add("UploadBatch", uuid); req.ContentLength = pvs.Length; req.ContentType = "application/octet-stream"; var reqStream = await req.GetRequestStreamAsync(); pvs.BlockCopyTo(reqStream); reqStream.Close(); var resp = (HttpWebResponse)await req.GetResponseAsync(); var respStream = resp.GetResponseStream(); var sr = new StreamReader(respStream); var retjson = sr.ReadToEnd(); sr.Close(); resp.Close(); req.Abort(); Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); if (!json.ContainsKey("ctx")) { return(null); } return(json["ctx"].ToString()); }
public async Task upload_streamAsync(string host, System.IO.Stream stream, string folder_id, string uploadToken, string keyname) { //前面的块分片传输,最后的块,整块一片传输,方便写程序 long flength = stream.Length; if (flength == 0) { return; } long nblock = flength / block_size; var viewStm = new PartViewStream(stream); List <string> ctxs = new List <string>(); // uuid 赋值给 http 头 uploadBatch,整个文件uuid必须相同 //(网上的文档说每一个小片chunk不相同是错误的) string uuid = System.Guid.NewGuid().ToString(); for (int iblock = 0; iblock < nblock; iblock++) { //先上传第一片 long from = iblock * block_size; viewStm.SetRange(from, from + chunk_size); string ctx = await upload_firstChunk(uuid, viewStm, iblock, uploadToken, host, keyname); for (int ichunk = 1; ichunk < block_size / chunk_size; ichunk++) { from += chunk_size; viewStm.SetRange(from, from + chunk_size); ctx = await upload_restChunk(uuid, viewStm, ctx, uploadToken, host, ichunk, keyname); } ctxs.Add(ctx); } //上传剩余的不完整块 if (flength % block_size != 0) { long from = nblock * block_size; long restLength = flength - from; // 上传最后块的第一片,这里只分一片,所以一次上传完毕 viewStm.SetRange(from, flength); string ctx = await upload_LastBlock(uuid, viewStm, uploadToken, host, nblock); ctxs.Add(ctx); } //所有的块上传完毕,开始合并所有的块为文件 await upload_mkfile(uuid, stream.Length, ctxs, host, uploadToken); //updateToken(resp); }
private async Task <string> upload_restChunk(string uuid, PartViewStream pvs, string ctx, string uploadToken, string host, int ichunk, string keyname) { ///POST /bput/<ctx>/<nextChunkOffset> ///Host: <UploadDomain> ///Authorization:<UploadToken> ///Content-Length:<ChunkSize> ///Content-Type:application/octet-stream ///UploadBatch:<uuid> ///Key:<key> /// ///<ChunkBinary> var uploadUrl = host + $"/bput/{ctx}/{ichunk * chunk_size}"; HttpWebRequest req = WebRequest.CreateHttp(uploadUrl); req.Method = "POST"; //req.Headers.Add("Qingzhen-Token", recentToken); req.ContentLength = pvs.Length; req.Headers.Add("Authorization", uploadToken); req.ContentType = "application/octet-stream"; req.Headers.Add("UploadBatch", uuid); //req.Headers.Add("Key", UrlSafeBase64.encode(keyname)); var reqStream = await req.GetRequestStreamAsync(); //await pvs.CopyToAsync(reqStream); // CopyTo(reqSteam) 使用在这个请求里可能发生异常,故用自己写的BlockCopyTo pvs.BlockCopyTo(reqStream); reqStream.Close(); HttpWebResponse resp = (HttpWebResponse)await req.GetResponseAsync(); var respStream = resp.GetResponseStream(); var sr = new StreamReader(respStream); var retjson = await sr.ReadToEndAsync(); sr.Close(); resp.Close(); req.Abort(); Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); if (!json.ContainsKey("ctx")) { return(null); } return(json["ctx"].ToString()); }
//class MyHttpClientHandlerProxy : HttpClientHandler //{ // string _token; // public MyHttpClientHandlerProxy(string token) { _token = token; } // protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) // { // request.Headers.Add("Authorization", _token); // var response = await base.SendAsync(request, cancellationToken); // return response; // HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url); // addHeads(req, head); // var ms = new MemoryStream(); // pvs.CopyTo(ms); // req.Content = new StreamContent(pvs); // var result = await _hc.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); // var retjson = result.Content.ReadAsStringAsync().Result; // Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); // string ctx = json["ctx"].ToString(); // return ctx; // } //} public async Task upload_stream_hc(string host, System.IO.Stream stream, string name, string folder_id, string uploadToken) { long flength = stream.Length; if (flength == 0) { return; } void addHeads(HttpRequestMessage req, Dictionary <string, string> heads) { req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("token", uploadToken); foreach (var h in heads) { req.Headers.Add(h.Key, h.Value); } } // uuid 赋值给 http 头 uploadBatch,整个文件uuid必须相同 //(网上的文档说每一个小片chunk不相同是错误的) string uuid = System.Guid.NewGuid().ToString(); var head = new Dictionary <string, string>() { //{ "Qingzhen-Token", recentToken }, //{ "Authorization", uploadToken }, { "UploadBatch", uuid } }; //_hc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("uploadToken); var pvs = new PartViewStream(stream); async Task <string> post(string url) { HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, url); addHeads(req, head); var ms = new MemoryStream(); pvs.CopyTo(ms); req.Content = new StreamContent(pvs); var result = await _hc.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); var retjson = result.Content.ReadAsStringAsync().Result; Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); string ctx = json["ctx"].ToString(); return(ctx); } long nblock = flength / block_size; List <string> ctxs = new List <string>(); //前面的块分片传输,最后的块,整块一片传输,方便写程序 for (int iblock = 0; iblock < nblock; iblock++) { //创建块并上传第一片 long from = iblock * block_size; pvs.SetRange(from, from + chunk_size); string url = $"{host}/mkblk/{pvs.Length}/{iblock}"; string ctx = await post(url); for (int ichunk = 1; ichunk < block_size / chunk_size; ichunk++) { from += chunk_size; pvs.SetRange(from, from + chunk_size); url = $"{host}/bput/{ctx}/{ichunk * chunk_size}"; ctx = await post(url); //ctx = await upload_restChunk(uuid, pvs, ctx, uploadToken, host, ichunk, keyname); } ctxs.Add(ctx); } //上传剩余的不完整块 if (flength % block_size != 0) { long from = nblock * block_size; long restLength = flength - from; // 上传最后块的第一片,这里只分一片,所以一次上传完毕 pvs.SetRange(from, flength); string url = $"{host}/mkblk/{pvs.Length}/{nblock}"; string ctx = await post(url); ctxs.Add(ctx); } //所有的块上传完毕,开始合并所有的块为文件 await upload_mkfile(uuid, stream.Length, ctxs, host, uploadToken); //updateToken(resp); ///var oneUrl = $"{host}/mkblk/{stream.Length}/0"; ///HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, oneUrl); ///addHeads(req, head); ///req.Content = new StreamContent(pvs); ///var result = await _hc.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); /// ///var retjson = result.Content.ReadAsStringAsync().Result; ///Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); ///bool ok = json.ContainsKey("ctx"); ///return; }
public async Task upload_streamAsync2(string filehost, System.IO.Stream stream, string uploadToken, string keyname) { long flength = stream.Length; if (flength == 0) { return; } void addHeads(HttpWebRequest req, Dictionary <string, string> heads) { foreach (var h in heads) { req.Headers.Add(h.Key, h.Value); } } /// uuid 赋值给 http 头 uploadBatch,整个文件uuid必须相同 ///(网上的文档说每一个小片chunk不相同是错误的) string uuid = System.Guid.NewGuid().ToString(); var head = new Dictionary <string, string>() { // { "Qingzhen-Token", recentToken }, { "Authorization", uploadToken }, { "UploadBatch", uuid } }; var pvs = new PartViewStream(stream); async Task <string> post(string url) { var retjson = await postStream(url, head, pvs, pvs.Length); Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); return(json["ctx"].ToString()); } long nblock = flength / block_size; List <string> ctxs = new List <string>(); string url = null; //前面的块分片传输,最后的块,整块一片传输,方便写程序 for (int iblock = 0; iblock < nblock; iblock++) { //创建块并上传第一片 long from = iblock * block_size; pvs.SetRange(from, from + chunk_size); url = $"{filehost}/mkblk/{block_size}/{iblock}"; string ctx = await post(url); for (int ichunk = 1; ichunk < block_size / chunk_size; ichunk++) { from += chunk_size; pvs.SetRange(from, from + chunk_size); url = $"{filehost}/bput/{ctx}/{ichunk * chunk_size}"; ctx = await post(url); //ctx = await upload_restChunk(uuid, pvs, ctx, uploadToken, host, ichunk, keyname); } ctxs.Add(ctx); } //上传剩余的不完整块 if (flength % block_size != 0) { long from = nblock * block_size; long restLength = flength - from; // 上传最后块的第一片,这里只分一片,所以一次上传完毕 pvs.SetRange(from, flength); url = $"{filehost}/mkblk/{pvs.Length}/{nblock}"; string ctx = await post(url); ctxs.Add(ctx); } //所有的块上传完毕,开始合并所有的块为文件 url = $"{filehost}/mkfile/{flength}"; var outStr = System.Linq.Enumerable.Aggregate(ctxs, (x0, x1) => x0 + "," + x1); var retjson = await postStr(url, head, outStr); Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(retjson); //json["response"] //await upload_mkfile(uuid, stream.Length, ctxs, host, uploadToken); //updateToken(resp); }