3

質問:

兄のホームページを作成しました。ここからアクセスできます:
http ://www.daniel-steiger.ch

Linuxでmono3を使用するMicrosoftASP.NETMVC3を使用し、nginxを使用するfastcgi(および私自身の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に報告しました。

間違った画像のmimeタイプを設定したため、これはすべて私のせいであるという応答が返ってきました。これは本当です。
ただし、その場合、同じコードがWindowsで正常に機能することに加えて、Chromeなどのスマートブラウザが通常、間違ったmime設定を検出し、正しい設定を使用するのは奇妙だと思いました。

そこで、mime-typeを「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 

最初は...
誰もがここで何が問題になっているのか/これらのバイトがどこから来ているのかを知っています(mono / fastcgiのバグが原因である可能性が高いという事実は別として)?

これは新しいコントローラーコードです:

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

ここでは、16進ダンプ(各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 ボットファイル: http://www。 daniel-steiger.ch/001a_1.txt

うーん、失敗したファイルの16進ダンプは5 MBで、元のファイルの16進ダンプは8.2MBです...

私は最新の安定した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
4

3 に答える 3

4

これは、チャンク転送エンコーディングに関連するバグのようです

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 サーバーからチャンクされたエンコーディングが返されない場合があります。

        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 にパッチを追加
Mono 3.2.3 で修正

于 2013-02-03T11:01:19.287 に答える
1
31 39 36 62 36 38 0D 0A

アスキーにあり196b68/r/nます。

  • この色はあなたのコードにどのように関連していますか?
  • 文字列196b68/r/nはプラットフォームに関連する何かを言っていますか?
于 2013-02-02T14:26:39.257 に答える
0

私はその Tools.Imaging.GetThumbnailStream() 関数を認識していませんし、Google も認識していません。それがあなた自身のコードまたはサードパーティのライブラリであると仮定すると、奇妙なバイトストリームのソースを探します。

于 2013-02-03T05:29:50.777 に答える