/// <summary> /// Gets or creates a TailInfo object that contains information about tailing /// the specified file. /// </summary> /// <param name="context">HttpContext object</param> /// <param name="fileName">The name of the file to tail.</param> /// <param name="lines">The number of lines to return on the initial request.</param> /// <returns>A TailInfo object that is saved on the session.</returns> private TailInfo GetTailInfo(HttpContext context, string fileName, int lines) { TailInfo ti = null; // Is there already tail information on the session? Hashtable ht = context.Session["TailInfo"] as Hashtable; if (ht == null) { context.Session["TailInfo"] = ht = new Hashtable(); } // See if there is information for this file in the hashtable. if (ht.ContainsKey(fileName)) { ti = ht[fileName] as TailInfo; } else { ht[fileName] = ti = new TailInfo(lines, -1); } return(ti); }
public void TailInfo_Test() { var tailinfo = new TailInfo(1000000); tailinfo.LastTail.ToShortDateString().Should().Be(DateTime.Now.ToShortDateString()); }
/// <summary> /// Enables processing of HTTP Web requests by a custom HttpHandler /// that implements the IHttpHandler interface. /// </summary> /// <param name="context">An HttpContext object that provides /// references to the intrinsic server objects (for example, /// Request, Response, Session, and Server) used to service HTTP requests.</param> public void ProcessRequest(HttpContext context) { // Setup the response. HttpRequest request = context.Request; HttpResponse response = context.Response; try { // Only respond to GET method. if (String.Compare(request.HttpMethod, "GET", true) == 0) { // The file name of the url is the file that is to be downloaded. string fileName = Path.GetFileName(request.Url.LocalPath); iFolderAdmin web = context.Session["Connection"] as iFolderAdmin; if (web == null) { context.Response.Redirect("Login.aspx"); } // Get the size of the file. long fileSize = GetFileSize(web, fileName); // New requests will contain the number of lines to send back. int lines = GetLineCount(request); // Get information about tailing the specified file. TailInfo ti = GetTailInfo(context, fileName, lines); // Get the line data. int length; ArrayList lineData = GetTailData(web, fileName, fileSize, ti, out length); // Setup the response. response.Clear(); response.BufferOutput = false; response.Cache.SetCacheability(HttpCacheability.NoCache); response.ContentType = "text/plain"; response.AddHeader("Content-Length", length.ToString()); foreach (byte[] line in lineData) { response.OutputStream.Write(line, 0, line.Length); } response.Close(); } else { log.Debug(context, "Error: Invalid http method - {0}", request.HttpMethod); response.StatusCode = ( int )HttpStatusCode.BadRequest; response.Close(); } } catch (Exception ex) { log.Debug(context, "Error: {0}", ex.Message); log.Debug(context, "Stack trace: {0}", ex.StackTrace); response.StatusCode = ( int )HttpStatusCode.InternalServerError; response.Close(); } }
/// <summary> /// Gets the specified tail data. /// </summary> /// <param name="web">iFolderAdmin object</param> /// <param name="fileName">The name of the file to tail.</param> /// <param name="fileLength">The current length of the file.</param> /// <param name="ti">The tail information saved on the session.</param> /// <param name="length">Receives the total length of the data in the ArrayList.</param> /// <returns>An array of byte arrays containing file data.</returns> private ArrayList GetTailData(iFolderAdmin web, string fileName, long fileLength, TailInfo ti, out int length) { ArrayList tailLines = new ArrayList(ti.Lines); length = 0; // Build the path to the log handler. UriBuilder uri = new UriBuilder(web.Url); uri.Path = String.Format("/simias10/admindata/{0}", fileName); // Is this a first request? if (ti.Offset == -1) { // Have to guess how much data to request. byte[] buffer = new byte[ti.Lines * 256]; // Read one buffer size from the end of the file. long readLength = (fileLength > buffer.Length) ? buffer.Length : fileLength; // Calculate the offset to read from. ti.Offset = fileLength - readLength; // Add the query string part. uri.Query = String.Format("offset={0}&length={1}", ti.Offset, readLength); // Build the web request to get the data. HttpWebRequest webRequest = WebRequest.Create(uri.Uri) as HttpWebRequest; webRequest.Method = "GET"; webRequest.PreAuthenticate = true; webRequest.Credentials = web.Credentials; webRequest.CookieContainer = web.CookieContainer; HttpWebResponse webResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream sr = webResponse.GetResponseStream(); int bytesRead = sr.Read(buffer, 0, ( int )readLength); if (bytesRead > 0) { // Get the specified number of lines until the data is all read. for (int lines = 0, eob = bytesRead - 1; (lines < ti.Lines) && (eob >= 0); ++lines) { byte[] line = GetLineData(buffer, eob, true); if (line.Length > 0) { tailLines.Add(line); eob -= line.Length; length += line.Length; } else { // No lines exist in the buffer. Return no data. eob = -1; } } // If any data was returned, update the offset. if (tailLines.Count > 0) { ti.Offset += bytesRead; tailLines.Reverse(); } } } finally { webResponse.Close(); } } else { // See if there is data to read. long readLength = fileLength - ti.Offset; if (readLength > 0) { // Make sure the read request is not too large. if (readLength > BufferSize) { readLength = BufferSize; } // Read to the end of the file. byte[] buffer = new byte[readLength]; // Add the query string part. uri.Query = String.Format("offset={0}&length={1}", ti.Offset, readLength); // Build the web request to get the data. HttpWebRequest webRequest = WebRequest.Create(uri.Uri) as HttpWebRequest; webRequest.Method = "GET"; webRequest.PreAuthenticate = true; webRequest.Credentials = web.Credentials; webRequest.CookieContainer = web.CookieContainer; HttpWebResponse webResponse = webRequest.GetResponse() as HttpWebResponse; try { Stream sr = webResponse.GetResponseStream(); int bytesRead = sr.Read(buffer, 0, ( int )readLength); if (bytesRead > 0) { // Get the specified number of lines until the data is all read. for (int eob = bytesRead - 1; eob >= 0;) { byte[] line = GetLineData(buffer, eob, false); if (line.Length > 0) { tailLines.Add(line); eob -= line.Length; length += line.Length; } else { // No lines exist in the buffer. Return no data. eob = -1; } } // If any data was returned, update the offset. if (tailLines.Count > 0) { ti.Offset += length; tailLines.Reverse(); } } } finally { webResponse.Close(); } } } return(tailLines); }