/// <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); }
/// <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); } }