private static bool ValidateEntityTag(HttpRequest request, HttpResponse response, FileRequest fileRequest)
        {
            if (request.Headers.ContainsKey("If-Match"))
            {
                string matchHeader = request.Headers["If-Match"];
                if (matchHeader != "*")
                {
                    var entitiesTags    = matchHeader.Split(FileRequest.CommaSplitArray);
                    int entitieTagIndex = 0;

                    for (; entitieTagIndex < entitiesTags.Length; entitieTagIndex++)
                    {
                        if (fileRequest.EntityTag == entitiesTags[entitieTagIndex])
                        {
                            break;
                        }
                    }

                    if (entitieTagIndex >= entitiesTags.Length)
                    {
                        response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
                        return(false);
                    }
                }
            }

            if (request.Headers.ContainsKey("If-None-Match"))
            {
                string noneMatchHeader = request.Headers["If-None-Match"];
                if (!string.IsNullOrEmpty(noneMatchHeader))
                {
                    if (noneMatchHeader == "*")
                    {
                        response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
                        return(false);
                    }

                    var entitiesTags = noneMatchHeader.Split(FileRequest.CommaSplitArray);
                    if (entitiesTags.All(entityTag => fileRequest.EntityTag == entityTag))
                    {
                        response.Headers["Etag"] = fileRequest.EntityTag;
                        response.StatusCode      = (int)HttpStatusCode.NotModified;
                        return(false);
                    }
                }
            }

            return(true);
        }
        public override Stream Handle(HttpRequest request, HttpResponse response)
        {
            Log.LogDebug("HandleStream get file");

            string file = string.Empty;

            if (request.Query.ContainsKey(string.Empty))
            {
                file = request.Query[string.Empty][0];
                file = HttpUtility.UrlDecode(file);
            }

            if (ProgramSettings.Settings.Dlna && !string.IsNullOrEmpty(file))
            {
                try {
                    var fileRequest = FileRequest.Create(request, file);

                    if (fileRequest.File.Exists && Tools.Tools.CheckAccessPath(fileRequest.File.FullName))
                    {
                        response.Headers.Add("Accept-Ranges", "bytes");
                        if (ValidateRanges(response, fileRequest) &&
                            ValidateModificationDate(request, response, fileRequest) &&
                            ValidateEntityTag(request, response, fileRequest))
                        {
                            response.Headers.Add("Last-Modified", fileRequest.File.LastWriteTime.ToString("r"));
                            response.Headers["Etag"] = fileRequest.EntityTag;

                            if (!fileRequest.RangeRequest)
                            {
                                response.ContentLength = fileRequest.File.Length;
                                response.ContentType   = fileRequest.ContentType;
                                response.StatusCode    = (int)HttpStatusCode.OK;

                                var fileStream = fileRequest.File.OpenRead();
                                fileStream.Position = 0;
                                return(fileStream);
                            }
                            else
                            {
                                response.ContentLength = fileRequest.GetContentLength();

                                if (!fileRequest.MultipartRequest)
                                {
                                    response.Headers.Add("Content-Range",
                                                         $"bytes {fileRequest.RangesStartIndexes[0]}-{fileRequest.RangesEndIndexes[0]}/{fileRequest.File.Length}");
                                    response.ContentType = fileRequest.ContentType;
                                }
                                else
                                {
                                    response.ContentType =
                                        $"multipart/byteranges; boundary={fileRequest.Boundary}";
                                }

                                response.StatusCode = (int)HttpStatusCode.PartialContent;
                                var fileStream = fileRequest.File.OpenRead();
                                fileStream.Position = fileRequest.RangesStartIndexes[0];
                                return(fileStream);
                            }
                        }
                    }
                    else
                    {
                        Log.LogDebug("File not found: {0}", file);
                        response.StatusCode = (int)HttpStatusCode.NotFound;
                    }
                } catch (Exception exception) {
                    Log.LogError(exception);
                    response.StatusCode = (int)HttpStatusCode.NotFound;
                }
            }
            else
            {
                Log.LogDebug("Incorrect parameter: {0}", file);

                response.StatusCode = (int)HttpStatusCode.NoContent;
            }

            return(null);
        }