/// <summary> /// Gets the file from the directory, and checks soms security /// </summary> /// <param name="dir"></param> /// <param name="filename"></param> /// <returns></returns> protected FileInfo GetImage(DirectoryInfo dir, string filename, IImageTemplate template) { if (string.IsNullOrEmpty(filename)) throw new ArgumentNullException("No filename given."); string fullFilename = Path.Combine(dir.FullName, filename); if (!fullFilename.StartsWith(dir.FullName)) throw new ArgumentException("Requested file " + fullFilename + " isn't within directory " + dir.FullName); FileInfo fi = new FileInfo(fullFilename); // plak templatename achter de file, en daarachter weer de extensie if (template != null) { string fileWithoutExtension = Path.GetFileNameWithoutExtension(fi.FullName); string extension = fi.Extension; fi = new FileInfo( Path.Combine( fi.Directory.FullName, string.Format("{0}_{1}{2}", fileWithoutExtension, template.Name, extension))); } return fi; }
/// <summary> /// manipulates the image and saves it to cachePath /// </summary> public Bitmap ApplyTemplate(Bitmap bmp, IImageTemplate template) { return ImageManipulation.Manipulate.Apply(bmp, template.Filters); }
protected FileInfo GetCachedImage(ISource source, string fileName, IImageTemplate template) { DirectoryInfo dir = GetSourceDirectory(source); string cachedImagePath = Path.Combine(GimmageConfig.Config.Cache.SourceDir.FullName, source.Name); if (source.Name == "N2") { string fileNameExtensionless = fileName.Substring(0, fileName.IndexOf('.')); char[] chars = fileNameExtensionless.ToCharArray(); string path = String.Empty; for (int i = 0; i < 3 || i < chars.Length; i++) { path += String.Format("{0}/", chars[i]); } path = path + fileName; } DirectoryInfo cacheSubDir = new DirectoryInfo(cachedImagePath); //fileName = source.Type == SourceType.file ? fileName : fileName.Replace('/', '_').Replace('\\', '_'); return GetImage(cacheSubDir, fileName, template); }
protected FileInfo GetCachedBackupImage(FileInfo backupImage, IImageTemplate template) { string cachedImagePath = Path.Combine(GimmageConfig.Config.Cache.SourceDir.FullName, "backup-images"); DirectoryInfo cacheSubDir = new DirectoryInfo(cachedImagePath); return GetImage(cacheSubDir, backupImage.Name, template); }
public void ServeImage(string fileName, byte[] fileContent, DateTime lastWriteTime, string mimeType, ISource source, IImageTemplate template, HttpResponse response, HttpRequest request) { // throws error if template is not found, because then the backup image can't be served either FileInfo cachedFile; try { cachedFile = GetCachedImage(source, fileName, template); } catch { // something error happens, serve one of the backup images FileInfo originalFile = GetBackupImage(); if (originalFile == null) throw; cachedFile = GetCachedBackupImage(originalFile, template); } // send not modified if (!IsModifiedSince(GetIfModSinceHeader(request), lastWriteTime)) { SendNotModified(response); return; } // save to disk, and send to response if (template != null && ShouldCacheBeUpdated(lastWriteTime, cachedFile)) { using (MemoryStream stream = new MemoryStream(fileContent)) { using (Bitmap bmp = ApplyTemplate(new Bitmap(stream), template)) { SaveToDisk(bmp, cachedFile, mimeType); } } } if (cachedFile.Exists) SendToResponse(response, cachedFile, mimeType); else SendToResponse(response, fileContent, lastWriteTime, mimeType); }
/// <summary> /// given the source filename and template return the complete filepath to which to save image /// </summary> /// <param name="source"></param> /// <param name="fileName"></param> /// <param name="template"></param> /// <returns></returns> private FileInfo getImageCacheFileName(ISource source, string fileName, IImageTemplate template) { DirectoryInfo dir = GetSourceDirectory(source); string cachedImagePath = Path.Combine(GimmageConfig.Config.Cache.SourceDir.FullName, source.Name); string path = getDBImageCachePath(source, fileName); DirectoryInfo cacheSubDir = new DirectoryInfo(path); return GetImage(cacheSubDir, fileName, template); }
/// <summary> /// hack for n2 / 9292 - server image from n2 database instead of file if possible /// </summary> /// <param name="fileName"></param> /// <param name="source"></param> /// <param name="template"></param> /// <param name="response"></param> /// <param name="request"></param> private void serveImageFromDatabase(string fileName, ISource source, IImageTemplate template, HttpResponse response, HttpRequest request) { // Hack: treat PDF files differently // Todo: store in local cache if (fileName.EndsWith(".pdf")) { SendToResponse(response, GetImageStreamFromDatabase(source, fileName), DateTime.MinValue, "application/pdf"); return; } //check if the templated image exists => if not => check if the original file exists on disk => if not => retrieve from database //check for templated image var cachedTemplateFile = getImageCacheFileName(source, fileName, template); if(cachedTemplateFile == null) throw new ArgumentNullException("getImageCacheFileName returned NULL, should not be"); if (!cachedTemplateFile.Exists) { //lock for thread safety, double check existance of template file before actually saving shit lock (String.Intern(cachedTemplateFile.ToString())) { if (!cachedTemplateFile.Exists) { //check if original file exists on disk or retrieve it from the database string path = getDBImageCachePath(source, fileName); var actualDirectory = Path.GetDirectoryName(Path.Combine(path, fileName)); // If there's a directory name in filename if (!Directory.Exists(actualDirectory)) Directory.CreateDirectory(actualDirectory); byte[] originalImgData = null; FileInfo originalFile = new FileInfo(Path.Combine(path, fileName)); if (log.IsDebugEnabled) log.DebugFormat("Going to render template '{0}' for original '{1}' since it did not exist on disk ({2})", template.Name, originalFile.ToString(), cachedTemplateFile.ToString()); if (!originalFile.Exists) { lock (String.Intern(originalFile.ToString())) { if (!originalFile.Exists) { //retrieve original from database and save it to disk originalImgData = GetImageStreamFromDatabase(source, fileName); try{ using (FileStream fs = new FileStream(originalFile.ToString(), FileMode.Create, FileAccess.Write)) { fs.Write(originalImgData, 0, originalImgData.Length); } } catch(Exception e){ //save to disk failed, but we have the image stream! rejoice! log.Error(string.Format("Could not save image '{0}' from database to disk '{1}', raw-image-stream from database will be used. (PERFORMANCE PENALTY!)", fileName, originalFile.ToString()), e); } } } } //the original is available as image on disk or (fastest) memory stream try { if (originalImgData != null) { //save original file stream as templated file to disk using (Bitmap img = ApplyTemplate((Bitmap)Bitmap.FromStream(new MemoryStream(originalImgData)), template)) { SaveToDisk(img, cachedTemplateFile, MimeType.GetMimeTypeByByteArray(originalImgData)); } SendToResponse(response, cachedTemplateFile, MimeType.GetMimeTypeByByteArray(originalImgData));//it is new } else { //originalFile.existed so we use that one as the base for our template transformations using (Bitmap img = ApplyTemplate(new Bitmap(originalFile.FullName), template)) { SaveToDisk(img, cachedTemplateFile, GetMimeType(originalFile)); } SendToResponse(response, cachedTemplateFile, GetMimeType(originalFile));//it is new } return;//we are done! :D } catch (Exception e) { //saving of the cached templated version failed, damnit log.Error(string.Format("Could not save cached template image to location '{0}'", cachedTemplateFile), e); throw;//return 500 error } } } } //verify if the images are the same, return 304 if so if (!IsModifiedSince(GetIfModSinceHeader(request), cachedTemplateFile)) { SendNotModified(response); } else { //not the same, return image SendToResponse(response, cachedTemplateFile, GetMimeType(cachedTemplateFile)); } }
private void serveImageFromFile(string fileName, ISource source, IImageTemplate template, HttpResponse response, HttpRequest request) { // throws error if template is not found, because then the backup image can't be served either FileInfo cachedFile; FileInfo originalFile; try { cachedFile = GetCachedImage(source, fileName, template); originalFile = GetOriginalImage(source, fileName); if (!originalFile.Exists) throw new FileNotFoundException("Not found: " + originalFile); } catch { // something error happens, serve one of the backup images originalFile = GetBackupImage(); if (originalFile == null) throw; cachedFile = GetCachedBackupImage(originalFile, template); } FileInfo fileToServe = template == null ? originalFile : cachedFile; // send not modified if (originalFile.Exists && !IsModifiedSince(GetIfModSinceHeader(request), fileToServe)) { SendNotModified(response); } else { // save to disk, and send to response if (template != null && ShouldCacheBeUpdated(originalFile, cachedFile)) { using (Bitmap bmp = ApplyTemplate(new Bitmap(originalFile.FullName), template)) { string mimeType = GetMimeType(cachedFile); SaveToDisk(bmp, cachedFile, mimeType); } } SendToResponse(response, fileToServe, GetMimeType(fileToServe)); } }
// [DebuggerStepThrough] // Ignore FileNotFound exceptions public void ServeImage(string fileName, ISource source, IImageTemplate template, HttpResponse response, HttpRequest request) { if (source == null) { SendFileNotFound(response); return; } try { switch (source.Type) { case SourceType.db: serveImageFromDatabase(fileName, source, template, response, request); break; case SourceType.share: case SourceType.file: serveImageFromFile(fileName, source, template, response, request); break; default: throw new NotImplementedException(string.Format("No imageServer implemented for sourceType '{0}'", source.Type)); } } catch (FileNotFoundException) { SendFileNotFound(response); } catch (Exception ex) { log.Error("Exception raised while serving immage!", ex); throw; } }