Browse Source

Rescue PlayTo function in case of malformed Xml response
(port from 10.8 fix)

SeaEagle1 2 years ago
parent
commit
9352a24374
1 changed files with 26 additions and 5 deletions
  1. 26 5
      Emby.Dlna/PlayTo/DlnaHttpClient.cs

+ 26 - 5
Emby.Dlna/PlayTo/DlnaHttpClient.cs

@@ -2,9 +2,11 @@
 
 
 using System;
 using System;
 using System.Globalization;
 using System.Globalization;
+using System.IO;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.Mime;
 using System.Net.Mime;
 using System.Text;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Xml;
 using System.Xml;
@@ -54,15 +56,34 @@ namespace Emby.Dlna.PlayTo
                     LoadOptions.None,
                     LoadOptions.None,
                     cancellationToken).ConfigureAwait(false);
                     cancellationToken).ConfigureAwait(false);
             }
             }
-            catch (XmlException ex)
+            catch (XmlException)
             {
             {
-                _logger.LogError(ex, "Failed to parse response");
-                if (_logger.IsEnabled(LogLevel.Debug))
+                // try correcting the Xml response with common errors
+                var xmlString = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
+
+                // find and replace unescaped ampersands (&)
+                Regex regex = new Regex(@"(&(?![a-z]*;))");
+                xmlString = regex.Replace(xmlString, @"&");
+
+                try
                 {
                 {
-                    _logger.LogDebug("Malformed response: {Content}\n", await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false));
+                    // retry reading Xml
+                    var xmlReader = new StringReader(xmlString);
+                    return await XDocument.LoadAsync(
+                        xmlReader,
+                        LoadOptions.None,
+                        cancellationToken).ConfigureAwait(false);
                 }
                 }
+                catch (XmlException ex)
+                {
+                    _logger.LogError(ex, "Failed to parse response");
+                    if (_logger.IsEnabled(LogLevel.Debug))
+                    {
+                        _logger.LogDebug("Malformed response: {Content}\n", xmlString);
+                    }
 
 
-                return null;
+                    return null;
+                }
             }
             }
         }
         }