Hello, I'm trying to create a simple Mono program that is configured as an external filter that simply reads from stdin and writes to stdout a modified version of a media file (images, videos...). Prior to reading from stdin I'm trying to craft a POC which simply replaces all requests' content with a hardcoded file ("Capture.PNG" in my case). The problem is that a timeout always occurs when I do this. [Wed Apr 13 11:26:51.906231 2016] [ext_filter:error] [pid 1899:tid 139929490360064] (70007)The timeout specified has expired: [client 10.0.216.137:15328] AH01466: apr_file_read(child output), len 18446744073709551615 [Wed Apr 13 11:26:51.906342 2016] [ext_filter:error] [pid 1899:tid 139929490360064] (70007)The timeout specified has expired: [client 10.0.216.137:15328] AH01468: ef_unified_filter() failed However, if I replace the filter line with this: "/bin/cat /var/www/html/Capture.PNG" it will always work correctly. Can anyone shed some light on this? Thank you in advance. PD. Find enclosed the source code and apache configuration I'm using. I'm also running Apache 2.4.7 on Ubuntu Server 14.04 which comes by default.
using System; using System.IO; namespace ApacheFilterExample1 { class Program { #if WINDOWS const string Sample1 = @"C:\Apache24\htdocs\Capture.PNG"; #else const string Sample1 = "/var/www/html/Capture.PNG"; #endif static int Main(string[] args) { try { byte[] bytes; using (Stream output = System.Console.OpenStandardOutput()) { bytes = File.ReadAllBytes(Sample1); output.Write(bytes, 0, bytes.Length); } Console.Error.WriteLine(String.Format("{0} bytes written.", bytes.Length.ToString())); return 0; } catch (Exception e) { Console.Error.WriteLine(e.Message); return -1; } } } }
using System; using System.IO; namespace ApacheFilterExample2 { class Program { #if WINDOWS const string Success = @"C:\Apache24\htdocs\Capture.PNG"; const string Failure = @"C:\Apache24\htdocs\Capture2.PNG"; #else const string Success = "/var/www/html/Capture.PNG"; const string Failure = "/var/www/html/Capture2.PNG"; #endif static int Main(string[] args) { try { //// if nothing is being piped in, then exit (not working correctly) //if (!IsPipedInput()) //{ // Console.Error.WriteLine("Nothing being piped in, waiting..."); // Thread.Sleep(250); // //return 0; //} Console.Error.WriteLine("Waiting for input."); byte[] fileBytes; if (System.Console.In.Peek() != -1) { Console.Error.WriteLine("Input available, opening stream..."); using (Stream s = System.Console.OpenStandardInput()) { Console.Error.WriteLine("Input stream open, reading from stream..."); byte[] buffer = new byte[4096]; using (MemoryStream ms = new MemoryStream()) { int read; while ((read = s.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, buffer.Length); } fileBytes = ms.ToArray(); Console.Error.WriteLine(String.Format("{0} bytes read from input stream. Opening output stream...", fileBytes.Length.ToString())); } } using (Stream output = System.Console.OpenStandardOutput()) { fileBytes = File.ReadAllBytes(Success); output.Write(fileBytes, 0, fileBytes.Length); Console.Error.WriteLine(String.Format("{0} bytes written to output stream.", fileBytes.Length.ToString())); output.Dispose(); } } else { Console.Error.WriteLine("Error, no data available to read."); using (Stream output = System.Console.OpenStandardOutput()) { fileBytes = File.ReadAllBytes(Failure); output.Write(fileBytes, 0, fileBytes.Length); Console.Error.WriteLine(String.Format("{0} bytes written to output stream (NO INPUT).", fileBytes.Length.ToString())); output.Dispose(); } } return 0; } catch (Exception ex) { Console.Error.WriteLine(String.Format("Error: \n{0}", ex.ToString())); using (Stream output = System.Console.OpenStandardOutput()) { byte[] fileBytes = File.ReadAllBytes(Failure); output.Write(fileBytes, 0, fileBytes.Length); Console.Error.WriteLine(String.Format("{0} bytes written to output stream (ERROR).", fileBytes.Length.ToString())); output.Dispose(); } return 0; } } private static bool IsPipedInput() { try { bool isKey = System.Console.KeyAvailable; return false; } catch { return true; } } } }
Attachment:
apache2.conf
Description: apache2.conf
Attachment:
FilterScript.sh
Description: FilterScript.sh
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx For additional commands, e-mail: users-help@xxxxxxxxxxxxxxxx