fix: presenting and serving unicode file names

This commit is contained in:
Massimo Melina 2020-05-03 16:27:01 +02:00
parent b654228675
commit 384d2d10f4
5 changed files with 24 additions and 13 deletions

7
.gitignore vendored
View File

@ -2,12 +2,15 @@ tmp/
__history/ __history/
__recovery/ __recovery/
win32/ win32/
.vscode/
*.vfs *.vfs
*.dcu *.dcu
*.exe *.exe
*.map *.map
hfs.ini
*.tmp *.tmp
*.bak *.bak
*.*- *.*-
*.corrupted *.corrupted
hfs.ini
hfs.identcache

Binary file not shown.

BIN
hfs.vrc

Binary file not shown.

View File

@ -102,6 +102,7 @@ type
RBM_STREAM // refer to bodyStream RBM_STREAM // refer to bodyStream
); );
body: ansistring; // specifies reply body according to bodyMode body: ansistring; // specifies reply body according to bodyMode
bodyFile: string;
bodyStream: Tstream; // note: the stream is automatically freed bodyStream: Tstream; // note: the stream is automatically freed
firstByte, lastByte: int64; // body interval for partial replies (206) firstByte, lastByte: int64; // body interval for partial replies (206)
realm: ansistring; // this will appear in the authentication dialog realm: ansistring; // this will appear in the authentication dialog
@ -528,7 +529,9 @@ while i<length(url) do
try try
url[j]:=ansichar(strToInt( '$'+url[i+1]+url[i+2] )); url[j]:=ansichar(strToInt( '$'+url[i+1]+url[i+2] ));
inc(i,2); // three chars for one inc(i,2); // three chars for one
except url[j]:='_' end; except url[j]:='_' end
else if i>j then
url[j]:=url[i];
end; end;
setLength(url, j); setLength(url, j);
if utf8 then if utf8 then
@ -1425,7 +1428,7 @@ if (state = HCS_REPLYING_HEADER) and (reply.mode <> HRM_REPLY_HEADER) then
reply.bodyMode:=RBM_STRING; reply.bodyMode:=RBM_STRING;
reply.body:=HRM2BODY[reply.mode]; reply.body:=HRM2BODY[reply.mode];
if reply.mode in [HRM_REDIRECT, HRM_MOVED] then if reply.mode in [HRM_REDIRECT, HRM_MOVED] then
reply.body:=stringReplace(reply.body, '%url%', reply.url, [rfReplaceAll]); reply.body:=replaceStr(reply.body, '%url%', reply.url);
initInputStream(); initInputStream();
end; end;
end; end;
@ -1502,7 +1505,7 @@ try
end; end;
RBM_FILE: RBM_FILE:
begin begin
i:=fileopen(reply.body, fmOpenRead+fmShareDenyNone); i:=fileopen(reply.bodyFile, fmOpenRead+fmShareDenyNone);
if i = -1 then exit; if i = -1 then exit;
stream:=TFileStream.Create(i); stream:=TFileStream.Create(i);
end; end;

View File

