Browse Source

Less string allocations

Bond-009 6 years ago
parent
commit
9ba6227db4

+ 13 - 12
Jellyfin.Server/SocketSharp/RequestMono.cs

@@ -11,7 +11,7 @@ namespace Jellyfin.Server.SocketSharp
 {
     public partial class WebSocketSharpRequest : IHttpRequest
     {
-        internal static string GetParameter(string header, string attr)
+        internal static string GetParameter(ReadOnlySpan<char> header, string attr)
         {
             int ap = header.IndexOf(attr, StringComparison.Ordinal);
             if (ap == -1)
@@ -31,13 +31,14 @@ namespace Jellyfin.Server.SocketSharp
                 ending = ' ';
             }
 
-            int end = header.IndexOf(ending, ap + 1);
+            var slice = header.Slice(ap + 1);
+            int end = slice.IndexOf(ending);
             if (end == -1)
             {
-                return ending == '"' ? null : header.Substring(ap);
+                return ending == '"' ? null : header.Slice(ap).ToString();
             }
 
-            return header.Substring(ap + 1, end - ap - 1);
+            return slice.Slice(0, end - ap - 1).ToString();
         }
 
         private async Task LoadMultiPart(WebROCollection form)
@@ -394,7 +395,7 @@ namespace Jellyfin.Server.SocketSharp
                 }
 
                 var elem = new Element();
-                string header;
+                ReadOnlySpan<char> header;
                 while ((header = ReadHeaders()) != null)
                 {
                     if (header.StartsWith("Content-Disposition:", StringComparison.OrdinalIgnoreCase))
@@ -404,7 +405,7 @@ namespace Jellyfin.Server.SocketSharp
                     }
                     else if (header.StartsWith("Content-Type:", StringComparison.OrdinalIgnoreCase))
                     {
-                        elem.ContentType = header.Substring("Content-Type:".Length).Trim();
+                        elem.ContentType = header.Slice("Content-Type:".Length).Trim().ToString();
                         elem.Encoding = GetEncoding(elem.ContentType);
                     }
                 }
@@ -452,7 +453,7 @@ namespace Jellyfin.Server.SocketSharp
                 return sb.ToString();
             }
 
-            private static string GetContentDispositionAttribute(string l, string name)
+            private static string GetContentDispositionAttribute(ReadOnlySpan<char> l, string name)
             {
                 int idx = l.IndexOf(name + "=\"", StringComparison.Ordinal);
                 if (idx < 0)
@@ -461,7 +462,7 @@ namespace Jellyfin.Server.SocketSharp
                 }
 
                 int begin = idx + name.Length + "=\"".Length;
-                int end = l.IndexOf('"', begin);
+                int end = l.Slice(begin).IndexOf('"');
                 if (end < 0)
                 {
                     return null;
@@ -472,10 +473,10 @@ namespace Jellyfin.Server.SocketSharp
                     return string.Empty;
                 }
 
-                return l.Substring(begin, end - begin);
+                return l.Slice(begin, end - begin).ToString();
             }
 
-            private string GetContentDispositionAttributeWithEncoding(string l, string name)
+            private string GetContentDispositionAttributeWithEncoding(ReadOnlySpan<char> l, string name)
             {
                 int idx = l.IndexOf(name + "=\"", StringComparison.Ordinal);
                 if (idx < 0)
@@ -484,7 +485,7 @@ namespace Jellyfin.Server.SocketSharp
                 }
 
                 int begin = idx + name.Length + "=\"".Length;
-                int end = l.IndexOf('"', begin);
+                int end = l.Slice(begin).IndexOf('"');
                 if (end < 0)
                 {
                     return null;
@@ -495,7 +496,7 @@ namespace Jellyfin.Server.SocketSharp
                     return string.Empty;
                 }
 
