为什么在图像的开始处有不需要的额外字节?

题:

我为我的兄弟做了一个主页,可以在这里find:
http://www.daniel-steiger.ch

它使用Linux上的Microsoft ASP.NET MVC3与单声道3,通过fastcginginx(加上我自己的DNS服务器)。

现在我知道这是一个不寻常的星座,但到目前为止,这一切都很好。
但是,我遇到了一个非常微妙的错误。

当在图库中点击缩略图图像时,我想通过图库控制器的FullImage方法在新选项卡中显示全尺寸图像。
例如,这个直接的url:
http://www.daniel-steiger.ch/gallery/FullImage/001.jpg

在Internet Explorer中,我将图像改为了文本。
在所有其他浏览器中显示“无效图像”消息。
我通过直接的文件URL调用图像解决了这个问题,
http://www.daniel-steiger.ch/Content/images/gallery/001.jpg?LastWriteTimeUTC=1358694795000

随后,我向单声道邮件列表报告了这个错误
http://mono.1490590.n4.nabble.com/Bug-in-mono-3-0-1-MVC3-File-FileResult-td4658382.html

现在我得到了答复,这是我的错,因为我设置了错误的图像MIMEtypes,这是/是真的。
然而,我发现奇怪的是,如果是这样的话,相同的代码在Windows上工作正常,再加上Chrome等智能浏览器通常会检测到错误的MIME设置并使用正确的设置。

于是我把MIMEtypes从“image / jpg”改为“image / jpeg”,并将项目重新部署到服务器。
我也检查了文件工具,如果图像实际上是一个JPEG图像,它是。

奇怪的是它仍然没有显示图像。
在Internet Explorer上,我现在得到“不可用”。
在所有其他浏览器上,我得到:图像无法显示,因为它包含错误。

我现在做了从图像包含错误的URL的图像。
wget http://www.daniel-steiger.ch/gallery/fullimage/001.jpg

然后我运行了无效和原始文件之间的二进制比较:

cmp -l 001.jpg 001a.jpg | awk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}' >> comparison.txt 

这是比较结果:

BinDiff 我的眼中涌出的是,Internet Explorer说他找不到的图像实际上是1.7 MB,并且包含额外的字节:

 31 39 36 62 36 38 0D 0A 

一开始…
任何人都有一个想法这里/这些字节可能来自哪里(除了最有可能从单声道/ fastcgi中的错误)这里有什么问题?

