mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-07-19 12:44:19 +01:00
Replace custom code with Asp.Net Core code
This commit is contained in:
@@ -10,8 +10,6 @@ namespace Emby.Server.Implementations.Services
|
||||
public class HttpResult
|
||||
: IHttpResult, IAsyncStreamWriter
|
||||
{
|
||||
public object Response { get; set; }
|
||||
|
||||
public HttpResult(object response, string contentType, HttpStatusCode statusCode)
|
||||
{
|
||||
this.Headers = new Dictionary<string, string>();
|
||||
@@ -21,6 +19,8 @@ namespace Emby.Server.Implementations.Services
|
||||
this.StatusCode = statusCode;
|
||||
}
|
||||
|
||||
public object Response { get; set; }
|
||||
|
||||
public string ContentType { get; set; }
|
||||
|
||||
public IDictionary<string, string> Headers { get; private set; }
|
||||
@@ -37,7 +37,7 @@ namespace Emby.Server.Implementations.Services
|
||||
|
||||
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
|
||||
{
|
||||
var response = RequestContext == null ? null : RequestContext.Response;
|
||||
var response = RequestContext?.Response;
|
||||
|
||||
if (this.Response is byte[] bytesResponse)
|
||||
{
|
||||
@@ -45,13 +45,14 @@ namespace Emby.Server.Implementations.Services
|
||||
|
||||
if (response != null)
|
||||
{
|
||||
response.OriginalResponse.ContentLength = contentLength;
|
||||
response.ContentLength = contentLength;
|
||||
}
|
||||
|
||||
if (contentLength > 0)
|
||||
{
|
||||
await responseStream.WriteAsync(bytesResponse, 0, contentLength, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
@@ -7,13 +6,14 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Emby.Server.Implementations.HttpServer;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace Emby.Server.Implementations.Services
|
||||
{
|
||||
public static class ResponseHelper
|
||||
{
|
||||
public static Task WriteToResponse(IResponse response, IRequest request, object result, CancellationToken cancellationToken)
|
||||
public static Task WriteToResponse(HttpResponse response, IRequest request, object result, CancellationToken cancellationToken)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace Emby.Server.Implementations.Services
|
||||
response.StatusCode = (int)HttpStatusCode.NoContent;
|
||||
}
|
||||
|
||||
response.OriginalResponse.ContentLength = 0;
|
||||
response.ContentLength = 0;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace Emby.Server.Implementations.Services
|
||||
httpResult.RequestContext = request;
|
||||
|
||||
response.StatusCode = httpResult.Status;
|
||||
response.StatusDescription = httpResult.StatusCode.ToString();
|
||||
}
|
||||
|
||||
var responseOptions = result as IHasHeaders;
|
||||
@@ -51,11 +50,11 @@ namespace Emby.Server.Implementations.Services
|
||||
{
|
||||
if (string.Equals(responseHeaders.Key, "Content-Length", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
response.OriginalResponse.ContentLength = long.Parse(responseHeaders.Value, CultureInfo.InvariantCulture);
|
||||
response.ContentLength = long.Parse(responseHeaders.Value, CultureInfo.InvariantCulture);
|
||||
continue;
|
||||
}
|
||||
|
||||
response.AddHeader(responseHeaders.Key, responseHeaders.Value);
|
||||
response.Headers.Add(responseHeaders.Key, responseHeaders.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,31 +73,31 @@ namespace Emby.Server.Implementations.Services
|
||||
switch (result)
|
||||
{
|
||||
case IAsyncStreamWriter asyncStreamWriter:
|
||||
return asyncStreamWriter.WriteToAsync(response.OutputStream, cancellationToken);
|
||||
return asyncStreamWriter.WriteToAsync(response.Body, cancellationToken);
|
||||
case IStreamWriter streamWriter:
|
||||
streamWriter.WriteTo(response.OutputStream);
|
||||
streamWriter.WriteTo(response.Body);
|
||||
return Task.CompletedTask;
|
||||
case FileWriter fileWriter:
|
||||
return fileWriter.WriteToAsync(response, cancellationToken);
|
||||
case Stream stream:
|
||||
return CopyStream(stream, response.OutputStream);
|
||||
return CopyStream(stream, response.Body);
|
||||
case byte[] bytes:
|
||||
response.ContentType = "application/octet-stream";
|
||||
response.OriginalResponse.ContentLength = bytes.Length;
|
||||
response.ContentLength = bytes.Length;
|
||||
|
||||
if (bytes.Length > 0)
|
||||
{
|
||||
return response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
|
||||
return response.Body.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
case string responseText:
|
||||
var responseTextAsBytes = Encoding.UTF8.GetBytes(responseText);
|
||||
response.OriginalResponse.ContentLength = responseTextAsBytes.Length;
|
||||
response.ContentLength = responseTextAsBytes.Length;
|
||||
|
||||
if (responseTextAsBytes.Length > 0)
|
||||
{
|
||||
return response.OutputStream.WriteAsync(responseTextAsBytes, 0, responseTextAsBytes.Length, cancellationToken);
|
||||
return response.Body.WriteAsync(responseTextAsBytes, 0, responseTextAsBytes.Length, cancellationToken);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
@@ -115,7 +114,7 @@ namespace Emby.Server.Implementations.Services
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task WriteObject(IRequest request, object result, IResponse response)
|
||||
public static async Task WriteObject(IRequest request, object result, HttpResponse response)
|
||||
{
|
||||
var contentType = request.ResponseContentType;
|
||||
var serializer = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType);
|
||||
@@ -127,11 +126,11 @@ namespace Emby.Server.Implementations.Services
|
||||
ms.Position = 0;
|
||||
|
||||
var contentLength = ms.Length;
|
||||
response.OriginalResponse.ContentLength = contentLength;
|
||||
response.ContentLength = contentLength;
|
||||
|
||||
if (contentLength > 0)
|
||||
{
|
||||
await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false);
|
||||
await ms.CopyToAsync(response.Body).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ namespace Emby.Server.Implementations.Services
|
||||
|
||||
public Task<object> Execute(HttpListenerHost httpHost, object requestDto, IRequest req)
|
||||
{
|
||||
req.Dto = requestDto;
|
||||
var requestType = requestDto.GetType();
|
||||
req.OperationName = requestType.Name;
|
||||
|
||||
@@ -161,9 +160,6 @@ namespace Emby.Server.Implementations.Services
|
||||
serviceRequiresContext.Request = req;
|
||||
}
|
||||
|
||||
if (req.Dto == null) // Don't override existing batched DTO[]
|
||||
req.Dto = requestDto;
|
||||
|
||||
//Executes the service and returns the result
|
||||
return ServiceExecGeneral.Execute(serviceType, req, service, requestDto, requestType.GetMethodName());
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Emby.Server.Implementations.Services
|
||||
foreach (var requestFilter in actionContext.RequestFilters)
|
||||
{
|
||||
requestFilter.RequestFilter(request, request.Response, requestDto);
|
||||
if (request.Response.OriginalResponse.HasStarted)
|
||||
if (request.Response.HasStarted)
|
||||
{
|
||||
Task.FromResult<object>(null);
|
||||
}
|
||||
|
||||
@@ -5,20 +5,21 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Emby.Server.Implementations.HttpServer;
|
||||
using MediaBrowser.Model.Services;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Emby.Server.Implementations.Services
|
||||
{
|
||||
public class ServiceHandler
|
||||
{
|
||||
public RestPath RestPath { get; }
|
||||
private RestPath _restPath;
|
||||
|
||||
public string ResponseContentType { get; }
|
||||
private string _responseContentType;
|
||||
|
||||
internal ServiceHandler(RestPath restPath, string responseContentType)
|
||||
{
|
||||
RestPath = restPath;
|
||||
ResponseContentType = responseContentType;
|
||||
_restPath = restPath;
|
||||
_responseContentType = responseContentType;
|
||||
}
|
||||
|
||||
protected static Task<object> CreateContentTypeRequest(HttpListenerHost host, IRequest httpReq, Type requestType, string contentType)
|
||||
@@ -54,7 +55,7 @@ namespace Emby.Server.Implementations.Services
|
||||
|
||||
private static string GetFormatContentType(string format)
|
||||
{
|
||||
//built-in formats
|
||||
// built-in formats
|
||||
switch (format)
|
||||
{
|
||||
case "json": return "application/json";
|
||||
@@ -63,16 +64,16 @@ namespace Emby.Server.Implementations.Services
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, IResponse httpRes, ILogger logger, CancellationToken cancellationToken)
|
||||
public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, HttpResponse httpRes, ILogger logger, CancellationToken cancellationToken)
|
||||
{
|
||||
httpReq.Items["__route"] = RestPath;
|
||||
httpReq.Items["__route"] = _restPath;
|
||||
|
||||
if (ResponseContentType != null)
|
||||
if (_responseContentType != null)
|
||||
{
|
||||
httpReq.ResponseContentType = ResponseContentType;
|
||||
httpReq.ResponseContentType = _responseContentType;
|
||||
}
|
||||
|
||||
var request = httpReq.Dto = await CreateRequest(httpHost, httpReq, RestPath, logger).ConfigureAwait(false);
|
||||
var request = await CreateRequest(httpHost, httpReq, _restPath, logger).ConfigureAwait(false);
|
||||
|
||||
httpHost.ApplyRequestFilters(httpReq, httpRes, request);
|
||||
|
||||
@@ -94,7 +95,7 @@ namespace Emby.Server.Implementations.Services
|
||||
if (RequireqRequestStream(requestType))
|
||||
{
|
||||
// Used by IRequiresRequestStream
|
||||
var requestParams = await GetRequestParams(httpReq).ConfigureAwait(false);
|
||||
var requestParams = GetRequestParams(httpReq.Response.HttpContext.Request);
|
||||
var request = ServiceHandler.CreateRequest(httpReq, restPath, requestParams, host.CreateInstance(requestType));
|
||||
|
||||
var rawReq = (IRequiresRequestStream)request;
|
||||
@@ -103,7 +104,7 @@ namespace Emby.Server.Implementations.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestParams = await GetFlattenedRequestParams(httpReq).ConfigureAwait(false);
|
||||
var requestParams = GetFlattenedRequestParams(httpReq.Response.HttpContext.Request);
|
||||
|
||||
var requestDto = await CreateContentTypeRequest(host, httpReq, restPath.RequestType, httpReq.ContentType).ConfigureAwait(false);
|
||||
|
||||
@@ -130,56 +131,42 @@ namespace Emby.Server.Implementations.Services
|
||||
/// <summary>
|
||||
/// Duplicate Params are given a unique key by appending a #1 suffix
|
||||
/// </summary>
|
||||
private static async Task<Dictionary<string, string>> GetRequestParams(IRequest request)
|
||||
private static Dictionary<string, string> GetRequestParams(HttpRequest request)
|
||||
{
|
||||
var map = new Dictionary<string, string>();
|
||||
|
||||
foreach (var name in request.QueryString.Keys)
|
||||
foreach (var pair in request.Query)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
// thank you ASP.NET
|
||||
continue;
|
||||
}
|
||||
|
||||
var values = request.QueryString[name];
|
||||
var values = pair.Value;
|
||||
if (values.Count == 1)
|
||||
{
|
||||
map[name] = values[0];
|
||||
map[pair.Key] = values[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
{
|
||||
map[name + (i == 0 ? "" : "#" + i)] = values[i];
|
||||
map[pair.Key + (i == 0 ? "" : "#" + i)] = values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT")))
|
||||
if (
|
||||
(IsMethod(request.Method, "POST") || IsMethod(request.Method, "PUT"))
|
||||
&& request.HasFormContentType)
|
||||
{
|
||||
var formData = await request.GetFormData().ConfigureAwait(false);
|
||||
if (formData != null)
|
||||
foreach (var pair in request.Form)
|
||||
{
|
||||
foreach (var name in formData.Keys)
|
||||
var values = pair.Value;
|
||||
if (values.Count == 1)
|
||||
{
|
||||
if (name == null)
|
||||
map[pair.Key] = values[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
{
|
||||
// thank you ASP.NET
|
||||
continue;
|
||||
}
|
||||
|
||||
var values = formData.GetValues(name);
|
||||
if (values.Count == 1)
|
||||
{
|
||||
map[name] = values[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
{
|
||||
map[name + (i == 0 ? "" : "#" + i)] = values[i];
|
||||
}
|
||||
map[pair.Key + (i == 0 ? "" : "#" + i)] = values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,36 +183,22 @@ namespace Emby.Server.Implementations.Services
|
||||
/// <summary>
|
||||
/// Duplicate params have their values joined together in a comma-delimited string
|
||||
/// </summary>
|
||||
private static async Task<Dictionary<string, string>> GetFlattenedRequestParams(IRequest request)
|
||||
private static Dictionary<string, string> GetFlattenedRequestParams(HttpRequest request)
|
||||
{
|
||||
var map = new Dictionary<string, string>();
|
||||
|
||||
foreach (var name in request.QueryString.Keys)
|
||||
foreach (var pair in request.Query)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
// thank you ASP.NET
|
||||
continue;
|
||||
}
|
||||
|
||||
map[name] = request.QueryString[name];
|
||||
map[pair.Key] = pair.Value;
|
||||
}
|
||||
|
||||
if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT")))
|
||||
if (
|
||||
(IsMethod(request.Method, "POST") || IsMethod(request.Method, "PUT"))
|
||||
&& request.HasFormContentType)
|
||||
{
|
||||
var formData = await request.GetFormData().ConfigureAwait(false);
|
||||
if (formData != null)
|
||||
foreach (var pair in request.Form)
|
||||
{
|
||||
foreach (var name in formData.Keys)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
// thank you ASP.NET
|
||||
continue;
|
||||
}
|
||||
|
||||
map[name] = formData[name];
|
||||
}
|
||||
map[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user