@ -1330,7 +1330,7 @@ result:=(mainfrm.listfileswithhiddenattributeChk.checked or (attr and faHidden =
end; // hasRightAttributes end; // hasRightAttributes
function hasRightAttributes(fn:string):boolean; overload; function hasRightAttributes(fn:string):boolean; overload;
begin result:=hasRightAttributes(GetFileAttributesA(pAnsiChar(ansiString(fn)))) end; begin result:=hasRightAttributes(GetFileAttributes(pChar(fn))) end;
function isAnyMacroIn(s:ansistring):boolean; inline; function isAnyMacroIn(s:ansistring):boolean; inline;
begin result:=pos(MARKER_OPEN, s) > 0 end; begin result:=pos(MARKER_OPEN, s) > 0 end;
@ -3242,7 +3242,7 @@ for i:=0 to length(parts)-1 do
n:=cur.getFirstChild(); n:=cur.getFirstChild();
while assigned(n) do while assigned(n) do
begin begin
found:=stringExists(n.text, s) or sameText(n.text, UTF8toString(s)); found:=sameText(n.text, s);
if found then break; if found then break;
n:=n.getNextSibling(); n:=n.getNextSibling();
end; end;
@ -3556,7 +3556,7 @@ try
diffTpl.fullText:=optUTF8(diffTpl.over, folder.getRecursiveDiffTplAsStr()); diffTpl.fullText:=optUTF8(diffTpl.over, folder.getRecursiveDiffTplAsStr());
isDMbrowser:= otpl = dmBrowserTpl; isDMbrowser:= otpl = dmBrowserTpl;
fullEncode:=not isDMbrowser; fullEncode:=FALSE;
ofsRelUrl:=length(folder.url(fullEncode))+1; ofsRelUrl:=length(folder.url(fullEncode))+1;
ofsRelItemUrl:=length(optUTF8(diffTpl, folder.pathTill()))+1; ofsRelItemUrl:=length(optUTF8(diffTpl, folder.pathTill()))+1;
// pathTill() is '/' for root, and 'just/folder', so we must accordingly consider a starting and trailing '/' for the latter case (bugfix by mars) // pathTill() is '/' for root, and 'just/folder', so we must accordingly consider a starting and trailing '/' for the latter case (bugfix by mars)
@ -4478,7 +4478,7 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn);
var var
data: TconnData; data: TconnData;
f: Tfile; f: Tfile;
url: ansistring; url: string;
procedure switchToDefaultFile(); procedure switchToDefaultFile();
var var
@ -4801,6 +4801,11 @@ var
assignFile(data.f^, data.uploadDest); assignFile(data.f^, data.uploadDest);
end; // getUploadDestinationFileName end; // getUploadDestinationFileName
procedure addContentDisposition(attach:boolean=TRUE);
begin
conn.addHeader( 'Content-Disposition: '+if_(attach, 'attachment; ')+'filename*=UTF-8''"'+UTF8encode(data.lastFN)+'";');
end;
procedure sessionSetup(); procedure sessionSetup();
begin begin
if (data = NIL) or assigned(data.session) then exit; if (data = NIL) or assigned(data.session) then exit;
@ -4948,7 +4953,7 @@ var
'%archive-size%', intToStr(tar.size) '%archive-size%', intToStr(tar.size)
]), data.lastFN); ]), data.lastFN);
if not noContentdispositionChk.checked then if not noContentdispositionChk.checked then
conn.addHeader('Content-Disposition: attachment; filename="'+data.lastFN+'";'); addContentDisposition();
except tar.free end; except tar.free end;
end; // serveTar end; // serveTar
@ -5029,7 +5034,7 @@ var
conn.reply.contentType:=if_(trim(getTill('<', s))='', 'text/html', 'text/plain'); conn.reply.contentType:=if_(trim(getTill('<', s))='', 'text/html', 'text/plain');
conn.reply.mode:=HRM_REPLY; conn.reply.mode:=HRM_REPLY;
conn.reply.bodyMode:=RBM_STRING; conn.reply.bodyMode:=RBM_STRING;
conn.reply.body:=s; conn.reply.body:=UTF8encode(s);
compressReply(data); compressReply(data);
end; // replyWithString end; // replyWithString
@ -5474,7 +5479,7 @@ var
data.eta.idx:=0; data.eta.idx:=0;
conn.reply.contentType:=name2mimetype(f.name, DEFAULT_MIME); conn.reply.contentType:=name2mimetype(f.name, DEFAULT_MIME);
conn.reply.bodyMode:=RBM_FILE; conn.reply.bodyMode:=RBM_FILE;
conn.reply.body:=f.resource; conn.reply.bodyFile:=f.resource;
data.downloadingWhat:=DW_FILE; data.downloadingWhat:=DW_FILE;
{ I guess this would not help in any way for files since we are already handling the 'if-modified-since' field { I guess this would not help in any way for files since we are already handling the 'if-modified-since' field
try try
@ -5493,7 +5498,7 @@ var
if (data.agent = 'MSIE') and (conn.getHeader('Accept') = '*/*') then if (data.agent = 'MSIE') and (conn.getHeader('Accept') = '*/*') then
s:=replaceStr(s, ' ','%20'); s:=replaceStr(s, ' ','%20');
if not noContentdispositionChk.checked or not b then if not noContentdispositionChk.checked or not b then
conn.addHeader( 'Content-Disposition: '+if_(not b, 'attachment; ')+'filename="'+s+'";' ); addContentDisposition(not b);
end; // handleRequest end; // handleRequest
procedure lastByte(); procedure lastByte();