mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-20 17:16:42 +00:00
make controller project portable
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Web;
|
||||
using MediaBrowser.Controller.Net;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
public class AsyncStreamWriter : IStreamWriter, IAsyncStreamWriter, IHasOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the source stream.
|
||||
/// </summary>
|
||||
/// <value>The source stream.</value>
|
||||
private IAsyncStreamSource _source;
|
||||
|
||||
public Action OnComplete { get; set; }
|
||||
public Action OnError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AsyncStreamWriter" /> class.
|
||||
/// </summary>
|
||||
public AsyncStreamWriter(IAsyncStreamSource source)
|
||||
{
|
||||
_source = source;
|
||||
}
|
||||
|
||||
public IDictionary<string, string> Options
|
||||
{
|
||||
get
|
||||
{
|
||||
var hasOptions = _source as IHasOptions;
|
||||
if (hasOptions != null)
|
||||
{
|
||||
return hasOptions.Options;
|
||||
}
|
||||
|
||||
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes to.
|
||||
/// </summary>
|
||||
/// <param name="responseStream">The response stream.</param>
|
||||
public void WriteTo(Stream responseStream)
|
||||
{
|
||||
var task = _source.WriteToAsync(responseStream);
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public async Task WriteToAsync(Stream responseStream)
|
||||
{
|
||||
await _source.WriteToAsync(responseStream).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,8 @@ using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations.HttpServer.SocketSharp;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Api.Swagger;
|
||||
using ServiceStack.Host;
|
||||
using ServiceStack.Host.Handlers;
|
||||
using ServiceStack.Host.HttpListener;
|
||||
using ServiceStack.Logging;
|
||||
using ServiceStack.Web;
|
||||
using System;
|
||||
@@ -24,6 +22,8 @@ using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.Security;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Services;
|
||||
using ServiceStack.Api.Swagger;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
@@ -100,7 +100,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
container.Adapter = _containerAdapter;
|
||||
|
||||
Plugins.RemoveAll(x => x is NativeTypesFeature);
|
||||
Plugins.Add(new SwaggerFeature());
|
||||
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"));
|
||||
|
||||
@@ -171,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// </summary>
|
||||
private void StartListener()
|
||||
{
|
||||
HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First());
|
||||
HostContext.Config.HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes.First());
|
||||
|
||||
_listener = GetListener();
|
||||
|
||||
@@ -183,6 +182,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
_listener.Start(UrlPrefixes);
|
||||
}
|
||||
|
||||
public static string GetHandlerPathIfAny(string listenerUrl)
|
||||
{
|
||||
if (listenerUrl == null) return null;
|
||||
var pos = listenerUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase);
|
||||
if (pos == -1) return null;
|
||||
var startHostUrl = listenerUrl.Substring(pos + "://".Length);
|
||||
var endPos = startHostUrl.IndexOf('/');
|
||||
if (endPos == -1) return null;
|
||||
var endHostUrl = startHostUrl.Substring(endPos + 1);
|
||||
return string.IsNullOrEmpty(endHostUrl) ? null : endHostUrl.TrimEnd('/');
|
||||
}
|
||||
|
||||
private IHttpListener GetListener()
|
||||
{
|
||||
return new WebSocketSharpListener(_logger, CertificatePath, _memoryStreamProvider);
|
||||
@@ -569,28 +580,28 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
base.Init();
|
||||
}
|
||||
|
||||
public override RouteAttribute[] GetRouteAttributes(Type requestType)
|
||||
public override Model.Services.RouteAttribute[] GetRouteAttributes(Type requestType)
|
||||
{
|
||||
var routes = base.GetRouteAttributes(requestType).ToList();
|
||||
var clone = routes.ToList();
|
||||
|
||||
foreach (var route in clone)
|
||||
{
|
||||
routes.Add(new RouteAttribute(NormalizeEmbyRoutePath(route.Path), route.Verbs)
|
||||
routes.Add(new Model.Services.RouteAttribute(NormalizeEmbyRoutePath(route.Path), route.Verbs)
|
||||
{
|
||||
Notes = route.Notes,
|
||||
Priority = route.Priority,
|
||||
Summary = route.Summary
|
||||
});
|
||||
|
||||
routes.Add(new RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs)
|
||||
routes.Add(new Model.Services.RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs)
|
||||
{
|
||||
Notes = route.Notes,
|
||||
Priority = route.Priority,
|
||||
Summary = route.Summary
|
||||
});
|
||||
|
||||
routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs)
|
||||
routes.Add(new Model.Services.RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs)
|
||||
{
|
||||
Notes = route.Notes,
|
||||
Priority = route.Priority,
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Web;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -11,7 +9,13 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Services;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Web;
|
||||
using IRequest = MediaBrowser.Model.Services.IRequest;
|
||||
using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
@@ -59,10 +63,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="contentType">Type of the content.</param>
|
||||
/// <param name="responseHeaders">The response headers.</param>
|
||||
/// <returns>IHasOptions.</returns>
|
||||
private IHasOptions GetHttpResult(object content, string contentType, IDictionary<string, string> responseHeaders = null)
|
||||
/// <returns>IHasHeaders.</returns>
|
||||
private IHasHeaders GetHttpResult(object content, string contentType, IDictionary<string, string> responseHeaders = null)
|
||||
{
|
||||
IHasOptions result;
|
||||
IHasHeaders result;
|
||||
|
||||
var stream = content as Stream;
|
||||
|
||||
@@ -140,11 +144,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
}
|
||||
|
||||
// Apply headers
|
||||
var hasOptions = optimizedResult as IHasOptions;
|
||||
var hasHeaders = optimizedResult as IHasHeaders;
|
||||
|
||||
if (hasOptions != null)
|
||||
if (hasHeaders != null)
|
||||
{
|
||||
AddResponseHeaders(hasOptions, responseHeaders);
|
||||
AddResponseHeaders(hasHeaders, responseHeaders);
|
||||
}
|
||||
|
||||
return optimizedResult;
|
||||
@@ -237,15 +241,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
result = factoryFn();
|
||||
|
||||
// Apply caching headers
|
||||
var hasOptions = result as IHasOptions;
|
||||
var hasHeaders = result as IHasHeaders;
|
||||
|
||||
if (hasOptions != null)
|
||||
if (hasHeaders != null)
|
||||
{
|
||||
AddResponseHeaders(hasOptions, responseHeaders);
|
||||
return hasOptions;
|
||||
AddResponseHeaders(hasHeaders, responseHeaders);
|
||||
return hasHeaders;
|
||||
}
|
||||
|
||||
IHasOptions httpResult;
|
||||
IHasHeaders httpResult;
|
||||
|
||||
var stream = result as Stream;
|
||||
|
||||
@@ -298,7 +302,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
public Task<object> GetStaticFileResult(IRequest requestContext,
|
||||
string path,
|
||||
FileShare fileShare = FileShare.Read)
|
||||
FileShareMode fileShare = FileShareMode.Read)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
@@ -323,7 +327,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
throw new ArgumentNullException("path");
|
||||
}
|
||||
|
||||
if (fileShare != FileShare.Read && fileShare != FileShare.ReadWrite)
|
||||
if (fileShare != FileShareMode.Read && fileShare != FileShareMode.ReadWrite)
|
||||
{
|
||||
throw new ArgumentException("FileShare must be either Read or ReadWrite");
|
||||
}
|
||||
@@ -352,9 +356,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="fileShare">The file share.</param>
|
||||
/// <returns>Stream.</returns>
|
||||
private Stream GetFileStream(string path, FileShare fileShare)
|
||||
private Stream GetFileStream(string path, FileShareMode fileShare)
|
||||
{
|
||||
return _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, fileShare);
|
||||
return _fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShare);
|
||||
}
|
||||
|
||||
public Task<object> GetStaticResult(IRequest requestContext,
|
||||
@@ -404,10 +408,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
}
|
||||
|
||||
var compress = ShouldCompressResponse(requestContext, contentType);
|
||||
var hasOptions = await GetStaticResult(requestContext, options, compress).ConfigureAwait(false);
|
||||
AddResponseHeaders(hasOptions, options.ResponseHeaders);
|
||||
var hasHeaders = await GetStaticResult(requestContext, options, compress).ConfigureAwait(false);
|
||||
AddResponseHeaders(hasHeaders, options.ResponseHeaders);
|
||||
|
||||
return hasOptions;
|
||||
return hasHeaders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -461,7 +465,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// </summary>
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
private async Task<IHasOptions> GetStaticResult(IRequest requestContext, StaticResultOptions options, bool compress)
|
||||
private async Task<IHasHeaders> GetStaticResult(IRequest requestContext, StaticResultOptions options, bool compress)
|
||||
{
|
||||
var isHeadRequest = options.IsHeadRequest;
|
||||
var factoryFn = options.ContentFactory;
|
||||
@@ -673,19 +677,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// <summary>
|
||||
/// Adds the response headers.
|
||||
/// </summary>
|
||||
/// <param name="hasOptions">The has options.</param>
|
||||
/// <param name="hasHeaders">The has options.</param>
|
||||
/// <param name="responseHeaders">The response headers.</param>
|
||||
private void AddResponseHeaders(IHasOptions hasOptions, IEnumerable<KeyValuePair<string, string>> responseHeaders)
|
||||
private void AddResponseHeaders(IHasHeaders hasHeaders, IEnumerable<KeyValuePair<string, string>> responseHeaders)
|
||||
{
|
||||
foreach (var item in responseHeaders)
|
||||
{
|
||||
hasOptions.Options[item.Key] = item.Value;
|
||||
hasHeaders.Headers[item.Key] = item.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public object GetAsyncStreamWriter(IAsyncStreamSource streamSource)
|
||||
{
|
||||
return new AsyncStreamWriter(streamSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using MediaBrowser.Controller.Net;
|
||||
using ServiceStack.Web;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
|
||||
@@ -5,12 +5,13 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ServiceStack;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
public class RangeRequestWriter : IStreamWriter, IAsyncStreamWriter, IHttpResult
|
||||
public class RangeRequestWriter : IAsyncStreamWriter, IHttpResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the source stream.
|
||||
@@ -47,20 +48,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// Additional HTTP Headers
|
||||
/// </summary>
|
||||
/// <value>The headers.</value>
|
||||
public Dictionary<string, string> Headers
|
||||
public IDictionary<string, string> Headers
|
||||
{
|
||||
get { return _options; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the options.
|
||||
/// </summary>
|
||||
/// <value>The options.</value>
|
||||
public IDictionary<string, string> Options
|
||||
{
|
||||
get { return Headers; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
|
||||
/// </summary>
|
||||
@@ -81,8 +73,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
this._logger = logger;
|
||||
|
||||
ContentType = contentType;
|
||||
Options["Content-Type"] = contentType;
|
||||
Options["Accept-Ranges"] = "bytes";
|
||||
Headers["Content-Type"] = contentType;
|
||||
Headers["Accept-Ranges"] = "bytes";
|
||||
StatusCode = HttpStatusCode.PartialContent;
|
||||
|
||||
Cookies = new List<Cookie>();
|
||||
@@ -112,8 +104,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
RangeLength = 1 + RangeEnd - RangeStart;
|
||||
|
||||
// Content-Length is the length of what we're serving, not the original content
|
||||
Options["Content-Length"] = RangeLength.ToString(UsCulture);
|
||||
Options["Content-Range"] = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
|
||||
Headers["Content-Length"] = RangeLength.ToString(UsCulture);
|
||||
Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
|
||||
|
||||
if (RangeStart > 0)
|
||||
{
|
||||
@@ -164,62 +156,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes to.
|
||||
/// </summary>
|
||||
/// <param name="responseStream">The response stream.</param>
|
||||
public void WriteTo(Stream responseStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Headers only
|
||||
if (IsHeadRequest)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var source = SourceStream)
|
||||
{
|
||||
// If the requested range is "0-", we can optimize by just doing a stream copy
|
||||
if (RangeEnd >= TotalContentLength - 1)
|
||||
{
|
||||
source.CopyTo(responseStream, BufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyToInternal(source, responseStream, RangeLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (OnComplete != null)
|
||||
{
|
||||
OnComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyToInternal(Stream source, Stream destination, long copyLength)
|
||||
{
|
||||
var array = new byte[BufferSize];
|
||||
int count;
|
||||
while ((count = source.Read(array, 0, array.Length)) != 0)
|
||||
{
|
||||
var bytesToCopy = Math.Min(count, copyLength);
|
||||
|
||||
destination.Write(array, 0, Convert.ToInt32(bytesToCopy));
|
||||
|
||||
copyLength -= bytesToCopy;
|
||||
|
||||
if (copyLength <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task WriteToAsync(Stream responseStream)
|
||||
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
@@ -46,21 +47,21 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
var vary = "Accept-Encoding";
|
||||
|
||||
var hasOptions = dto as IHasOptions;
|
||||
var hasHeaders = dto as IHasHeaders;
|
||||
var sharpResponse = res as WebSocketSharpResponse;
|
||||
|
||||
if (hasOptions != null)
|
||||
if (hasHeaders != null)
|
||||
{
|
||||
if (!hasOptions.Options.ContainsKey("Server"))
|
||||
if (!hasHeaders.Headers.ContainsKey("Server"))
|
||||
{
|
||||
hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1, UPnP/1.0 DLNADOC/1.50";
|
||||
//hasOptions.Options["Server"] = "Mono-HTTPAPI/1.1";
|
||||
hasHeaders.Headers["Server"] = "Mono-HTTPAPI/1.1, UPnP/1.0 DLNADOC/1.50";
|
||||
//hasHeaders.Headers["Server"] = "Mono-HTTPAPI/1.1";
|
||||
}
|
||||
|
||||
// Content length has to be explicitly set on on HttpListenerResponse or it won't be happy
|
||||
string contentLength;
|
||||
|
||||
if (hasOptions.Options.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
|
||||
if (hasHeaders.Headers.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
|
||||
{
|
||||
var length = long.Parse(contentLength, UsCulture);
|
||||
|
||||
@@ -85,13 +86,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
}
|
||||
}
|
||||
|
||||
string hasOptionsVary;
|
||||
if (hasOptions.Options.TryGetValue("Vary", out hasOptionsVary))
|
||||
string hasHeadersVary;
|
||||
if (hasHeaders.Headers.TryGetValue("Vary", out hasHeadersVary))
|
||||
{
|
||||
vary = hasOptionsVary;
|
||||
vary = hasHeadersVary;
|
||||
}
|
||||
|
||||
hasOptions.Options["Vary"] = vary;
|
||||
hasHeaders.Headers["Vary"] = vary;
|
||||
}
|
||||
|
||||
//res.KeepAlive = false;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using MediaBrowser.Controller.Connect;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Security;
|
||||
using ServiceStack.Web;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
@@ -21,7 +21,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
|
||||
public AuthorizationInfo GetAuthorizationInfo(object requestContext)
|
||||
{
|
||||
var req = new ServiceStackServiceRequest((IRequest)requestContext);
|
||||
var req = new ServiceRequest((IRequest)requestContext);
|
||||
return GetAuthorizationInfo(req);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using MediaBrowser.Controller.Net;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Auth;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
public class SessionAuthProvider : CredentialsAuthProvider
|
||||
{
|
||||
private readonly ISessionContext _sessionContext;
|
||||
|
||||
public SessionAuthProvider(ISessionContext sessionContext)
|
||||
{
|
||||
_sessionContext = sessionContext;
|
||||
}
|
||||
|
||||
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsAuthorized(IAuthSession session, IAuthTokens tokens, Authenticate request = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void SaveUserAuth(IServiceBase authService, IAuthSession session, IAuthRepository authRepo, IAuthTokens tokens)
|
||||
{
|
||||
}
|
||||
|
||||
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
|
||||
{
|
||||
return base.Authenticate(authService, session, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Security;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using ServiceStack.Web;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
@@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
|
||||
public Task<SessionInfo> GetSession(object requestContext)
|
||||
{
|
||||
var req = new ServiceStackServiceRequest((IRequest)requestContext);
|
||||
var req = new ServiceRequest((IRequest)requestContext);
|
||||
return GetSession(req);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
||||
|
||||
public Task<User> GetUser(object requestContext)
|
||||
{
|
||||
var req = new ServiceStackServiceRequest((IRequest)requestContext);
|
||||
var req = new ServiceRequest((IRequest)requestContext);
|
||||
return GetUser(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
@@ -857,28 +858,28 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
return output.ToString();
|
||||
}
|
||||
|
||||
public static NameValueCollection ParseQueryString(string query)
|
||||
public static QueryParamCollection ParseQueryString(string query)
|
||||
{
|
||||
return ParseQueryString(query, Encoding.UTF8);
|
||||
}
|
||||
|
||||
public static NameValueCollection ParseQueryString(string query, Encoding encoding)
|
||||
public static QueryParamCollection ParseQueryString(string query, Encoding encoding)
|
||||
{
|
||||
if (query == null)
|
||||
throw new ArgumentNullException("query");
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException("encoding");
|
||||
if (query.Length == 0 || (query.Length == 1 && query[0] == '?'))
|
||||
return new NameValueCollection();
|
||||
return new QueryParamCollection();
|
||||
if (query[0] == '?')
|
||||
query = query.Substring(1);
|
||||
|
||||
NameValueCollection result = new HttpQSCollection();
|
||||
QueryParamCollection result = new QueryParamCollection();
|
||||
ParseQueryString(query, encoding, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void ParseQueryString(string query, Encoding encoding, NameValueCollection result)
|
||||
internal static void ParseQueryString(string query, Encoding encoding, QueryParamCollection result)
|
||||
{
|
||||
if (query.Length == 0)
|
||||
return;
|
||||
|
||||
@@ -5,8 +5,8 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using MediaBrowser.Model.Services;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Web;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
@@ -83,7 +83,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
}
|
||||
}
|
||||
|
||||
public NameValueCollection Form
|
||||
public QueryParamCollection Form
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -155,14 +155,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
throw new HttpRequestValidationException(msg);
|
||||
}
|
||||
|
||||
static void ValidateNameValueCollection(string name, NameValueCollection coll)
|
||||
static void ValidateNameValueCollection(string name, QueryParamCollection coll)
|
||||
{
|
||||
if (coll == null)
|
||||
return;
|
||||
|
||||
foreach (string key in coll.Keys)
|
||||
foreach (var pair in coll)
|
||||
{
|
||||
string val = coll[key];
|
||||
var key = pair.Name;
|
||||
var val = pair.Value;
|
||||
if (val != null && val.Length > 0 && IsInvalidString(val))
|
||||
ThrowValidationException(name, key, val);
|
||||
}
|
||||
@@ -348,7 +349,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
}
|
||||
}
|
||||
}
|
||||
class WebROCollection : NameValueCollection
|
||||
class WebROCollection : QueryParamCollection
|
||||
{
|
||||
bool got_id;
|
||||
int id;
|
||||
@@ -369,28 +370,29 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
}
|
||||
public void Protect()
|
||||
{
|
||||
IsReadOnly = true;
|
||||
//IsReadOnly = true;
|
||||
}
|
||||
|
||||
public void Unprotect()
|
||||
{
|
||||
IsReadOnly = false;
|
||||
//IsReadOnly = false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
foreach (string key in AllKeys)
|
||||
foreach (var pair in this)
|
||||
{
|
||||
if (result.Length > 0)
|
||||
result.Append('&');
|
||||
|
||||
var key = pair.Name;
|
||||
if (key != null && key.Length > 0)
|
||||
{
|
||||
result.Append(key);
|
||||
result.Append('=');
|
||||
}
|
||||
result.Append(Get(key));
|
||||
result.Append(pair.Value);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations.Logging;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Web;
|
||||
using SocketHttpListener.Net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,6 +9,8 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Services;
|
||||
using ServiceStack;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
@@ -102,12 +102,19 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
var endpoint = ctx.Request.RemoteEndPoint.ToString();
|
||||
var url = ctx.Request.RawUrl;
|
||||
var queryString = new NameValueCollection(ctx.Request.QueryString ?? new NameValueCollection());
|
||||
var queryString = ctx.Request.QueryString ?? new NameValueCollection();
|
||||
|
||||
var queryParamCollection = new QueryParamCollection();
|
||||
|
||||
foreach (var key in queryString.AllKeys)
|
||||
{
|
||||
queryParamCollection[key] = queryString[key];
|
||||
}
|
||||
|
||||
var connectingArgs = new WebSocketConnectingEventArgs
|
||||
{
|
||||
Url = url,
|
||||
QueryString = queryString,
|
||||
QueryString = queryParamCollection,
|
||||
Endpoint = endpoint
|
||||
};
|
||||
|
||||
@@ -127,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
WebSocketConnected(new WebSocketConnectEventArgs
|
||||
{
|
||||
Url = url,
|
||||
QueryString = queryString,
|
||||
QueryString = queryParamCollection,
|
||||
WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger),
|
||||
Endpoint = endpoint
|
||||
});
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Funq;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Services;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Host;
|
||||
using ServiceStack.Web;
|
||||
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
|
||||
{
|
||||
@@ -27,8 +33,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
this.request = httpContext.Request;
|
||||
this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
|
||||
|
||||
this.RequestPreferences = new RequestPreferences(this);
|
||||
}
|
||||
|
||||
public HttpListenerRequest HttpRequest
|
||||
@@ -53,8 +57,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
|
||||
public RequestAttributes RequestAttributes { get; set; }
|
||||
|
||||
public IRequestPreferences RequestPreferences { get; private set; }
|
||||
|
||||
public T TryResolve<T>()
|
||||
{
|
||||
if (typeof(T) == typeof(IHttpRequest))
|
||||
@@ -324,22 +326,34 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
get { return request.UserAgent; }
|
||||
}
|
||||
|
||||
private NameValueCollectionWrapper headers;
|
||||
public INameValueCollection Headers
|
||||
private QueryParamCollection headers;
|
||||
public QueryParamCollection Headers
|
||||
{
|
||||
get { return headers ?? (headers = new NameValueCollectionWrapper(request.Headers)); }
|
||||
get { return headers ?? (headers = ToQueryParams(request.Headers)); }
|
||||
}
|
||||
|
||||
private NameValueCollectionWrapper queryString;
|
||||
public INameValueCollection QueryString
|
||||
private QueryParamCollection queryString;
|
||||
public QueryParamCollection QueryString
|
||||
{
|
||||
get { return queryString ?? (queryString = new NameValueCollectionWrapper(MyHttpUtility.ParseQueryString(request.Url.Query))); }
|
||||
get { return queryString ?? (queryString = MyHttpUtility.ParseQueryString(request.Url.Query)); }
|
||||
}
|
||||
|
||||
private NameValueCollectionWrapper formData;
|
||||
public INameValueCollection FormData
|
||||
private QueryParamCollection formData;
|
||||
public QueryParamCollection FormData
|
||||
{
|
||||
get { return formData ?? (formData = new NameValueCollectionWrapper(this.Form)); }
|
||||
get { return formData ?? (formData = this.Form); }
|
||||
}
|
||||
|
||||
private QueryParamCollection ToQueryParams(NameValueCollection collection)
|
||||
{
|
||||
var result = new QueryParamCollection();
|
||||
|
||||
foreach (var key in collection.AllKeys)
|
||||
{
|
||||
result[key] = collection[key];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsLocal
|
||||
|
||||
@@ -5,20 +5,21 @@ using System.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Host;
|
||||
using ServiceStack.Web;
|
||||
using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse;
|
||||
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
|
||||
using IRequest = MediaBrowser.Model.Services.IRequest;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
public class WebSocketSharpResponse : IHttpResponse
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly HttpListenerResponse response;
|
||||
private readonly HttpListenerResponse _response;
|
||||
|
||||
public WebSocketSharpResponse(ILogger logger, HttpListenerResponse response, IRequest request)
|
||||
{
|
||||
_logger = logger;
|
||||
this.response = response;
|
||||
this._response = response;
|
||||
Items = new Dictionary<string, object>();
|
||||
Request = request;
|
||||
}
|
||||
@@ -28,28 +29,28 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
public Dictionary<string, object> Items { get; private set; }
|
||||
public object OriginalResponse
|
||||
{
|
||||
get { return response; }
|
||||
get { return _response; }
|
||||
}
|
||||
|
||||
public int StatusCode
|
||||
{
|
||||
get { return this.response.StatusCode; }
|
||||
set { this.response.StatusCode = value; }
|
||||
get { return this._response.StatusCode; }
|
||||
set { this._response.StatusCode = value; }
|
||||
}
|
||||
|
||||
public string StatusDescription
|
||||
{
|
||||
get { return this.response.StatusDescription; }
|
||||
set { this.response.StatusDescription = value; }
|
||||
get { return this._response.StatusDescription; }
|
||||
set { this._response.StatusDescription = value; }
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return response.ContentType; }
|
||||
set { response.ContentType = value; }
|
||||
get { return _response.ContentType; }
|
||||
set { _response.ContentType = value; }
|
||||
}
|
||||
|
||||
public ICookies Cookies { get; set; }
|
||||
//public ICookies Cookies { get; set; }
|
||||
|
||||
public void AddHeader(string name, string value)
|
||||
{
|
||||
@@ -59,22 +60,22 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
return;
|
||||
}
|
||||
|
||||
response.AddHeader(name, value);
|
||||
_response.AddHeader(name, value);
|
||||
}
|
||||
|
||||
public string GetHeader(string name)
|
||||
{
|
||||
return response.Headers[name];
|
||||
return _response.Headers[name];
|
||||
}
|
||||
|
||||
public void Redirect(string url)
|
||||
{
|
||||
response.Redirect(url);
|
||||
_response.Redirect(url);
|
||||
}
|
||||
|
||||
public Stream OutputStream
|
||||
{
|
||||
get { return response.OutputStream; }
|
||||
get { return _response.OutputStream; }
|
||||
}
|
||||
|
||||
public object Dto { get; set; }
|
||||
@@ -82,9 +83,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
public void Write(string text)
|
||||
{
|
||||
var bOutput = System.Text.Encoding.UTF8.GetBytes(text);
|
||||
response.ContentLength64 = bOutput.Length;
|
||||
_response.ContentLength64 = bOutput.Length;
|
||||
|
||||
var outputStream = response.OutputStream;
|
||||
var outputStream = _response.OutputStream;
|
||||
outputStream.Write(bOutput, 0, bOutput.Length);
|
||||
Close();
|
||||
}
|
||||
@@ -97,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
|
||||
try
|
||||
{
|
||||
this.response.CloseOutputStream(_logger);
|
||||
this._response.CloseOutputStream(_logger);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -113,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
response.OutputStream.Flush();
|
||||
_response.OutputStream.Flush();
|
||||
}
|
||||
|
||||
public bool IsClosed
|
||||
@@ -127,19 +128,19 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
//you can happily set the Content-Length header in Asp.Net
|
||||
//but HttpListener will complain if you do - you have to set ContentLength64 on the response.
|
||||
//workaround: HttpListener throws "The parameter is incorrect" exceptions when we try to set the Content-Length header
|
||||
response.ContentLength64 = contentLength;
|
||||
_response.ContentLength64 = contentLength;
|
||||
}
|
||||
|
||||
public void SetCookie(Cookie cookie)
|
||||
{
|
||||
var cookieStr = cookie.AsHeaderValue();
|
||||
response.Headers.Add(HttpHeaders.SetCookie, cookieStr);
|
||||
_response.Headers.Add(HttpHeaders.SetCookie, cookieStr);
|
||||
}
|
||||
|
||||
public bool SendChunked
|
||||
{
|
||||
get { return response.SendChunked; }
|
||||
set { response.SendChunked = value; }
|
||||
get { return _response.SendChunked; }
|
||||
set { _response.SendChunked = value; }
|
||||
}
|
||||
|
||||
public bool KeepAlive { get; set; }
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
using MediaBrowser.Model.Logging;
|
||||
using ServiceStack.Web;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using ServiceStack;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Class StreamWriter
|
||||
/// </summary>
|
||||
public class StreamWriter : IStreamWriter, IAsyncStreamWriter, IHasOptions
|
||||
public class StreamWriter : IAsyncStreamWriter, IHasHeaders
|
||||
{
|
||||
private ILogger Logger { get; set; }
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// Gets the options.
|
||||
/// </summary>
|
||||
/// <value>The options.</value>
|
||||
public IDictionary<string, string> Options
|
||||
public IDictionary<string, string> Headers
|
||||
{
|
||||
get { return _options; }
|
||||
}
|
||||
@@ -58,11 +58,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
SourceStream = source;
|
||||
Logger = logger;
|
||||
|
||||
Options["Content-Type"] = contentType;
|
||||
Headers["Content-Type"] = contentType;
|
||||
|
||||
if (source.CanSeek)
|
||||
{
|
||||
Options["Content-Length"] = source.Length.ToString(UsCulture);
|
||||
Headers["Content-Length"] = source.Length.ToString(UsCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,54 +83,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
_bytes = source;
|
||||
Logger = logger;
|
||||
|
||||
Options["Content-Type"] = contentType;
|
||||
Headers["Content-Type"] = contentType;
|
||||
|
||||
Options["Content-Length"] = source.Length.ToString(UsCulture);
|
||||
Headers["Content-Length"] = source.Length.ToString(UsCulture);
|
||||
}
|
||||
|
||||
private const int BufferSize = 81920;
|
||||
|
||||
/// <summary>
|
||||
/// Writes to.
|
||||
/// </summary>
|
||||
/// <param name="responseStream">The response stream.</param>
|
||||
public void WriteTo(Stream responseStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_bytes != null)
|
||||
{
|
||||
responseStream.Write(_bytes, 0, _bytes.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var src = SourceStream)
|
||||
{
|
||||
src.CopyTo(responseStream, BufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error streaming data", ex);
|
||||
|
||||
if (OnError != null)
|
||||
{
|
||||
OnError();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (OnComplete != null)
|
||||
{
|
||||
OnComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task WriteToAsync(Stream responseStream)
|
||||
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using ServiceStack.Web;
|
||||
using System.IO;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user