private void context_EndRequest(object sender, EventArgs e) { HttpResponse response = HttpContext.Current.Response; HttpRequest request = HttpContext.Current.Request; // // Check for the X-Send headers // bool remove = false; // we check for temp first, so any software that wants to use it can, as a fallback, // also set the regular x-sendfile header in case on that system this version of the // dll is not deployed string filePath = response.Headers.Get("X-Sendfile-Temporary"); if (filePath == null) { filePath = response.Headers.Get("X-Sendfile"); } else { remove = true; } if (filePath == null) { filePath = response.Headers.Get("X-Accel-Redirect"); } if (filePath != null) { // // Determine the file path and ready the response // if (ConfigurationManager.AppSettings["XSendDir"] != null) { filePath = Path.Combine(ConfigurationManager.AppSettings["XSendDir"], filePath); // if there is a base path set (file will be located above this) } else if (ConfigurationManager.AppSettings["XAccelLocation"] != null) { filePath = filePath.Replace(ConfigurationManager.AppSettings["XAccelLocation"], ConfigurationManager.AppSettings["XAccelRoot"]); } response.Clear(); // Clears output buffer response.Headers.Remove("X-Sendfile"); // Remove unwanted headers response.Headers.Remove("X-Sendfile-Temporary"); response.Headers.Remove("X-Accel-Redirect"); // // Set the cache policy // if (ConfigurationManager.AppSettings["XSendCache"] == null) { response.Cache.SetCacheability(HttpCacheability.NoCache); } else if (ConfigurationManager.AppSettings["XSendCache"] == "Public") { response.Cache.SetCacheability(HttpCacheability.Public); } else { response.Cache.SetCacheability(HttpCacheability.Private); } // // Get the file information and set headers appropriately // FileInfo file = new FileInfo(filePath); if (!file.Exists) { throw new HttpException(404, "File_does_not_exist"); } if (filePath[filePath.Length - 1] == '.') { throw new HttpException(404, "File_does_not_exist"); } response.Cache.SetLastModified(file.LastWriteTimeUtc); response.Headers.Remove("Content-Length"); if (!String.IsNullOrEmpty(request.ServerVariables["HTTP_RANGE"])) { //request for chunk RangeDownload(file.FullName, HttpContext.Current); } else { response.AddHeader("Content-Length", file.Length.ToString()); response.AppendHeader("Accept-Ranges", "bytes"); // // Check if we want to detect the mime type of the current content // if (ConfigurationManager.AppSettings["XSendMime"] == null) { Microsoft.Web.Administration.ConfigurationSection staticContentSection = WebConfigurationManager.GetSection(HttpContext.Current, "system.webServer/staticContent"); Microsoft.Web.Administration.ConfigurationElementCollection staticContentCollection = staticContentSection.GetCollection(); var mt = staticContentCollection.Where( a => a.Attributes["fileExtension"].Value.ToString().ToLower() == file.Extension.ToLower() ).FirstOrDefault(); if (mt != null) { response.ContentType = mt.GetAttributeValue("mimeType").ToString(); } else { response.ContentType = "application/octet-stream"; } } // // Set a content disposition if it is not already set by the application // if (response.Headers["Content-Disposition"] == null) { response.AppendHeader("Content-Disposition", "inline;filename=" + file.Name); } // // Send the file without loading it into memory // response.TransmitFile(file.FullName); if (remove) { // note that the little Flush below causes the full file to load into // IIS memory but we need that be able to delete it // Note that on many concurrent requests, that means each request // will load the full output into memory, which wil remain there for // a while because the client needs time to download. Unfortunately // I found no way to dispose of the file once the last byte has been // sent response.Flush(); File.Delete(file.FullName); } } } }
private void context_EndRequest(object sender, EventArgs e) { HttpResponse response = HttpContext.Current.Response; HttpRequest request = HttpContext.Current.Request; // // Check for the X-Send headers // string filePath = response.Headers.Get("X-Sendfile"); if (filePath == null) { filePath = response.Headers.Get("X-Accel-Redirect"); } if (filePath != null) { // // Determine the file path and ready the response // if (ConfigurationManager.AppSettings["XSendDir"] != null) { filePath = Path.Combine(ConfigurationManager.AppSettings["XSendDir"], filePath); // if there is a base path set (file will be located above this) } else if (ConfigurationManager.AppSettings["XAccelLocation"] != null) { filePath = filePath.Replace(ConfigurationManager.AppSettings["XAccelLocation"], ConfigurationManager.AppSettings["XAccelRoot"]); } response.Clear(); // Clears output buffer response.Headers.Remove("X-Sendfile"); // Remove unwanted headers response.Headers.Remove("X-Accel-Redirect"); // // Set the cache policy // if (ConfigurationManager.AppSettings["XSendCache"] == null) { response.Cache.SetCacheability(HttpCacheability.NoCache); } else if (ConfigurationManager.AppSettings["XSendCache"] == "Public") { response.Cache.SetCacheability(HttpCacheability.Public); } else { response.Cache.SetCacheability(HttpCacheability.Private); } // // Get the file information and set headers appropriately // FileInfo file = new FileInfo(filePath); if (!file.Exists) { throw new HttpException(404, "File_does_not_exist"); } if (filePath[filePath.Length - 1] == '.') { throw new HttpException(404, "File_does_not_exist"); } response.Cache.SetLastModified(file.LastWriteTimeUtc); response.Headers.Remove("Content-Length"); if (!String.IsNullOrEmpty(request.ServerVariables["HTTP_RANGE"])) { //request for chunk RangeDownload(file.FullName, HttpContext.Current); } else { response.AddHeader("Content-Length", file.Length.ToString()); response.AppendHeader("Accept-Ranges", "bytes"); // // Check if we want to detect the mime type of the current content // if (ConfigurationManager.AppSettings["XSendMime"] == null) { Microsoft.Web.Administration.ConfigurationSection staticContentSection = WebConfigurationManager.GetSection(HttpContext.Current, "system.webServer/staticContent"); Microsoft.Web.Administration.ConfigurationElementCollection staticContentCollection = staticContentSection.GetCollection(); var mt = staticContentCollection.Where( a => a.Attributes["fileExtension"].Value.ToString().ToLower() == file.Extension.ToLower() ).FirstOrDefault(); if (mt != null) { response.ContentType = mt.GetAttributeValue("mimeType").ToString(); } else { response.ContentType = "application/octet-stream"; } } // // Set a content disposition if it is not already set by the application // if (response.Headers["Content-Disposition"] == null) { response.AppendHeader("Content-Disposition", "inline;filename=" + file.Name); } // // Send the file without loading it into memory // response.TransmitFile(file.FullName); } } }
public void RunDeploy(String[] args) { if (args.Length < 3) { Console.Error.WriteLine("rdfWebDeploy: Error: 3 Arguments are required in order to use the -deploy mode, type rdfWebDeploy -help to see usage summary"); return; } if (args.Length > 3) { if (!this.SetOptions(args.Skip(3).ToArray())) { Console.Error.WriteLine("rdfWebDeploy: Deployment aborted since one/more options were not valid"); return; } } if (this._noLocalIIS) { Console.WriteLine("rdfWebDeploy: No Local IIS Server available so switching to -xmldeploy mode"); XmlDeploy xdeploy = new XmlDeploy(); xdeploy.RunXmlDeploy(args); return; } //Define the Server Manager object Admin.ServerManager manager = null; try { //Connect to the Server Manager if (!this._noIntegratedRegistration) { manager = new Admin.ServerManager(); } //Open the Configuration File System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration(args[1], this._site); Console.Out.WriteLine("rdfWebDeploy: Opened the Web.config file for the specified Web Application"); //Detect Folders String appFolder = Path.GetDirectoryName(config.FilePath); String binFolder = Path.Combine(appFolder, "bin\\"); String appDataFolder = Path.Combine(appFolder, "App_Data\\"); if (!Directory.Exists(binFolder)) { Directory.CreateDirectory(binFolder); Console.WriteLine("rdfWebDeploy: Created a bin\\ directory for the web application"); } if (!Directory.Exists(appDataFolder)) { Directory.CreateDirectory(appDataFolder); Console.WriteLine("rdfWebDeploy: Created an App_Data\\ directory for the web application"); } //Deploy dotNetRDF and required DLLs to the bin directory of the application String sourceFolder = RdfWebDeployHelper.ExecutablePath; IEnumerable <String> dlls = RdfWebDeployHelper.RequiredDLLs; if (this._sql) { dlls = dlls.Concat(RdfWebDeployHelper.RequiredSqlDLLs); } if (this._virtuoso) { dlls = dlls.Concat(RdfWebDeployHelper.RequiredVirtuosoDLLs); } if (this._fulltext) { dlls = dlls.Concat(RdfWebDeployHelper.RequiredFullTextDLLs); } foreach (String dll in dlls) { if (File.Exists(Path.Combine(sourceFolder, dll))) { File.Copy(Path.Combine(sourceFolder, dll), Path.Combine(binFolder, dll), true); Console.WriteLine("rdfWebDeploy: Deployed " + dll + " to the web applications bin directory"); } else { Console.Error.WriteLine("rdfWebDeploy: Error: Required DLL " + dll + " which needs deploying to the web applications bin directory could not be found"); return; } } //Deploy the configuration file to the App_Data directory if (File.Exists(args[2])) { File.Copy(args[2], Path.Combine(appDataFolder, args[2]), true); Console.WriteLine("rdfWebDeploy: Deployed the configuration file to the web applications App_Data directory"); } else if (!File.Exists(Path.Combine(appDataFolder, args[2]))) { Console.Error.WriteLine("rdfWebDeploy: Error: Unable to continue deployment as the configuration file " + args[2] + " could not be found either locally for deployment to the App_Data folder or already present in the App_Data folder"); return; } //Set the AppSetting for the configuration file config.AppSettings.Settings.Remove("dotNetRDFConfig"); config.AppSettings.Settings.Add("dotNetRDFConfig", "~/App_Data/" + Path.GetFileName(args[2])); Console.WriteLine("rdfWebDeploy: Set the \"dotNetRDFConfig\" appSetting to \"~/App_Data/" + Path.GetFileName(args[2]) + "\""); //Now load the Configuration Graph from the App_Data folder Graph g = new Graph(); FileLoader.Load(g, Path.Combine(appDataFolder, args[2])); Console.WriteLine("rdfWebDeploy: Successfully deployed required DLLs and appSettings"); Console.WriteLine(); //Get the sections of the Configuration File we want to edit HttpHandlersSection handlersSection = config.GetSection("system.web/httpHandlers") as HttpHandlersSection; if (handlersSection == null) { Console.Error.WriteLine("rdfWebDeploy: Error: Unable to access the Handlers section of the web applications Web.Config file"); return; } //Detect Handlers from the Configution Graph and deploy IUriNode rdfType = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType)); IUriNode dnrType = g.CreateUriNode(new Uri(ConfigurationLoader.PropertyType)); IUriNode httpHandler = g.CreateUriNode(new Uri(ConfigurationLoader.ClassHttpHandler)); //Deploy for IIS Classic Mode if (!this._noClassicRegistration) { Console.WriteLine("rdfWebDeploy: Attempting deployment for IIS Classic Mode"); foreach (INode n in g.GetTriplesWithPredicateObject(rdfType, httpHandler).Select(t => t.Subject)) { if (n.NodeType == NodeType.Uri) { String handlerPath = ((IUriNode)n).Uri.AbsolutePath; INode type = g.GetTriplesWithSubjectPredicate(n, dnrType).Select(t => t.Object).FirstOrDefault(); if (type == null) { Console.Error.WriteLine("rdfWebDeploy: Error: Cannot deploy the Handler <" + n.ToString() + "> as there is no dnr:type property specified"); continue; } if (type.NodeType == NodeType.Literal) { String handlerType = ((ILiteralNode)type).Value; //First remove any existing registration handlersSection.Handlers.Remove("*", handlerPath); //Then add the new registration handlersSection.Handlers.Add(new HttpHandlerAction(handlerPath, handlerType, "*")); Console.WriteLine("rdfWebDeploy: Deployed the Handler <" + n.ToString() + "> to the web applications Web.Config file"); } else { Console.Error.WriteLine("rdfWebDeploy: Error: Cannot deploy the Handler <" + n.ToString() + "> as the value given for the dnr:type property is not a Literal"); continue; } } else { Console.Error.WriteLine("rdfWebDeploy: Error: Cannot deploy a Handler which is not specified as a URI Node"); } } //Deploy Negotiate by File Extension if appropriate if (this._negotiate) { HttpModulesSection modulesSection = config.GetSection("system.web/httpModules") as HttpModulesSection; if (modulesSection == null) { Console.Error.WriteLine("rdfWebDeploy: Error: Unable to access the Modules section of the web applications Web.Config file"); return; } modulesSection.Modules.Remove("NegotiateByExtension"); modulesSection.Modules.Add(new HttpModuleAction("NegotiateByExtension", "VDS.RDF.Web.NegotiateByFileExtension")); Console.WriteLine("rdfWebDeploy: Deployed the Negotiate by File Extension Module"); } Console.WriteLine("rdfWebDeploy: Successfully deployed for IIS Classic Mode"); } //Save the completed Configuration File config.Save(ConfigurationSaveMode.Minimal); Console.WriteLine(); //Deploy for IIS Integrated Mode if (!this._noIntegratedRegistration) { Console.WriteLine("rdfWebDeploy: Attempting deployment for IIS Integrated Mode"); Admin.Configuration adminConfig = manager.GetWebConfiguration(this._site, args[1]); Admin.ConfigurationSection newHandlersSection = adminConfig.GetSection("system.webServer/handlers"); Admin.ConfigurationElementCollection newHandlers = newHandlersSection.GetCollection(); foreach (INode n in g.GetTriplesWithPredicateObject(rdfType, httpHandler).Select(t => t.Subject)) { if (n.NodeType == NodeType.Uri) { String handlerPath = ((IUriNode)n).Uri.AbsolutePath; INode type = g.GetTriplesWithSubjectPredicate(n, dnrType).Select(t => t.Object).FirstOrDefault(); if (type == null) { Console.Error.WriteLine("rdfWebDeploy: Error: Cannot deploy the Handler <" + n.ToString() + "> as there is no dnr:type property specified"); continue; } if (type.NodeType == NodeType.Literal) { String handlerType = ((ILiteralNode)type).Value; //First remove any existing registration foreach (Admin.ConfigurationElement oldReg in newHandlers.Where(el => el.GetAttributeValue("name").Equals(handlerPath)).ToList()) { newHandlers.Remove(oldReg); } //Then add the new registration Admin.ConfigurationElement reg = newHandlers.CreateElement("add"); reg["name"] = handlerPath; reg["path"] = handlerPath; reg["verb"] = "*"; reg["type"] = handlerType; newHandlers.AddAt(0, reg); Console.WriteLine("rdfWebDeploy: Deployed the Handler <" + n.ToString() + "> to the web applications Web.Config file"); } else { Console.Error.WriteLine("rdfWebDeploy: Error: Cannot deploy the Handler <" + n.ToString() + "> as the value given for the dnr:type property is not a Literal"); continue; } } else { Console.Error.WriteLine("rdfWebDeploy: Error: Cannot deploy a Handler which is not specified as a URI Node"); } //Deploy Negotiate by File Extension if appropriate if (this._negotiate) { Admin.ConfigurationSection newModulesSection = adminConfig.GetSection("system.webServer/modules"); if (newModulesSection == null) { Console.Error.WriteLine("rdfWebDeploy: Error: Unable to access the Modules section of the web applications Web.Config file"); return; } //First remove the Old Module Admin.ConfigurationElementCollection newModules = newModulesSection.GetCollection(); foreach (Admin.ConfigurationElement oldReg in newModules.Where(el => el.GetAttribute("name").Equals("NegotiateByExtension")).ToList()) { newModules.Remove(oldReg); } //Then add the new Module Admin.ConfigurationElement reg = newModules.CreateElement("add"); reg["name"] = "NegotiateByExtension"; reg["type"] = "VDS.RDF.Web.NegotiateByFileExtension"; newModules.AddAt(0, reg); Console.WriteLine("rdfWebDeploy: Deployed the Negotiate by File Extension Module"); } } manager.CommitChanges(); Console.WriteLine("rdfWebDeploy: Successfully deployed for IIS Integrated Mode"); } } catch (ConfigurationException configEx) { Console.Error.WriteLine("rdfWebDeploy: Configuration Error: " + configEx.Message); } catch (Exception ex) { Console.Error.WriteLine("rdfWebDeploy: Error: " + ex.Message); Console.Error.WriteLine(ex.StackTrace); } finally { if (manager != null) { manager.Dispose(); } } }
private void context_EndRequest(object sender, EventArgs e) { HttpResponse response = HttpContext.Current.Response; HttpRequest request = HttpContext.Current.Request; // // Check for the X-Send headers // string filePath = response.Headers.Get("X-Sendfile"); if (filePath == null) { filePath = response.Headers.Get("X-Accel-Redirect"); } if (filePath != null) { // // Determine the file path and ready the response // if (ConfigurationManager.AppSettings["XSendDir"] != null) { filePath = Path.Combine(ConfigurationManager.AppSettings["XSendDir"], filePath); // if there is a base path set (file will be located above this) } else if (ConfigurationManager.AppSettings["XAccelLocation"] != null) { filePath = filePath.Replace(ConfigurationManager.AppSettings["XAccelLocation"], ConfigurationManager.AppSettings["XAccelRoot"]); } response.Clear(); // Clears output buffer response.Headers.Remove("X-Sendfile"); // Remove unwanted headers response.Headers.Remove("X-Accel-Redirect"); // // Set the cache policy // if (ConfigurationManager.AppSettings["XSendCache"] == null) { response.Cache.SetCacheability(HttpCacheability.NoCache); } else if (ConfigurationManager.AppSettings["XSendCache"] == "Public") { response.Cache.SetCacheability(HttpCacheability.Public); } else { response.Cache.SetCacheability(HttpCacheability.Private); } // // Get the file information and set headers appropriately // if (!FileUtil.FileExists(filePath)) { throw new HttpException(404, "File_does_not_exist"); } if (filePath[filePath.Length - 1] == '.') { throw new HttpException(404, "File_does_not_exist"); } FileInfo file = new FileInfo(filePath); response.Cache.SetLastModified(file.LastWriteTimeUtc); response.Headers.Remove("Content-Length"); DateTime dateTime = new DateTime(file.LastWriteTime.Year, file.LastWriteTime.Month, file.LastWriteTime.Day, file.LastWriteTime.Hour, file.LastWriteTime.Minute, file.LastWriteTime.Second, 0); DateTime now = DateTime.Now; string range = request.Headers["Range"]; // // Call into .net static file handler to do the heavy lifting for us // Massive hacks. Should work for all version of .net // // http://dotnetinside.com/framework/v2.0.50727/System.Web/StaticFileHandler // http://typedescriptor.net/browse/types/7243-System.Web.StaticFileHandler // http://stackoverflow.com/questions/7829478/how-to-execute-a-private-static-method-with-optional-parameters-via-reflection // // var genEtag = typeof(System.Web.StaticFileHandler).GetMethod("GenerateETag", BindingFlags.Static | BindingFlags.NonPublic); string etag = genEtag.Invoke(obj: null, parameters: new object[] { HttpContext.Current, dateTime, now }); var rangeRequest = typeof(System.Web.StaticFileHandler).GetMethod("ProcessRangeRequest", BindingFlags.Static | BindingFlags.NonPublic); if (StringUtil.StringStartsWithIgnoreCase(range, "bytes") && rangeRequest.Invoke(obj: null, parameters: new object[] { HttpContext.Current, filePath, file.Length, range, etag, dateTime })) { return; } response.AddHeader("Content-Length", file.Length.ToString()); response.AppendHeader("Accept-Ranges", "bytes"); response.Cache.SetIgnoreRangeRequests(); // // Check if we want to detect the mime type of the current content // if (ConfigurationManager.AppSettings["XSendMime"] == null) { Microsoft.Web.Administration.ConfigurationSection staticContentSection = WebConfigurationManager.GetSection(HttpContext.Current, "system.webServer/staticContent"); Microsoft.Web.Administration.ConfigurationElementCollection staticContentCollection = staticContentSection.GetCollection(); var mt = staticContentCollection.Where( a => a.Attributes["fileExtension"].Value.ToString().ToLower() == file.Extension.ToLower() ).FirstOrDefault(); if (mt != null) { response.ContentType = mt.GetAttributeValue("mimeType").ToString(); } else { response.ContentType = "application/octet-stream"; } } // // Set a content disposition if it is not already set by the application // if (response.Headers["Content-Disposition"] == null) { response.AppendHeader("Content-Disposition", "inline;filename=" + file.Name); } // // Send the file without loading it into memory // response.TransmitFile(file.FullName); } }