Beispiel #1
0
        /************************ Section 结构 ************************
         * Content-Length: 60408
         * Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
         *
         * --ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
         * Content-Disposition: form-data; name="fixedvolume"
         *
         * photo
         * --ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
         * Content-Disposition: form-data;name="72 x 72 (.png)"; filename="photo.jpg"
         * Content-Type: application/octet-stream
         * Content-Transfer-Encoding: binary
         *
         * ... binary data of the jpg ...
         * --ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
         * Content-Disposition: form-data;name="thumbnail"; filename="thumbnail.jpg"
         * Content-Type: application/octet-stream
         * Content-Transfer-Encoding: binary
         *
         * ... binary data of the jpg ...
         * --ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
         * Content-Disposition: form-data;name="00:00:06 (480 x 288)"; filename="ImageStabilization.wmv"
         * Content-Type: application/octet-stream
         * Content-Transfer-Encoding: binary
         *
         * ... binary data ...
         * --ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--
         ****************************/

        public async Task Handle()
        {
            // 读取boundary
            var boundary = _context.Request.GetMultipartBoundary();

            if (string.IsNullOrEmpty(boundary))
            {
                // 不支持的媒体类型
                _context.Response.StatusCode = 415;
                Log.Information("无Boundary,上传失败");
                return;
            }

            SortedSetCache cache = null;

            _db = new MySqlAccess(false);

            // 记录已成功接收的文件,以备后续异常时删除这些文件
            List <FileDesc> sucFiles = new List <FileDesc>();

            try
            {
                var reader  = new MultipartReader(boundary, _context.Request.Body);
                var section = await reader.ReadNextSectionAsync(_context.RequestAborted);

                var fmSection = section.AsFormDataSection();
                if (fmSection != null && fmSection.Name == "fixedvolume")
                {
                    // 选择固定卷
                    _volume = (await fmSection.GetValueAsync()).ToLower();
                    if (!Cfg.FixedVolumes.Contains(_volume))
                    {
                        // 无此固定卷,状态码:未满足前提条件
                        _context.Response.StatusCode = 412;
                        Log.Information("不存在固定卷 {0},上传失败!", _volume);
                        return;
                    }
                    section = await reader.ReadNextSectionAsync(_context.RequestAborted);
                }
                else
                {
                    // 选择正在使用数最低的卷
                    cache   = new SortedSetCache(Cfg.VolumeKey);
                    _volume = await cache.GetMin();

                    // 该卷使用数加1
                    await cache.Increment(_volume);
                }

                // Section顺序:固定路径(可无),文件,文件,缩略图,文件
                // 缩略图由客户端生成,因提取视频帧耗资源,属于前面的文件
                FileDesc lastFile = null;
                while (section != null)
                {
                    var fileSection = section.AsFileSection();
                    if (fileSection != null)
                    {
                        if (fileSection.Name == "thumbnail")
                        {
                            if (lastFile != null)
                            {
                                // 将缩略图复制到同路径
                                // 命名规则:原文件名添加后缀"-t.jpg",如 143203944767549440.wmv-t.jpg
                                string fullPath = Path.Combine(Cfg.Root, lastFile.Path + Cfg.ThumbPostfix);
                                try
                                {
                                    using (var writeStream = File.Create(fullPath))
                                    {
                                        await fileSection.FileStream.CopyToAsync(writeStream, _bufferSize, _context.RequestAborted);
                                    }
                                }
                                catch { }
                                lastFile = null;
                            }
                        }
                        else
                        {
                            lastFile = await ReceiveFile(fileSection);

                            sucFiles.Add(lastFile);
                        }
                    }
                    section = await reader.ReadNextSectionAsync(_context.RequestAborted);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "处理上传文件异常");
                _result.Clear();

                if (sucFiles.Count > 0)
                {
                    // 删除已上传成功的文件和记录
                    StringBuilder sb = new StringBuilder();
                    foreach (var desc in sucFiles)
                    {
                        FileInfo fi = new FileInfo(Path.Combine(Cfg.Root, desc.Path));
                        if (fi.Exists)
                        {
                            try
                            {
                                fi.Delete();
                            }
                            catch { }
                        }
                        sb.Append(',');
                        sb.Append(desc.ID);
                    }

                    try
                    {
                        await _db.Exec($"delete from fsm_file where id in ({sb.ToString().TrimStart(',')})");
                    }
                    catch { }
                }
            }
            finally
            {
                await _db.Close(true);

                // 卷使用数减1
                if (cache != null)
                {
                    await cache.Decrement(_volume);
                }
            }

            await Response();
        }
Beispiel #2
0
Datei: Cfg.cs Projekt: Daoting/dt
        /// <summary>
        /// 初始化文件服务
        /// </summary>
        public static void Init()
        {
            // BaseDirectory程序集所在的目录,不可用Directory.GetCurrentDirectory()!
            Root = Path.Combine(AppContext.BaseDirectory, "drive");
            var dir = new DirectoryInfo(Root);

            if (!dir.Exists)
            {
                dir.Create();
            }

            // 固定卷
            var           fv = Kit.GetCfg <string>("FixedVolume");
            StringBuilder sb = new StringBuilder("初始化固定卷");

            if (!string.IsNullOrEmpty(fv))
            {
                var vols = fv.Split(';');
                foreach (var vol in vols)
                {
                    var v = vol.Trim().ToLower();
                    if (v != string.Empty)
                    {
                        string path = Path.Combine(Root, v);
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                        FixedVolumes.Add(v);
                        sb.Append(" ");
                        sb.Append(v);
                    }
                }
            }
            sb.Append(",普通卷");

            // 普通卷
            SortedSetCache cache = new SortedSetCache(VolumeKey);
            var            subs  = dir.GetDirectories();

            if (subs != null && subs.Length > 0)
            {
                foreach (var sub in subs)
                {
                    // 非固定卷
                    string v = sub.Name.ToLower();
                    if (!FixedVolumes.Contains(v))
                    {
                        Volumes.Add(sub.Name);
                        // 加入缓存
                        cache.Increment(v, 0).Wait();
                        sb.Append(" ");
                        sb.Append(v);
                    }
                }
            }
            // 无普通卷时创建默认卷v0
            if (Volumes.Count == 0)
            {
                Volumes.Add(_defaultVol);
                Directory.CreateDirectory(Path.Combine(Root, _defaultVol));
                cache.Increment(_defaultVol, 0).Wait();
                sb.Append(" ");
                sb.Append(_defaultVol);
            }

            Log.Information(sb.ToString());
        }