-                string temp = l.Substring(begin, end - begin);
+                ReadOnlySpan<char> temp = l.Slice(begin, end - begin);
                 byte[] source = new byte[temp.Length];
                 for (int i = temp.Length - 1; i >= 0; i--)
                 {

+ 37 - 29
Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs

@@ -57,18 +57,37 @@ namespace Jellyfin.Server.SocketSharp
         public string XRealIp => string.IsNullOrEmpty(request.Headers["X-Real-IP"]) ? null : request.Headers["X-Real-IP"];
 
         private string remoteIp;
-        public string RemoteIp =>
-            remoteIp ??
-            (remoteIp = CheckBadChars(XForwardedFor) ??
-                        NormalizeIp(CheckBadChars(XRealIp) ??
-                         (request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null)));
+        public string RemoteIp
+        {
+            get
+            {
+                if (remoteIp != null)
+                {
+                    return remoteIp;
+                }
+
+                var temp = CheckBadChars(XForwardedFor);
+                if (temp.Length != 0)
+                {
+                    return remoteIp = temp.ToString();
+                }
+
+                temp = CheckBadChars(XRealIp);
+                if (temp.Length != 0)
+                {
+                    return remoteIp = NormalizeIp(temp).ToString();
+                }
+
+                return remoteIp = NormalizeIp(request.RemoteEndPoint?.Address.ToString()).ToString();
+            }
+        }
 
         private static readonly char[] HttpTrimCharacters = new char[] { (char)0x09, (char)0xA, (char)0xB, (char)0xC, (char)0xD, (char)0x20 };
 
         // CheckBadChars - throws on invalid chars to be not found in header name/value
-        internal static string CheckBadChars(string name)
+        internal static ReadOnlySpan<char> CheckBadChars(ReadOnlySpan<char> name)
         {
-            if (name == null || name.Length == 0)
+            if (name.Length == 0)
             {
                 return name;
             }
@@ -99,7 +118,7 @@ namespace Jellyfin.Server.SocketSharp
                         }
                         else if (c == 127 || (c < ' ' && c != '\t'))
                         {
-                            throw new ArgumentException("net_WebHeaderInvalidControlChars");
+                            throw new ArgumentException("net_WebHeaderInvalidControlChars", nameof(name));
                         }
 
                         break;
@@ -113,7 +132,7 @@ namespace Jellyfin.Server.SocketSharp
                             break;
                         }
 
-                        throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
+                        throw new ArgumentException("net_WebHeaderInvalidCRLFChars", nameof(name));
                     }
 
                     case 2:
@@ -124,14 +143,14 @@ namespace Jellyfin.Server.SocketSharp
                             break;
                         }
 
-                        throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
+                        throw new ArgumentException("net_WebHeaderInvalidCRLFChars", nameof(name));
                     }
                 }
             }
 
             if (crlf != 0)
             {
-                throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
+                throw new ArgumentException("net_WebHeaderInvalidCRLFChars", nameof(name));
             }
 
             return name;
@@ -150,16 +169,16 @@ namespace Jellyfin.Server.SocketSharp
             return false;
         }
 
-        private string NormalizeIp(string ip)
+        private ReadOnlySpan<char> NormalizeIp(ReadOnlySpan<char> ip)
         {
-            if (!string.IsNullOrWhiteSpace(ip))
+            if (ip.Length != 0 && !ip.IsWhiteSpace())
             {
                 // Handle ipv4 mapped to ipv6
                 const string srch = "::ffff:";
                 var index = ip.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
                 if (index == 0)
                 {
-                    ip = ip.Substring(srch.Length);
+                    ip = ip.Slice(srch.Length);
                 }
             }
 
@@ -302,17 +321,6 @@ namespace Jellyfin.Server.SocketSharp
             return null;
         }
 
-        public static string LeftPart(string strVal, char needle)
-        {
-            if (strVal == null)
-            {
-                return null;
-            }
-
-            var pos = strVal.IndexOf(needle, StringComparison.Ordinal);
-            return pos == -1 ? strVal : strVal.Substring(0, pos);
-        }
-
         public static ReadOnlySpan<char> LeftPart(ReadOnlySpan<char> strVal, char needle)
         {
             if (strVal == null)
@@ -350,7 +358,7 @@ namespace Jellyfin.Server.SocketSharp
                     }
 
                     this.pathInfo = System.Net.WebUtility.UrlDecode(pathInfo);
-                    this.pathInfo = NormalizePathInfo(pathInfo, mode);
+                    this.pathInfo = NormalizePathInfo(pathInfo, mode).ToString();
                 }
 
                 return this.pathInfo;
@@ -517,14 +525,14 @@ namespace Jellyfin.Server.SocketSharp
             }
         }
 
-        public static string NormalizePathInfo(string pathInfo, string handlerPath)
+        public static ReadOnlySpan<char> NormalizePathInfo(string pathInfo, string handlerPath)
         {
             if (handlerPath != null)
             {
-                var trimmed = pathInfo.TrimStart('/');
+                var trimmed = pathInfo.AsSpan().TrimStart('/');
                 if (trimmed.StartsWith(handlerPath, StringComparison.OrdinalIgnoreCase))
                 {
-                    return trimmed.Substring(handlerPath.Length);
+                    return trimmed.Slice(handlerPath.Length).ToString();
                 }
             }
 

+ 1 - 1
MediaBrowser.WebDashboard/jellyfin-web

@@ -1 +1 @@
-Subproject commit ec5a3b6e5efb6041153b92818aee562f20ee994d
+Subproject commit b4842e325e9d7d708193b4a27060cfe4c978df5e