protected void Page_Load(object Sender, EventArgs E) { // Pull out the http request HttpRequest request = HttpContext.Current.Request; if (String.IsNullOrEmpty(SobekCM_Database.Connection_String)) { Custom_Tracer tracer = new Custom_Tracer(); try { tracer.Add_Trace("SobekCM_Page_Globals.Constructor", String.Empty); // Don't really need to *build* these, so just define them as a new ones if null if (Global.Checked_List == null) { Global.Checked_List = new Checked_Out_Items_List(); } if (Global.Search_History == null) { Global.Search_History = new Recent_Searches(); } // Make sure all the needed data is loaded into the Application State Application_State_Builder.Build_Application_State(tracer, false, ref Global.Skins, ref Global.Translation, ref Global.Codes, ref Global.Item_List, ref Global.Icon_List, ref Global.Stats_Date_Range, ref Global.Thematic_Headings, ref Global.Collection_Aliases, ref Global.IP_Restrictions, ref Global.URL_Portals, ref Global.Mime_Types, ref Global.Item_Viewer_Priority); tracer.Add_Trace("SobekCM_Page_Globals.Constructor", "Application State validated or built"); // Check that something is saved for the original requested URL (may not exist if not forwarded) if (!HttpContext.Current.Items.Contains("Original_URL")) { HttpContext.Current.Items["Original_URL"] = request.Url.ToString(); } } catch (Exception ee) { // Send to the dashboard if ((HttpContext.Current.Request.UserHostAddress == "127.0.0.1") || (HttpContext.Current.Request.UserHostAddress == HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"]) || (HttpContext.Current.Request.Url.ToString().IndexOf("localhost") >= 0)) { // Create an error message string errorMessage; if ((SobekCM_Library_Settings.Database_Connections.Count == 0) || (String.IsNullOrEmpty(SobekCM_Library_Settings.Database_Connections[0].Connection_String))) { errorMessage = "No database connection string found!"; string configFileLocation = AppDomain.CurrentDomain.BaseDirectory + "config/sobekcm.xml"; try { if (!File.Exists(configFileLocation)) { errorMessage = "Missing config/sobekcm.xml configuration file on the web server.<br />Ensure the configuration file 'sobekcm.xml' exists in a 'config' subfolder directly under the web application.<br />Example configuration is:" + "<div style=\"background-color: #bbbbbb; margin-left: 30px; margin-top:10px; padding: 3px;\"><?xml version="1.0" encoding="UTF-8" standalone="yes" ?><br /> <configuration><br />   <connection_string type="MSSQL">data source=localhost\\instance;initial catalog=SobekCM;integrated security=Yes;</connection_string><br />   <error_emails>[email protected]</error_emails><br />   <error_page>http://ufdc.ufl.edu/error.html</error_page><br /></configuration></div>"; } } catch { errorMessage = "No database connection string found.<br />Likely an error reading the configuration file due to permissions on the web server.<br />Ensure the configuration file 'sobekcm.xml' exists in a 'config' subfolder directly under the web application.<br />Example configuration is:" + "<div style=\"background-color: #bbbbbb; margin-left: 30px; margin-top:10px; padding: 3px;\"><?xml version="1.0" encoding="UTF-8" standalone="yes" ?><br /> <configuration><br />   <connection_string type="MSSQL">data source=localhost\\instance;initial catalog=SobekCM;integrated security=Yes;</connection_string><br />   <error_emails>[email protected]</error_emails><br />   <error_page>http://ufdc.ufl.edu/error.html</error_page><br /></configuration></div>"; } } else { if (ee.Message.IndexOf("The EXECUTE permission") >= 0) { errorMessage = "Permissions error while connecting to the database and pulling necessary data.<br /><br />Confirm the following:<ul><li>IIS is configured correctly to use anonymous authentication</li><li>Anonymous user (or service account) is part of the sobek_users role in the database.</li></ul>"; } else { errorMessage = "Error connecting to the database and pulling necessary data.<br /><br />Confirm the following:<ul><li>Database connection string is correct ( " + SobekCM_Library_Settings.Database_Connections[0].Connection_String + ")</li><li>IIS is configured correctly to use anonymous authentication</li><li>Anonymous user (or service account) is part of the sobek_users role in the database.</li></ul>"; } } // Wrap this into the SobekCM Exception SobekCM_Traced_Exception newException = new SobekCM_Traced_Exception(errorMessage, ee, tracer); // Save this to the session state, and then forward to the dashboard HttpContext.Current.Session["Last_Exception"] = newException; HttpContext.Current.Response.Redirect("dashboard.aspx", true); } else { throw ee; } } } string bibID = null; string vid = null; // Is this a robot? They should never get access to files this way if (SobekCM_Navigation_Object.Is_UserAgent_IP_Robot(request.UserAgent, request.UserHostAddress)) { Response.Clear(); Response.Output.WriteLine("RESTRICTED ITEM"); return; } // Get any url rewrite which occurred if (Request.QueryString["urlrelative"] != null) { string urlrewrite = Request.QueryString["urlrelative"].ToLower(); if (urlrewrite.Length > 4) { // Split the url relative list string[] url_relative_info = urlrewrite.Split("/".ToCharArray()); List <string> url_relative_list = (from thisPart in url_relative_info where thisPart.Length > 0 select thisPart.ToLower()).ToList(); // Now, look for BIBID and VID //if ((SobekCM_Database.Verify_Item_Lookup_Object(true, ref Global.Item_List, null)) && (Global.Item_List.Contains_BibID(url_relative_list[2].ToUpper()))) if ((url_relative_list.Count > 2) && (url_relative_list[2].Length == 10)) { // This is a BibID for an existing title with at least one public item bibID = url_relative_list[2].ToUpper(); // Is the next part a VID? if (url_relative_list.Count > 3) { string possible_vid = url_relative_list[3].Trim().PadLeft(5, '0'); int vid_as_int; if (Int32.TryParse(possible_vid, out vid_as_int)) { vid = possible_vid; } } } // Only continue if there is a BibID / VID if ((!String.IsNullOrEmpty(bibID)) && (!String.IsNullOrEmpty(vid))) { // Determine the new URL StringBuilder urlBuilder = new StringBuilder(SobekCM_Library_Settings.Image_Server_Network + bibID.Substring(0, 2) + "\\" + bibID.Substring(2, 2) + "\\" + bibID.Substring(4, 2) + "\\" + bibID.Substring(6, 2) + "\\" + bibID.Substring(8) + "\\" + vid + "\\" + url_relative_list[4], 250); for (int i = 5; i < url_relative_list.Count; i++) { urlBuilder.Append("\\" + url_relative_list[i]); } file_url = urlBuilder.ToString(); // Get the extension string extension = Path.GetExtension(file_url); if (extension != null) { // Lookup the MIME type by extension Mime_Type_Info mimeType = null; if (Global.Mime_Types.ContainsKey(extension.ToLower())) { mimeType = Global.Mime_Types[extension.ToLower()]; } if ((mimeType != null) && (!mimeType.isBlocked)) { // Since everything is valid, check the database bool isDark; short restrictions; SobekCM_Database.Get_Item_Restrictions(bibID, vid, null, out isDark, out restrictions); // If not DARK, and is restricted, check for access here if ((!isDark) && (restrictions > 0)) { // Does this user already have IP restriction mask determined? // Determine which IP Ranges this IP address belongs to, if not already determined. if (HttpContext.Current.Session["IP_Range_Membership"] == null) { int ip_mask = Global.IP_Restrictions.Restrictive_Range_Membership(request.UserHostAddress); HttpContext.Current.Session["IP_Range_Membership"] = ip_mask; } int current_user_mask = Convert.ToInt32(HttpContext.Current.Session["IP_Range_Membership"]); // Perform bitwise comparison int comparison = restrictions & current_user_mask; if (comparison == 0) { // If the user is Shibboleth authenticated, that is okay User_Object possible_user = HttpContext.Current.Session["user"] as User_Object; if ((possible_user == null) || (possible_user.Authentication_Type != User_Authentication_Type_Enum.Shibboleth)) { isDark = true; } } } if (!isDark) { // Should this be forwarded for this mimetype? if (mimeType.shouldForward) { StringBuilder forwardBuilder = new StringBuilder(SobekCM_Library_Settings.Image_URL + bibID.Substring(0, 2) + "/" + bibID.Substring(2, 2) + "/" + bibID.Substring(4, 2) + "/" + bibID.Substring(6, 2) + "/" + bibID.Substring(8) + "/" + vid + "/" + url_relative_list[4], 250); for (int i = 5; i < url_relative_list.Count; i++) { forwardBuilder.Append("/" + url_relative_list[i]); } Response.Redirect(forwardBuilder.ToString()); } else { Response.Clear(); Response.ContentType = mimeType.MIME_Type; string filename = file_url; if (File.Exists(filename)) { using (FileStream sourceStream = File.OpenRead(filename)) { sourceStream.CopyTo(Response.OutputStream, 32768); } } Response.End(); } } else { Response.Clear(); Response.Output.WriteLine("RESTRICTED ITEM"); } } } } } } //public static async Task CopyToAsync(this Stream source, Stream destination) //{ // int i = 0; // var buffers = new [] { new byte[0x1000], new byte[0x1000] }; // Task writeTask = null; // while(true) // { // var readTask = source.ReadAsync(buffers[i], 0, buffers[i].Length))>0; // if (writeTask != null) await Task.WhenAll(readTask, writeTask); // int bytesRead = await readTask; // if (bytesRead == 0) break; // writeTask = destination.WriteAsync(buffers[i], 0, bytesRead); // i ^= 1; // swap buffers // } //} }