Merge pull request #2305 from ludovic-henry/fix-threadpool-36414
[mono.git] / mcs / class / System / System.Net / HttpListenerResponse.cs
index 3d465008c3d422bbc884e2cde8d6318e0e20fe15..dcc553036e1aea112b7e5d6f864e92e58e84e119 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0 && SECURITY_DEP
+#if SECURITY_DEP
 
 using System.Globalization;
 using System.IO;
@@ -49,7 +49,10 @@ namespace System.Net {
                string status_description = "OK";
                bool chunked;
                HttpListenerContext context;
+               
                internal bool HeadersSent;
+               internal object headers_lock = new object ();
+               
                bool force_close_chunked;
 
                internal HttpListenerResponse (HttpListenerContext context)
@@ -331,8 +334,8 @@ namespace System.Net {
 
                void Close (bool force)
                {
-                       context.Connection.Close (force);
                        disposed = true;
+                       context.Connection.Close (force);
                }
 
                public void Close ()
@@ -471,23 +474,16 @@ namespace System.Net {
                                headers.SetInternal ("Location", location);
 
                        if (cookies != null) {
-                               bool firstDone = false;
-                               StringBuilder cookieSB = new StringBuilder ();
-                               foreach (Cookie cookie in cookies) {
-                                       if (firstDone)
-                                               cookieSB.Append (",");
-                                       firstDone = true;
-                                       cookieSB.Append (cookie.ToClientString ());
-                               }
-                               headers.SetInternal("Set-Cookie2", cookieSB.ToString ());
+                               foreach (Cookie cookie in cookies)
+                                       headers.SetInternal ("Set-Cookie", CookieToClientString (cookie));
                        }
 
-                       StreamWriter writer = new StreamWriter (ms, encoding);
+                       StreamWriter writer = new StreamWriter (ms, encoding, 256);
                        writer.Write ("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
-                       string headers_str = headers.ToString ();
+                       string headers_str = headers.ToStringMultiValue ();
                        writer.Write (headers_str);
                        writer.Flush ();
-                       int preamble = encoding.GetPreamble ().Length;
+                       int preamble = (encoding.CodePage == 65001) ? 3 : encoding.GetPreamble ().Length;
                        if (output_stream == null)
                                output_stream = context.Connection.GetResponseStream ();
 
@@ -496,6 +492,51 @@ namespace System.Net {
                        HeadersSent = true;
                }
 
+               static string CookieToClientString (Cookie cookie)
+               {
+                       if (cookie.Name.Length == 0)
+                               return String.Empty;
+
+                       StringBuilder result = new StringBuilder (64);
+
+                       if (cookie.Version > 0)
+                               result.Append ("Version=").Append (cookie.Version).Append (";");
+
+                       result.Append (cookie.Name).Append ("=").Append (cookie.Value);
+
+                       if (cookie.Path != null && cookie.Path.Length != 0)
+                               result.Append (";Path=").Append (QuotedString (cookie, cookie.Path));
+
+                       if (cookie.Domain != null && cookie.Domain.Length != 0)
+                               result.Append (";Domain=").Append (QuotedString (cookie, cookie.Domain));                       
+
+                       if (cookie.Port != null && cookie.Port.Length != 0)
+                               result.Append (";Port=").Append (cookie.Port);  
+
+                       return result.ToString ();
+               }
+
+               static string QuotedString (Cookie cookie, string value)
+               {
+                       if (cookie.Version == 0 || IsToken (value))
+                               return value;
+                       else 
+                               return "\"" + value.Replace("\"", "\\\"") + "\"";
+               }       
+
+               static string tspecials = "()<>@,;:\\\"/[]?={} \t";   // from RFC 2965, 2068
+
+           static bool IsToken (string value) 
+               {
+                       int len = value.Length;
+                       for (int i = 0; i < len; i++) {
+                           char c = value [i];
+                               if (c < 0x20 || c >= 0x7f || tspecials.IndexOf (c) != -1)
+                                       return false;
+                       }
+                       return true;
+               }
+
                public void SetCookie (Cookie cookie)
                {
                        if (cookie == null)