@@ -57,6 +57,8 @@ TDWSExtension = record
5757 Str : String;
5858 Typ : TFileAccessType;
5959 end ;
60+ TDWSExtensions = array of TDWSExtension;
61+ PDWSExtensions = ^TDWSExtensions;
6062
6163 THttpSys2WebServer = class (TInterfacedSelfObject, IHttpSys2WebServer, IWebServerInfo)
6264 protected
@@ -71,7 +73,7 @@ THttpSys2WebServer = class (TInterfacedSelfObject, IHttpSys2WebServer, IWebSe
7173 // Used to implement a lazy flush on FileAccessInfoCaches
7274 FCacheCounter : Cardinal;
7375 FFileAccessInfoCacheSize : Integer;
74- FDWSExtensions : array [' / ' ..' Z ' ] of array of TDWSExtension ;
76+ FDWSExtensions : array [' a ' ..' z ' ] of TDWSExtensions ;
7577 FDefaultFileAccessType : TFileAccessType;
7678 FMethodsNotAllowed : TWebRequestMethodVerbs;
7779 FURLRewriter : TdwsURLRewriter;
@@ -82,8 +84,9 @@ THttpSys2WebServer = class (TInterfacedSelfObject, IHttpSys2WebServer, IWebSe
8284 function HttpPort : Integer;
8385 function HttpsPort : Integer;
8486
85- class function NormalizedExtensionLastChar (lastChar : Char) : Char; static ; inline;
87+ function NormalizedExtensionLastChar (lastChar : Char) : Char; inline;
8688 procedure RegisterExtensions (list : TdwsJSONValue; typ : TFileAccessType);
89+ procedure SortExtensionsByLength ;
8790
8891 function FileAccessTypeFromFileName (const fileName : TFileName) : TFileAccessType;
8992
@@ -282,13 +285,13 @@ destructor THttpSys2WebServer.Destroy;
282285
283286// NormalizedExtensionLastChar
284287//
285- class function THttpSys2WebServer.NormalizedExtensionLastChar (lastChar : Char) : Char;
288+ function THttpSys2WebServer.NormalizedExtensionLastChar (lastChar : Char) : Char;
286289begin
287290 case lastChar of
288- ' 0 ' ..' 9 ' , ' A ' .. ' Z ' : Result := lastChar;
289- ' a ' ..' z ' : Result := Char(Ord(lastChar) + (Ord(' A ' ) - Ord(' a ' )));
291+ ' a ' ..' z ' : Result := lastChar;
292+ ' A ' ..' Z ' : Result := Char(Ord(lastChar) + (Ord(' a ' ) - Ord(' A ' )));
290293 else
291- Result := ' / ' ; // catch all
294+ Result := Low(FDWSExtensions) ; // catch all
292295 end ;
293296end ;
294297
@@ -315,6 +318,24 @@ procedure THttpSys2WebServer.RegisterExtensions(list : TdwsJSONValue; typ : TFil
315318 end ;
316319end ;
317320
321+ // SortExtensionsByLength
322+ //
323+ procedure THttpSys2WebServer.SortExtensionsByLength ;
324+ begin
325+ for var lastChar := Low(FDWSExtensions) to High(FDWSExtensions) do begin
326+ var extensions : PDWSExtensions := @FDWSExtensions[lastChar];
327+ var n := Length(extensions^);
328+ for var i := 0 to n - 2 do begin
329+ var maxIdx := i;
330+ for var j := i + 1 to n - 1 do
331+ if Length(extensions^[j].Str) > Length(extensions^[maxIdx].Str) then
332+ maxIdx := j;
333+ if maxIdx <> i then
334+ ExchangeBytes(extensions^[i], extensions^[maxIdx], SizeOf(TDWSExtension));
335+ end ;
336+ end ;
337+ end ;
338+
318339// FileAccessTypeFromFileName
319340//
320341function THttpSys2WebServer.FileAccessTypeFromFileName (const fileName : TFileName) : TFileAccessType;
@@ -323,11 +344,12 @@ function THttpSys2WebServer.FileAccessTypeFromFileName(const fileName : TFileNam
323344begin
324345 if fileName <> ' ' then
325346 lastChar := NormalizedExtensionLastChar(fileName[Length(fileName)])
326- else lastChar := ' / ' ;
347+ else lastChar := Low(FDWSExtensions) ;
327348
328- for var i := 0 to High(FDWSExtensions[lastChar]) do begin
329- if StrIEndsWith(fileName, FDWSExtensions[lastChar][i].Str) then
330- Exit(FDWSExtensions[lastChar][i].Typ);
349+ var extensions : PDWSExtensions := @FDWSExtensions[lastChar];
350+ for var i := 0 to High(extensions^) do begin
351+ if StrIEndsWith(fileName, extensions^[i].Str) then
352+ Exit(extensions^[i].Typ);
331353 end ;
332354 Result := FDefaultFileAccessType;
333355end ;
@@ -419,6 +441,8 @@ procedure THttpSys2WebServer.Initialize(const basePath : TFileName; options : Td
419441 FDefaultFileAccessType := fatRAW;
420442 end ;
421443
444+ SortExtensionsByLength;
445+
422446 FURLInfos := EnumerateURLInfos(serverOptions);
423447 for i := 0 to High(FURLInfos) do
424448 FServer.AddUrl(FURLInfos[i]);
0 commit comments