2010-06-30 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web / StaticFileHandler.cs
index d8222d5efaaa3cd34b77b4f9b331cb4e68bc4b80..822cd68a735e8a6a4c37a687aba7e5c288ce856f 100644 (file)
@@ -5,6 +5,7 @@
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
 // (C) 2002 Ximian, Inc (http://www.ximian.com)
+// (C) 2003-2009 Novell, Inc (http://novell.com)
 //
 
 //
 using System;
 using System.Globalization;
 using System.IO;
+using System.Web.Util;
+using System.Web.Hosting;
 
 namespace System.Web
 {
        class StaticFileHandler : IHttpHandler
        {
+               static bool ValidFileName (string fileName)
+               {
+                       if (!RuntimeHelpers.RunningOnWindows)
+                               return true;
+
+                       if (fileName == null || fileName.Length == 0)
+                               return false;
+
+                       return (!StrUtils.EndsWith (fileName, " ") && !StrUtils.EndsWith (fileName, "."));
+               }
+               
                public void ProcessRequest (HttpContext context)
                {
                        HttpRequest request = context.Request;
                        HttpResponse response = context.Response;
+
+                       if (HostingEnvironment.HaveCustomVPP) {
+                               VirtualFile vf = null;
+                               VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
+                               string vpath = request.FilePath;
+                               
+                               if (vpp.FileExists (vpath))
+                                       vf = vpp.GetFile (vpath);
+
+                               if (vf == null)
+                                       throw new HttpException (404, "Path '" + vpath + "' was not found.", vpath);
+
+                               response.ContentType = MimeTypes.GetMimeType (vpath);
+                               response.TransmitFile (vf, true);
+                               return;
+                       }
+                       
                        string fileName = request.PhysicalPath;
                        FileInfo fi = new FileInfo (fileName);
-                       if (!fi.Exists)
-                               throw new HttpException (404, "File '" + request.FilePath + "' not found.");
+                       if (!fi.Exists || !ValidFileName (fileName))
+                               throw new HttpException (404, "Path '" + request.FilePath + "' was not found.", request.FilePath);
 
                        if ((fi.Attributes & FileAttributes.Directory) != 0) {
                                response.Redirect (request.Path + '/');
                                return;
                        }
-
+                       
                        string strHeader = request.Headers ["If-Modified-Since"];
                        try {
                                if (strHeader != null) {
                                        DateTime dtIfModifiedSince = DateTime.ParseExact (strHeader, "r", null);
-                                       DateTime ftime = fi.LastWriteTime.ToUniversalTime ();
+                                       DateTime ftime;
+#if TARGET_JVM
+                                       try 
+                                       {
+                                               ftime = fi.LastWriteTime.ToUniversalTime ();
+                                       } 
+                                       catch (NotSupportedException) 
+                                       {
+                                               // The file is in a WAR, it might be modified with last redeploy.
+                                               try {
+                                                       ftime = (DateTime) AppDomain.CurrentDomain.GetData (".appStartTime");
+                                               }
+                                               catch {
+                                                       ftime = DateTime.MaxValue;
+                                               }
+                                       }
+#else
+                                       ftime = fi.LastWriteTime.ToUniversalTime ();
+#endif
                                        if (ftime <= dtIfModifiedSince) {
                                                response.StatusCode = 304;
                                                return;
@@ -65,11 +114,9 @@ namespace System.Web
                        try {
                                DateTime lastWT = fi.LastWriteTime.ToUniversalTime ();
                                response.AddHeader ("Last-Modified", lastWT.ToString ("r"));
-
                                response.ContentType = MimeTypes.GetMimeType (fileName);
-                               response.AppendHeader ("Content-Length", fi.Length.ToString (CultureInfo.InvariantCulture));
-                               response.TransmitFile (fileName);
-                       } catch (Exception e) {
+                               response.TransmitFile (fileName, true);
+                       } catch (Exception) {
                                throw new HttpException (403, "Forbidden.");
                        }
                }