make controller project portable

This commit is contained in:
Luke Pulverenti
2016-10-25 15:02:04 -04:00
parent edbe28d9fc
commit ef6b90b8e6
441 changed files with 21169 additions and 18588 deletions

View File

@@ -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);
}
}
}

View File

@@ -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,

View File

@@ -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);
}
}
}

View File

@@ -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
{

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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
});

View File

@@ -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

View File

@@ -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; }

View File

@@ -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
{

View File

@@ -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
{