diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 3f55bd7fb8..07f3bd020f 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -79,8 +79,10 @@ + + diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs similarity index 91% rename from MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs rename to Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs index 543eb4afe2..ec14c32c8f 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Collections.Specialized; using System.Globalization; using System.IO; @@ -7,7 +8,7 @@ using System.Text; using System.Threading.Tasks; using MediaBrowser.Model.Services; -namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +namespace Emby.Server.Implementations.HttpServer.SocketSharp { public partial class WebSocketSharpRequest : IHttpRequest { @@ -68,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp input.Position = e.Start; input.Read(copy, 0, (int)e.Length); - form.Add(e.Name, (e.Encoding ?? ContentEncoding).GetString(copy)); + form.Add(e.Name, (e.Encoding ?? ContentEncoding).GetString(copy, 0, copy.Length)); } else { @@ -76,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp // We use a substream, as in 2.x we will support large uploads streamed to disk, // HttpPostedFile sub = new HttpPostedFile(e.Filename, e.ContentType, input, e.Start, e.Length); - files.AddFile(e.Name, sub); + files[e.Name] = sub; } } } @@ -89,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (form == null) { form = new WebROCollection(); - files = new HttpFileCollection(); + files = new Dictionary(); if (IsContentType("multipart/form-data", true)) { @@ -224,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (starts_with) return StrUtils.StartsWith(ContentType, ct, true); - return String.Compare(ContentType, ct, true, Helpers.InvariantCulture) == 0; + return string.Equals(ContentType, ct, StringComparison.OrdinalIgnoreCase); } async Task LoadWwwForm() @@ -287,67 +288,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp WebROCollection form; - HttpFileCollection files; + Dictionary files; - public sealed class HttpFileCollection : NameObjectCollectionBase - { - internal HttpFileCollection() - { - } - - internal void AddFile(string name, HttpPostedFile file) - { - BaseAdd(name, file); - } - - public void CopyTo(Array dest, int index) - { - /* XXX this is kind of gross and inefficient - * since it makes a copy of the superclass's - * list */ - object[] values = BaseGetAllValues(); - values.CopyTo(dest, index); - } - - public string GetKey(int index) - { - return BaseGetKey(index); - } - - public HttpPostedFile Get(int index) - { - return (HttpPostedFile)BaseGet(index); - } - - public HttpPostedFile Get(string key) - { - return (HttpPostedFile)BaseGet(key); - } - - public HttpPostedFile this[string key] - { - get - { - return Get(key); - } - } - - public HttpPostedFile this[int index] - { - get - { - return Get(index); - } - } - - public string[] AllKeys - { - get - { - return BaseGetAllKeys(); - } - } - } class WebROCollection : QueryParamCollection { bool got_id; @@ -589,29 +531,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp internal sealed class StrUtils { - StrUtils() { } - - public static bool StartsWith(string str1, string str2) - { - return StartsWith(str1, str2, false); - } - public static bool StartsWith(string str1, string str2, bool ignore_case) { - int l2 = str2.Length; - if (l2 == 0) - return true; - - int l1 = str1.Length; - if (l2 > l1) + if (string.IsNullOrWhiteSpace(str1)) + { return false; + } - return 0 == String.Compare(str1, 0, str2, 0, l2, ignore_case, Helpers.InvariantCulture); - } - - public static bool EndsWith(string str1, string str2) - { - return EndsWith(str1, str2, false); + var comparison = ignore_case ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; + return str1.IndexOf(str2, comparison) == 0; } public static bool EndsWith(string str1, string str2, bool ignore_case) @@ -624,7 +552,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (l2 > l1) return false; - return 0 == String.Compare(str1, l1 - l2, str2, 0, l2, ignore_case, Helpers.InvariantCulture); + var comparison = ignore_case ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; + return str1.IndexOf(str2, comparison) == str1.Length - str2.Length - 1; } } @@ -742,7 +671,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp for (int i = temp.Length - 1; i >= 0; i--) source[i] = (byte)temp[i]; - return encoding.GetString(source); + return encoding.GetString(source, 0, source.Length); } bool ReadBoundary() diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs similarity index 94% rename from MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs rename to Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 628e5cc7e4..b3fcde7456 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -1,20 +1,20 @@ using System; using System.Collections.Generic; using System.IO; +using System.Net; using System.Text; using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.HttpServer.SocketSharp; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Services; -using ServiceStack; using SocketHttpListener.Net; using IHttpFile = MediaBrowser.Model.Services.IHttpFile; using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest; using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse; using IResponse = MediaBrowser.Model.Services.IResponse; -namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp +namespace Emby.Server.Implementations.HttpServer.SocketSharp { public partial class WebSocketSharpRequest : IHttpRequest { @@ -327,19 +327,30 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp var pi = httpReq.PathInfo; if (pi == null || pi.Length <= formatMaxLength) return null; if (pi[0] == '/') pi = pi.Substring(1); - format = pi.LeftPart('/'); + format = LeftPart(pi, '/'); if (format.Length > formatMaxLength) return null; } - format = format.LeftPart('.').ToLower(); + format = LeftPart(format, '.').ToLower(); if (format.Contains("json")) return "application/json"; if (format.Contains("xml")) return Xml; return null; } + public static string LeftPart(string strVal, char needle) + { + if (strVal == null) return null; + var pos = strVal.IndexOf(needle); + return pos == -1 + ? strVal + : strVal.Substring(0, pos); + } + public bool HasExplicitResponseContentType { get; private set; } + public static string HandlerFactoryPath; + private string pathInfo; public string PathInfo { @@ -347,7 +358,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { if (this.pathInfo == null) { - var mode = HttpListenerHost.HandlerFactoryPath; + var mode = HandlerFactoryPath; var pos = request.RawUrl.IndexOf("?"); if (pos != -1) @@ -363,7 +374,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp this.pathInfo = request.RawUrl; } - this.pathInfo = this.pathInfo.UrlDecode(); + this.pathInfo = WebUtility.UrlDecode(pathInfo); this.pathInfo = NormalizePathInfo(pathInfo, mode); } return this.pathInfo; @@ -427,9 +438,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (cookies == null) { cookies = new Dictionary(); - for (var i = 0; i < this.request.Cookies.Count; i++) + foreach (var cookie in this.request.Cookies) { - var httpCookie = this.request.Cookies[i]; + var httpCookie = (Cookie) cookie; cookies[httpCookie.Name] = new System.Net.Cookie(httpCookie.Name, httpCookie.Value, httpCookie.Path, httpCookie.Domain); } } @@ -539,10 +550,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return httpFiles = new IHttpFile[0]; httpFiles = new IHttpFile[files.Count]; - for (var i = 0; i < files.Count; i++) + var i = 0; + foreach (var pair in files) { - var reqFile = files[i]; - + var reqFile = pair.Value; httpFiles[i] = new HttpFile { ContentType = reqFile.ContentType, @@ -550,6 +561,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp FileName = reqFile.FileName, InputStream = reqFile.InputStream, }; + i++; } } return httpFiles; @@ -561,14 +573,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (stream is MemoryStream) { var other = (MemoryStream)stream; - try - { - return new MemoryStream(other.GetBuffer(), 0, (int)other.Length, false, true); - } - catch (UnauthorizedAccessException) + + byte[] buffer; + if (streamProvider.TryGetBuffer(other, out buffer)) { - return new MemoryStream(other.ToArray(), 0, (int)other.Length, false, true); + return streamProvider.CreateNew(buffer); } + return streamProvider.CreateNew(other.ToArray()); } return stream; @@ -577,7 +588,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public static string GetHandlerPathIfAny(string listenerUrl) { if (listenerUrl == null) return null; - var pos = listenerUrl.IndexOf("://", StringComparison.InvariantCultureIgnoreCase); + var pos = listenerUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase); if (pos == -1) return null; var startHostUrl = listenerUrl.Substring(pos + "://".Length); var endPos = startHostUrl.IndexOf('/'); @@ -589,7 +600,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public static string NormalizePathInfo(string pathInfo, string handlerPath) { if (handlerPath != null && pathInfo.TrimStart('/').StartsWith( - handlerPath, StringComparison.InvariantCultureIgnoreCase)) + handlerPath, StringComparison.OrdinalIgnoreCase)) { return pathInfo.TrimStart('/').Substring(handlerPath.Length); } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 4218370ac4..f0a9c5ca3c 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -2,10 +2,8 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.HttpServer.SocketSharp; using ServiceStack; using ServiceStack.Host; -using ServiceStack.Web; using System; using System.Collections.Generic; using System.IO; @@ -158,14 +156,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer return this; } - public static string HandlerFactoryPath; - /// /// Starts the Web Service /// private void StartListener() { - HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes.First()); + WebSocketSharpRequest.HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes.First()); _listener = GetListener(); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index a253753c56..6fb4f9e36d 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -111,8 +111,6 @@ - -