Example #1
0
        /// <summary>
        ///     Get a file for a request. If the
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="imageIdRef">The image identifier reference.</param>
        /// <param name="generateEtagFn">The generate e-tag function.</param>
        /// <returns>
        ///     The file response or a NotModified response if the e-tag matches.
        /// </returns>
        public static HttpResponseMessage GetFileForRequest(HttpRequestMessage request, ERM.EntityRef imageIdRef, Func <ERM.EntityRef, string> generateEtagFn)
        {
            string etag = generateEtagFn(imageIdRef);

            // If the request contains the same e-tag then return a not modified
            if (request.Headers.IfNoneMatch != null &&
                request.Headers.IfNoneMatch.Any(et => et.Tag == etag))
            {
                var notModifiedResponse = new HttpResponseMessage(HttpStatusCode.NotModified);
                notModifiedResponse.Headers.ETag = new EntityTagHeaderValue(etag, false);
                return(notModifiedResponse);
            }

            // Return the image
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(FileRepositoryHelper.GetFileDataStreamForEntity(imageIdRef))
            };

            response.Headers.ETag         = new EntityTagHeaderValue(etag, false);
            response.Headers.CacheControl = new CacheControlHeaderValue
            {
                MustRevalidate = true,
                MaxAge         = new TimeSpan(0)
            };

            // Yuck. You gotta do what you gotta do.
            bool isIosDevice = false;

            if (request.Headers.UserAgent != null)
            {
                isIosDevice = request.Headers.UserAgent.Any(ua => IosMobileRegex.IsMatch(ua.ToString()));
            }

            string contentType = string.Empty;

            // Note: We are not setting the content length because the CompressionHandler will compress the stream.
            // Specifying the length here will cause the browser to hang as the actual data it
            // receives (as it is compressed) will be less than the specified content length.
            FileDetails dbFileType = FileRepositoryHelper.GetStreamContentType(imageIdRef);

            if (dbFileType != null)
            {
                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = dbFileType.Filename
                };

                // Found that specifying specific mime types on IOS mobile
                // causes safari to raise errors.
                // However, found that on Android the download
                // manager requires the mime type so that the downloaded
                // file can be opened by tapping.
                if (!isIosDevice)
                {
                    if (!string.IsNullOrWhiteSpace(dbFileType.ContentType))
                    {
                        contentType = dbFileType.ContentType;
                    }
                    else
                    {
                        // Attempt to get a mime type from the file name
                        if (!string.IsNullOrWhiteSpace(dbFileType.Filename))
                        {
                            contentType = MimeMapping.GetMimeMapping(dbFileType.Filename);
                        }
                    }
                }
            }

            // If we don't have a content type, fallback to the generic one.
            if (string.IsNullOrWhiteSpace(contentType))
            {
                contentType = "application/octet-stream";
            }

            response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);

            return(response);
        }