mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-02-10 22:52:25 +00:00
fix turkish character recognition problems
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace ServiceStack.Host
|
||||
@@ -54,11 +55,11 @@ namespace ServiceStack.Host
|
||||
return requestFactoryFn != null ? requestFactoryFn(httpReq) : null;
|
||||
}
|
||||
|
||||
public static RestPath FindMatchingRestPath(string httpMethod, string pathInfo, out string contentType)
|
||||
public static RestPath FindMatchingRestPath(string httpMethod, string pathInfo, ILogger logger, out string contentType)
|
||||
{
|
||||
pathInfo = GetSanitizedPathInfo(pathInfo, out contentType);
|
||||
|
||||
return ServiceStackHost.Instance.ServiceController.GetRestPathForRequest(httpMethod, pathInfo);
|
||||
return ServiceStackHost.Instance.ServiceController.GetRestPathForRequest(httpMethod, pathInfo, logger);
|
||||
}
|
||||
|
||||
public static string GetSanitizedPathInfo(string pathInfo, out string contentType)
|
||||
@@ -93,7 +94,7 @@ namespace ServiceStack.Host
|
||||
if (this.RestPath == null)
|
||||
{
|
||||
string contentType;
|
||||
this.RestPath = FindMatchingRestPath(httpMethod, pathInfo, out contentType);
|
||||
this.RestPath = FindMatchingRestPath(httpMethod, pathInfo, new NullLogger(), out contentType);
|
||||
|
||||
if (contentType != null)
|
||||
ResponseContentType = contentType;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using ServiceStack.Serialization;
|
||||
|
||||
namespace ServiceStack.Host
|
||||
@@ -46,11 +47,11 @@ namespace ServiceStack.Host
|
||||
|
||||
public string[] Verbs
|
||||
{
|
||||
get
|
||||
{
|
||||
return allowsAllVerbs
|
||||
? new[] { ActionContext.AnyAction }
|
||||
: AllowedVerbs.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
get
|
||||
{
|
||||
return allowsAllVerbs
|
||||
? new[] { ActionContext.AnyAction }
|
||||
: AllowedVerbs.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,31 +76,36 @@ namespace ServiceStack.Host
|
||||
return parts;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetFirstMatchHashKeys(string[] pathPartsForMatching)
|
||||
public static List<string> GetFirstMatchHashKeys(string[] pathPartsForMatching)
|
||||
{
|
||||
var hashPrefix = pathPartsForMatching.Length + PathSeperator;
|
||||
return GetPotentialMatchesWithPrefix(hashPrefix, pathPartsForMatching);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetFirstMatchWildCardHashKeys(string[] pathPartsForMatching)
|
||||
public static List<string> GetFirstMatchWildCardHashKeys(string[] pathPartsForMatching)
|
||||
{
|
||||
const string hashPrefix = WildCard + PathSeperator;
|
||||
return GetPotentialMatchesWithPrefix(hashPrefix, pathPartsForMatching);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPotentialMatchesWithPrefix(string hashPrefix, string[] pathPartsForMatching)
|
||||
private static List<string> GetPotentialMatchesWithPrefix(string hashPrefix, string[] pathPartsForMatching)
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
foreach (var part in pathPartsForMatching)
|
||||
{
|
||||
yield return hashPrefix + part;
|
||||
list.Add(hashPrefix + part);
|
||||
|
||||
var subParts = part.Split(ComponentSeperator);
|
||||
if (subParts.Length == 1) continue;
|
||||
|
||||
foreach (var subPart in subParts)
|
||||
{
|
||||
yield return hashPrefix + subPart;
|
||||
list.Add(hashPrefix + subPart);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public RestPath(Type requestType, string path, string verbs, string summary = null, string notes = null)
|
||||
@@ -220,16 +226,14 @@ namespace ServiceStack.Host
|
||||
|
||||
private readonly Dictionary<string, string> propertyNamesMap = new Dictionary<string, string>();
|
||||
|
||||
public static Func<RestPath, string, string[], int> CalculateMatchScore { get; set; }
|
||||
|
||||
public int MatchScore(string httpMethod, string[] withPathInfoParts)
|
||||
public int MatchScore(string httpMethod, string[] withPathInfoParts, ILogger logger)
|
||||
{
|
||||
if (CalculateMatchScore != null)
|
||||
return CalculateMatchScore(this, httpMethod, withPathInfoParts);
|
||||
|
||||
int wildcardMatchCount;
|
||||
var isMatch = IsMatch(httpMethod, withPathInfoParts, out wildcardMatchCount);
|
||||
if (!isMatch) return -1;
|
||||
var isMatch = IsMatch(httpMethod, withPathInfoParts, logger, out wildcardMatchCount);
|
||||
if (!isMatch)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var score = 0;
|
||||
|
||||
@@ -255,19 +259,33 @@ namespace ServiceStack.Host
|
||||
/// For performance withPathInfoParts should already be a lower case string
|
||||
/// to minimize redundant matching operations.
|
||||
/// </summary>
|
||||
/// <param name="httpMethod"></param>
|
||||
/// <param name="withPathInfoParts"></param>
|
||||
/// <param name="wildcardMatchCount"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsMatch(string httpMethod, string[] withPathInfoParts, out int wildcardMatchCount)
|
||||
public bool IsMatch(string httpMethod, string[] withPathInfoParts, ILogger logger, out int wildcardMatchCount)
|
||||
{
|
||||
wildcardMatchCount = 0;
|
||||
|
||||
if (withPathInfoParts.Length != this.PathComponentsCount && !this.IsWildCardPath) return false;
|
||||
if (!this.allowsAllVerbs && !StringContains(this.allowedVerbs, httpMethod)) return false;
|
||||
if (withPathInfoParts.Length != this.PathComponentsCount && !this.IsWildCardPath)
|
||||
{
|
||||
//logger.Info("withPathInfoParts mismatch for {0} for {1}", httpMethod, string.Join("/", withPathInfoParts));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ExplodeComponents(ref withPathInfoParts)) return false;
|
||||
if (this.TotalComponentsCount != withPathInfoParts.Length && !this.IsWildCardPath) return false;
|
||||
if (!this.allowsAllVerbs && !StringContains(this.allowedVerbs, httpMethod))
|
||||
{
|
||||
//logger.Info("allowsAllVerbs mismatch for {0} for {1} allowedverbs {2}", httpMethod, string.Join("/", withPathInfoParts), this.allowedVerbs);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ExplodeComponents(ref withPathInfoParts))
|
||||
{
|
||||
//logger.Info("ExplodeComponents mismatch for {0} for {1}", httpMethod, string.Join("/", withPathInfoParts));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.TotalComponentsCount != withPathInfoParts.Length && !this.IsWildCardPath)
|
||||
{
|
||||
//logger.Info("TotalComponentsCount mismatch for {0} for {1}", httpMethod, string.Join("/", withPathInfoParts));
|
||||
return false;
|
||||
}
|
||||
|
||||
int pathIx = 0;
|
||||
for (var i = 0; i < this.TotalComponentsCount; i++)
|
||||
@@ -277,7 +295,7 @@ namespace ServiceStack.Host
|
||||
if (i < this.TotalComponentsCount - 1)
|
||||
{
|
||||
// Continue to consume up until a match with the next literal
|
||||
while (pathIx < withPathInfoParts.Length && withPathInfoParts[pathIx] != this.literalsToMatch[i + 1])
|
||||
while (pathIx < withPathInfoParts.Length && !LiteralsEqual(withPathInfoParts[pathIx], this.literalsToMatch[i + 1]))
|
||||
{
|
||||
pathIx++;
|
||||
wildcardMatchCount++;
|
||||
@@ -286,6 +304,7 @@ namespace ServiceStack.Host
|
||||
// Ensure there are still enough parts left to match the remainder
|
||||
if ((withPathInfoParts.Length - pathIx) < (this.TotalComponentsCount - i - 1))
|
||||
{
|
||||
//logger.Info("withPathInfoParts length mismatch for {0} for {1}", httpMethod, string.Join("/", withPathInfoParts));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -306,7 +325,11 @@ namespace ServiceStack.Host
|
||||
continue;
|
||||
}
|
||||
|
||||
if (withPathInfoParts.Length <= pathIx || withPathInfoParts[pathIx] != literalToMatch) return false;
|
||||
if (withPathInfoParts.Length <= pathIx || !LiteralsEqual(withPathInfoParts[pathIx], literalToMatch))
|
||||
{
|
||||
//logger.Info("withPathInfoParts2 length mismatch for {0} for {1}. not equals: {2} != {3}.", httpMethod, string.Join("/", withPathInfoParts), withPathInfoParts[pathIx], literalToMatch);
|
||||
return false;
|
||||
}
|
||||
pathIx++;
|
||||
}
|
||||
}
|
||||
@@ -314,6 +337,22 @@ namespace ServiceStack.Host
|
||||
return pathIx == withPathInfoParts.Length;
|
||||
}
|
||||
|
||||
private bool LiteralsEqual(string str1, string str2)
|
||||
{
|
||||
// Most cases
|
||||
if (string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle turkish i
|
||||
str1 = str1.ToUpperInvariant();
|
||||
str2 = str2.ToUpperInvariant();
|
||||
|
||||
// Invariant IgnoreCase would probably be better but it's not available in PCL
|
||||
return string.Equals(str1, str2, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
private bool ExplodeComponents(ref string[] withPathInfoParts)
|
||||
{
|
||||
var totalComponents = new List<string>();
|
||||
@@ -374,9 +413,9 @@ namespace ServiceStack.Host
|
||||
if (string.Equals("ignore", variableName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
pathIx++;
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
throw new ArgumentException("Could not find property "
|
||||
+ variableName + " on " + RequestType.GetOperationName());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace ServiceStack.Host
|
||||
@@ -135,7 +136,7 @@ namespace ServiceStack.Host
|
||||
appHost.RestPaths.AddRange(RestPathMap.Values.SelectMany(x => x));
|
||||
}
|
||||
|
||||
public RestPath GetRestPathForRequest(string httpMethod, string pathInfo)
|
||||
public RestPath GetRestPathForRequest(string httpMethod, string pathInfo, ILogger logger)
|
||||
{
|
||||
var matchUsingPathParts = RestPath.GetPathPartsForMatching(pathInfo);
|
||||
|
||||
@@ -144,19 +145,23 @@ namespace ServiceStack.Host
|
||||
var yieldedHashMatches = RestPath.GetFirstMatchHashKeys(matchUsingPathParts);
|
||||
foreach (var potentialHashMatch in yieldedHashMatches)
|
||||
{
|
||||
if (!this.RestPathMap.TryGetValue(potentialHashMatch, out firstMatches)) continue;
|
||||
if (!this.RestPathMap.TryGetValue(potentialHashMatch, out firstMatches))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var bestScore = -1;
|
||||
foreach (var restPath in firstMatches)
|
||||
{
|
||||
var score = restPath.MatchScore(httpMethod, matchUsingPathParts);
|
||||
var score = restPath.MatchScore(httpMethod, matchUsingPathParts, logger);
|
||||
if (score > bestScore) bestScore = score;
|
||||
}
|
||||
|
||||
if (bestScore > 0)
|
||||
{
|
||||
foreach (var restPath in firstMatches)
|
||||
{
|
||||
if (bestScore == restPath.MatchScore(httpMethod, matchUsingPathParts))
|
||||
if (bestScore == restPath.MatchScore(httpMethod, matchUsingPathParts, logger))
|
||||
return restPath;
|
||||
}
|
||||
}
|
||||
@@ -170,14 +175,14 @@ namespace ServiceStack.Host
|
||||
var bestScore = -1;
|
||||
foreach (var restPath in firstMatches)
|
||||
{
|
||||
var score = restPath.MatchScore(httpMethod, matchUsingPathParts);
|
||||
var score = restPath.MatchScore(httpMethod, matchUsingPathParts, logger);
|
||||
if (score > bestScore) bestScore = score;
|
||||
}
|
||||
if (bestScore > 0)
|
||||
{
|
||||
foreach (var restPath in firstMatches)
|
||||
{
|
||||
if (bestScore == restPath.MatchScore(httpMethod, matchUsingPathParts))
|
||||
if (bestScore == restPath.MatchScore(httpMethod, matchUsingPathParts, logger))
|
||||
return restPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,19 @@ namespace ServiceStack
|
||||
}
|
||||
|
||||
string contentType;
|
||||
var restPath = RestHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out contentType);
|
||||
if (restPath != null)
|
||||
return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
|
||||
var restPath = RestHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, logger, out contentType);
|
||||
|
||||
if (restPath != null)
|
||||
{
|
||||
return new RestHandler
|
||||
{
|
||||
RestPath = restPath,
|
||||
RequestName = restPath.RequestType.GetOperationName(),
|
||||
ResponseContentType = contentType
|
||||
};
|
||||
}
|
||||
|
||||
logger.Error("Could not find handler for {0}", pathInfo);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user