这是新的控制器代码btw:

 namespace Homepage.Controllers { public class GalleryController : Controller { protected static string GetImageDirectory() { string bd = AppDomain.CurrentDomain.BaseDirectory; string strImageDirectory = System.IO.Path.Combine(bd, "Content"); strImageDirectory = System.IO.Path.Combine(strImageDirectory, "images"); strImageDirectory = System.IO.Path.Combine(strImageDirectory, "gallery"); return strImageDirectory; } // End Function GetImageDirectory protected static string strImageDirectory = GetImageDirectory(); public FileResult FullImage(string id) { string strFileName = System.IO.Path.Combine(strImageDirectory, id); //return new FilePathResult("CorrectFullPathAndFileName", "CorrectMime"); //return File(strFileName, "image/jpg"); // Old return File(strFileName, "image/jpeg"); // New } // End Action FullImage public FileResult Thumb(string id) { //return Redirect(id); string strFileName = System.IO.Path.Combine(strImageDirectory, id); System.IO.Stream ms = Tools.Imaging.GetThumbnailStream(strFileName, System.Drawing.Imaging.ImageFormat.Png); return File(ms, "image/png"); /* using (System.IO.Stream ms = Tools.Imaging.GetThumbnailStream(strFileName, System.Drawing.Imaging.ImageFormat.Png)) { return File(ms, "image/png"); }*/ } // End Action Thumb } // End Class GalleryController : Controller } // End Namespace Homepage.Controllers 

编辑:
它变得陌生:
还有一个额外的序列

 0d 0a 0d 0a 30 0d 0a 0d 0a 

最后…

我只是做了hexdump,发现原始文件有文件大小(屏住呼吸):

 00196b68 

这里hexdumps(每个8 MB):

规范格式(hexdump -C 001.jpg> 001.txt):
原始文件: http : //www.daniel-steiger.ch/001.txt
修补文件: http ://www.daniel-steiger.ch/001a.txt

纯转储(hexdump 001.jpg> 001_1.txt):
原始文件: http : //www.daniel-steiger.ch/001_1.txt
Botched文件: http ://www.daniel-steiger.ch/001a_1.txt

嗯,hex文件的垃圾转储是5 MB的,原来的是8.2 MB的… … –

我使用最新的稳定的nginx:

 sudo -s nginx=stable # use nginx=development for latest development version add-apt-repository ppa:nginx/$nginx apt-get update apt-get install nginx 

Tools.Imaging的完整代码(在此期间将Tools重命名为MvcTools,以匹配程序集名称空间)

 using System; using System.Text; namespace MvcTools { public class Imaging { //public static System.Drawing.Size m_sMaxThumbNailDimensions = new System.Drawing.Size(200, 200); public static System.Drawing.Size m_sMaxThumbNailDimensions = new System.Drawing.Size(300, 300); public static System.IO.Stream GetImageAsStream( string strOrgFileName , System.Drawing.Imaging.ImageFormat ifOutputFormat ) { return GetImageAsStream(strOrgFileName, ifOutputFormat, 1024); } // End Function GetImage public static System.IO.Stream GetImageAsStream( string strOrgFileName ,System.Drawing.Imaging.ImageFormat ifOutputFormat ,int rez ) { System.IO.MemoryStream ms = null; if (!System.IO.File.Exists(strOrgFileName)) throw new System.IO.FileNotFoundException(strOrgFileName); try { using (System.Drawing.Image imgSourceImage = System.Drawing.Image.FromFile(strOrgFileName)) { ms = new System.IO.MemoryStream(); imgSourceImage.Save(ms, ifOutputFormat); ms.Position = 0; } // End Using imgSourceImage } // End Try catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.GetType().ToString()); System.Windows.Forms.MessageBox.Show(ex.Message); //Response.Write(ex.Message); } // End Catch return ms; } // End Function GetImageAsStream public static System.Drawing.Size GetThumbnailSize(string strOrgFileName) { System.Drawing.Size sThumbNailSizeToUse = new System.Drawing.Size(); try { using (System.Drawing.Image imgSourceImage = System.Drawing.Image.FromFile(strOrgFileName)) { decimal decPixToSubstract = 0; decimal decPercentage; if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) { if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) { decPercentage = (((decimal)imgSourceImage.Size.Width - (decimal)m_sMaxThumbNailDimensions.Width) / (decimal)imgSourceImage.Size.Width); decPixToSubstract = decPercentage * imgSourceImage.Size.Height; sThumbNailSizeToUse.Width = m_sMaxThumbNailDimensions.Width; sThumbNailSizeToUse.Height = imgSourceImage.Size.Height - (int)decPixToSubstract; } // End if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) else { decPercentage = (((decimal)imgSourceImage.Size.Height - (decimal)m_sMaxThumbNailDimensions.Height) / (decimal)imgSourceImage.Size.Height); decPixToSubstract = decPercentage * (decimal)imgSourceImage.Size.Width; sThumbNailSizeToUse.Height = m_sMaxThumbNailDimensions.Height; sThumbNailSizeToUse.Width = imgSourceImage.Size.Width - (int)decPixToSubstract; } // End else of if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) } // End if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) else { sThumbNailSizeToUse.Width = imgSourceImage.Size.Width; sThumbNailSizeToUse.Height = imgSourceImage.Size.Height; } // End else of if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) } // End Using imgSourceImage } // End Try catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); //Response.Write(ex.Message); } // End Catch return sThumbNailSizeToUse; } // End Sub GetThumbnailSize(string strOrgFileName) // http://stackoverflow.com/questions/7319842/mvc3-razor-thumbnail-resize-image-ideas // http://stackoverflow.com/questions/1528525/alternatives-to-system-drawing-for-use-with-asp-net/1528908#1528908 public static void GenerateThumbnailFile( string strPhysicalPath, string strOrgFileName, string strThumbnailFileName, System.Drawing.Imaging.ImageFormat ifOutputFormat, int rez ) { try { using (System.Drawing.Image imgSourceImage = System.Drawing.Image.FromFile(strOrgFileName)) { //System.Drawing.Image oImg = System.Drawing.Image.FromStream(fil.InputStream); decimal decPixToSubstract = 0; decimal decPercentage; //default System.Drawing.Size sThumbNailSizeToUse = new System.Drawing.Size(); if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) { if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) { decPercentage = (((decimal)imgSourceImage.Size.Width - (decimal)m_sMaxThumbNailDimensions.Width) / (decimal)imgSourceImage.Size.Width); decPixToSubstract = decPercentage * imgSourceImage.Size.Height; sThumbNailSizeToUse.Width = m_sMaxThumbNailDimensions.Width; sThumbNailSizeToUse.Height = imgSourceImage.Size.Height - (int)decPixToSubstract; } // End if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) else { decPercentage = (((decimal)imgSourceImage.Size.Height - (decimal)m_sMaxThumbNailDimensions.Height) / (decimal)imgSourceImage.Size.Height); decPixToSubstract = decPercentage * (decimal)imgSourceImage.Size.Width; sThumbNailSizeToUse.Height = m_sMaxThumbNailDimensions.Height; sThumbNailSizeToUse.Width = imgSourceImage.Size.Width - (int)decPixToSubstract; } // End else of if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) } // End if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) else { sThumbNailSizeToUse.Width = imgSourceImage.Size.Width; sThumbNailSizeToUse.Height = imgSourceImage.Size.Height; } // End else of if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) using (System.Drawing.Bitmap bmpThumbnail = new System.Drawing.Bitmap(sThumbNailSizeToUse.Width, sThumbNailSizeToUse.Height)) { bmpThumbnail.SetResolution(rez, rez); using (System.Drawing.Image imgThumbNail = bmpThumbnail) { using (System.Drawing.Graphics gGraphicsContext = System.Drawing.Graphics.FromImage(imgThumbNail)) { gGraphicsContext.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; gGraphicsContext.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; gGraphicsContext.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; System.Drawing.Rectangle rThumbnailDimension = new System.Drawing.Rectangle(0, 0, sThumbNailSizeToUse.Width, sThumbNailSizeToUse.Height); gGraphicsContext.DrawImage(imgSourceImage, rThumbnailDimension); } // End Using gGraphicsContext imgThumbNail.Save(System.IO.Path.Combine(strPhysicalPath, strThumbnailFileName), ifOutputFormat); } // End Using imgThumbNail } // End Using bmpThumbnail } // End Using imgSourceImage } // End Try catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); //Response.Write(ex.Message); } // End Catch } // End Function GenerateThumbNail public static System.IO.Stream GetThumbnailStream( string strOrgFileName , System.Drawing.Imaging.ImageFormat ifOutputFormat ) { return GetThumbnailStream(strOrgFileName, ifOutputFormat, 1024); } // End Function GetThumbnailStream public static System.IO.Stream GetThumbnailStream( string strOrgFileName ,System.Drawing.Imaging.ImageFormat ifOutputFormat ,int rez ) { System.IO.MemoryStream ms = null; try { using (System.Drawing.Image imgSourceImage = System.Drawing.Image.FromFile(strOrgFileName)) { decimal decPixToSubstract = 0; decimal decPercentage; System.Drawing.Size sThumbNailSizeToUse = new System.Drawing.Size(); if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) { if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) { decPercentage = (((decimal)imgSourceImage.Size.Width - (decimal)m_sMaxThumbNailDimensions.Width) / (decimal)imgSourceImage.Size.Width); decPixToSubstract = decPercentage * imgSourceImage.Size.Height; sThumbNailSizeToUse.Width = m_sMaxThumbNailDimensions.Width; sThumbNailSizeToUse.Height = imgSourceImage.Size.Height - (int)decPixToSubstract; } // End if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) else { decPercentage = (((decimal)imgSourceImage.Size.Height - (decimal)m_sMaxThumbNailDimensions.Height) / (decimal)imgSourceImage.Size.Height); decPixToSubstract = decPercentage * (decimal)imgSourceImage.Size.Width; sThumbNailSizeToUse.Height = m_sMaxThumbNailDimensions.Height; sThumbNailSizeToUse.Width = imgSourceImage.Size.Width - (int)decPixToSubstract; } // End else of if (imgSourceImage.Size.Width > imgSourceImage.Size.Height) } // End if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) else { sThumbNailSizeToUse.Width = imgSourceImage.Size.Width; sThumbNailSizeToUse.Height = imgSourceImage.Size.Height; } // End else of if (m_sMaxThumbNailDimensions.Width < imgSourceImage.Size.Width || m_sMaxThumbNailDimensions.Height < imgSourceImage.Size.Height) using (System.Drawing.Bitmap bmpThumbnail = new System.Drawing.Bitmap(sThumbNailSizeToUse.Width, sThumbNailSizeToUse.Height)) { bmpThumbnail.SetResolution(rez, rez); using (System.Drawing.Image imgThumbNail = bmpThumbnail) { using (System.Drawing.Graphics gGraphicsContext = System.Drawing.Graphics.FromImage(imgThumbNail)) { gGraphicsContext.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; gGraphicsContext.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; gGraphicsContext.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; System.Drawing.Rectangle rThumbnailDimension = new System.Drawing.Rectangle(0, 0, sThumbNailSizeToUse.Width, sThumbNailSizeToUse.Height); gGraphicsContext.DrawImage(imgSourceImage, rThumbnailDimension); ms = new System.IO.MemoryStream(); imgThumbNail.Save(ms, ifOutputFormat); ms.Position = 0; } // End Using gGraphicsContext } // End Using imgThumbNail } // End Using bmpThumbnail /* byte[] buffer = null; using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { imgThumbNail.Save(ms, ifOutputFormat); buffer = ms.ToArray(); } */ // Exerts from Page_Load method //Response.ContentType = "image/" + extension; //Response.OutputStream.Write(pBuffer, 0, pBuffer.Length); //Response.End(); //imgThumbNail.Save(System.IO.Path.Combine(strPhysicalPath, strThumbnailFileName), ifOutputFormat); } // End Using imgSourceImage } // End Try catch (Exception ex) { //Console.WriteLine(ex.Message); System.Windows.Forms.MessageBox.Show(ex.Message); //Response.Write(ex.Message); } // End Catch //System.Windows.Forms.MessageBox.Show("image/" + ifOutputFormat.ToString().ToLower()); return ms; } // End Function GenerateThumbNail } // End Class Imaging } // End Namespace Tools 

这似乎是一个涉及Chuncked传输编码的错误

 Class: System.Web.HttpResponse (or one of its dependencies) Method: TransmitFile(string filename) 

编辑:
在构造函数中有这样的代码:

 if (worker_request != null) use_chunked = (worker_request.GetHttpVersion () == "HTTP/1.1"); 

修补它来检查CGI(如果CGI,服务器处理文件传输,所以根据RFC 3875可能没有从FastCGI服务器返回的chuncked编码。

  internal HttpResponse (HttpWorkerRequest worker_request, HttpContext context) : this () { WorkerRequest = worker_request; this.context = context; #if !TARGET_J2EE if (worker_request != null) { if(worker_request.GetHttpVersion () == "HTTP/1.1") { string GatewayIface = context.Request.serverVariables["GATEWAY_INTERFACE"]; use_chunked = (GatewayIface == null || !GatewayIface.StartsWith("CGI")); } else use_chunked = false; } #endif writer = new HttpWriter (this); } 

添加了修补程序到https://bugzilla.xamarin.com/show_bug.cgi?id=10001
固定在单声道3.2.3

 31 39 36 62 36 38 0D 0A 

ascii是196b68/r/n

  • 这个颜色是否与你的代码有关?
  • 字符串196b68/r/n与你的平台有关?

我不认识到,Tools.Imaging.GetThumbnailStream()函数,也不是谷歌。 假设这是你自己的代码或第三方库,我会在那里寻找奇怪字节流的来源。