Skip to content

Commit 20c78e4

Browse files
author
Eric
committed
Ensure extensions are checked longest-first
1 parent 2a38f50 commit 20c78e4

1 file changed

Lines changed: 34 additions & 10 deletions

File tree

Demos/HttpSys2WebServer/UHttpSys2WebServer.pas

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
286289
begin
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;
293296
end;
294297

@@ -315,6 +318,24 @@ procedure THttpSys2WebServer.RegisterExtensions(list : TdwsJSONValue; typ : TFil
315318
end;
316319
end;
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
//
320341
function THttpSys2WebServer.FileAccessTypeFromFileName(const fileName : TFileName) : TFileAccessType;
@@ -323,11 +344,12 @@ function THttpSys2WebServer.FileAccessTypeFromFileName(const fileName : TFileNam
323344
begin
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;
333355
end;
@@ -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

Comments
 (0)