From f91f4738ea6694cf66cb92e70b2c9136f116a4f1 Mon Sep 17 00:00:00 2001
From: Andreas Katzig <akatzig@chimera-entertainment.de>
Date: Mon, 13 Jun 2016 14:34:10 +0200
Subject: [PATCH 1/4] Use TryParse to read the PortNumber from the fast cgi
 request

---
 .../AppHosts/AspNet/AspNetNativeWebRequest.cs | 23 ++++++++++++-------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
index 96474d4..dfd85d2 100644
--- a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
+++ b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
@@ -84,14 +84,21 @@ static AspNetNativeWebRequest ()
 		private int input_data_offset;
 
 		public int PortNumber {
-			get {
-				if (port < 0)
-					//FIXME: tryparse
-					port = int.Parse (GetParameter (
-						"SERVER_PORT"));
-
-				return port;
-			}
+			get
+			{
+			    if (port < 0)
+			    {
+			        if (!int.TryParse(GetParameter("SERVER_PORT"), out port))
+			        {
+                        Logger.Write(LogLevel.Error, "fastcgi_param 'SERVER_PORT' not set! Setting to default value '80'! "
+                            + "Please add 'fastcgi_param SERVER_PORT $server_port;' to your webserver config!");
+			            port = 80;
+			        }
+
+			    }
+
+                return port;
+            }
 		}
 
 		public string Path {

From 3e3987c42306e338f72b04d89c5778cd524bcb8f Mon Sep 17 00:00:00 2001
From: Andreas Katzig <akatzig@chimera-entertainment.de>
Date: Mon, 13 Jun 2016 14:35:54 +0200
Subject: [PATCH 2/4] Using string.IsNullOrEmpty more often in
 AspNetNativeWebRequest

---
 .../AppHosts/AspNet/AspNetNativeWebRequest.cs    | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
index dfd85d2..e3565b6 100644
--- a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
+++ b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
@@ -317,7 +317,7 @@ public override string GetRawUrl ()
 
 			StringBuilder b = new StringBuilder (GetUriPath ());
 			string query = GetQueryString ();
-			if (query != null && query.Length > 0) {
+			if (!string.IsNullOrEmpty(query)) {
 				b.Append ('?');
 				b.Append (query);
 			}
@@ -344,17 +344,17 @@ public override string GetHttpVersion ()
 		public override string GetLocalAddress ()
 		{
 			string address = GetParameter ("SERVER_ADDR");
-			if (address != null && address.Length > 0)
+			if (!string.IsNullOrEmpty(address))
 				return address;
 
 			address = AddressFromHostName (
 				GetParameter ("HTTP_HOST"));
-			if (address != null && address.Length > 0)
+			if (!string.IsNullOrEmpty(address))
 				return address;
 
 			address = AddressFromHostName (
 				GetParameter ("SERVER_NAME"));
-			if (address != null && address.Length > 0)
+			if (!string.IsNullOrEmpty(address))
 				return address;
 
 			return base.GetLocalAddress ();
@@ -385,7 +385,7 @@ public override byte [] GetQueryStringRawBytes ()
 		public override string GetRemoteAddress ()
 		{
 			string addr = GetParameter ("REMOTE_ADDR");
-			return addr != null && addr.Length > 0 ?
+			return !string.IsNullOrEmpty(addr) ?
 				addr : base.GetRemoteAddress ();
 		}
 
@@ -406,7 +406,7 @@ public override string GetRemoteName ()
 		public override int GetRemotePort ()
 		{
 			string port = GetParameter ("REMOTE_PORT");
-			if (port == null || port.Length == 0)
+			if (string.IsNullOrEmpty(port))
 				return base.GetRemotePort ();
 
 			try {
@@ -423,7 +423,7 @@ public override string GetServerVariable (string name)
 			if (value == null)
 				value = Environment.GetEnvironmentVariable (name);
 
-			return value != null ? value : base.GetServerVariable (name);
+			return value ?? base.GetServerVariable (name);
 		}
 
 		public override string GetUriPath ()
@@ -577,7 +577,7 @@ private static string AddressFromHostName (string host)
 
 		private static string HostNameFromString (string host)
 		{
-			if (host == null || host.Length == 0)
+			if (string.IsNullOrEmpty(host))
 				return null;
 
 			int colon_index = host.IndexOf (':');

From 49edfc0b039bf51614a18a7bf3d16d6cd5fcd539 Mon Sep 17 00:00:00 2001
From: Andreas Katzig <akatzig@chimera-entertainment.de>
Date: Mon, 13 Jun 2016 14:51:52 +0200
Subject: [PATCH 3/4] Some minor refactorings for AspNetNativeWebRequest.
 Especially added logging to AddBodyPart

---
 .../AppHosts/AspNet/AspNetNativeWebRequest.cs | 54 ++++++++++++-------
 src/HyperFastCgi/Interfaces/IWebRequest.cs    |  5 +-
 2 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
index e3565b6..ce8d239 100644
--- a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
+++ b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
@@ -88,8 +88,7 @@ public int PortNumber {
 			{
 			    if (port < 0)
 			    {
-			        if (!int.TryParse(GetParameter("SERVER_PORT"), out port))
-			        {
+			        if (!int.TryParse(GetParameter("SERVER_PORT"), out port)) {
                         Logger.Write(LogLevel.Error, "fastcgi_param 'SERVER_PORT' not set! Setting to default value '80'! "
                             + "Please add 'fastcgi_param SERVER_PORT $server_port;' to your webserver config!");
 			            port = 80;
@@ -161,34 +160,48 @@ public void AddHeader (string header, string value)
 			}
 		}
 
+        /// <summary>
+        /// TODO errors can happen here, changing return value to bool and then evaluating the return value outside could help
+        /// </summary>
+        /// <param name="data"></param>
 		public void AddBodyPart (byte[] data)
 		{
 			if (input_data == null) {
-				int len = 0;
+				int len;
 				string slen = GetParameter ("CONTENT_LENGTH");
 
 				if (slen == null) {
-					//TODO: error, throw an exception
+                    //Instead of throwing an Exception, write to error log and return
+                    Logger.Write(LogLevel.Error, "fastcgi_param 'CONTENT_LENGTH' not set! "
+                        + "Please add 'fastcgi_param SERVER_PORT $server_port;' to your webserver config!");
+
+                    return;
 				}
+
 				if (!int.TryParse (slen, NumberStyles.None, CultureInfo.InvariantCulture, out len)) {
-					//TODO: error, throw an exception
+                    Logger.Write(LogLevel.Error, "Invalid CONTENT_LENGTH: {0}", slen);
+
+                    return;
 				}
 
 				input_data = new byte[len];
 			}
 
 			if (input_data_offset + data.Length > input_data.Length) {
-				//TODO: throw an exception
+                //Instead of throwing an Exception, write to error log and return
+                Logger.Write(LogLevel.Error, "Buffer too small: input_data (size {0}) but should be at least {1}", input_data.Length, (input_data_offset + data.Length));
+
+                return;
 			}
 
-			Buffer.BlockCopy (data, 0, input_data, input_data_offset, data.Length);
+            Buffer.BlockCopy (data, 0, input_data, input_data_offset, data.Length);
 			input_data_offset += data.Length;
 		}
 
 		public string GetParameter (string parameter)
 		{
 			if (parameter_table != null && parameter_table.ContainsKey (parameter))
-				return (string)parameter_table [parameter];
+				return parameter_table [parameter];
 
 			return null;
 		}
@@ -275,8 +288,7 @@ public override void SendResponseFromMemory (byte[] data, int length)
 
 		public override void SendStatus (int statusCode, string statusDescription)
 		{
-			AppendHeaderLine ("Status: {0} {1}",
-				statusCode, statusDescription);
+			AppendHeaderLine ("Status: {0} {1}", statusCode, statusDescription);
 		}
 
 		public override void SendUnknownResponseHeader (string name, string value)
@@ -301,7 +313,7 @@ public override bool IsEntireEntityBodyIsPreloaded ()
 
 		public override string GetPathInfo ()
 		{
-			return GetParameter ("PATH_INFO") ?? String.Empty;
+			return GetParameter ("PATH_INFO") ?? string.Empty;
 		}
 
 		public override string GetRawUrl ()
@@ -420,7 +432,7 @@ public override string GetServerVariable (string name)
 		{
 			string value = GetParameter (name);
 
-			if (value == null)
+			if (value == null && name != null)
 				value = Environment.GetEnvironmentVariable (name);
 
 			return value ?? base.GetServerVariable (name);
@@ -560,7 +572,7 @@ private static string AddressFromHostName (string host)
 			if (host == null || host.Length > 126)
 				return null;
 
-			System.Net.IPAddress[] addresses = null;
+			IPAddress[] addresses = null;
 			try {
 				addresses = Dns.GetHostAddresses (host);
 			} catch (System.Net.Sockets.SocketException) {
@@ -599,15 +611,17 @@ private static void SetDefaultIndexFiles (string list)
 			List<string> files = new List<string> ();
 
 			string [] fs = list.Split (',');
-			foreach (string f in fs) {
-				string trimmed = f.Trim ();
-				if (trimmed == "")
-					continue;
+		    for (int index = 0; index < fs.Length; index++)
+		    {
+		        string f = fs[index];
+		        string trimmed = f.Trim();
+		        if (trimmed == "")
+		            continue;
 
-				files.Add (trimmed);
-			}
+		        files.Add(trimmed);
+		    }
 
-			indexFiles = files.ToArray ();
+		    indexFiles = files.ToArray ();
 		}
 
 		#endregion
diff --git a/src/HyperFastCgi/Interfaces/IWebRequest.cs b/src/HyperFastCgi/Interfaces/IWebRequest.cs
index b219d52..e80ffec 100644
--- a/src/HyperFastCgi/Interfaces/IWebRequest.cs
+++ b/src/HyperFastCgi/Interfaces/IWebRequest.cs
@@ -41,11 +41,12 @@ public interface IWebRequest
 		/// </summary>
 		/// <param name="name">Header name.</param>
 		/// <param name="value">Header value.</param>
-		/// <remarks>This method is called by transport when new header has come<remarks> 
+		/// <remarks>This method is called by transport when new header has come</remarks> 
 		void AddHeader(string name, string value);
 
 		/// <summary>
 		/// Adds the content data
+		/// TODO: Change return value to "bool" to be able to report (buffer) errors?
 		/// </summary>
 		/// <param name="data">content data</param>
 		/// <remarks>The method is called by transport to add the part of content (post) data. 
@@ -62,7 +63,7 @@ public interface IWebRequest
 		/// Processes the request.
 		/// </summary>
 		/// <param name="response">Response</param>
-		/// <remarks>The method is called by transport to process Web Request<remarks>
+		/// <remarks>The method is called by transport to process Web Request</remarks>
 		void Process (IWebResponse response);
 	}
 }

From b48ccfec489f3f221837d2a8612db37aa7de409d Mon Sep 17 00:00:00 2001
From: Andreas Katzig <akatzig@chimera-entertainment.de>
Date: Mon, 13 Jun 2016 15:27:51 +0200
Subject: [PATCH 4/4] Some more smaller refactorings

---
 .../AppHosts/AspNet/AspNetNativeWebRequest.cs | 10 ++--
 .../AppHosts/AspNet/MonoWorkerRequest.cs      | 48 +++++++++----------
 .../AppHosts/Raw/BaseRawRequest.cs            |  8 ++--
 src/HyperFastCgi/Interfaces/IWebResponse.cs   |  4 +-
 4 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
index ce8d239..761746b 100644
--- a/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
+++ b/src/HyperFastCgi/AppHosts/AspNet/AspNetNativeWebRequest.cs
@@ -149,7 +149,7 @@ public AspNetNativeWebRequest (ulong requestId, int requestNumber, IApplicationH
 
 		public void AddHeader (string header, string value)
 		{
-			if (!String.IsNullOrEmpty (header)) {
+			if (!string.IsNullOrEmpty (header)) {
 				int idx = HttpWorkerRequest.GetKnownRequestHeaderIndex (header);
 
 				if (idx != -1) {
@@ -634,16 +634,16 @@ public void Process (IWebResponse response)
 		#endregion
 
 		#region IWebResponse implementation
-		public void Send (int status, string description, IDictionary<string, string> headers)
+		public void Send (int status, string description, IDictionary<string, string> sendHeaders)
 		{
 			SendStatus (status, description);
-			foreach (KeyValuePair<string, string> pair in headers) {
+			foreach (KeyValuePair<string, string> pair in sendHeaders) {
 				SendUnknownResponseHeader (pair.Key, pair.Value);
 			}
 		}
-		public void Send (int status, string description, IDictionary<string, string> headers, byte[] response)
+		public void Send (int status, string description, IDictionary<string, string> sendHeaders, byte[] response)
 		{
-			Send (status, description, headers);
+			Send (status, description, sendHeaders);
 			SendResponseFromMemory (response, response.Length);
 		}
 		public void Send (byte[] response)
diff --git a/src/HyperFastCgi/AppHosts/AspNet/MonoWorkerRequest.cs b/src/HyperFastCgi/AppHosts/AspNet/MonoWorkerRequest.cs
index 0f3f088..ce43c47 100644
--- a/src/HyperFastCgi/AppHosts/AspNet/MonoWorkerRequest.cs
+++ b/src/HyperFastCgi/AppHosts/AspNet/MonoWorkerRequest.cs
@@ -150,7 +150,7 @@ static MonoWorkerRequest ()
 		}
 
 		public MonoWorkerRequest (HyperFastCgi.Interfaces.IApplicationHost appHost)
-			: base (String.Empty, String.Empty, null)
+			: base (string.Empty, string.Empty, null)
 		{
 			if (appHost == null)
 				throw new ArgumentNullException ("appHost");
@@ -256,12 +256,11 @@ public override string MapPath (string path)
 			if (eventResult != null)
 				return eventResult;
 
-			string hostVPath = HostVPath;
+			string currentHostVPath = HostVPath;
 			int hostVPathLen = HostVPath.Length;
 			int pathLen = path != null ? path.Length : 0;
-			bool inThisApp;
 
-			inThisApp = path.StartsWith (hostVPath, StringComparison.Ordinal);
+		    bool inThisApp = path.StartsWith (currentHostVPath, StringComparison.Ordinal);
 
 			if (pathLen == 0 || (inThisApp && (pathLen == hostVPathLen || (pathLen == hostVPathLen + 1 && path [pathLen - 1] == '/')))) {
 				if (needToReplacePathSeparator)
@@ -314,18 +313,14 @@ public void ProcessRequest ()
 				error = ex.GetHtmlErrorMessage ();
 			} catch (Exception ex) {
 				inUnhandledException = true;
-				HttpException hex = new HttpException (400, "Bad request", ex);
-				if (hex != null) // just a precaution
-					error = hex.GetHtmlErrorMessage ();
-				else
-					error = String.Format (defaultExceptionHtml, ex.Message);
+                error = new HttpException(400, "Bad request", ex).GetHtmlErrorMessage();
 			}
 
 			if (!inUnhandledException)
 				return;
 
-			if (error.Length == 0)
-				error = String.Format (defaultExceptionHtml, "Unknown error");
+			if (error != null && error.Length == 0)
+				error = string.Format (defaultExceptionHtml, "Unknown error");
 
 			try {
 				SendStatus (400, "Bad request");
@@ -333,17 +328,20 @@ public void ProcessRequest ()
 				SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
 
 				Encoding enc = Encoding.UTF8;
-				if (enc == null)
-					enc = Encoding.ASCII;
 
-				byte[] bytes = enc.GetBytes (error);
+                SendUnknownResponseHeader("Content-Type", "text/html; charset=" + enc.WebName);
+
+			    if (error != null)
+			    {
+			        byte[] bytes = enc.GetBytes(error);
+			        SendUnknownResponseHeader("Content-Length", bytes.Length.ToString());
+			        SendResponseFromMemory(bytes, bytes.Length);
+			    }
+
+			    FlushResponse (true);
 
-				SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
-				SendUnknownResponseHeader ("Content-Length", bytes.Length.ToString ());
-				SendResponseFromMemory (bytes, bytes.Length);
-				FlushResponse (true);
 			} catch (Exception ex) { // should "never" happen
-				throw ex;
+				throw; // rethrow
 			}
 		}
 
@@ -380,7 +378,7 @@ public override void SendKnownResponseHeader (int index, string value)
 		public override string GetServerVariable (string name)
 		{
 			if (server_variables == null)
-				return String.Empty;
+				return string.Empty;
 
 			if (IsSecure ()) {
 				X509Certificate client = ClientCertificate;
@@ -388,7 +386,7 @@ public override string GetServerVariable (string name)
 				case "CERT_COOKIE":
 					if (cert_cookie == null) {
 						if (client == null)
-							cert_cookie = String.Empty;
+							cert_cookie = string.Empty;
 						else
 							cert_cookie = client.GetCertHashString ();
 					}
@@ -396,7 +394,7 @@ public override string GetServerVariable (string name)
 				case "CERT_ISSUER":
 					if (cert_issuer == null) {
 						if (client == null)
-							cert_issuer = String.Empty;
+							cert_issuer = string.Empty;
 						else
 							cert_issuer = client.Issuer;
 					}
@@ -404,7 +402,7 @@ public override string GetServerVariable (string name)
 				case "CERT_SERIALNUMBER":
 					if (cert_serial == null) {
 						if (client == null)
-							cert_serial = String.Empty;
+							cert_serial = string.Empty;
 						else
 							cert_serial = client.GetSerialNumberString ();
 					}
@@ -412,7 +410,7 @@ public override string GetServerVariable (string name)
 				case "CERT_SUBJECT":
 					if (cert_subject == null) {
 						if (client == null)
-							cert_subject = String.Empty;
+							cert_subject = string.Empty;
 						else
 							cert_subject = client.Subject;
 					}
@@ -421,7 +419,7 @@ public override string GetServerVariable (string name)
 			}
 
 			string s = server_variables [name];
-			return (s == null) ? String.Empty : s;
+			return s ?? string.Empty;
 		}
 
 		public void AddServerVariable (string name, string value)
diff --git a/src/HyperFastCgi/AppHosts/Raw/BaseRawRequest.cs b/src/HyperFastCgi/AppHosts/Raw/BaseRawRequest.cs
index b507646..05e7e10 100644
--- a/src/HyperFastCgi/AppHosts/Raw/BaseRawRequest.cs
+++ b/src/HyperFastCgi/AppHosts/Raw/BaseRawRequest.cs
@@ -114,16 +114,16 @@ public IDictionary<string, string> ServerVariables {
 
 		#region IWebResponse implementation
 
-		public void Send (int status, string description, IDictionary<string, string> headers)
+		public void Send (int status, string description, IDictionary<string, string> sendHeaders)
 		{
 			Status = status;
 			StatusDescription = description;
-			responseHeaders = (Dictionary<string,string>)headers;
+			responseHeaders = (Dictionary<string,string>)sendHeaders;
 		}
 
-		public void Send (int status, string description, IDictionary<string, string> headers, byte[] response)
+		public void Send (int status, string description, IDictionary<string, string> sendHeaders, byte[] response)
 		{
-			Send (status, description, headers);
+			Send (status, description, sendHeaders);
 			Send (response);
 		}
 
diff --git a/src/HyperFastCgi/Interfaces/IWebResponse.cs b/src/HyperFastCgi/Interfaces/IWebResponse.cs
index 48c2ed7..be81116 100644
--- a/src/HyperFastCgi/Interfaces/IWebResponse.cs
+++ b/src/HyperFastCgi/Interfaces/IWebResponse.cs
@@ -8,9 +8,9 @@ public interface IWebResponse
 	{
 		IWebRequest Request { get; }
 
-		void Send (int status, string description, IDictionary<string,string> headers);
+		void Send (int status, string description, IDictionary<string,string> sendHeaders);
 
-		void Send (int status, string description, IDictionary<string,string> headers, byte[] response);
+		void Send (int status, string description, IDictionary<string,string> sendHeaders, byte[] response);
 
 		void Send (byte[] response);