[http] Convert string output data using BOM header when available. Fixes #19667
[mono.git] / mcs / class / System.Net.Http / System.Net.Http / HttpContent.cs
index 77419d28cd4e904648dda1f9c67f7abce7ceba6c..95d3e6d08dae6fb6b773892c735dbe40b3858876 100644 (file)
@@ -167,14 +167,32 @@ namespace System.Net.Http
                        if (buffer.Length == 0)
                                return string.Empty;
 
+                       var buf = buffer.GetBuffer ();
+                       var buf_length = (int) buffer.Length;
+                       int preambleLength = 0;
                        Encoding encoding;
+
                        if (headers != null && headers.ContentType != null && headers.ContentType.CharSet != null) {
                                encoding = Encoding.GetEncoding (headers.ContentType.CharSet);
+                               preambleLength = StartsWith (buf, buf_length, encoding.GetPreamble ());
                        } else {
-                               encoding = Encoding.UTF8;
+                               encoding = WebClient.GetEncodingFromBuffer (buf, buf_length, ref preambleLength) ?? Encoding.UTF8;
+                       }
+
+                       return encoding.GetString (buf, preambleLength, buf_length - preambleLength);
+               }
+
+               static int StartsWith (byte[] array, int length, byte[] value)
+               {
+                       if (length < value.Length)
+                               return 0;
+
+                       for (int i = 0; i < value.Length; ++i) {
+                               if (array [i] != value [i])
+                                       return 0;
                        }
 
-                       return encoding.GetString (buffer.GetBuffer (), 0, (int) buffer.Length);
+                       return value.Length;
                }
 
                protected internal abstract Task SerializeToStreamAsync (Stream stream, TransportContext context);