Esempio n. 1
0
        /// <summary>
        /// Method that processes the Uri.
        /// </summary>
        /// <param name="request">Information sent by the browser about the request.</param>
        /// <param name="response">Information that is being sent back to the client.</param>
        /// <param name="session">Session object used during the client connection.</param>
        /// <returns><c>true</c> if this module is able to handle the request, else <c>false</c>.</returns>
        /// <exception cref="InternalServerException">If an exception occured in the server.</exception>
        /// <exception cref="ForbiddenException">If the file path is forbidden.</exception>
        public override bool Process(IHttpRequest request, IHttpResponse response, IHttpSession session)
        {
            ResourcePath resourcePath;
            Uri          uri = request.Uri;

            if (!uri.AbsolutePath.StartsWith(ResourceHttpAccessUrlUtils.RESOURCE_ACCESS_PATH))
            {
                return(false);
            }
            if (!ResourceHttpAccessUrlUtils.ParseResourceURI(uri, out resourcePath))
            {
                throw new BadRequestException(string.Format("Illegal request syntax. Correct syntax is '{0}'", ResourceHttpAccessUrlUtils.SYNTAX));
            }
            if (!IsAllowedToAccess(resourcePath))
            {
                ServiceRegistration.Get <ILogger>().Warn("ResourceAccessModule: Client tries to access forbidden resource '{0}'", resourcePath);
                throw new ForbiddenException(string.Format("Access of resource '{0}' not allowed", resourcePath));
            }

            try
            {
                IFileSystemResourceAccessor fsra = GetResourceAccessor(resourcePath);
                using (Stream resourceStream = fsra.OpenRead())
                {
                    response.ContentType = GuessMimeType(resourceStream, resourcePath.FileName);

                    if (!string.IsNullOrEmpty(request.Headers["If-Modified-Since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(request.Headers["If-Modified-Since"]);
                        if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                        {
                            response.Status = HttpStatusCode.NotModified;
                        }
                    }

                    response.AddHeader("Last-Modified", fsra.LastChanged.ToUniversalTime().ToString("r"));

                    string        byteRangesSpecifier = request.Headers["Range"];
                    IList <Range> ranges      = ParseRanges(byteRangesSpecifier, resourceStream.Length);
                    bool          onlyHeaders = request.Method == "Headers" || response.Status == HttpStatusCode.NotModified;
                    if (ranges != null && ranges.Count == 1)
                    {
                        // We only support one range
                        SendRange(response, resourceStream, ranges[0], onlyHeaders);
                    }
                    else
                    {
                        SendWholeFile(response, resourceStream, onlyHeaders);
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                throw new InternalServerException(string.Format("Failed to proccess resource '{0}'", resourcePath), ex);
            }

            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Method that processes the Uri.
        /// </summary>
        public override async Task Invoke(IOwinContext context)
        {
            var          request  = context.Request;
            var          response = context.Response;
            ResourcePath resourcePath;
            Uri          uri = request.Uri;

            if (!uri.AbsolutePath.StartsWith(ResourceHttpAccessUrlUtils.RESOURCE_SERVER_BASE_PATH) || !uri.AbsolutePath.Contains(ResourceHttpAccessUrlUtils.RESOURCE_ACCESS_PATH))
            {
                await Next.Invoke(context);

                return;
            }
            if (!ResourceHttpAccessUrlUtils.ParseResourceURI(uri, out resourcePath))
            {
                response.StatusCode   = (int)HttpStatusCode.BadRequest;
                response.ReasonPhrase = string.Format("Illegal request syntax. Correct syntax is '{0}'", ResourceHttpAccessUrlUtils.SYNTAX);
                return;
            }
            if (!IsAllowedToAccess(resourcePath))
            {
                ServiceRegistration.Get <ILogger>().Warn("ResourceAccessModule: Client tries to access forbidden resource '{0}'", resourcePath);
                response.StatusCode   = (int)HttpStatusCode.Forbidden;
                response.ReasonPhrase = string.Format("Access of resource '{0}' not allowed", resourcePath);
                return;
            }

            try
            {
                IFileSystemResourceAccessor fsra = GetResourceAccessor(resourcePath);
                using (Stream resourceStream = fsra.OpenRead())
                {
                    response.ContentType = GuessMimeType(resourceStream, resourcePath.FileName);

                    if (!string.IsNullOrEmpty(request.Headers["If-Modified-Since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(request.Headers["If-Modified-Since"], System.Globalization.CultureInfo.InvariantCulture);
                        if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                        {
                            response.StatusCode = (int)HttpStatusCode.NotModified;
                        }
                    }

                    response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r");

                    string        byteRangesSpecifier = request.Headers["Range"];
                    IList <Range> ranges      = ParseRanges(byteRangesSpecifier, resourceStream.Length);
                    bool          onlyHeaders = request.Method == "Headers" || response.StatusCode == (int)HttpStatusCode.NotModified;

                    CancellationTokenSource cts = new CancellationTokenSource();
                    if (ranges != null && ranges.Count == 1)
                    {
                        // We only support one range
                        await SendRange(response, resourceStream, ranges[0], onlyHeaders, cts.Token);
                    }
                    else
                    {
                        await SendWholeFile(response, resourceStream, onlyHeaders, cts.Token);
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                response.StatusCode   = (int)HttpStatusCode.InternalServerError;
                response.ReasonPhrase = string.Format("Failed to proccess resource '{0}': {1}", resourcePath, ex.Message);
            }
        }