Compare commits

..

No commits in common. "master" and "v2.4-beta03" have entirely different histories.

27 changed files with 2790 additions and 3592 deletions

2
.gitignore vendored
View File

@ -3,13 +3,11 @@ __history/
__recovery/ __recovery/
win32/ win32/
.vscode/ .vscode/
.idea/
*.vfs *.vfs
*.dcu *.dcu
*.exe *.exe
*.map *.map
*.tmp *.tmp
*.dll
*.bak *.bak
*.*- *.*-
*.corrupted *.corrupted

View File

@ -1,26 +1,5 @@
# Obsolete
This is the repository of the old HFS.
I'm working on HFS 3 on another repository. Check it out!
https://github.com/rejetto/hfs
## Introduction
You can use HFS (HTTP File Server) to send and receive files. You can use HFS (HTTP File Server) to send and receive files.
It's different from classic file sharing because it uses web technology. It's different from classic file sharing because it uses web technology.
It also differs from classic web servers because it's very easy to use and runs "right out-of-the box". It also differs from classic web servers because it's very easy to use and runs "right out-of-the box".
The virtual file system will allow you to easily share even one single file. The virtual file system will allow you to easily share even one single file.
## Dev notes
Initially developed in 2002 with Delphi 6, now with Delphi 10.3.3 (Community Edition).
Icons are generated at http://fontello.com/ . Use fontello.json for further modifications.
For the default template we are targeting compatibility with Chrome 49 as it's the latest version running on Windows XP.
Warning: Delphi Community Edition 10.4 removed support for command-line compilation, and is thus unable to compile JEDI Code Library, and is thus unable to compile HFS2, ref [Community Edition no longer includes the command-line compilers](https://blogs.embarcadero.com/delphi-cbuilder-community-editions-now-available-in-version-10-4-2/#comment-1339) - meaning the last version of Community Edition cabale of compiling HFS2 is Delphi 10.3.x
## Libs used
- [ICS v8.64](http://www.overbyte.be) by François PIETTE
- [TRegExpr v0.952b](https://github.com/andgineer/TRegExpr/releases) by Andrey V. Sorokin
- [JEDI Code Library v2.7](https://github.com/project-jedi/jcl)
- [Kryvich's Delphi Localizer v4.1](http://sites.google.com/site/kryvich)

View File

@ -1,5 +1,5 @@
{ {
Copyright (C) 2002-2020 Massimo Melina (www.rejetto.com) Copyright (C) 2002-2012 Massimo Melina (www.rejetto.com)
This file is part of HFS ~ HTTP File Server. This file is part of HFS ~ HTTP File Server.
@ -23,20 +23,9 @@ unit classesLib;
interface interface
uses uses
iniFiles, types, hslib, strUtils, sysUtils, classes, math, system.Generics.Collections, iniFiles, types, hslib, strUtils, sysUtils, classes, math, system.Generics.Collections;
OverbyteIcsWSocket, OverbyteIcshttpProt;
type type
TantiDos = class
protected
accepted: boolean;
Paddress: string;
public
constructor create;
destructor Destroy; override;
function accept(conn:ThttpConn; address:string=''):boolean;
end;
TfastStringAppend = class TfastStringAppend = class
protected protected
buff: string; buff: string;
@ -99,7 +88,6 @@ type
constructor create; constructor create;
destructor Destroy; override; destructor Destroy; override;
function addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; virtual; function addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; virtual;
function contains(src:string):boolean;
function count():integer; function count():integer;
procedure reset(); virtual; procedure reset(); virtual;
property totalSize:int64 read getTotal; property totalSize:int64 read getTotal;
@ -150,7 +138,7 @@ type
PtplSection = ^TtplSection; PtplSection = ^TtplSection;
TtplSection = record TtplSection = record
name, txt: string; name, txt: string;
nolog, public, noList, cache: boolean; nolog, nourl, cache: boolean;
ts: Tdatetime; ts: Tdatetime;
end; end;
@ -201,12 +189,6 @@ type
destructor Destroy; override; destructor Destroy; override;
end; end;
ThttpClient = class(TSslHttpCli)
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
class function createURL(url:string):ThttpClient;
end;
Ttlv = class Ttlv = class
protected protected
cur, bound: integer; cur, bound: integer;
@ -232,94 +214,6 @@ implementation
uses uses
utilLib, main, windows, dateUtils, forms; utilLib, main, windows, dateUtils, forms;
const folderConcurrents: integer = 0;
const MAX_CONCURRENTS = 3;
const ip2availability: Tdictionary<string,Tdatetime> = NIL;
constructor TantiDos.create();
begin
accepted:=FALSE;
end;
function TantiDos.accept(conn:ThttpConn; address:string=''):boolean;
procedure reject();
resourcestring
MSG_ANTIDOS_REPLY = 'Please wait, server busy';
begin
conn.reply.mode:=HRM_OVERLOAD;
conn.addHeader(ansistring('Refresh: '+intToStr(1+random(2)))); // random for less collisions
conn.reply.body:=UTF8Encode(MSG_ANTIDOS_REPLY);
end;
begin
if address= '' then
address:=conn.address;
if ip2availability = NIL then
ip2availability:=Tdictionary<string,Tdatetime>.create();
try
if ip2availability[address] > now() then // this specific address has to wait?
begin
reject();
exit(FALSE);
end;
except
end;
if folderConcurrents >= MAX_CONCURRENTS then // max number of concurrent folder loading, others are postponed
begin
reject();
exit(FALSE);
end;
inc(folderConcurrents);
Paddress:=address;
ip2availability.AddOrSetValue(address, now()+1/HOURS);
accepted:=TRUE;
Result:=TRUE;
end;
destructor TantiDos.Destroy;
var
pair: Tpair<string,Tdatetime>;
t: Tdatetime;
begin
if not accepted then
exit;
t:=now();
if folderConcurrents = MAX_CONCURRENTS then // serving multiple addresses at max capacity, let's give a grace period for others
ip2availability[Paddress]:=t + 1/SECONDS
else
ip2availability.Remove(Paddress);
dec(folderConcurrents);
// purge leftovers
for pair in ip2availability do
if pair.Value < t then
ip2availability.Remove(pair.Key);
end;
class function ThttpClient.createURL(url:string):ThttpClient;
begin
if startsText('https://', url)
and not httpsCanWork() then
exit(NIL);
result:=ThttpClient.Create(NIL);
result.URL:=url;
end;
constructor ThttpClient.create(AOwner: TComponent);
begin
inherited;
followRelocation:=TRUE;
agent:=HFS_HTTP_AGENT;
SslContext := TSslContext.Create(NIL);
end; // create
destructor ThttpClient.Destroy;
begin
SslContext.free;
SslContext:=NIl;
inherited destroy;
end;
constructor TperIp.create(); constructor TperIp.create();
begin begin
limiter:=TspeedLimiter.create(); limiter:=TspeedLimiter.create();
@ -525,16 +419,6 @@ if cachedTotal < 0 then calculate();
result:=cachedTotal; result:=cachedTotal;
end; // getTotal end; // getTotal
function TarchiveStream.contains(src:string):boolean;
var
i: integer;
begin
for i:=0 to Length(flist)-1 do
if flist[i].src = src then
exit(TRUE);
result:=FALSE;
end;
function TarchiveStream.addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; function TarchiveStream.addFile(src:string; dst:string=''; data:Tobject=NIL):boolean;
function getMtime(fh:Thandle):int64; function getMtime(fh:Thandle):int64;
@ -620,7 +504,10 @@ end; // reset
function TtarStream.fsInit():boolean; function TtarStream.fsInit():boolean;
begin begin
if assigned(fs) and (fs.FileName = flist[cur].src) then if assigned(fs) and (fs.FileName = flist[cur].src) then
exit(TRUE); begin
result:=TRUE;
exit;
end;
result:=FALSE; result:=FALSE;
try try
freeAndNIL(fs); freeAndNIL(fs);
@ -859,12 +746,10 @@ var
var var
i, posBak: int64; i, posBak: int64;
n: integer;
begin begin
posBak:=pos; posBak:=pos;
p:=@buffer; p:=@buffer;
n:=length(flist); while (count > 0) and (cur < length(flist)) do
while (count > 0) and (cur < n) do
case where of case where of
TW_HEADER: TW_HEADER:
begin begin
@ -1028,7 +913,7 @@ if sections.containsKey(section) then
result:=sections[section] result:=sections[section]
else else
result:=NIL; result:=NIL;
if inherit and assigned(over) and (result = NIL) then if inherit and assigned(over) and ((result = NIL) or (trim(result.txt) = '')) then
result:=over.getSection(section); result:=over.getSection(section);
end; // getSection end; // getSection
@ -1043,7 +928,7 @@ else
end; // getTxt end; // getTxt
function Ttpl.getTxtByExt(fileExt:string):string; function Ttpl.getTxtByExt(fileExt:string):string;
begin result:=getTxt('file'+fileExt) end; begin result:=getTxt('file.'+fileExt) end;
procedure Ttpl.fromString(txt:string); procedure Ttpl.fromString(txt:string);
var var
@ -1092,53 +977,13 @@ var
end; // findNextSection end; // findNextSection
procedure saveInSection(); procedure saveInSection();
var
base: TtplSection;
function parseFlagsAndAcceptSection(flags:TStringDynArray):boolean;
var
f, k, v, s: string;
i: integer;
begin
for f in flags do
begin
i:=pos('=',f);
if i = 0 then
begin
if f='no log' then
base.nolog:=TRUE
else if f='public' then
base.public:=TRUE
else if f='no list' then
base.noList:=TRUE
else if f='cache' then
base.cache:=TRUE;
Continue;
end;
k:=copy(f,1,i-1);
v:=copy(f,i+1,MAXINT);
if k = 'build' then
begin
s:=chop('-',v);
if (v > '') and (VERSION_BUILD > v) // max
or (s > '') and (VERSION_BUILD < s) then // min
exit(FALSE);
end
else if k = 'ver' then
if fileMatch(v, VERSION) then continue
else exit(FALSE)
else if k = 'template' then
if fileMatch(v, getTill(#13,getTxt('template id'))) then continue
else exit(FALSE)
end;
result:=TRUE;
end;
var var
ss: TStringDynArray; ss: TStringDynArray;
s, si: string; s: string;
i: integer;
base: TtplSection;
till: pchar; till: pchar;
append, prepend, add: boolean; append: boolean;
sect, from: PtplSection; sect, from: PtplSection;
begin begin
till:=pred(bos); till:=pred(bos);
@ -1146,49 +991,44 @@ var
if till^ = #10 then dec(till); if till^ = #10 then dec(till);
if till^ = #13 then dec(till); if till^ = #13 then dec(till);
base:=default(TtplSection);
base.txt:=getStr(ptxt, till); base.txt:=getStr(ptxt, till);
// there may be flags after |
s:=cur_section;
cur_section:=chop('|', s);
base.nolog:=ansiPos('no log', s) > 0;
base.nourl:=ansiPos('private', s) > 0;
base.cache:=ansiPos('cache', s) > 0;
base.ts:=now(); base.ts:=now();
ss:=split('|',cur_section);
cur_section:=popString(ss);
if not parseFlagsAndAcceptSection(ss) then
exit;
prepend:=startsStr('^', cur_section); s:=cur_section;
append:=startsStr('+', cur_section); append:=ansiStartsStr('+', s);
add:=prepend or append; if append then
if add then delete(s,1,1);
delete(cur_section,1,1);
// there may be several section names separated by = // there may be several section names separated by =
ss:=split('=', cur_section); ss:=split('=', s);
// handle the main section specific case // handle the main section specific case
if ss = NIL then if ss = NIL then addString('', ss);
addString('', ss);
// assign to every name the same txt // assign to every name the same txt
for si in ss do for i:=0 to length(ss)-1 do
begin begin
s:=trim(si); s:=trim(ss[i]);
sect:=getSection(s, FALSE); sect:=getSection(s, FALSE);
from:=NIL; from:=NIL;
if sect = NIL then // not found if sect = NIL then // not found
begin begin
if add then if append then
from:=getSection(s); from:=getSection(s);
sect:=newSection(s); sect:=newSection(s);
end end
else else
if add then if append then
from:=sect; from:=sect;
if from<>NIL then if from<>NIL then
begin // inherit from it begin // inherit from it
if append then sect.txt:=from.txt+base.txt;
sect.txt:=from.txt+base.txt
else
sect.txt:=base.txt+CRLF+from.txt;
sect.nolog:=from.nolog or base.nolog; sect.nolog:=from.nolog or base.nolog;
sect.public:=from.public or base.public; sect.nourl:=from.nourl or base.nourl;
sect.noList:=from.noList or base.noList;
continue; continue;
end; end;
sect^:=base; sect^:=base;
@ -1197,13 +1037,14 @@ var
end; // saveInSection end; // saveInSection
const const
UTF8_BOM = #$EF#$BB#$BF; BOM = #$EF#$BB#$BF;
var var
first: boolean; first: boolean;
begin begin
if ansiStartsStr(UTF8_BOM, txt) then // this is used by some unicode files. at the moment we just ignore it.
delete(txt, 1, length(UTF8_BOM)); if ansiStartsStr(BOM, txt) then
delete(txt, 1, length(BOM));
if txt = '' then exit; if txt = '' then exit;
src:=src+txt; src:=src+txt;
cur_section:=''; cur_section:='';
@ -1248,8 +1089,8 @@ function Ttlv.pop(var value:string; var raw:ansistring):integer;
var var
n: integer; n: integer;
begin begin
if isOver() then result:=-1;
exit(-1); // finished if isOver() then exit; // finished
result:=integer((@whole[cur])^); result:=integer((@whole[cur])^);
n:=Pinteger(@whole[cur+4])^; n:=Pinteger(@whole[cur+4])^;
raw:=copy(whole, cur+8, n); raw:=copy(whole, cur+8, n);
@ -1268,7 +1109,10 @@ function Ttlv.down():boolean;
begin begin
// do we have anything to recur on? // do we have anything to recur on?
if (cur = 1) then if (cur = 1) then
exit(FALSE); begin
result:=false;
exit;
end;
// push into the stack // push into the stack
if (stackTop = length(stack)) then // space over if (stackTop = length(stack)) then // space over
setLength(stack, stackTop+10); // make space setLength(stack, stackTop+10); // make space
@ -1285,7 +1129,10 @@ end; // down
function Ttlv.up():boolean; function Ttlv.up():boolean;
begin begin
if stackTop = 0 then if stackTop = 0 then
exit(FALSE); begin
result:=false;
exit;
end;
dec(stackTop); dec(stackTop);
bound:=stack[stackTop]; bound:=stack[stackTop];
dec(stackTop); dec(stackTop);

1
country.cache Normal file
View File

@ -0,0 +1 @@
127.0.0.1=(Private Address) (XX)

View File

@ -1,7 +1,10 @@
1 24 "WindowsXP.manifest" 1 24 "WindowsXP.manifest"
defaultTpl TEXT default.tpl defaultTpl TEXT default.tpl
dmBrowserTpl TEXT dmBrowser.tpl dmBrowserTpl TEXT dmBrowser.tpl
invertban TEXT invertban.txt
filelistTpl TEXT filelist.tpl filelistTpl TEXT filelist.tpl
uploadDisabled TEXT upload_disabled.txt
uploadHowTo TEXT upload_how.txt
alias TEXT alias.txt alias TEXT alias.txt
IPservices TEXT ipservices.txt IPservices TEXT ipservices.txt
jquery TEXT jquery.min.js jquery TEXT jquery.min.js

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,3 @@
{$A+,B-,C+,E-,F-,G+,H+,I-,J+,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,X+,Y+,Z1}
{$DEFINE NOT STABLE } {$DEFINE NOT STABLE }
{$IFDEF STABLE } {$IFDEF STABLE }
{$ASSERTIONS OFF} {$ASSERTIONS OFF}

9
developer notes.txt Normal file
View File

@ -0,0 +1,9 @@
Initially developed with Delphi 6, now with Delphi 10.3.3
Icons are generated at http://fontello.com/ . Use fontello.json for further modifications.
=== LIBS USED
ICS v8.63 by François PIETTE http://www.overbyte.be
TRegExpr v0.952 by Andrey V. Sorokin http://www.regexpstudio.com/TRegExpr/TRegExpr.html
JEDI Code Library v2.7 https://github.com/project-jedi/jcl
Kryvich's Delphi Localizer v4.1 http://sites.google.com/site/kryvich

133
hfs.dof Normal file
View File

@ -0,0 +1,133 @@
[FileVersion]
Version=6.0
[Compiler]
A=8
B=0
C=1
D=1
E=0
F=0
G=1
H=1
I=1
J=0
K=0
L=1
M=0
N=1
O=1
P=1
Q=0
R=0
S=0
T=0
U=0
V=1
W=1
X=1
Y=2
Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[Linker]
MapFile=3
OutputObjs=0
ConsoleApp=1
DebugInfo=0
RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=Http File Server - www.rejetto.com/hfs
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=$(DELPHI)\Lib\Debug;C:\code\other\compiled
Packages=vcl;rtl;vclx;VclSmp;DJCL60;IcsDel60
Conditionals=
DebugSourceDirs=C:\code\other\ics\Delphi\Vc32\
UsePackages=0
[Parameters]
RunParams=
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=6
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1040
CodePage=1252
[Version Info Keys]
CompanyName=rejetto
FileDescription=
FileVersion=1.6.0.0
InternalName=HFS
LegalCopyright=Copyright (C) 2002-2004 Massimo Melina (www.rejetto.com)
LegalTrademarks=
OriginalFilename=hfs.exe
ProductName=Http File Server
ProductVersion=1.0.0.0
Comments=
[Excluded Packages]
c:\programmi\borland\delphi6\Bin\dclshlctrls60.bpl=Shell Control Property and Component Editors
c:\programmi\borland\delphi6\Projects\Bpl\dclusr60.bpl=Borland User Components
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclBaseExpertD60.bpl=JCL Package containing common units for JCL Experts
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclDebugExpertD60.bpl=JCL Debug IDE extension
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclProjectAnalysisExpertD60.bpl=JCL Project Analyzer
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclFavoriteFoldersExpertD60.bpl=JCL Open and Save IDE dialogs with favorite folders
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclThreadNameExpertD60.bpl=JCL Thread Name IDE expert
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclUsesExpertD60.bpl=JCL Uses Wizard
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JclSIMDViewExpertD60.bpl=JCL Debug Window of XMM registers
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvAppFrmD6D.bpl=JVCL Application and Form Components
C:\PROGRA~1\Borland\Delphi6\Projects\Bpl\JvCoreD6D.bpl=JVCL Core Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvBandsD6D.bpl=JVCL Band Objects
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvCmpD6D.bpl=JVCL Non-Visual Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvCryptD6D.bpl=JVCL Encryption and Compression Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvCtrlsD6D.bpl=JVCL Visual Controls
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvCustomD6D.bpl=JVCL Custom Controls
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvDlgsD6D.bpl=JVCL Dialog Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvDockingD6D.bpl=JVCL Docking Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvDotNetCtrlsD6D.bpl=JVCL DotNet Controls
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvGlobusD6D.bpl=JVCL Globus Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvHMID6D.bpl=JVCL HMI Controls design time unit
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvInterpreterD6D.bpl=JVCL Interpreter Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvJansD6D.bpl=JVCL Jans Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvManagedThreadsD6D.bpl=JVCL Managed Threads
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvMMD6D.bpl=JVCL Multimedia and Image Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvNetD6D.bpl=JVCL Network Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvPageCompsD6D.bpl=JVCL Page Style Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvPluginD6D.bpl=JVCL Plugin Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvPrintPreviewD6D.bpl=JVCL Print Preview Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvRuntimeDesignD6D.bpl=JVCL Runtime Design Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvStdCtrlsD6D.bpl=JVCL Standard Controls
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvSystemD6D.bpl=JVCL System Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvTimeFrameworkD6D.bpl=JVCL Time Framework
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvUIBD6D.bpl=JVCL Unified Interbase Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvValidatorsD6D.bpl=JVCL Validators and Error Provider Components
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvWizardD6D.bpl=JVCL Wizard Design Time Package
C:\Programmi\Borland\Delphi6\Projects\Bpl\JvXPCtrlsD6D.bpl=JVCL XP Controls
C:\PROGRAMMI\BORLAND\DELPHI6\Bin\PDIFac60.bpl=Interface for ProDelphi viewer
c:\programmi\borland\delphi6\Bin\dcl31w60.bpl=Delphi 1.0 Compatibility Components
c:\programmi\borland\delphi6\Projects\Bpl\VirtualTreesD6D.bpl=Virtual Treeview
[HistoryLists\hlDebugSourcePath]
Count=1
Item0=C:\code\other\ics\Delphi\Vc32\
[HistoryLists\hlUnitAliases]
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[HistoryLists\hlSearchPath]
Count=1
Item0=$(DELPHI)\Lib\Debug;C:\code\other\compiled

View File

@ -206,31 +206,31 @@
</Platforms> </Platforms>
<ModelSupport>False</ModelSupport> <ModelSupport>False</ModelSupport>
<Deployment Version="3"> <Deployment Version="3">
<DeployFile LocalName="hfs.dpr" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Enabled>false</Enabled>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="hfs.exe" Configuration="Debug" Class="ProjectOutput"> <DeployFile LocalName="hfs.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteName>hfs.exe</RemoteName> <RemoteName>hfs.exe</RemoteName>
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="hfs.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>hfs.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="hfs.dpr" Configuration="Debug" Class="ProjectFile"> <DeployFile LocalName="hfs.dpr" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="hfs.dpr" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Enabled>false</Enabled>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="hfs.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>hfs.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols"> <DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32"> <Platform Name="OSX32">
<Operation>1</Operation> <Operation>1</Operation>

1804
hfs.drc

File diff suppressed because it is too large Load Diff

185
hfs.dsk Normal file
View File

@ -0,0 +1,185 @@
[Closed Files]
File_0=SourceModule,'C:\code\mine\hfs\whatsnew.txt',0,1,13,28,45,0,0
File_1=SourceModule,'C:\code\mine\hslib\hslib.pas',0,1,901,26,924,0,0
File_2=SourceModule,'C:\code\mine\hfs\utillib.pas',0,1,46,1,80,0,0
File_3=SourceModule,'C:\code\mine\hfs\todo.txt',0,1,1,1,1,0,0
File_4=SourceModule,'C:\code\other\ics\Delphi\Vc32\WSocket.pas',0,1,2948,36,2957,0,0
File_5=SourceModule,'C:\code\other\ics\Delphi\Vc32\WSocketS.pas',0,1,48,46,265,0,0
File_6=SourceModule,'C:\code\other\ics\Delphi\Vc32\UUEncode.pas',0,1,64,21,82,0,0
File_7=SourceModule,'C:\code\mine\andrq\utilLib.pas',0,1,3737,25,3767,0,0
File_8=SourceModule,'C:\code\mine\andrq\prefDlg.pas',0,1,570,27,590,1,0
[Modules]
Module0=C:\code\mine\hfs\main.pas
Count=1
EditWindowCount=1
[C:\code\mine\hfs\main.pas]
ModuleType=SourceModule
FormState=1
FormOnTop=0
[C:\Programmi\Borland\Delphi6\Projects\ProjectGroup1.bpg]
FormState=0
FormOnTop=0
[C:\code\mine\hfs\hfs.dpr]
FormState=0
FormOnTop=0
[EditWindow0]
ViewCount=1
CurrentView=0
View0=0
MessageView=MessageView@EditWindow0
Create=1
Visible=1
State=0
Left=190
Top=101
Width=834
Height=639
MaxLeft=-4
MaxTop=97
ClientWidth=826
ClientHeight=612
LeftPanelSize=0
RightPanelSize=0
BottomPanelSize=0
BottomPanelClients=MessageView@EditWindow0
BottomPanelData=00000400010000000B0000004D6573736167655669657700000000000000000000000000000000000100000000000000000B0000004D65737361676556696577FFFFFFFF
[View0]
Module=C:\code\mine\hfs\main.pas
CursorX=33
CursorY=63
TopLine=41
LeftCol=1
[Watches]
Count=1
Watch0='h',256,0,18,1,0
[Breakpoints]
Count=0
[AddressBreakpoints]
Count=0
[Main Window]
Create=1
Visible=1
State=2
Left=0
Top=0
Width=1024
Height=105
MaxLeft=-4
MaxTop=-4
MaxWidth=1032
MaxHeight=105
ClientWidth=1024
ClientHeight=78
[ProjectManager]
Create=1
Visible=0
State=0
Left=369
Top=372
Width=438
Height=303
MaxLeft=-1
MaxTop=-1
ClientWidth=430
ClientHeight=279
TBDockHeight=303
LRDockWidth=438
Dockable=1
[CPUWindow]
Create=1
Visible=0
State=0
Left=245
Top=207
Width=533
Height=353
MaxLeft=-1
MaxTop=-1
ClientWidth=525
ClientHeight=326
DumpPane=79
DisassemblyPane=187
RegisterPane=231
FlagPane=64
[AlignmentPalette]
Create=1
Visible=0
State=0
Left=200
Top=107
Width=156
Height=82
MaxLeft=-1
MaxTop=-1
ClientWidth=150
ClientHeight=60
[PropertyInspector]
Create=1
Visible=1
State=0
Left=0
Top=119
Width=190
Height=621
MaxLeft=-1
MaxTop=-1
ClientWidth=182
ClientHeight=597
TBDockHeight=621
LRDockWidth=190
Dockable=1
SplitPos=85
ArrangeBy=Name
SelectedItem=Caption
ExpandedItems=
HiddenCategories=
[ObjectTree]
Create=1
Visible=1
State=0
Left=1
Top=99
Width=190
Height=252
MaxLeft=-1
MaxTop=-1
ClientWidth=182
ClientHeight=228
TBDockHeight=252
LRDockWidth=190
Dockable=1
[MessageView@EditWindow0]
Create=1
Visible=0
State=0
Left=12
Top=0
Width=814
Height=52
MaxLeft=-1
MaxTop=-1
ClientWidth=814
ClientHeight=52
TBDockHeight=52
LRDockWidth=443
Dockable=1
[DockHosts]
DockHostCount=0

3
hfs.events Normal file
View File

@ -0,0 +1,3 @@
[+download]
{.remove header|ETag.}
{.remove header|Set-cookie.}

422
hfs.lng
View File

@ -1,5 +1,5 @@
; Kryvich's Delphi Localizer Language File. ; Kryvich's Delphi Localizer Language File.
; Generated by K.D.L. Scanner, 02/08/2020 18:30:32 ; Generated by K.D.L. Scanner, 24/05/2020 20:02:17
Humanize=1 Humanize=1
HumanizedCR=\^ HumanizedCR=\^
@ -120,8 +120,6 @@ filemenu.Editresource1.Caption=Edit resource...
filemenu.CopyURL1.Caption=Copy URL address filemenu.CopyURL1.Caption=Copy URL address
filemenu.CopyURL1.Hint=just double click! filemenu.CopyURL1.Hint=just double click!
filemenu.CopyURLwithpassword1.Caption=Copy URL with password filemenu.CopyURLwithpassword1.Caption=Copy URL with password
filemenu.CopyURLwithdifferentaddress1.Caption=Copy URL with different host address
filemenu.CopyURLwithfingerprint1.Caption=Copy URL with fingerprint
filemenu.Browseit1.Caption=Browse it filemenu.Browseit1.Caption=Browse it
filemenu.SetURL1.Caption=Set URL... filemenu.SetURL1.Caption=Set URL...
filemenu.Openit1.Caption=Open it filemenu.Openit1.Caption=Open it
@ -129,6 +127,8 @@ filemenu.Flagasnew1.Caption=Flag as new
filemenu.Resetnewflag1.Caption=Reset <new> flag filemenu.Resetnewflag1.Caption=Reset <new> flag
filemenu.Setuserpass1.Caption=Set user/pass... filemenu.Setuserpass1.Caption=Set user/pass...
filemenu.Resetuserpass1.Caption=Reset user/pass filemenu.Resetuserpass1.Caption=Reset user/pass
filemenu.CopyURLwithdifferentaddress1.Caption=Copy URL with different host address
filemenu.CopyURLwithfingerprint1.Caption=Copy URL with fingerprint
filemenu.Purge1.Caption=Purge... filemenu.Purge1.Caption=Purge...
filemenu.Switchtovirtual1.Caption=Change to virtual-folder filemenu.Switchtovirtual1.Caption=Change to virtual-folder
filemenu.Switchtorealfolder1.Caption=Change to real-folder filemenu.Switchtorealfolder1.Caption=Change to real-folder
@ -282,6 +282,7 @@ menu.Debug1.dumpTrafficChk.Caption=Dump traffic
menu.Debug1.Showcustomizedoptions1.Caption=Show customized options... menu.Debug1.Showcustomizedoptions1.Caption=Show customized options...
menu.Debug1.highSpeedChk.Caption=Experimental high speed handling menu.Debug1.highSpeedChk.Caption=Experimental high speed handling
menu.Debug1.macrosLogChk.Caption=Enable macros.log menu.Debug1.macrosLogChk.Caption=Enable macros.log
menu.Debug1.Appendmacroslog1.Caption=Append macros.log
menu.Debug1.Runscript1.Caption=Run script... menu.Debug1.Runscript1.Caption=Run script...
menu.Debug1.showMemUsageChk.Caption=Show memory usage menu.Debug1.showMemUsageChk.Caption=Show memory usage
menu.Debug1.noContentdispositionChk.Caption=No Content-disposition menu.Debug1.noContentdispositionChk.Caption=No Content-disposition
@ -396,7 +397,7 @@ pageCtrl.accountsPage.accountpropGrp.Label8.Caption=Notes
pageCtrl.accountsPage.accountpropGrp.accountenabledChk.Caption=&Enabled pageCtrl.accountsPage.accountpropGrp.accountenabledChk.Caption=&Enabled
pageCtrl.accountsPage.accountpropGrp.ignoreLimitsChk.Caption=&Ignore limits pageCtrl.accountsPage.accountpropGrp.ignoreLimitsChk.Caption=&Ignore limits
pageCtrl.accountsPage.accountpropGrp.pwdBox.EditLabel.Caption=&Password pageCtrl.accountsPage.accountpropGrp.pwdBox.EditLabel.Caption=&Password
pageCtrl.accountsPage.accountpropGrp.redirBox.EditLabel.Caption{1}=After login, redirect to pageCtrl.accountsPage.accountpropGrp.redirBox.EditLabel.Caption=After ~login, redirect to
pageCtrl.accountsPage.accountpropGrp.accountLinkBox.EditLabel.Caption=Member of pageCtrl.accountsPage.accountpropGrp.accountLinkBox.EditLabel.Caption=Member of
pageCtrl.accountsPage.accountpropGrp.groupChk.Caption=&Group pageCtrl.accountsPage.accountpropGrp.groupChk.Caption=&Group
pageCtrl.accountsPage.accountpropGrp.groupsBtn.Caption=Choose... pageCtrl.accountsPage.accountpropGrp.groupsBtn.Caption=Choose...
@ -451,283 +452,141 @@ Panel1.Button1.Caption=&Yes
Panel1.Button2.Caption=&No Panel1.Button2.Caption=&No
[ResourceStrings] [ResourceStrings]
64656_main_MSG_NUM_ADDR=In this moment there are %d different addresses 64820_main_MSG{1}=The current template is using macros.\^Do you want to cancel this action?
64657_main_MSG_NUM_ADDR_DL=In this moment there are %d different addresses downloading 64801_main_REMOVE_SHELL=Remove from shell context menu
64658_main_MSG_MAX_LINES=Max lines on screen. 64802_main_S_OFF=Switch OFF
64659_main_MSG_APACHE_LOG_FMT=Apache log file format 64803_main_S_ON{1}=Switch ON
64660_main_MSG_APACHE_LOG_FMT_LONG=Here you can specify how to format the log file complying Apache standard.\^Leave blank to get bare copy of screen on file.\^\^Example:\^ %h %l %u %t "%r" %>s %b 64804_main_LOG=Log
64661_main_MSG_ICONS_ADDED=%d new icons added 64820_main_MSG=You are invited to re-insert your No-IP configuration, otherwise the updater won't work as expected.
64662_main_MSG_DDNS_DISABLED=Dynamic DNS updater disabled 64820_main_MSG{1}=Max simultaneous addresses.
64663_main_MSG_MD5_WARN=This option creates an .md5 file for every new calculated fingerprint.\^Use with care to get not your disk invaded by these files. 64809_main_MSG2=In this moment there are %d different addresses
64664_main_MSG_AUTO_MD5=Auto fingerprint 64820_main_MSG{1}=Max simultaneous addresses downloading.
64665_main_MSG_AUTO_MD5_LONG=When you add files and no fingerprint is found, it is calculated.\^To avoid long waitings, set a limit to file size (in KiloBytes).\^Leave empty to disable, and have no fingerprint created. 64809_main_MSG2{1}=In this moment there are %d different addresses downloading
64666_main_MSG_UPL_HOWTO=1. Add a folder (choose "real folder")\^\^You should now see a RED folder in your virtual file sytem, inside HFS\^\^2. Right click on this folder\^3. Properties -> Permissions -> Upload\^4. Check on "Anyone"\^5. Ok\^\^Now anyone who has access to your HFS server can upload files to you. 64820_main_MSG{1}=Max lines on screen
64672_main_MSG_EVENTS_HLP=For help on how to use this file please refer http://www.rejetto.com/wiki/?title=HFS:_Event_scripts 64820_main_MSG{1}=Here you can specify how to format the log file complying Apache standard.\^Leave blank to get bare copy of screen on file.\^\^Example:\^ %h %l %u %t "%r" %>s %b
64673_main_MSG_EDIT_RES=Edit resource 64820_main_MSG{1}=This option creates an .md5 file for every new calculated fingerprint.\^Use with care to get not your disk invaded by these files.
64674_main_MSG_TPL_USE_MACROS=The current template is using macros.\^Do you want to cancel this action? 64820_main_MSG{1}=When you add files and no fingerprint is found, it is calculated.\^To avoid long waitings, set a limit to file size (in KiloBytes).\^Leave empty to disable, and have no fingerprint created.
64675_main_REMOVE_SHELL=Remove from shell context menu 64820_main_MSG{1}=Specify your addresses, each per line
64676_main_S_OFF=Switch OFF 64820_main_MSG{1}=Can't find external address\^( %s )
64677_main_S_ON{1}=Switch ON 64820_main_MSG{1}=This option makes pointless the option "Find external address at startup", which has now been disabled for your convenience.
64678_main_LOG=Log 64820_main_MSG{1}=Enter URL for updating.\^%ip% will be translated to your external IP.
64679_main_MSG_RE_NOIP=You are invited to re-insert your No-IP configuration, otherwise the updater won't work as expected. 64820_main_MSG{1}=The upload will fail if your disk has less than the specified amount of free MegaBytes.
64680_main_MSG_TRAY_DEF=%ip%\^Uptime: %uptime%\^Downloads: %downloads% 64820_main_MSG{1}=This string will be appended to the filename.\^\^If you need more control, enter a string with %name% in it, and this symbol will be replaced by the original filename.
64681_main_MSG_CLEAN_START=Clean start 64822_main_MSG_BEFORE=Here you can test if your server does work on the Internet.\^If you are not interested in serving files over the Internet, this is NOT for you.\^\^We'll now perform a test involving network activity.\^In order to complete this test, you may need to allow HFS's activity in your firewall, by clicking Allow on the warning prompt.\^\^WARNING: for the duration of the test, all ban rules and limits on the number of connections won't apply.
64682_main_MSG_RESTORE_BAK=A file system backup has been created for a system shutdown.\^Do you want to restore this backup? 64823_main_MSG_OK=The test is successful. The server should be working fine.
64683_main_MSG_EXT_ADDR_FAIL=Search for external address failed 64824_main_MSG_OK_PORT=Port %s is not working, but another working port has been found and set: %s.
64684_main_MSG_TO_EXPERT=Switch to expert mode. 64825_main_MSG_3=You may be behind a router or firewall.
64685_main_MSG_DONT_LOG_HINT=Select the files/folder you don't want to be logged,\^then right click and select "Don't log". 64826_main_MSG_6=You are behind a router.\^Ensure it is configured to forward port %s to your computer.
64686_main_MSG_DL_PERC=Downloading %d%% 64827_main_MSG_7=You may be behind a firewall.\^Ensure nothing is blocking HFS.
64687_main_MSG_UNINSTALL_WARN=Delete HFS and all settings? 64820_main_MSG{1}="Suggest" the browser to open directly the specified files.\^Other files should pop up a save dialog.
64688_main_MSG_SELF_3=You may be behind a router or firewall. 64820_main_MSG{1}=You should not use this option unless you really know its meaning.\^Continue?
64689_main_MSG_SELF_6=You are behind a router.\^Ensure it is configured to forward port %s to your computer. 64830_main_HELP=For help on how to use this file please refer http://www.rejetto.com/wiki/?title=HFS:_Event_scripts
64690_main_MSG_SELF_7=You may be behind a firewall.\^Ensure nothing is blocking HFS. 64831_main_CAPTION=Edit resource
64691_main_MSG_RET_EXT=Retrieving external address... 64832_main_MSG_CORRUPTED=This file does not contain valid data.
64692_main_MSG_SELF_CANT_ON=Unable to switch the server on 64833_main_MSG_MACROS_FOUND=!!!!!!!!! DANGER !!!!!!!!!\^This file contains macros.\^Don't accept macros from people you don't trust.\^\^Trust this file?
64693_main_MSG_SELF_CANT_LIST=Self test cannot be performed because HFS was configured to accept connections only on 127.0.0.1 64834_main_MSG_INFO=Last stable version: %s\^\^Last untested version: %s\^
64694_main_MSG_SELF_CANT_S=Self test doesn't support HTTPS.\^It's likely it won't work. 64835_main_MSG_NEWER=There's a new version available online: %s
64695_main_MSG_SELF_ING=Self testing... 64836_main_ARE_EXPERT{1}=You are in Expert mode
64696_main_MSG_TEST_CANC=Test cancelled 64837_main_ARE_EASY=You are in Easy mode
64697_main_MSG_TEST_INET=Testing internet connection... 64838_main_SW2EXPERT=Switch to Expert mode
64698_main_MSG_SELF_UNAV=Sorry, the test is unavailable at the moment 64839_main_SW2EASY=Switch to Easy mode
64699_main_MSG_SELF_NO_INET=Your internet connection does not work 64820_main_MSG{1}=Enter the number of MINUTES with no download after which the program automatically shuts down.\^Leave blank to get no timeout.
64700_main_MSG_SELF_NO_ANSWER=The test failed: server does not answer. 64820_main_MSG{1}=This function does not save any previous information to the log file.\^Instead, it saves all information that appears in the log box in real-time (from when you click "OK", below).\^Specify a filename for the log.\^If you leave the filename blank, no log file is saved.\^\^Here are some symbols you can use in the filename to split the log:\^ %d% -- day of the month (1..31)\^ %m% -- month (1..12)\^ %y% -- year (2000..)\^ %dow% -- day of the week (0..6)\^ %w% -- week of the year (1..53)\^ %user% -- username surrounded by parenthesis
64701_main_MSG_OPEN_BROW=Open directly in browser 64820_main_MSG{1}=Please insert an URL for the link\^\^Do not forget to specify http:// or whatever.\^%%ip%% will be translated to your address
64702_main_MSG_OPEN_BROW_LONG="Suggest" the browser to open directly the specified files.\^Other files should pop up a save dialog. 64820_main_MSG{1}=The realm string is shown on the user/pass dialog of the browser.\^Here you can customize the realm for the login button
64703_main_MSG_HIDE_PORT=You should not use this option unless you really know its meaning.\^Continue? 64820_main_MSG{1}=The connection is kicked after a timeout.\^Specify in seconds.\^Leave blank to get no timeout.
64704_main_MSG_RESET_TOT=Do you want to reset total in/out? 64820_main_MSG{1}=All changes will be lost\^Continue?
64705_main_MSG_DISAB_FIND_EXT=This option makes pointless the option "Find external address at startup", which has now been disabled for your convenience. 64820_main_MSG{1}=Enter the number of MINUTES files stay flagged from their addition.\^Leave blank to disable.
64706_main_MSG_ENT_URL=Enter URL 64820_main_MSG{1}=Any event from the following IP address mask will be not logged.
64707_main_MSG_ENT_URL_LONG=Enter URL for updating.\^%ip% will be translated to your external IP. 64876_main_LIMIT{1}=Speed limit
64708_main_MSG_ENT_USR=Enter user 64849_main_MSG_MAX_BW_1=Max bandwidth for single address (KB/s).
64709_main_MSG_ENT_PWD=Enter password 64850_main_LIMIT1=Speed limit for single address
64710_main_MSG_ENT_HOST=Enter host 64851_main_NODL=No downloads timeout:
64711_main_MSG_ENT_HOST_LONG=Enter domain (full form!) 64820_main_MSG{1}=Graph refresh rate: %d (tenths of second)
64712_main_MSG_HOST_FORM=Please, enter it in the FULL form, with dots 64820_main_MSG{1}=Max simultaneous connections to serve.\^Most people don't know this function well, and have problems. If you are unsure, please use the "Max simultaneous downloads".
64713_main_MSG_MIN_SPACE=Min disk space 64809_main_MSG2{1}=In this moment there are %d active connections
64714_main_MSG_MIN_SPACE_LONG=The upload will fail if your disk has less than the specified amount of free MegaBytes. 64820_main_MSG{1}=Max simultaneous downloads.
64715_main_MSG_REN_PART=Rename partial uploads 64809_main_MSG2{1}=In this moment there are %d active downloads
64716_main_MSG_REN_PART_LONG=This string will be appended to the filename.\^\^If you need more control, enter a string with %name% in it, and this symbol will be replaced by the original filename. 64820_main_MSG{1}=Max simultaneous connections to accept from a single IP address.\^Most people don't know this function well, and have problems. If you are unsure, please use the "Max simultaneous downloads from a single IP address".
64717_main_MSG_SELF_BEFORE=Here you can test if your server does work on the Internet.\^If you are not interested in serving files over the Internet, this is NOT for you.\^\^We'll now perform a test involving network activity.\^In order to complete this test, you may need to allow HFS's activity in your firewall, by clicking Allow on the warning prompt.\^\^WARNING: for the duration of the test, all ban rules and limits on the number of connections won't apply. 64820_main_MSG{1}=Max simultaneous downloads from a single IP address.
64718_main_MSG_SELF_OK=The test is successful. The server should be working fine. 64859_main_MSG_TITLE=Loading VFS
64719_main_MSG_SELF_OK_PORT=Port %s is not working, but another working port has been found and set: %s. 64860_main_MSG_OLD=This file is old and uses different settings.\^The "let browse" folder option will be reset.\^Re-saving the file will update its format.
64720_main_MSG_LOG_FILE=Log file 64861_main_MSG_UNK_FK=This file has been created with a newer version.\^Some data was discarded because unknown.\^If you save the file now, the discarded data will NOT be saved.
64721_main_MSG_LOG_FILE_LONG=This function does not save any previous information to the log file.\^Instead, it saves all information that appears in the log box in real-time (from when you click "OK", below).\^Specify a filename for the log.\^If you leave the filename blank, no log file is saved.\^\^Here are some symbols you can use in the filename to split the log:\^ %d% -- day of the month (1..31)\^ %m% -- month (1..12)\^ %y% -- year (2000..)\^ %dow% -- day of the week (0..6)\^ %w% -- week of the year (1..53)\^ %user% -- username surrounded by parenthesis 64862_main_MSG_VIS_ONLY_ANON=This VFS file uses the "Visible only to anonymous users" feature.\^This feature is not available anymore.\^You can achieve similar results by restricting access to @anonymous,\^then enabling "List protected items only for allowed users".
64722_main_MSG_SET_URL=Set URL 64863_main_MSG_AUTO_DISABLED=Because of the problems encountered in loading,\^automatic saving has been disabled\^until you save manually or load another one.
64723_main_MSG_SET_URL_LONG=Please insert an URL for the link\^\^Do not forget to specify http:// or whatever.\^%%ip%% will be translated to your address 64864_main_IN_SPEED=In: %.1f KB/s
64724_main_MSG_REALM=Login realm 64865_main_BANS=Ban rules: %d
64725_main_MSG_REALM_LONG=The realm string is shown on the user/pass dialog of the browser.\^Here you can customize the realm for the login button 64866_main_MEMORY=Mem
64726_main_MSG_INACT_TIMEOUT=Connection inactivity timeout 64867_main_CUSTOMIZED=Customized template
64727_main_MSG_INACT_TIMEOUT_LONG=The connection is kicked after a timeout.\^Specify in seconds.\^Leave blank to get no timeout. 64868_main_ITEMS=VFS: %d items
64728_main_MSG_CHANGES_LOST=All changes will be lost\^Continue? 64869_main_MSG1=%s item(s) already exists:\^%s\^\^Continue?
64729_main_MSG_FLAG_NEW=Flag new files 64820_main_MSG{1}=Leave empty to disable this feature.\^Here you can specify a mask.\^When a file is requested, if the mask doesn't match the "Referer" HTTP field, the request is rejected.
64730_main_MSG_FLAG_NEW_LONG=Enter the number of MINUTES files stay flagged from their addition.\^Leave blank to disable. 64871_main_MSG_BETTERSTOP=\^Going on may lead to problems.\^It is adviced to stop loading.\^Stop?
64731_main_MSG_DONT_LOG_MASK=Do not log address 64872_main_MSG_BADCRC=This file is corrupted (CRC).
64732_main_MSG_DONT_LOG_MASK_LONG=Any event from the following IP address mask will be not logged. 64835_main_MSG_NEWER{1}=This file has been created with a newer and incompatible version.
64733_main_MSG_CUST_IP=Custom IP addresses 64874_main_MSG_ZLIB=This file is corrupted (ZLIB).
64734_main_MSG_CUST_IP_LONG=Specify your addresses, each per line 64875_main_MSG_BAKAVAILABLE=This file is corrupted but a backup is available.\^Continue with backup?
64735_main_MSG_NO_EXT_IP=Can't find external address\^( %s ) 64876_main_LIMIT=Limit
64736_main_MSG_TENTH_SEC=Tenths of second 64877_main_TOP_SPEED=Top speed
64737_main_MSG_LOADING_VFS=Loading VFS 64878_main_MSG_MAX_BW=Max bandwidth (KB/s).
64738_main_MSG_VFS_OLD=This file is old and uses different settings.\^The "let browse" folder option will be reset.\^Re-saving the file will update its format. 64879_main_ZEROMSG=Zero is an effective limit.\^To disable instead, leave empty.
64739_main_MSG_UNK_FK=This file has been created with a newer version.\^Some data was discarded because unknown.\^If you save the file now, the discarded data will NOT be saved. 64880_main_AUTOSAVE=Auto save every:
64740_main_MSG_VIS_ONLY_ANON=This VFS file uses the "Visible only to anonymous users" feature.\^This feature is not available anymore.\^You can achieve similar results by restricting access to @anonymous,\^then enabling "List protected items only for allowed users". 64820_main_MSG{1}=Auto-save %s.\^Specify in seconds.\^Leave blank to disable.
64741_main_MSG_AUTO_DISABLED=Because of the problems encountered in loading,\^automatic saving has been disabled\^until you save manually or load another one. 64882_main_MSG_MIN=We don't accept less than %d
64742_main_MSG_CORRUPTED=This file does not contain valid data. 64883_main_MSG_BAN=Your ban configuration may have been screwed up.\^Please verify it.
64743_main_MSG_MACROS_FOUND=!!!!!!!!! DANGER !!!!!!!!!\^This file contains macros.\^Don't accept macros from people you don't trust.\^\^Trust this file? 64820_main_MSG{1}=Can't save options there.\^Should I try to save to user registry?
64744_main_MSG_UPD_INFO=Last stable version: %s\^\^Last untested version: %s\^ 64885_main_MSG_SAVE_ERROR=Cannot save the update
64745_main_MSG_NEWER=There's a new version available online: %s 64886_main_MSG_LIMITED=The auto-update feature cannot work because it requires the "Only 1 instance" option enabled.\^\^Your browser will now be pointed to the update, so you can install it manually.
64746_main_MSG_SRC_UPD=Searching for updates... 64887_main_MSG_UPDATE=You are invited to use the new version.\^\^Update now?
64747_main_ARE_EXPERT{1}=You are in Expert mode 64888_main_MSG_FROMDISK=Update info has been read from local file.\^To resume normal operation of the updater, delete the file hfs.updateinfo.txt from the HFS program folder.
64748_main_ARE_EASY=You are in Easy mode 64889_main_COPY=Copy to clipboard
64749_main_SW2EXPERT=Switch to Expert mode 64890_main_ALREADY=Already in clipboard
64750_main_SW2EASY=Switch to Easy mode 64891_main_NOSPACE=Out of space
64751_main_MSG_DL_TIMEOUT_LONG=Enter the number of MINUTES with no download after which the program automatically shuts down.\^Leave blank to get no timeout. 64892_main_CONN=Connections: %d
64752_main_MSG_NEWER_INCOMP=This file has been created with a newer and incompatible version. 64893_main_TOT_IN=Total In: %s
64753_main_MSG_ZLIB=This file is corrupted (ZLIB). 64894_main_TOT_OUT{1}=Total Out: %s
64754_main_MSG_BAKAVAILABLE=This file is corrupted but a backup is available.\^Continue with backup? 64895_main_OUT_SPEED=Out: %.1f KB/s
64755_main_MSG_CANT_LOAD_SAVE=Cannot load or save while adding files 64896_main_MSG_DDNS_notdonator=an option specified requires payment
64756_main_MSG_OPEN_VFS=Open VFS file 64897_main_MSG_DDNS_badagent=banned client
64757_main_LIMIT{2}=Limit 64820_main_MSG{1}=There are %d open connections from this address.\^Do you want to kick them all now?
64758_main_TOP_SPEED=Top speed 64809_main_MSG2{1}=You can edit the address.\^Masks and ranges are allowed.
64759_main_MSG_MAX_BW=Max bandwidth (KB/s). 64820_main_MSG{1}=This option is NOT compatible with "dynamic dns updater".\^Continue?
64760_main_MSG_LIM0=Zero is an effective limit.\^To disable instead, leave empty. 64809_main_MSG2{1}=There are %d connections open.\^Do you want to close them now?
64761_main_MSG_MAX_BW_1=Max bandwidth for single address (KB/s). 64902_main_FAILED=Login failed
64762_main_MSG_GRAPH_RATE_MENU=Graph refresh rate: %d (tenths of second) 64876_main_LIMIT{1}=Max simultaneous addresses: %s ...
64763_main_MSG_MAX_CON_LONG=Max simultaneous connections to serve.\^Most people don't know this function well, and have problems. If you are unsure, please use the "Max simultaneous downloads". 64876_main_LIMIT{1}=Max simultaneous addresses downloading: %s ...
64764_main_MSG_WARN_CONN=In this moment there are %d active connections 64876_main_LIMIT{1}=Max connections: %s ...
64765_main_MSG_WARN_ACT_DL=In this moment there are %d active downloads 64876_main_LIMIT{1}=Max connections from single address: %s ...
64766_main_MSG_MAX_CON_SING_LONG=Max simultaneous connections to accept from a single IP address.\^Most people don't know this function well, and have problems. If you are unsure, please use the "Max simultaneous downloads from a single IP address". 64876_main_LIMIT{1}=Max simultaneous downloads: %s ...
64767_main_MSG_GRAPH_RATE{1}=Graph refresh rate 64876_main_LIMIT{1}=Max simultaneous downloads from single address: %s ...
64768_main_MSG_VFS_DONT_CONS_DL_MASK=Don't consider as download (mask): %s 64909_main_FINGERPRINT=Create fingerprint on addition under %d KB
64769_main_MSG_VFS_INHERITED= [inherited] 64910_main_NO_FINGERPRINT=Create fingerprint on addition: disabled
64770_main_MSG_VFS_EXTERNAL= [external] 64820_main_MSG{1}=Please insert a comment for "%s".\^You should use HTML: <br> for break line.
64771_main_MSG_CON_HINT=Connection time: %s\^Last request time: %s\^Agent: %s 64912_main_MSG_EMPTY_NO_LIMIT=Leave blank to get no limits.
64772_main_MSG_CON_STATE_IDLE=idle 64913_main_MSG_ADDRESSES_EXCEED=The following addresses exceed the limit:\^%s
64773_main_MSG_CON_STATE_REQ=requesting 64914_main_MSG_NO_TEMP=Cannot save temporary file
64774_main_MSG_CON_STATE_RCV=receiving 64915_main_MSG_ERROR_REGISTRY=Can't write to registry.\^You may lack necessary rights.
64775_main_MSG_CON_STATE_THINK=thinking 64916_main_MSG_MANY_ITEMS=You are putting many files.\^Try using real folders instead of virtual folders.\^Read documentation or ask on the forum for help.
64776_main_MSG_CON_STATE_REP=replying 64917_main_MSG_ADD_TO_HFS="Add to HFS" has been added to your Window's Explorer right-click menu.
64777_main_MSG_CON_STATE_SEND=sending 64918_main_MSG_SINGLE_INSTANCE=Sorry, this feature only works with the "Only 1 instance" option enabled.\^\^You can find this option under Menu -> Start/Exit\^(only in expert mode)
64778_main_MSG_CON_STATE_DISC=disconnected 64919_main_MSG_COMM_ERROR=Network error. Request failed.
64779_main_MSG_TPL_RESET=The template has been reset 64920_main_MSG_DDNS_badauth=invalid user/password
64780_main_MSG_ALLO_REF=Allowed referer 64921_main_MSG_DDNS_notfqdn=incomplete hostname, required form aaa.bbb.com
64781_main_MSG_ALLO_REF_LONG=Leave empty to disable this feature.\^Here you can specify a mask.\^When a file is requested, if the mask doesn't match the "Referer" HTTP field, the request is rejected. 64922_main_MSG_DDNS_nohost=specified hostname does not exist
64782_main_MSG_BETTERSTOP=\^Going on may lead to problems.\^It is adviced to stop loading.\^Stop? 64923_main_MSG_DDNS_notyours=specified hostname belongs to another username
64783_main_MSG_BADCRC=This file is corrupted (CRC). 64924_main_MSG_DDNS_numhost=too many or too few hosts found
64784_main_MSG_VFS_HIDE_EMPTY=Hidden if empty 64925_main_MSG_DDNS_abuse=specified hostname is blocked for update abuse
64785_main_MSG_VFS_NOT_BROW=Not browsable 64926_main_MSG_DDNS_dnserr=server error
64786_main_MSG_VFS_HIDE_EMPTY_FLD=Hide empty folders 64927_main_MSG_DDNS_911=server error
64787_main_MSG_VFS_HIDE_EXT=Hide extention 64935_main_S_PORT_LABEL=Port: %s
64788_main_MSG_VFS_ARCABLE=Archivable 64936_main_S_PORT_ANY=any
64789_main_MSG_VFS_DEF_MASK=Default file mask: %s 64937_main_DISABLED=disabled
64790_main_MSG_VFS_ACCESS=Access for 64938_main_MSG_UNPROTECTED_LINKS=Links are NOT actually protected.\^The feature is there to be used with the "list protected items only..." option.\^Continue?
64791_main_MSG_VFS_UPLOAD=Upload allowed for 64939_main_MSG_SAME_NAME=An item with the same name is already present in this folder.\^Continue?
64792_main_MSG_VFS_DELETE=Delete allowed for 64940_main_MSG_OPTIONS_SAVED=Options saved
64793_main_MSG_VFS_COMMENT=Comment: %s 64941_main_MSG_SOME_LOCKED=Some items were not affected because locked
64794_main_MSG_VFS_REALM=Realm: %s 64942_main_MSG_ITEM_LOCKED=The item is locked
64795_main_MSG_VFS_DIFF_TPL=Diff template: %s 64943_main_MSG_INVALID_VALUE=Invalid value
64796_main_MSG_VFS_FILES_FLT=Files filter: %s
64797_main_MSG_VFS_FLD_FLT=Folders filter: %s
64798_main_MSG_VFS_UPL_FLT=Upload filter: %s
64799_main_MSG_VFS_DONT_CONS_DL=Don't consider as download
64800_main_IN_SPEED=In: %.1f KB/s
64801_main_BANS=Ban rules: %d
64802_main_MEMORY=Mem
64803_main_CUST_TPL=Customized template
64804_main_VFS_ITEMS=VFS: %d items
64805_main_MSG_ITEM_EXISTS=%s item(s) already exists:\^%s\^\^Continue?
64806_main_MSG_INSTALL_TPL=Install this template?
64807_main_MSG_FOLDER_UPLOAD=Do you want ANYONE to be able to upload to this folder?
64808_main_MSG_VFS_DRAG_INVIT=Drag your files here
64809_main_MSG_VFS_URL=URL: %s
64810_main_MSG_VFS_PATH=Path: %s
64811_main_MSG_VFS_SIZE=Size: %s
64812_main_MSG_VFS_DLS=Downloads: %s
64813_main_MSG_VFS_INVISIBLE=Invisible
64814_main_MSG_VFS_DL_FORB=Download forbidden
64815_main_MSG_VFS_DONT_LOG=Don't log
64816_main_MSG_UPD_DL=Downloading new version...
64817_main_MSG_UPDATE=You are invited to use the new version.\^\^Update now?
64818_main_MSG_REQUESTING=Requesting...
64819_main_MSG_CHK_UPD=Checking for updates
64820_main_MSG_CHK_UPD_FAIL=Check update: failed
64821_main_MSG_CHK_UPD_HEAD=Check update:
64822_main_MSG_CHK_UPD_VER=new version found: %s
64823_main_MSG_CHK_UPD_VER_EXT=Build #%s (current is #%s)
64824_main_MSG_CHK_UPD_NONE=no new version
64825_main_TO_CLIP=Copy to clipboard
64826_main_ALREADY_CLIP=Already in clipboard
64827_main_MSG_NO_SPACE=Out of space
64828_main_CONN=Connections: %d
64829_main_TOT_IN=Total In: %s
64830_main_TOT_OUT{1}=Total Out: %s
64831_main_OUT_SPEED=Out: %.1f KB/s
64832_main_MSG_FILE_ADD_ABORT=File addition was aborted.\^The list of files is incomplete.
64833_main_MSG_ADDING=Adding item #%d
64834_main_MSG_INV_FILENAME=Invalid filename
64835_main_MSG_DELETE=Delete?
64836_main_AUTOSAVE=Auto save every:
64837_main_SECONDS=%d seconds
64838_main_MSG_SPD_LIMIT_SING=Speed limit for single address
64839_main_MSG_SPD_LIMIT=Speed limit
64840_main_MSG_AUTO_SAVE=Auto-save %s
64841_main_MSG_AUTO_SAVE_LONG=Auto-save %s.\^Specify in seconds.\^Leave blank to disable.
64842_main_MSG_MIN=We don't accept less than %d
64843_main_MSG_BAN=Your ban configuration may have been screwed up.\^Please verify it.
64844_main_MSG_CANT_SAVE_OPT=Can't save options there.\^Should I try to save to user registry?
64845_main_MSG_UPD_SAVE_ERROR=Cannot save the update
64846_main_MSG_UPD_REQ_ONLY1=The auto-update feature cannot work because it requires the "Only 1 instance" option enabled.\^\^Your browser will now be pointed to the update, so you can install it manually.
64847_main_MSG_UPD_WAIT=Waiting for last requests to be served, then we'll update
64848_main_MSG_LOG_HEAD=Served head
64849_main_MSG_LOG_NOT_MOD=Not modified, use cache
64850_main_MSG_LOG_REDIR=Redirected to %s
64851_main_MSG_LOG_NOT_SERVED=Not served: %d - %s
64852_main_MSG_LOG_UPL=Uploading %s
64853_main_MSG_LOG_UPLOADED=Fully uploaded %s - %s @ %sB/s
64854_main_MSG_LOG_UPL_FAIL=Upload failed %s
64855_main_MSG_LOG_DL=Fully downloaded - %s @ %sB/s - %s
64856_main_MSG_LOGIN_FAILED=Login failed
64857_main_MSG_MIN_DISK_REACHED=Minimum disk space reached.
64858_main_MSG_UPL_NAME_FORB=File name or extension forbidden.
64859_main_MSG_UPL_CANT_CREATE=Error creating file.
64860_main_FINGERPRINT=Create fingerprint on addition under %d KB
64861_main_NO_FINGERPRINT=Create fingerprint on addition: disabled
64862_main_MSG_SAVE_VFS=Your current file system is not saved.\^Save it?
64863_main_MSG_INP_COMMENT=Please insert a comment for "%s".\^You should use HTML: <br> for break line.
64864_main_MSG_BAN_CMT=Ban comment
64865_main_MSG_BAN_CMT_LONG=A comment for this ban...
64866_main_MSG_BREAK_DYN_DNS=This option is NOT compatible with "dynamic dns updater".\^Continue?
64867_main_MSG_CANT_OPEN_PORT=Cannot open port.
64868_main_MSG_PORT_USED_BY=It is already used by %s
64869_main_MSG_PORT_BLOCKED=Something is blocking, maybe your system firewall.
64870_main_MSG_KICK_ALL=There are %d connections open.\^Do you want to close them now?
64871_main_MSG_TPL_INCOMPATIBLE=The template you are trying to load is not compatible with current HFS version.\^HFS will now use default template.\^Ask on the forum if you need further help.
64872_main_MSG_LOG_SERVER_START=Server start
64873_main_MSG_LOG_SERVER_STOP=Server stop
64874_main_MSG_LOG_CONNECTED=Connected
64875_main_MSG_LOG_DISC_SRV=Disconnected by server
64876_main_MSG_LOG_DISC=Disconnected
64877_main_MSG_LOG_GOT=Got %d bytes
64878_main_MSG_LOG_BYTES_SENT=%s bytes sent
64879_main_MSG_LOG_SERVED=Served %s
64880_main_MSG_DDNS_FAIL=DNS update failed: %s\^User intervention is required.
64881_main_MSG_DDNS_REPLY_SIZE=%d bytes reply
64882_main_MSG_DDNS_badauth=invalid user/password
64883_main_MSG_DDNS_notfqdn=incomplete hostname, required form aaa.bbb.com
64884_main_MSG_DDNS_nohost=specified hostname does not exist
64885_main_MSG_DDNS_notyours=specified hostname belongs to another username
64886_main_MSG_DDNS_numhost=too many or too few hosts found
64887_main_MSG_DDNS_abuse=specified hostname is blocked for update abuse
64888_main_MSG_DDNS_dnserr=server error
64889_main_MSG_DDNS_911=server error
64890_main_MSG_DDNS_notdonator=an option specified requires payment
64891_main_MSG_DDNS_badagent=banned client
64892_main_MSG_BAN_MASK=Ban IP mask
64893_main_MSG_IP_MASK_LONG=You can edit the address.\^Masks and ranges are allowed.
64894_main_MSG_KICK_ADDR=There are %d open connections from this address.\^Do you want to kick them all now?
64895_main_MSG_BAN_ALREADY=This IP address is already banned
64896_main_MSG_ADDRESSES_EXCEED=The following addresses exceed the limit:\^%s
64897_main_MSG_NO_TEMP=Cannot save temporary file
64898_main_MSG_ERROR_REGISTRY=Can't write to registry.\^You may lack necessary rights.
64899_main_MSG_MANY_ITEMS=You are putting many files.\^Try using real folders instead of virtual folders.\^Read documentation or ask on the forum for help.
64900_main_MSG_ADD_TO_HFS="Add to HFS" has been added to your Window's Explorer right-click menu.
64901_main_MSG_SINGLE_INSTANCE=Sorry, this feature only works with the "Only 1 instance" option enabled.\^\^You can find this option under Menu -> Start/Exit\^(only in expert mode)
64902_main_MSG_COMM_ERROR=Network error. Request failed.
64903_main_MSG_CON_PAUSED=paused
64904_main_MSG_CON_SENT=%s / %s sent
64905_main_MSG_CON_RECEIVED=%s / %s received
64906_main_MSG_DDNS_NO_REPLY=no reply
64907_main_MSG_DDNS_OK=successful
64908_main_MSG_DDNS_UNK=unknown reply: %s
64909_main_MSG_DDNS_ERR=error: %s
64910_main_MSG_DDNS_REQ=DNS update requested for %s: %s
64911_main_MSG_DDNS_DOING=Updating dynamic DNS...
64912_main_MSG_MAX_CON_SING=Max connections from single address
64913_main_MSG_MAX_SIM_ADDR{1}=Max simultaneous addresses
64914_main_MSG_MAX_SIM_ADDR_DL=Max simultaneous addresses downloading
64915_main_MSG_MAX_SIM_DL_SING{2}=Max simultaneous downloads from single address
64916_main_MSG_MAX_SIM_DL=Max simultaneous downloads
64917_main_MSG_SET_LIMIT=Set limit
64918_main_MSG_UNPROTECTED_LINKS=Links are NOT actually protected.\^The feature is there to be used with the "list protected items only..." option.\^Continue?
64919_main_MSG_SAME_NAME=An item with the same name is already present in this folder.\^Continue?
64920_main_MSG_CONTINUE=Continue?
64921_main_MSG_PROCESSING=Processing...
64922_main_MSG_SPEED_KBS=%.1f kB/s
64923_main_MSG_OPTIONS_SAVED=Options saved
64924_main_MSG_SOME_LOCKED=Some items were not affected because locked
64925_main_MSG_ITEM_LOCKED=The item is locked
64926_main_MSG_INVALID_VALUE=Invalid value
64927_main_MSG_EMPTY_NO_LIMIT=Leave blank to get no limits.
64935_classesLib_MSG_ANTIDOS_REPLY=Please wait, server busy
64936_optionsDlg_MSG_INVERT_BAN=Normal behavior of the Ban is to prevent access to the addresses you specify (also called black-list).\^If you want the opposite, to allow the addresses that you specify (white-list), enter all addresses in a single row preceded by a \ character.\^\^Let say you want to allow all your 192.168 local network plus your office at 1.1.1.1.\^Just put this IP address mask: \192.168.*;1.1.1.1\^The opening \ character inverts the logic, so everything else is banned.\^\^If you want to know more about address masks, check the guide.
64937_main_S_PORT_LABEL=Port: %s
64938_main_S_PORT_ANY=any
64939_main_DISABLED=disabled
64940_main_S_OK=Ok
64941_main_MSG_MENU_VAL= (%s)
64942_main_MSG_DL_TIMEOUT{1}=No downloads timeout
64943_main_MSG_MAX_CON=Max connections
65046_OverbyteIcsHttpContCod_ERR_GETCODING_OVERRIDE=GetCoding must be overridden in %s
65088_OverbyteIcsCharsetUtils_sHebrewISOVisual=Hebrew (ISO-Visual) 65088_OverbyteIcsCharsetUtils_sHebrewISOVisual=Hebrew (ISO-Visual)
65089_OverbyteIcsCharsetUtils_sHebrewWindows=Hebrew (Windows) 65089_OverbyteIcsCharsetUtils_sHebrewWindows=Hebrew (Windows)
65090_OverbyteIcsCharsetUtils_sJapaneseJIS=Japanese (JIS) 65090_OverbyteIcsCharsetUtils_sJapaneseJIS=Japanese (JIS)
@ -742,6 +601,7 @@ Panel1.Button2.Caption=&No
65099_OverbyteIcsCharsetUtils_sVietnameseWindows=Vietnamese (Windows) 65099_OverbyteIcsCharsetUtils_sVietnameseWindows=Vietnamese (Windows)
65100_OverbyteIcsCharsetUtils_sWesternEuropeanISO=Western European (ISO) 65100_OverbyteIcsCharsetUtils_sWesternEuropeanISO=Western European (ISO)
65101_OverbyteIcsCharsetUtils_sWesternEuropeanWindows=Western European (Windows) 65101_OverbyteIcsCharsetUtils_sWesternEuropeanWindows=Western European (Windows)
65102_OverbyteIcsHttpContCod_ERR_GETCODING_OVERRIDE=GetCoding must be overridden in %s
65104_OverbyteIcsCharsetUtils_sBalticISO=Baltic (ISO) 65104_OverbyteIcsCharsetUtils_sBalticISO=Baltic (ISO)
65105_OverbyteIcsCharsetUtils_sBalticWindows=Baltic (Windows) 65105_OverbyteIcsCharsetUtils_sBalticWindows=Baltic (Windows)
65106_OverbyteIcsCharsetUtils_sCentralEuropeanISO=Central European (ISO) 65106_OverbyteIcsCharsetUtils_sCentralEuropeanISO=Central European (ISO)

160
hslib.pas
View File

@ -1,5 +1,5 @@
{ {
Copyright (C) 2002-2020 Massimo Melina (www.rejetto.com) Copyright (C) 2002-2014 Massimo Melina (www.rejetto.com)
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,7 +19,6 @@ Copyright (C) 2002-2020 Massimo Melina (www.rejetto.com)
HTTP Server Lib HTTP Server Lib
==== TO DO ==== TO DO
* https
* upload bandwidth control (can it be done without multi-threading?) * upload bandwidth control (can it be done without multi-threading?)
} }
@ -30,7 +29,7 @@ unit HSlib;
interface interface
uses uses
OverbyteIcsWSocket, classes, messages, winprocs, forms, extctrls, sysutils, system.contnrs, strUtils, winsock, inifiles, types; OverbyteIcsWSocket, OverbyteIcsWSockets, classes, messages, winprocs, forms, extctrls, sysutils, system.contnrs, strUtils, winsock, inifiles, types;
const const
VERSION = '2.11.0'; VERSION = '2.11.0';
@ -104,7 +103,7 @@ type
); );
body: ansistring; // specifies reply body according to bodyMode body: ansistring; // specifies reply body according to bodyMode
bodyFile: string; 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, // this will appear in the authentication dialog realm, // this will appear in the authentication dialog
reason, // customized reason phrase reason, // customized reason phrase
@ -157,7 +156,6 @@ type
P_requestCount: integer; P_requestCount: integer;
P_destroying: boolean; // destroying is in progress P_destroying: boolean; // destroying is in progress
P_sndBuf: integer; P_sndBuf: integer;
P_v6: boolean;
persistent: boolean; persistent: boolean;
disconnecting: boolean; // disconnected() has been called disconnecting: boolean; // disconnected() has been called
lockCount: integer; // prevent freeing of the object lockCount: integer; // prevent freeing of the object
@ -206,7 +204,7 @@ type
eventData: ansistring; eventData: ansistring;
ignoreSpeedLimit: boolean; ignoreSpeedLimit: boolean;
limiters: TobjectList; // every connection can be bound to a number of TspeedLimiter limiters: TobjectList; // every connection can be bound to a number of TspeedLimiter
constructor create(server:ThttpSrv; acceptingSock:Twsocket); constructor create(server:ThttpSrv);
destructor Destroy; override; destructor Destroy; override;
procedure disconnect(); procedure disconnect();
procedure addHeader(s:ansistring; overwrite:boolean=TRUE); // set an additional header line. If overwrite=false will always append. procedure addHeader(s:ansistring; overwrite:boolean=TRUE); // set an additional header line. If overwrite=false will always append.
@ -221,7 +219,6 @@ type
function initInputStream():boolean; function initInputStream():boolean;
property address:string read P_address; // other peer ip address property address:string read P_address; // other peer ip address
property port:string read P_port; // other peer port property port:string read P_port; // other peer port
property v6:boolean read P_v6;
property requestCount:integer read P_requestCount; property requestCount:integer read P_requestCount;
property bytesToSend:int64 read getBytesToSend; property bytesToSend:int64 read getBytesToSend;
property bytesToPost:int64 read getBytesToPost; property bytesToPost:int64 read getBytesToPost;
@ -264,7 +261,7 @@ type
procedure calculateSpeed(); procedure calculateSpeed();
procedure processDisconnecting(); procedure processDisconnecting();
public public
sock, sock6: Twsocket; // listening socket sock: TwsocketServer; // listening socket
conns, // full list of connected clients conns, // full list of connected clients
disconnecting, // list of pending disconnections disconnecting, // list of pending disconnections
offlines, // disconnected clients to be freed offlines, // disconnected clients to be freed
@ -293,7 +290,7 @@ const
MINIMUM_CHUNK_SIZE = 2*1024; MINIMUM_CHUNK_SIZE = 2*1024;
MAXIMUM_CHUNK_SIZE = 1024*1024; MAXIMUM_CHUNK_SIZE = 1024*1024;
HRM2CODE: array [ThttpReplyMode] of integer = (200, 200, 403, 401, 404, 400, HRM2CODE: array [ThttpReplyMode] of integer = (200, 200, 403, 401, 404, 400,
500, 0, 0, 405, 302, 429, 413, 301, 304 ); 500, 0, 0, 405, 302, 503, 413, 301, 304 );
METHOD2STR: array [ThttpMethod] of ansistring = ('UNK','GET','POST','HEAD'); METHOD2STR: array [ThttpMethod] of ansistring = ('UNK','GET','POST','HEAD');
HRM2STR: array [ThttpReplyMode] of ansistring = ('Head+Body', 'Head only', 'Deny', HRM2STR: array [ThttpReplyMode] of ansistring = ('Head+Body', 'Head only', 'Deny',
'Unauthorized', 'Not found', 'Bad request', 'Internal error', 'Close', 'Unauthorized', 'Not found', 'Bad request', 'Internal error', 'Close',
@ -337,7 +334,6 @@ uses
Windows, ansistrings; Windows, ansistrings;
const const
CRLF = #13#10; CRLF = #13#10;
HEADER_LIMITER: ansistring = CRLF+CRLF;
MAX_REQUEST_LENGTH = 64*1024; MAX_REQUEST_LENGTH = 64*1024;
MAX_INPUT_BUFFER_LENGTH = 256*1024; MAX_INPUT_BUFFER_LENGTH = 256*1024;
// used as body content when the user did not specify any // used as body content when the user did not specify any
@ -353,7 +349,7 @@ const
'', '',
'405 - Method not allowed', '405 - Method not allowed',
'<html><head><meta http-equiv="refresh" content="url=%url%" /></head><body onload=''window.location="%url%"''>302 - <a href="%url%">Redirection to %url%</a></body></html>', '<html><head><meta http-equiv="refresh" content="url=%url%" /></head><body onload=''window.location="%url%"''>302 - <a href="%url%">Redirection to %url%</a></body></html>',
'429 - Server is overloaded, retry later', '503 - Server is overloaded, retry later',
'413 - The request has exceeded the max length allowed', '413 - The request has exceeded the max length allowed',
'301 - Moved permanently to <a href="%url%">%url%</a>', '301 - Moved permanently to <a href="%url%">%url%</a>',
'' // RFC2616: The 304 response MUST NOT contain a message-body '' // RFC2616: The 304 response MUST NOT contain a message-body
@ -389,11 +385,28 @@ begin if c then result:=a else result:=b end;
function min(a,b:integer):integer; function min(a,b:integer):integer;
begin if a < b then result:=a else result:=b end; begin if a < b then result:=a else result:=b end;
// this table is to be used by ipos(), to be calculated once
var
upcaseTab: array [char] of char;
function ipos(ss, s: string; ofs:integer=1):integer; overload; function ipos(ss, s: string; ofs:integer=1):integer; overload;
procedure initTab();
var
i: char;
tmp: string;
begin
for i:=#0 to #255 do
begin
tmp:=ansiUppercase(i);
upcaseTab[i]:=tmp[1];
end;
end;
var var
rss, rs, rss1, p: pchar; rss, rs, rss1, p: pchar;
l: integer; l: integer;
begin begin
if upcaseTab[#1] = #0 then initTab();
result:=0; result:=0;
l:=length(s); l:=length(s);
if (l < ofs) or (l = 0) or (ss = '') then exit; if (l < ofs) or (l = 0) or (ss = '') then exit;
@ -405,7 +418,7 @@ for result:=ofs to l do
begin begin
rss:=rss1; rss:=rss1;
p:=rs; p:=rs;
while (rss^ <> #0) and (rss^ = upcase(p^)) do while (rss^ <> #0) and (rss^ = upcaseTab[p^]) do
begin begin
inc(rss); inc(rss);
inc(p); inc(p);
@ -423,7 +436,7 @@ begin
repeat repeat
result:=posEx(ss, s, ofs); result:=posEx(ss, s, ofs);
if result = 0 then exit; if result = 0 then exit;
repeat repeat
qpos:=posEx(quote, s, ofs); qpos:=posEx(quote, s, ofs);
if qpos = 0 then exit; // there's no quoting, our result will fit if qpos = 0 then exit; // there's no quoting, our result will fit
@ -499,43 +512,6 @@ while i <= length(s) do
end; end;
end; // base64decode end; // base64decode
function validUTF8(s:rawbytestring):boolean;
var
i, more, len: integer;
c: byte;
begin
len:=length(s);
i:=0;
while i < len do
begin
inc(i);
c:=ord(s[i]);
if c < $80 then
continue;
if c >= $FE then
exit(FALSE);
if c >= $F0 then
more:=3
else if c >= $E0 then
more:=2
else if c >= $C0 then
more:=1
else
exit(FALSE);
if i+more > len then
exit(FALSE);
while more > 0 do
begin
inc(i);
c:=ord(s[i]);
if (c < $80) or (c > $C0) then
exit(FALSE);
dec(more);
end;
end;
result:=TRUE;
end; // validUTF8
function decodeURL(url:ansistring; utf8:boolean=TRUE):string; function decodeURL(url:ansistring; utf8:boolean=TRUE):string;
var var
i, j: integer; i, j: integer;
@ -555,11 +531,10 @@ while i<length(url) do
url[j]:=url[i]; url[j]:=url[i];
end; end;
setLength(url, j); setLength(url, j);
if utf8 and validUTF8(url) then if utf8 then
begin begin
result:=utf8ToString(url); result:=utf8ToString(url);
// if the string is not UTF8 compliant, the result is empty, or sometimes same length (but ruined) if result='' then // if the string is not UTF8 compliant, the result is empty
if (result='') or (length(result)=length(url)) then
result:=url; result:=url;
end end
else else
@ -579,8 +554,7 @@ if url = '' then
encodeHTML:=[]; encodeHTML:=[];
if nonascii then if nonascii then
encodeHTML:=[#128..#255]; encodeHTML:=[#128..#255];
encodePerc:=[#0..#31,'#','%','?','"','''','&','<','>',':', encodePerc:=[#0..#31,'#','%','?','"','''','&','<','>',':'];
',',';']; // these for content-disposition
// actually ':' needs encoding only in relative url // actually ':' needs encoding only in relative url
if spaces then include(encodePerc,' '); if spaces then include(encodePerc,' ');
if not htmlEncoding then if not htmlEncoding then
@ -677,7 +651,7 @@ end; // chopline
function chopLine(var s:ansistring):ansistring; overload; function chopLine(var s:ansistring):ansistring; overload;
begin begin
result:=chop(#10,s); result:=chop(pos(#10,s),1,s);
if (result>'') and (result[length(result)]=#13) then if (result>'') and (result[length(result)]=#13) then
setlength(result, length(result)-1); setlength(result, length(result)-1);
end; // chopline end; // chopline
@ -699,12 +673,16 @@ try
result:=TRUE; result:=TRUE;
if onAddress = '*' then if onAddress = '*' then
with sock6 do try
begin sock.MultiListenSockets.Clear();
addr:='::'; with sock.MultiListenSockets.Add do
Port:=sock.port; begin
try listen except end; addr := '::';
end; Port := sock.port
end;
sock.MultiListen();
except end;
notify(HE_OPEN, NIL); notify(HE_OPEN, NIL);
except except
end; end;
@ -714,24 +692,21 @@ procedure ThttpSrv.stop();
begin begin
if sock = NIL then exit; if sock = NIL then exit;
try sock.Close() except end; try sock.Close() except end;
try sock6.Close() except end; try sock.multiListenSockets.clear() except end;
end; end;
procedure ThttpSrv.connected(Sender: TObject; Error: Word); procedure ThttpSrv.connected(Sender: TObject; Error: Word);
begin if error=0 then ThttpConn.create(self, sender as Twsocket) end; begin if error=0 then ThttpConn.create(self) end;
procedure ThttpSrv.disconnected(Sender: TObject; Error: Word); procedure ThttpSrv.disconnected(Sender: TObject; Error: Word);
begin notify(HE_CLOSE, NIL) end; begin notify(HE_CLOSE, NIL) end;
constructor ThttpSrv.create(); constructor ThttpSrv.create();
begin begin
sock:=TWSocket.create(NIL); sock:=TWSocketServer.create(NIL);
sock.OnSessionAvailable:=connected; sock.OnSessionAvailable:=connected;
sock.OnSessionClosed:=disconnected; sock.OnSessionClosed:=disconnected;
sock.OnBgException:=bgexception; sock.OnBgException:=bgexception;
sock6:=TWSocket.create(NIL);
sock6.OnSessionAvailable:=connected;
sock6.OnBgException:=bgexception;
conns:=TobjectList.create; conns:=TobjectList.create;
conns.OwnsObjects:=FALSE; conns.OwnsObjects:=FALSE;
@ -877,6 +852,7 @@ end; // timerEvent
procedure ThttpSrv.notify(ev:ThttpEvent; conn:ThttpConn); procedure ThttpSrv.notify(ev:ThttpEvent; conn:ThttpConn);
begin begin
if not assigned(onEvent) then exit; if not assigned(onEvent) then exit;
//if assigned(sock) then sock.pause();
if assigned(conn) then if assigned(conn) then
begin begin
inc(conn.lockCount); inc(conn.lockCount);
@ -962,13 +938,13 @@ begin canClose:=FALSE end;
////////// CLIENT ////////// CLIENT
constructor ThttpConn.create(server:ThttpSrv; acceptingSock:Twsocket); constructor ThttpConn.create(server:ThttpSrv);
var var
i: integer; i: integer;
begin begin
// init socket // init socket
sock:=Twsocket.create(NIL); sock:=Twsocket.create(NIL);
sock.Dup(acceptingSock.accept()); sock.Dup(server.sock.Accept);
sock.OnDataAvailable:=dataavailable; sock.OnDataAvailable:=dataavailable;
sock.OnSessionClosed:=disconnected; sock.OnSessionClosed:=disconnected;
sock.onSendData:=senddata; sock.onSendData:=senddata;
@ -981,7 +957,6 @@ limiters:=TObjectList.create;
limiters.ownsObjects:=FALSE; limiters.ownsObjects:=FALSE;
P_address:=sock.GetPeerAddr(); P_address:=sock.GetPeerAddr();
P_port:=sock.GetPeerPort(); P_port:=sock.GetPeerPort();
P_v6:=pos(':', address) > 0;
state:=HCS_IDLE; state:=HCS_IDLE;
srv:=server; srv:=server;
srv.conns.add(self); srv.conns.add(self);
@ -1214,8 +1189,8 @@ procedure ThttpConn.processInputBuffer();
var var
i: integer; i: integer;
s, l, k, v: ansistring; s, l, k, c: string;
ws: widestring;
begin begin
repeat repeat
{ When the buffer is stuffed with file bytes only, we can avoid calling pos() and chop(). { When the buffer is stuffed with file bytes only, we can avoid calling pos() and chop().
@ -1256,12 +1231,11 @@ procedure ThttpConn.processInputBuffer();
break; break;
end; end;
// we wait for the header to be complete // we wait for the header to be complete
if posEx(HEADER_LIMITER, buffer, i+length(post.boundary)) = 0 then if posEx(CRLF+CRLF, buffer, i+length(post.boundary)) = 0 then break;
break;
handleLeftData(i); handleLeftData(i);
post.filename:=''; post.filename:='';
post.data:=''; post.data:='';
post.header:=chop(HEADER_LIMITER, buffer); post.header:=chop(CRLF+CRLF, buffer);
chopLine(post.header); chopLine(post.header);
// parse the header part // parse the header part
s:=post.header; s:=post.header;
@ -1270,28 +1244,25 @@ procedure ThttpConn.processInputBuffer();
l:=chopLine(s); l:=chopLine(s);
if l = '' then continue; if l = '' then continue;
k:=chop(':', l); k:=chop(':', l);
if not sameText(k, 'Content-Disposition') then // we are only interested in content-disposition: form-data if not sameText(k, 'Content-Disposition') then continue; // we are not interested in other fields
continue;
k:=trim(chop(';', l)); k:=trim(chop(';', l));
if not sameText(k, 'form-data') then if not sameText(k, 'form-data') then continue;
continue;
while l > '' do while l > '' do
begin begin
v:=chop(nonQuotedPos(';', l), 1, l); c:=chop(nonQuotedPos(';', l), l);
k:=trim(chop('=', v)); k:=UTF8toString(rawByteString(trim(chop('=', c))));
ws:=UTF8toString(ansiDequotedStr(v,'"')); c:=UTF8toString(rawByteString(ansiDequotedStr(c,'"')));
if sameText(k, 'filename') then if sameText(k, 'filename') then
begin begin
delete(ws, 1, lastDelimiter('/\',ws)); delete(c, 1, lastDelimiter('/\',c));
post.filename:=ws; post.filename:=c;
end end;
else if sameText(k, 'name') then if sameText(k, 'name') then
post.varname:=ws; post.varname:=c;
end; end;
end; end;
lastPostItemPos:=bytesPosted-length(buffer); lastPostItemPos:=bytesPosted-length(buffer);
if post.filename = '' then if post.filename = '' then continue;
continue;
firstPostFile:=FALSE; firstPostFile:=FALSE;
tryNotify(HE_POST_FILE); tryNotify(HE_POST_FILE);
until false; until false;
@ -1375,7 +1346,7 @@ if buffer = '' then exit;
if state = HCS_IDLE then if state = HCS_IDLE then
begin begin
state:=HCS_REQUESTING; state:=HCS_REQUESTING;
reply.contentType:='text/html; charset=utf-8'; reply.contentType:='text/html';
notify(HE_REQUESTING); notify(HE_REQUESTING);
end; end;
case state of case state of
@ -1393,7 +1364,7 @@ notify(HE_REQUESTED);
if not initInputStream() then if not initInputStream() then
begin begin
reply.mode:=HRM_INTERNAL_ERROR; reply.mode:=HRM_INTERNAL_ERROR;
reply.contentType:='text/html; charset=utf-8'; reply.contentType:='text/html';
notify(HE_CANT_OPEN_FILE); notify(HE_CANT_OPEN_FILE);
end; end;
notify(HE_STREAM_READY); notify(HE_STREAM_READY);
@ -1599,7 +1570,7 @@ end; // initInputStream
function ThttpConn.sendNextChunk(max:integer=MAXINT):integer; function ThttpConn.sendNextChunk(max:integer=MAXINT):integer;
var var
n, toSend: int64; n: int64;
buf: ansistring; buf: ansistring;
begin begin
result:=0; result:=0;
@ -1611,8 +1582,7 @@ if (n = 0) or (bytesSentLastItem = 0) then n:=max;
if n > MAXIMUM_CHUNK_SIZE then n:=MAXIMUM_CHUNK_SIZE; if n > MAXIMUM_CHUNK_SIZE then n:=MAXIMUM_CHUNK_SIZE;
if n < MINIMUM_CHUNK_SIZE then n:=MINIMUM_CHUNK_SIZE; if n < MINIMUM_CHUNK_SIZE then n:=MINIMUM_CHUNK_SIZE;
if n > max then n:=max; if n > max then n:=max;
toSend:=bytesToSend; if n > bytesToSend then n:=bytesToSend;
if n > toSend then n:=toSend;
if n = 0 then exit; if n = 0 then exit;
setLength(buf, n); setLength(buf, n);
n:=stream.read(buf[1], n); n:=stream.read(buf[1], n);

8
invertban.txt Normal file
View File

@ -0,0 +1,8 @@
Normal behavior of the Ban is to prevent access to the addresses you specify (also called black-list).
If you want the opposite, to allow the addresses that you specify (white-list), enter all addresses in a single row preceded by a \ character.
Let say you want to allow all your 192.168 local network plus your office at 1.1.1.1.
Just put this IP address mask: \192.168.*;1.1.1.1
The opening \ character inverts the logic, so everything else is banned.
If you want to know more about address masks, check the guide.

View File

@ -2,7 +2,7 @@ object mainFrm: TmainFrm
Left = 293 Left = 293
Top = 219 Top = 219
Caption = 'HFS ~ HTTP File Server' Caption = 'HFS ~ HTTP File Server'
ClientHeight = 436 ClientHeight = 483
ClientWidth = 879 ClientWidth = 879
Color = clBtnFace Color = clBtnFace
Constraints.MinHeight = 260 Constraints.MinHeight = 260
@ -218,7 +218,7 @@ object mainFrm: TmainFrm
Left = 0 Left = 0
Top = 83 Top = 83
Width = 879 Width = 879
Height = 353 Height = 400
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
@ -231,7 +231,7 @@ object mainFrm: TmainFrm
object splitV: TSplitter object splitV: TSplitter
Left = 313 Left = 313
Top = 0 Top = 0
Height = 242 Height = 289
Beveled = True Beveled = True
Constraints.MaxWidth = 3 Constraints.MaxWidth = 3
Constraints.MinWidth = 3 Constraints.MinWidth = 3
@ -241,7 +241,7 @@ object mainFrm: TmainFrm
end end
object splitH: TSplitter object splitH: TSplitter
Left = 0 Left = 0
Top = 242 Top = 289
Width = 879 Width = 879
Height = 5 Height = 5
Cursor = crVSplit Cursor = crVSplit
@ -257,7 +257,7 @@ object mainFrm: TmainFrm
Left = 316 Left = 316
Top = 0 Top = 0
Width = 563 Width = 563
Height = 242 Height = 289
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
TabOrder = 1 TabOrder = 1
@ -265,7 +265,7 @@ object mainFrm: TmainFrm
Left = 0 Left = 0
Top = 23 Top = 23
Width = 563 Width = 563
Height = 219 Height = 266
Align = alClient Align = alClient
Font.Charset = ANSI_CHARSET Font.Charset = ANSI_CHARSET
Font.Color = clWindowText Font.Color = clWindowText
@ -557,7 +557,7 @@ object mainFrm: TmainFrm
Left = 0 Left = 0
Top = 0 Top = 0
Width = 313 Width = 313
Height = 242 Height = 289
Align = alLeft Align = alLeft
BevelOuter = bvNone BevelOuter = bvNone
Caption = 'filesPnl' Caption = 'filesPnl'
@ -566,7 +566,7 @@ object mainFrm: TmainFrm
Left = 0 Left = 0
Top = 23 Top = 23
Width = 313 Width = 313
Height = 219 Height = 266
Align = alClient Align = alClient
BevelInner = bvLowered BevelInner = bvLowered
BevelOuter = bvSpace BevelOuter = bvSpace
@ -616,7 +616,7 @@ object mainFrm: TmainFrm
end end
object connPnl: TPanel object connPnl: TPanel
Left = 0 Left = 0
Top = 247 Top = 294
Width = 879 Width = 879
Height = 106 Height = 106
Align = alBottom Align = alBottom
@ -749,13 +749,6 @@ object mainFrm: TmainFrm
AutoHotkeys = maManual AutoHotkeys = maManual
Caption = 'Copy URL with password' Caption = 'Copy URL with password'
end end
object CopyURLwithdifferentaddress1: TMenuItem
Caption = 'Copy URL with different host address'
end
object CopyURLwithfingerprint1: TMenuItem
Caption = 'Copy URL with fingerprint'
OnClick = CopyURLwithfingerprint1Click
end
object Browseit1: TMenuItem object Browseit1: TMenuItem
Caption = 'Browse it' Caption = 'Browse it'
ImageIndex = 26 ImageIndex = 26
@ -792,6 +785,13 @@ object mainFrm: TmainFrm
object N11: TMenuItem object N11: TMenuItem
Caption = '-' Caption = '-'
end end
object CopyURLwithdifferentaddress1: TMenuItem
Caption = 'Copy URL with different host address'
end
object CopyURLwithfingerprint1: TMenuItem
Caption = 'Copy URL with fingerprint'
OnClick = CopyURLwithfingerprint1Click
end
object Purge1: TMenuItem object Purge1: TMenuItem
Caption = 'Purge...' Caption = 'Purge...'
OnClick = Purge1Click OnClick = Purge1Click
@ -2963,6 +2963,10 @@ object mainFrm: TmainFrm
AutoCheck = True AutoCheck = True
Caption = 'Enable macros.log' Caption = 'Enable macros.log'
end end
object Appendmacroslog1: TMenuItem
AutoCheck = True
Caption = 'Append macros.log'
end
object Runscript1: TMenuItem object Runscript1: TMenuItem
Caption = 'Run script...' Caption = 'Run script...'
OnClick = Runscript1Click OnClick = Runscript1Click

1772
main.pas

File diff suppressed because it is too large Load Diff

62
notes.txt Normal file
View File

@ -0,0 +1,62 @@
=== 4GB+ FILES DOWNLOAD SUPPORT
Reget Deluxe 4.1
MetaProducts Download Express 1.7
Getright
Firefox 2.0
=== 2GB+ FILES UPLOAD SUPPORT
firefox 3.0: no
=== HOW TO CREATE BIG FILES
fsutil file createnew <filename> <filesize>
=== HOW TO DOWNLOAD WITH NO DISK ACTIVITY (SPEED TEST)
create a big file as above
then download this way: wget -q -O nul http://localhost/big
=== SUBMITTED TO
www.nonags.com
www.sharewareconnection.com
=== LISTED ON
www.sofotex.com
www.download3000.com
www.onekit.com
www.all4you.dk/FreewareWorld
www.snapfiles.com
sourceforge
www.freedownloadscenter.com
download.freenet.de
www.softonic.com
www.portablefreeware.com
www.download.com
www.freewarepub.org
www.handyarchive.com
www.softpedia.com
www.acidfiles.com
www.fileedge.com
www.freewarepark.com
=== REVIEWS
http://www.technospot.net/blogs/host-a-web-server-on-your-home-pc/
http://www.snapfiles.com/get/hfs.html
http://www.downloadsquad.com/2006/05/24/hft-quick-and-easy-http-file-server/
http://www.caseytech.com/how-to-host-a-web-site-from-your-computer/
http://www.chip.de/downloads/c1_downloads_29480524.html
http://blog.pcserenity.com/2009/01/easy-conten-sharing-with-windows.html
http://hfs.onehelp.ch
http://www.lanacion.com.ar/nota.asp?nota_id=1148507
http://blogmotion.fr/systeme/partage-windows-hfs-3947
ita
http://lafabbricadibyte.wordpress.com/2007/05/01/hfs-file-server-http-gratuito-per-windows/
http://server.html.it/articoli/leggi/2335/hfs-file-sharing-via-http/
=== OTHER SOFTWARE BASED ON HFS
http://www.wrinx.com/products/pfs/
commercial, licensed
http://www.powernetservers.com/pnwfs.php
commercial, probably unlicensed
=== INSTALLABLE PLUGINS
log links usage
http://www.rejetto.com/forum/index.php/topic,7765.msg1047258.html#msg1047258

View File

@ -222,9 +222,9 @@ object optionsFrm: ToptionsFrm
Top = 106 Top = 106
Width = 198 Width = 198
Height = 22 Height = 22
EditLabel.Width = 105 EditLabel.Width = 111
EditLabel.Height = 14 EditLabel.Height = 14
EditLabel.Caption = 'After login, redirect to' EditLabel.Caption = 'After ~login, redirect to'
TabOrder = 4 TabOrder = 4
OnChange = redirBoxChange OnChange = redirBoxChange
end end

View File

@ -834,16 +834,7 @@ procedure ToptionsFrm.okBtnClick(Sender: TObject);
begin if saveValues() then close() end; begin if saveValues() then close() end;
procedure ToptionsFrm.Button1Click(Sender: TObject); procedure ToptionsFrm.Button1Click(Sender: TObject);
resourcestring MSG_INVERT_BAN = begin msgDlg(getRes('invertBan')) end;
'Normal behavior of the Ban is to prevent access to the addresses you specify (also called black-list).'
+#13'If you want the opposite, to allow the addresses that you specify (white-list), enter all addresses in a single row preceded by a \ character.'
+#13
+#13'Let say you want to allow all your 192.168 local network plus your office at 1.1.1.1.'
+#13'Just put this IP address mask: \192.168.*;1.1.1.1'
+#13'The opening \ character inverts the logic, so everything else is banned.'
+#13
+#13'If you want to know more about address masks, check the guide.';
begin msgDlg(MSG_INVERT_BAN) end;
procedure ToptionsFrm.groupsBtnClick(Sender: TObject); procedure ToptionsFrm.groupsBtnClick(Sender: TObject);
var var

View File

@ -1,5 +1,5 @@
{ {
Copyright (C) 2002-2020 Massimo Melina (www.rejetto.com) Copyright (C) 2002-2012 Massimo Melina (www.rejetto.com)
This file is part of HFS ~ HTTP File Server. This file is part of HFS ~ HTTP File Server.
@ -67,8 +67,6 @@ s:='';
if ts then if ts then
s:='<hr>'+dateTimeToStr(now())+CRLF; s:='<hr>'+dateTimeToStr(now())+CRLF;
s:=s+#13'<dt>'+htmlEncode(textIn)+'</dt><dd>'+htmlEncode(textOut)+'</dd>'; s:=s+#13'<dt>'+htmlEncode(textIn)+'</dt><dd>'+htmlEncode(textOut)+'</dd>';
if sizeOfFile(MACROS_LOG_FILE) = 0 then
s:=HEADER+s;
result:=appendTextFile(MACROS_LOG_FILE, s); result:=appendTextFile(MACROS_LOG_FILE, s);
end; // macrosLog end; // macrosLog
@ -161,18 +159,16 @@ var
procedure deprecatedMacro(what:string=''; instead:string=''); procedure deprecatedMacro(what:string=''; instead:string='');
begin mainfrm.add2log('WARNING, deprecated macro: '+first(what, name)+nonEmptyConcat(' - Use instead: ',instead), NIL, clRed) end; begin mainfrm.add2log('WARNING, deprecated macro: '+first(what, name)+nonEmptyConcat(' - Use instead: ',instead), NIL, clRed) end;
procedure unsatisfied(b:boolean=TRUE);
begin
if b then
macroError('cannot be used here')
end;
function satisfied(p:pointer):boolean; function satisfied(p:pointer):boolean;
begin begin
result:=assigned(p); result:=assigned(p);
unsatisfied(not result); if not result then
macroError('cannot be used here');
end; end;
procedure unsatisfied(b:boolean=TRUE);
begin if b then macroError('cannot be used here') end;
function parEx(idx:integer; name:string=''; doTrim:boolean=TRUE):string; overload; function parEx(idx:integer; name:string=''; doTrim:boolean=TRUE):string; overload;
var var
i: integer; i: integer;
@ -264,9 +260,9 @@ var
result:=staticVars; result:=staticVars;
delete(varname,1,length(G_VAR_PREFIX)); delete(varname,1,length(G_VAR_PREFIX));
end end
else if assigned(md.cd) then else if satisfied(md.cd) then
result:=md.cd.vars result:=md.cd.vars
else if assigned(md.tempVars) then else if satisfied(md.tempVars) then
result:=md.tempVars result:=md.tempVars
else else
raise Exception.create('no namespace available'); raise Exception.create('no namespace available');
@ -295,7 +291,7 @@ var
if not satisfied(space) then exit; if not satisfied(space) then exit;
i:=space.indexOfName(varname); i:=space.indexOfName(varname);
if i < 0 then if i < 0 then
if value = '' then exit(TRUE) // all is good the way it is if value = '' then exit // all is good the way it is
else i:=space.add(varname+'='+value) else i:=space.add(varname+'='+value)
else else
if value > '' then // in case of empty value, there's no need to assign, because we are going to delete it (after we cleared the bound object) if value > '' then // in case of empty value, there's no need to assign, because we are going to delete it (after we cleared the bound object)
@ -459,8 +455,7 @@ var
vars: Tstrings; vars: Tstrings;
s: string; s: string;
begin begin
if not satisfied(md.cd) then if not satisfied(md.cd) then exit;
exit;
try try
result:=md.cd.conn.request.url; result:=md.cd.conn.request.url;
if pars.count < 2 then exit; if pars.count < 2 then exit;
@ -662,40 +657,16 @@ var
procedure inc_(v:integer=+1); procedure inc_(v:integer=+1);
begin begin
try result:='';
setVar(p, intToStr(strToIntDef(getVar(p),0)+v*parI(1,1))); try setVar(p, intToStr(strToIntDef(getVar(p),0)+v*parI(1,1))) except end;
result:='';
except
end;
end; // inc_ end; // inc_
procedure convert(); procedure convert();
var
dst, s: string;
c: ansichar;
begin begin
dst:=par(1); if sameText(p, 'ansi') and sameText(par(1), 'utf-8') then
s:=par(2); result:=ansiToUTF8(ansistring(par(2)))
if sameText(p, 'ansi') and sameText(dst, 'utf-8') then else if sameText(p, 'utf-8') and sameText(par(1), 'ansi') then
result:=string(ansiToUTF8(ansistring(s))) result:=utf8ToAnsi(ansistring(par(2)))
else if sameText(p, 'utf-8') then
if sameText(dst, 'ansi') then
result:=utf8ToAnsi(ansistring(s))
else if dst='dec' then
begin
result:='';
for c in UTF8encode(s) do
result:=result+intToStr(ord(c))+',';
setLength(result, length(result)-1);
end
else if dst='hex' then
begin
result:='';
for c in UTF8encode(s) do
result:=result+intToHex(ord(c));
end;
if isFalse(par('macros')) then
result:=noMacrosAllowed(result);
end; // convert end; // convert
procedure encodeuri(); procedure encodeuri();
@ -950,37 +921,6 @@ var
finally free end; finally free end;
end; // foreach end; // foreach
procedure forLine();
var
lines: TStringList;
line, code, run: string;
i: integer;
begin
code:=macroDequote(par(pars.count-1));
lines:=TStringList.create();
with TfastStringAppend.create do
try
lines.text:= getVar(par('var'));
for line in lines do
begin
i:=pos('=',line);
if i > 0 then
begin
setVar('line-key', Copy(line, 1, i-1));
setVar('line-value', Copy(line, i+1, MAXINT));
end;
setVar('line', line);
run:=code;
applyMacrosAndSymbols(run, cbMacros, cbData);
append(run);
end;
result:=reset();
finally
Free;
lines.Free;
end;
end; //forLine
procedure for_(); procedure for_();
var var
b, e, i, d: integer; b, e, i, d: integer;
@ -1104,7 +1044,6 @@ var
procedure load(fn:string; varname:string=''); procedure load(fn:string; varname:string='');
var var
from, size: int64; from, size: int64;
s: ansistring;
begin begin
result:=''; result:='';
from:=parI('from', 0); from:=parI('from', 0);
@ -1123,17 +1062,11 @@ var
try result:=httpGet(fn, from, size) try result:=httpGet(fn, from, size)
except result:='' end except result:='' end
else else
begin result:=loadFile(uri2diskMaybe(fn), from, size);
s:=loadFile(uri2diskMaybe(fn), from, size);
result:=UTF8ToString(s);
if result = '' then
result:=s;
end;
if varname = '' then if varname = '' then
begin begin
if anyCharIn('/\',fn) then if anyCharIn('/\',fn) then result:=macroQuote(result);
result:=macroQuote(result);
exit; exit;
end; end;
if ansiStartsStr(ENCODED_TABLE_HEADER, result) then if ansiStartsStr(ENCODED_TABLE_HEADER, result) then
@ -1232,20 +1165,20 @@ var
'information=64' 'information=64'
); );
var var
code: integer; i, j, code: integer;
decode: TStringDynArray; decode: TStringDynArray;
s, d: string; s: string;
buttons, icon: boolean; buttons, icon: boolean;
begin begin
decode:=split(' ',par(1)); decode:=split(' ',par(1));
code:=0; code:=0;
for d in decode do for i:=0 to length(decode)-1 do
for s in STR2CODE do for j:=1 to length(STR2CODE) do
if startsStr(d+'=', s) then begin
begin s:=STR2CODE[j];
inc(code, strToIntDef(substr(s, 2+d.length), 0)); if ansiStartsStr(decode[i], s) then
Break inc(code, strToIntDef(substr(s, 1+pos('=',s)), 0));
end; end;
buttons:=code AND 15 > 0; buttons:=code AND 15 > 0;
icon:=code SHR 4 > 0; icon:=code SHR 4 > 0;
if not icon and buttons then if not icon and buttons then
@ -1374,20 +1307,19 @@ var
if not satisfied(space) then exit; if not satisfied(space) then exit;
// set the table variable as text // set the table variable as text
v:=par(1); v:=par(1);
space.values[p]:=nonEmptyConcat('', space.values[p], CRLF)+v;
// access the table object // access the table object
i:=space.indexOfName(p); i:=space.indexOfName(p);
if i < 0 then h:=space.objects[i] as THashedStringList;
if h = NIL then
begin begin
h:=ThashedStringList.create(); h:=ThashedStringList.create();
space.AddPair(p, v, h); space.objects[i]:=h;
end end;
else
h:=space.objects[i] as THashedStringList;
// fill the object // fill the object
k:=chop('=',v); k:=chop('=',v);
v:=macroDequote(v); v:=macroDequote(v);
h.values[k]:=v; h.values[k]:=v;
space.values[p]:=h.text;
end; // setTable end; // setTable
procedure disconnect(); procedure disconnect();
@ -1480,8 +1412,7 @@ var
exit; exit;
end; end;
a:=findEnabledLinkedAccount(a, split(';',s)); a:=findEnabledLinkedAccount(a, split(';',s));
if assigned(a) then if assigned(a) then result:=a.user;
result:=a.user;
end; // memberOf end; // memberOf
procedure canArchive(f:Tfile); procedure canArchive(f:Tfile);
@ -1941,15 +1872,9 @@ try
disconnect(); disconnect();
if name = 'stop server' then if name = 'stop server' then
begin
stopServer(); stopServer();
exit('');
end;
if name = 'start server' then if name = 'start server' then
begin
startServer(); startServer();
exit('');
end;
if name = 'focus' then if name = 'focus' then
@ -1966,7 +1891,10 @@ try
begin begin
try try
if isFalse(parEx('if')) then if isFalse(parEx('if')) then
exit(''); begin
result:='';
exit;
end;
except end; except end;
result:=md.cd.disconnectReason; // return the previous state result:=md.cd.disconnectReason; // return the previous state
if pars.count > 0 then md.cd.disconnectReason:=p; if pars.count > 0 then md.cd.disconnectReason:=p;
@ -2001,19 +1929,13 @@ try
result:=jsEncode(p, first(par(1),'''"')); result:=jsEncode(p, first(par(1),'''"'));
if name = 'base64' then if name = 'base64' then
result:=string(base64encode(UTF8encode(p))); result:=base64encode(UTF8encode(p));
if name = 'base64decode' then if name = 'base64decode' then
begin
result:=utf8ToString(base64decode(ansistring(p))); result:=utf8ToString(base64decode(ansistring(p)));
if isFalse(par('macros')) then
result:=noMacrosAllowed(result);
end;
if name = 'md5' then if name = 'md5' then
result:=strMD5(p); result:=strMD5(p);
if name = 'sha1' then if name = 'sha1' then
result:=strSHA1(p); result:=strSHA1(p);
if name = 'sha256' then
result:=strSHA256(p);
if name = 'vfs select' then if name = 'vfs select' then
if pars.count = 0 then if pars.count = 0 then
@ -2086,7 +2008,7 @@ try
encodeuri(); encodeuri();
if name = 'decodeuri' then if name = 'decodeuri' then
result:=noMacrosAllowed(decodeURL(ansistring(p))); result:=decodeURL(ansistring(p));
if name = 'set cfg' then if name = 'set cfg' then
trueIf(mainfrm.setcfg(p)); trueIf(mainfrm.setcfg(p));
@ -2503,12 +2425,8 @@ try
minOrMax(); minOrMax();
if stringExists(name, ['if','if not']) then if stringExists(name, ['if','if not']) then
begin if isFalse(p) xor (length(name) > 2) then result:=macroDequote(par(2))
try p:=getVar(parEx('var'));
except end;
if isTrue(p) xor (length(name) = 2) then result:=macroDequote(par(2))
else result:=macroDequote(par(1)); else result:=macroDequote(par(1));
end;
if stringExists(name, ['=','>','>=','<','<=','<>','!=']) then if stringExists(name, ['=','>','>=','<','<=','<>','!=']) then
trueIf(compare(name, p, par(1))); trueIf(compare(name, p, par(1)));
@ -2524,9 +2442,6 @@ try
if name = 'cut' then if name = 'cut' then
cut(); cut();
if name ='for line' then
forLine();
if pars.count < 3 then exit; // from here, only macros with at least 3 parameters if pars.count < 3 then exit; // from here, only macros with at least 3 parameters
if name ='for each' then if name ='for each' then

View File

@ -1,12 +1,12 @@
- update doesn't work without 'only 1 instance' (it's the -q)
+ replace shellExtDlg.gif with transparent png (english system) + replace shellExtDlg.gif with transparent png (english system)
+ self-test supporting https
+ expiring links + expiring links
* dismiss regexp lib http://docwiki.embarcadero.com/Libraries/Rio/en/System.RegularExpressions.TRegEx * dismiss regexp lib http://docwiki.embarcadero.com/Libraries/Rio/en/System.RegularExpressions.TRegEx
+ ipv6
+ load *.events + load *.events
+ url auth limited to resource + url auth limited to resource
+ global limit speed for downloads (browsing excluded) + global limit speed for downloads (browsing excluded)
* consider letting comment "protected" files. Can it really cause harm? + [tpl id] [SECTION|for-tpl=MASK]
* consider letting comment "protected" files. Can it really cause harm?
* flag to enable lnk files in a folder (disabled by default) * flag to enable lnk files in a folder (disabled by default)
+ sign exe http://www.rejetto.com/forum/hfs-~-http-file-server/'unsafe'/msg1061437/#msg1061437 + sign exe http://www.rejetto.com/forum/hfs-~-http-file-server/'unsafe'/msg1061437/#msg1061437
* cache reReplace * cache reReplace
@ -24,20 +24,13 @@
+ macros missing to cache a folder: {.reply|content=|var=|code=|filename=|mime=.} + macros missing to cache a folder: {.reply|content=|var=|code=|filename=|mime=.}
- unexpected scripting behavior http://www.rejetto.com/forum/index.php/topic,9728.msg1054517.html#msg1054517 - unexpected scripting behavior http://www.rejetto.com/forum/index.php/topic,9728.msg1054517.html#msg1054517
in handleItem() translate only symbols, and run all macros at the end in handleItem() translate only symbols, and run all macros at the end
document: [section|ver=MASK|build=MIN-MAX|template=MASK]
document: {.if|var}
document: {.exec|out|timeout|exitcode.}
document: [+section] document: [+section]
document: {.set item|diff template.} document: {.set item|diff template.}
document: {.add header|overwrite=0.} document: single line diff templates
document: {.calc| ][ } document: disconnection reason|if=XXX
document: single line diff templates (file path)
document: {.disconnection reason|if=XXX.}
document: %url% document: %url%
document: commands returning white space: add folder, save, set account, exec, mkdir, chdir, delete, rename, move copy, set document: commands returning white space: add folder, save, set account, exec, mkdir, chdir, delete, rename, move copy, set
document: pipe, base64, base64decode, dir, disk free, filetime, file changed, load tpl, sha256, for line document: dir, disk free, filetime, file changed, load tpl
document {.convert|macros|dec|hex.}
document: new event [login]
+ event to filter logging http://www.rejetto.com/forum/index.php/topic,9784.0.html + event to filter logging http://www.rejetto.com/forum/index.php/topic,9784.0.html
- wrong browser http://www.rejetto.com/forum/index.php/topic,9710.0.html - wrong browser http://www.rejetto.com/forum/index.php/topic,9710.0.html
solution: solution:
@ -48,14 +41,18 @@ document: new event [login]
+ upload to non-browsable folder + upload to non-browsable folder
- android doesn't upload http://www.rejetto.com/forum/index.php/topic,9699.0/topicseen.html#msg1054287 - android doesn't upload http://www.rejetto.com/forum/index.php/topic,9699.0/topicseen.html#msg1054287
- android doesn't work with passwords http://www.rejetto.com/forum/index.php/topic,9575.msg1054029.html#msg1054029 - android doesn't work with passwords http://www.rejetto.com/forum/index.php/topic,9575.msg1054029.html#msg1054029
? default tpl: check with IE6
? default tpl: consider css data uri http://www.nczonline.net/blog/2010/07/06/data-uris-make-css-sprites-obsolete/ ? default tpl: consider css data uri http://www.nczonline.net/blog/2010/07/06/data-uris-make-css-sprites-obsolete/
+ next VFS file format version should be text (yaml or json) + default tpl: support for rawr thumbnails
+ next VFS file format version should be XML-based
+ remove the "progress" from "log what", and use [progress|no log] instead + remove the "progress" from "log what", and use [progress|no log] instead
? {.rename.} should update descript.ion
+ folder archive depth limit http://www.rejetto.com/forum/index.php/topic,8546.msg1050027.html#msg1050027 + folder archive depth limit http://www.rejetto.com/forum/index.php/topic,8546.msg1050027.html#msg1050027
? in getPage() many %symbols% are translated in a way incompatible with {.section.} ? in getPage() many %symbols% are translated in a way incompatible with {.section.}
? Windows Script Interfaces ? Windows Script Interfaces
? {.image|src=file|width=x|dst=outfile.} ? {.image|src=file|width=x|dst=outfile.}
+ user input through {.dialog.} or similar + replace /~imgXX with ?mode=icon&id=XX
+ user input through {.dialog.}
+ show missing files in VFS http://www.rejetto.com/forum/index.php/topic,8203.new.html + show missing files in VFS http://www.rejetto.com/forum/index.php/topic,8203.new.html
* {.cache.} should be able to work on a simple variable * {.cache.} should be able to work on a simple variable
+ plugins system http://www.rejetto.com/wiki/index.php/HFS:_plugins_design + plugins system http://www.rejetto.com/wiki/index.php/HFS:_plugins_design
@ -69,6 +66,8 @@ document: new event [login]
+ log event to filter www.rejetto.com/forum/?topic=7332.0 + log event to filter www.rejetto.com/forum/?topic=7332.0
? integration with mediainfo.dll www.rejetto.com/forum/?topic=7329 ? integration with mediainfo.dll www.rejetto.com/forum/?topic=7329
+ folder archive log, just as for deletion http://www.rejetto.com/forum/index.php?topic=6904.msg1042974;topicseen#msg1042974 + folder archive log, just as for deletion http://www.rejetto.com/forum/index.php?topic=6904.msg1042974;topicseen#msg1042974
- upload doesn't work on chinese folders with uneven length www.rejetto.com/forum/?topic=5382
- chinese problems since #161 www.rejetto.com/forum/?topic=5344
- AV with RealVNC on hints by mouse hovering www.rejetto.com/forum/?topic=5261 - AV with RealVNC on hints by mouse hovering www.rejetto.com/forum/?topic=5261
- N-Stalker can locally crash HFS - N-Stalker can locally crash HFS
- AV in #179 http://www.rejetto.com/forum/index.php?topic=5653.msg1033457#msg1033457 www.rejetto.com/forum/?topic=5681 - AV in #179 http://www.rejetto.com/forum/index.php?topic=5653.msg1033457#msg1033457 www.rejetto.com/forum/?topic=5681
@ -93,12 +92,13 @@ document: new event [login]
+ an updated hint on virtual folders, to explain how to get upload working + an updated hint on virtual folders, to explain how to get upload working
- requesting a non-existant file inside an unauthorized folder, apache replies 401, hfs 404. try to comply. - requesting a non-existant file inside an unauthorized folder, apache replies 401, hfs 404. try to comply.
+ make %list% available in every page + make %list% available in every page
+ support for ALT+F4 with option "Minimize to tray clicking the close button" www.rejetto.com/forum/?topic=6351 + support for ALT+F4 with option "Minimize to tray clicking the close button" www.rejetto.com/forum/?topic=6351
+ replace and delete icons http://www.rejetto.com/forum/index.php?topic=6317.msg1038157#msg1038157 + replace and delete icons http://www.rejetto.com/forum/index.php?topic=6317.msg1038157#msg1038157
+ self-test supporting https
? currently the delete permission is only inside a folder. you can't mark a file or delete the marked folder. is this ok? ? currently the delete permission is only inside a folder. you can't mark a file or delete the marked folder. is this ok?
+ when a link is protected (no access for this user) it may be displayed as a link to the %item-name%, then 401, and if login is successful provide a redirection + when a link is protected (no access for this user) it may be displayed as a link to the %item-name%, then 401, and if login is successful provide a redirection
+ change folder/link/generic-file icons (via GUI, without editing the template) + change folder/link/generic-file icons (via GUI, without editing the template)
+ a way to get bigger icons (client side) + a way to get bigger icons (client side)
+ be able to produce rss http://www.rejetto.com/forum/index.php?topic=5846.msg1035481#msg1035481 + be able to produce rss http://www.rejetto.com/forum/index.php?topic=5846.msg1035481#msg1035481
* better warning message http://www.rejetto.com/forum/index.php?topic=5795.msg1034406#msg1034406 * better warning message http://www.rejetto.com/forum/index.php?topic=5795.msg1034406#msg1034406
? on the fly files compression www.rejetto.com/forum/?topic=5492 ? on the fly files compression www.rejetto.com/forum/?topic=5492
@ -106,7 +106,7 @@ document: new event [login]
? auto-removing folders www.rejetto.com/forum/?topic=3149 ? auto-removing folders www.rejetto.com/forum/?topic=3149
+ last-access-time for files www.rejetto.com/forum/?topic=5266 + last-access-time for files www.rejetto.com/forum/?topic=5266
+ expiration time for account www.rejetto.com/forum/?topic=5409 + expiration time for account www.rejetto.com/forum/?topic=5409
+ warn the user if there's no useful IP address http://www.rejetto.com/forum/index.php?topic=3193.msg1031371#msg1031371 + warn the user if there's no useful IP address http://www.rejetto.com/forum/index.php?topic=3193.msg1031371#msg1031371
+ GUI suggestions www.rejetto.com/forum/?topic=5334 + GUI suggestions www.rejetto.com/forum/?topic=5334
+ {.cookie.} http://www.rejetto.com/forum/index.php?topic=5349.0 + {.cookie.} http://www.rejetto.com/forum/index.php?topic=5349.0
+ restrict access to -> ip mask www.rejetto.com/forum/?topic=5244 + restrict access to -> ip mask www.rejetto.com/forum/?topic=5244
@ -127,37 +127,37 @@ document: new event [login]
+ per-folder no-limit + per-folder no-limit
+ windows auth (NLTM? seems to be available in ICS) www.rejetto.com/forum/?topic=3762 + windows auth (NLTM? seems to be available in ICS) www.rejetto.com/forum/?topic=3762
+ more stats www.rejetto.com/forum/?topic=4968 + more stats www.rejetto.com/forum/?topic=4968
+ to disable single ban rules + to disable single ban rules
+ ban by hostname + ban by hostname
+ edit comments for real folders www.rejetto.com/forum/?topic=4667 + edit comments for real folders www.rejetto.com/forum/?topic=4667
+ a way to pass ini commands through the command line + a way to pass ini commands through the command line
+ create folders via command line www.rejetto.com/forum/?topic=3955 + create folders via command line www.rejetto.com/forum/?topic=3955
? support mp3ToIon www.rejetto.com/forum/?topic=4600 ? support mp3ToIon www.rejetto.com/forum/?topic=4600
+ download only for <account-list> + download only for <account-list>
+ account: see all transfers in ~progress http://www.rejetto.com/forum/index.php/topic,9325.msg1053416/topicseen.html#msg1053416 + account: see all transfers in ~progress http://www.rejetto.com/forum/index.php/topic,9325.msg1053416/topicseen.html#msg1053416
+ limit account to a host mask + limit account to a host mask
+ tray icons for uploads + tray icons for uploads
+ MAC filter + MAC filter
+ if robots.txt does not exist, an option "don't be listed on search engines" + if robots.txt does not exist, an option "don't be listed on search engines"
+ menu -> limits -> temporarily disable all limits + menu -> limits -> temporarily disable all limits
+ menu -> limits -> max speed for each address + menu -> limits -> max speed for each address
+ option to display counter for folders as number of accesses instead of total access to files in it + option to display counter for folders as number of accesses instead of total access to files in it
+ autodisabling accounts www.rejetto.com/forum/?topic=5379 + autodisabling accounts www.rejetto.com/forum/?topic=5379
+ on update, propose a link to the "what's new" page + on update, propose a link to the "what's new" page
+ add special folder (expert mode): let you specify a special folder, like documents, or manually enter a path (useful for relative paths), or GUID + add special folder (expert mode): let you specify a special folder, like documents, or manually enter a path (useful for relative paths), or GUID
+ logs rotation (hfs always append) + logs rotation (hfs always append)
+ double address bar, one for LAN and one for the Internet + double address bar, one for LAN and one for the Internet
+ per user diff-tpl (apply both folder and user diff-tpl.s, and let the user decide priority, default:user,folder) + per user diff-tpl (apply both folder and user diff-tpl.s, and let the user decide priority, default:user,folder)
+ "Folder image mask", a file mask indicating the external file that should be used as icon (~img_folder) + "Folder image mask", a file mask indicating the external file that should be used as icon (~img_folder)
+ to be able to add icons from multi-icon files (like shell32.dll) + to be able to add icons from multi-icon files (like shell32.dll)
+ installer (saving to registry, and making ini-file the new default, don't ask for shell menu) + installer (saving to registry, and making ini-file the new default, don't ask for shell menu)
+ support unicode filenames (FindFirstFileW. Cannot be done because widgets don't support unicode) + support unicode filenames (FindFirstFileW. Cannot be done because widgets don't support unicode)
* show "(home)" instead of "/" in VFS * show "(home)" instead of "/" in VFS
+ show updateinfo notice also in autocheck + show updateinfo notice also in autocheck
+ top 10 downloaded files + top 10 downloaded files
+ after the self test fails, and a router problem is detected, prompt a wizard for portforwad.com (extract routers list) + after the self test fails, and a router problem is detected, prompt a wizard for portforwad.com (extract routers list)
+ export vfs map as txt/html + export vfs map as txt/html
+ specific message for each disabled account + specific message for each disabled account
+ search for files including meta information (id3 tag) www.rejetto.com/forum/?topic=5312 + search for files including meta information (id3 tag) www.rejetto.com/forum/?topic=5312
+ multiupload using flash + multiupload using flash
? support shortcut to folders in real-folders ? support shortcut to folders in real-folders
@ -185,7 +185,7 @@ document: new event [login]
* stop using /~commands and move all of them in the standard ?name=value form * stop using /~commands and move all of them in the standard ?name=value form
VER 3 VER 3
+ new kind of folder (no more real/virtual folders) + new kind of folder (no more real/virtual folders)
VER 3.5 VER 3.5
+ search for files + search for files

5
upload_disabled.txt Normal file
View File

@ -0,0 +1,5 @@
You selected a virtual folder.
Upload is NOT available for virtual folders, only for real folders.
=== How to get a real folder?
Add a folder from your disk, then click on "Real Folder".

10
upload_how.txt Normal file
View File

@ -0,0 +1,10 @@
1. Add a folder (choose "real folder")
You should now see a RED folder in your virtual file sytem, inside HFS
2. Right click on this folder
3. Properties -> Permissions -> Upload
4. Check on "Anyone"
5. Ok
Now anyone who has access to your HFS server can upload files to you.

View File

@ -1,5 +1,5 @@
{ {
Copyright (C) 2002-2020 Massimo Melina (www.rejetto.com) Copyright (C) 2002-2012 Massimo Melina (www.rejetto.com)
This file is part of HFS ~ HTTP File Server. This file is part of HFS ~ HTTP File Server.
@ -44,7 +44,6 @@ type
TnameExistsFun = function(user:string):boolean; TnameExistsFun = function(user:string):boolean;
procedure doNothing(); inline; // useful for readability procedure doNothing(); inline; // useful for readability
function httpsCanWork():boolean;
function accountExists(user:string; evenGroups:boolean=FALSE):boolean; function accountExists(user:string; evenGroups:boolean=FALSE):boolean;
function getAccount(user:string; evenGroups:boolean=FALSE):Paccount; function getAccount(user:string; evenGroups:boolean=FALSE):Paccount;
function nodeToFile(n:TtreeNode):Tfile; function nodeToFile(n:TtreeNode):Tfile;
@ -166,14 +165,14 @@ function replaceString(var ss:TStringDynArray; old, new:string):integer;
function popString(var ss:TstringDynArray):string; function popString(var ss:TstringDynArray):string;
procedure insertString(s:string; idx:integer; var ss:TStringDynArray); procedure insertString(s:string; idx:integer; var ss:TStringDynArray);
function removeString(var a:TStringDynArray; idx:integer; l:integer=1):boolean; overload; function removeString(var a:TStringDynArray; idx:integer; l:integer=1):boolean; overload;
function removeString(s:string; var a:TStringDynArray; onlyOnce:boolean=TRUE; ci:boolean=TRUE; keepOrder:boolean=TRUE):boolean; overload; function removeString(find:string; var a:TStringDynArray):boolean; overload;
procedure removeStrings(find:string; var a:TStringDynArray); procedure removeStrings(find:string; var a:TStringDynArray);
procedure toggleString(s:string; var ss:TStringDynArray); procedure toggleString(s:string; var ss:TStringDynArray);
function onlyString(s:string; ss:TStringDynArray):boolean; function onlyString(s:string; ss:TStringDynArray):boolean;
function addArray(var dst:TstringDynArray; src:array of string; where:integer=-1; srcOfs:integer=0; srcLn:integer=-1):integer; function addArray(var dst:TstringDynArray; src:array of string; where:integer=-1; srcOfs:integer=0; srcLn:integer=-1):integer;
function removeArray(var src:TstringDynArray; toRemove:array of string):integer; function removeArray(var src:TstringDynArray; toRemove:array of string):integer;
function addUniqueArray(var a:TstringDynArray; b:array of string):integer; function addUniqueArray(var a:TstringDynArray; b:array of string):integer;
procedure uniqueStrings(var a:TstringDynArray; ci:Boolean=TRUE); procedure uniqueStrings(var a:TstringDynArray);
function idxOf(s:string; a:array of string; isSorted:boolean=FALSE):integer; function idxOf(s:string; a:array of string; isSorted:boolean=FALSE):integer;
function stringExists(s:string; a:array of string; isSorted:boolean=FALSE):boolean; function stringExists(s:string; a:array of string; isSorted:boolean=FALSE):boolean;
function listToArray(l:Tstrings):TstringDynArray; function listToArray(l:Tstrings):TstringDynArray;
@ -255,7 +254,6 @@ function strSHA256(s:string):string;
function strSHA1(s:string):string; function strSHA1(s:string):string;
function strMD5(s:string):string; function strMD5(s:string):string;
function strToOem(s:string):ansistring; function strToOem(s:string):ansistring;
function strToBytes(s:ansistring):Tbytes;
implementation implementation
@ -641,14 +639,13 @@ if i < 0 then addString(s, ss)
else removeString(ss, i); else removeString(ss, i);
end; // toggleString end; // toggleString
procedure uniqueStrings(var a:TstringDynArray; ci:Boolean=TRUE); procedure uniqueStrings(var a:TstringDynArray);
var var
i, j: integer; i, j: integer;
begin begin
for i:=length(a)-1 downto 1 do for i:=length(a)-1 downto 1 do
for j:=i-1 downto 0 do for j:=i-1 downto 0 do
if ci and SameText(a[i], a[j]) if ansiCompareText(a[i], a[j]) = 0 then
or not ci and (a[i] = a[j]) then
begin begin
removeString(a, i); removeString(a, i);
break; break;
@ -669,6 +666,10 @@ begin
until false; until false;
end; // removeStrings end; // removeStrings
// remove first instance of the specified string
function removeString(find:string; var a:TStringDynArray):boolean;
begin result:=removeString(a, idxOf(find,a)) end;
function removeArray(var src:TstringDynArray; toRemove:array of string):integer; function removeArray(var src:TstringDynArray; toRemove:array of string):integer;
var var
i, l, ofs: integer; i, l, ofs: integer;
@ -742,35 +743,6 @@ while idx+l < length(a) do
setLength(a, idx); setLength(a, idx);
end; // removestring end; // removestring
function removeString(s:string; var a:TStringDynArray; onlyOnce:boolean=TRUE; ci:boolean=TRUE; keepOrder:boolean=TRUE):boolean; overload;
var i, lessen:integer;
begin
result:=FALSE;
if a = NIL then
exit;
lessen:=0;
try
for i:=length(a)-1 to 0 do
if ci and sameText(a[i], s)
or not ci and (a[i]=s) then
begin
result:=TRUE;
if keepOrder then
removeString(a, i)
else
begin
inc(lessen);
a[i]:=a[length(a)-lessen];
end;
if onlyOnce then
exit;
end;
finally
if lessen > 0 then
setLength(a, length(a)-lessen);
end;
end;
function dotted(i:int64):string; function dotted(i:int64):string;
begin begin
result:=intToStr(i); result:=intToStr(i);
@ -1240,8 +1212,14 @@ end;
// exec but does not wait for the process to end // exec but does not wait for the process to end
function execNew(cmd:string):boolean; function execNew(cmd:string):boolean;
var
si: TStartupInfo;
pi: TProcessInformation;
begin begin
result:=32 < ShellExecute(0, nil, 'cmd.exe', pchar('/C '+cmd), nil, SW_SHOW); fillchar(si, sizeOf(si), 0);
fillchar(pi, sizeOf(pi), 0);
si.cb:=sizeOf(si);
result:=createProcess(NIL,pchar(cmd),NIL,NIL,FALSE,0,NIL,NIL,si,pi)
end; // execNew end; // execNew
function addArray(var dst:TstringDynArray; src:array of string; where:integer=-1; srcOfs:integer=0; srcLn:integer=-1):integer; function addArray(var dst:TstringDynArray; src:array of string; where:integer=-1; srcOfs:integer=0; srcLn:integer=-1):integer;
@ -1678,103 +1656,71 @@ result:=inputQueryLongdlg.ShowModal() = mrOk;
if result then value:=inputQueryLongdlg.inputBox.Text; if result then value:=inputQueryLongdlg.inputBox.Text;
end; // inputQueryLong end; // inputQueryLong
function dllIsPresent(name:string):boolean;
var h: HMODULE;
begin
h:=LoadLibrary(@name);
result:= h<>0;
FreeLibrary(h);
end;
function httpsCanWork():boolean;
const
files: array of string = ['libcrypto-1_1.dll','libssl-1_1.dll'];
baseUrl = 'http://rejetto.com/hfs/';
// these should be made resourcestring but then a runtime error is raised
MSG = 'An HTTPS action is required but some files are missing. Download them?';
MSG_OK = 'Download completed';
MSG_KO = 'Download failed';
var
s: string;
missing: TStringDynArray;
begin
missing:=NIL;
for s in files do
if not FileExists(s) and not dllIsPresent(s) then
addString(s, missing);
if missing=NIL then
exit(TRUE);
if msgDlg(MSG, MB_OKCANCEL+MB_ICONQUESTION) <> MROK then
exit(FALSE);
for s in missing do
if not httpGetFile(baseUrl+s, s, 2, mainfrm.statusBarHttpGetUpdate) then
begin
msgDlg(MSG_KO, MB_ICONERROR);
exit(FALSE);
end;
mainfrm.setStatusBarText(MSG_OK);
result:=TRUE;
end; // httpsCanWork
function httpGet(url:string; from:int64=0; size:int64=-1):string; function httpGet(url:string; from:int64=0; size:int64=-1):string;
var var
http: THttpCli;
reply: Tstringstream; reply: Tstringstream;
begin begin
if size = 0 then if size = 0 then
exit(''); begin
result:='';
exit;
end;
reply:=TStringStream.Create(''); reply:=TStringStream.Create('');
with ThttpClient.createURL(url) do try
http:=Thttpcli.create(NIL);
try try
rcvdStream:=reply; http.URL:=url;
http.followRelocation:=TRUE;
http.rcvdStream:=reply;
http.agent:=HFS_HTTP_AGENT;
if (from <> 0) or (size > 0) then if (from <> 0) or (size > 0) then
contentRangeBegin:=intToStr(from); http.contentRangeBegin:=intToStr(from);
if size > 0 then if size > 0 then
contentRangeEnd:=intToStr(from+size-1); http.contentRangeEnd:=intToStr(from+size-1);
get(); http.get();
result:=reply.dataString; result:=reply.dataString;
if sameText('utf-8', reGet(ContentType, '; *charset=(.+) *($|;)')) then finally http.free end
Result:=UTF8ToString(result); finally reply.free end
finally
reply.free;
Free;
end
end; // httpGet end; // httpGet
function httpFileSize(url:string):int64; function httpFileSize(url:string):int64;
var
http: THttpCli;
begin begin
with ThttpClient.createURL(url) do http:=Thttpcli.create(NIL);
try
http.URL:=url;
http.Agent:=HFS_HTTP_AGENT;
try try
try http.head();
head(); result:=http.contentLength
result:=contentLength except result:=-1 end;
except result:=-1 finally http.free end
end;
finally free
end;
end; // httpFileSize end; // httpFileSize
function httpGetFile(url, filename:string; tryTimes:integer=1; notify:TdocDataEvent=NIL):boolean; function httpGetFile(url, filename:string; tryTimes:integer=1; notify:TdocDataEvent=NIL):boolean;
var var
supposed: integer; http: THttpCli;
reply: Tfilestream; reply: Tfilestream;
supposed: integer;
begin begin
reply:=TfileStream.Create(filename, fmCreate); reply:=TfileStream.Create(filename, fmCreate);
with ThttpClient.createURL(url) do try
http:=Thttpcli.create(NIL);
try try
rcvdStream:=reply; http.URL:=url;
onDocData:=notify; http.RcvdStream:=reply;
http.Agent:=HFS_HTTP_AGENT;
http.OnDocData:=notify;
result:=TRUE; result:=TRUE;
try get() try http.get()
except result:=FALSE except result:=FALSE end;
end; supposed:=http.ContentLength;
supposed:=ContentLength; finally http.free end
finally finally reply.free end;
reply.free;
free;
end;
result:= result and (sizeOfFile(filename)=supposed); result:= result and (sizeOfFile(filename)=supposed);
if not result then if not result then deleteFile(filename);
deleteFile(filename);
if not result and (tryTimes > 1) then if not result and (tryTimes > 1) then
result:=httpGetFile(url, filename, tryTimes-1, notify); result:=httpGetFile(url, filename, tryTimes-1, notify);
@ -2116,8 +2062,7 @@ if to_ = NIL then
end; end;
l:=to_-from+1; l:=to_-from+1;
setLength(result, l); setLength(result, l);
if l > 0 then if l > 0 then strLcopy(@result[1], from, l);
strLcopy(@result[1], from, l);
end; // getStr end; // getStr
function poss(chars:TcharSet; s:string; ofs:integer=1):integer; function poss(chars:TcharSet; s:string; ofs:integer=1):integer;
@ -2220,7 +2165,7 @@ const
var var
sa : TSecurityAttributes; sa : TSecurityAttributes;
ReadPipe,WritePipe : THandle; ReadPipe,WritePipe : THandle;
start : TStartUpInfoW; start : TStartUpInfoA;
ProcessInfo : TProcessInformation; ProcessInfo : TProcessInformation;
Buffer : Pansichar; Buffer : Pansichar;
TotalBytesRead, TotalBytesRead,
@ -2251,7 +2196,7 @@ else
timeout:=now()+timeout/SECONDS; timeout:=now()+timeout/SECONDS;
// Create a Console Child Process with redirected input and output // Create a Console Child Process with redirected input and output
try try
if CreateProcess(nil, PChar(dosApp), @sa, @sa, true, CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then if CreateProcessA(nil, PansiChar(ansistring(DosApp)), @sa, @sa, true, CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then
repeat repeat
result:=TRUE; result:=TRUE;
// wait for end of child process // wait for end of child process
@ -2261,22 +2206,16 @@ try
// so that the pipe is not blocked by an overflow. New information // so that the pipe is not blocked by an overflow. New information
// can be written from the console app to the pipe only if there is // can be written from the console app to the pipe only if there is
// enough buffer space. // enough buffer space.
if not PeekNamedPipe(ReadPipe, @Buffer[TotalBytesRead], ReadBuffer, @BytesRead, @TotalBytesAvail, @BytesLeftThisMessage ) if not PeekNamedPipe(ReadPipe, @Buffer[TotalBytesRead], ReadBuffer,
or (BytesRead > 0) and not ReadFile(ReadPipe, Buffer[TotalBytesRead], BytesRead, BytesRead, nil ) then @BytesRead, @TotalBytesAvail, @BytesLeftThisMessage ) then
break; break
else if BytesRead > 0 then
ReadFile(ReadPipe, Buffer[TotalBytesRead], BytesRead, BytesRead, nil );
inc(TotalBytesRead, BytesRead); inc(TotalBytesRead, BytesRead);
until (Apprunning <> WAIT_TIMEOUT) or (now() >= timeout); until (Apprunning <> WAIT_TIMEOUT) or (now() >= timeout);
if IsTextUnicode(Buffer, TotalBytesRead, NIL) then Buffer[TotalBytesRead]:= #0;
begin OemToCharA(PansiChar(Buffer),Buffer);
Pchar(@Buffer[TotalBytesRead])^:= #0; output:=string(ansistrings.strPas(Buffer));
output:=pchar(Buffer)
end
else
begin
Buffer[TotalBytesRead]:= #0;
OemToCharA(Buffer,Buffer);
output:=string(ansistrings.strPas(Buffer));
end;
finally finally
GetExitCodeProcess(ProcessInfo.hProcess, exitcode); GetExitCodeProcess(ProcessInfo.hProcess, exitcode);
TerminateProcess(ProcessInfo.hProcess, 0); TerminateProcess(ProcessInfo.hProcess, 0);
@ -2582,8 +2521,7 @@ var
i:=mImp+dir; i:=mImp+dir;
repeat repeat
j:=i+dir; j:=i+dir;
if (j > 0) and (j <= length(s)) if (j > 0) and (j <= length(s)) and charInSet(s[j], ['0'..'9','.']) then
and (charInSet(s[j], ['0'..'9','.','E']) or (j>1) and charInSet(s[j],['+','-']) and (s[j-1]='E')) then
i:=j i:=j
else else
break; break;
@ -2613,7 +2551,6 @@ begin
end; end;
if (i = 1) // a starting operator is not an operator if (i = 1) // a starting operator is not an operator
or (s[i-1]='E') // exponential syntax
or (v <= mImpV) // left-to-right precedence or (v <= mImpV) // left-to-right precedence
then continue; then continue;
// we got a better one, record it // we got a better one, record it
@ -2943,7 +2880,7 @@ finally
end; end;
end; // deltree end; // deltree
function strToBytes(s:ansistring):Tbytes; function str2bytes(s:ansistring):Tbytes;
begin begin
setLength(result, length(s)); setLength(result, length(s));
move(s[1], result[0], length(result)); move(s[1], result[0], length(result));
@ -2953,7 +2890,7 @@ function stringToGif(s:ansistring; gif:TgifImage=NIL):TgifImage;
var var
ss: Tbytesstream; ss: Tbytesstream;
begin begin
ss:=Tbytesstream.create(strToBytes(s)); ss:=Tbytesstream.create(str2bytes(s));
try try
if gif = NIL then if gif = NIL then
gif:=TGIFImage.Create(); gif:=TGIFImage.Create();

View File

@ -12,24 +12,16 @@ propaganda
Mobile-friendly template Mobile-friendly template
Unicode support Unicode support
Encrypted login, and logout Encrypted login, and logout
DoS protection
IPv6
/propaganda /propaganda
+ new default template + new default template
+ new login system, session based, with logout + new login system, session based, with logout
+ IPv6 support
+ DoS protection https://rejetto.com/forum/index.php?topic=13060.msg1065962#msg1065962
+ {.set item|name.} + {.set item|name.}
+ {.get item|icon.} + {.get item|icon.}
+ {.set cfg.} + {.set cfg.}
+ {.for line.}
+ {.if|var}
+ cache for jquery and template sections + cache for jquery and template sections
+ new template commands: base64, base64decode, md5, sha1, sha256 + new template commands: base64, base64decode, md5, sha1
+ *.diff.tpl in exe's folder + *.diff.tpl in exe's folder
+ default mime-type for mkv + default mime-type for mkv
+ 'no list' section flag
+ https client support (not server)
- fixed template handling of section names with both '+' and '=' present - fixed template handling of section names with both '+' and '=' present
- fixed LNK files to deleted items - fixed LNK files to deleted items
- fixed comments files were not updated upon deletion of files - fixed comments files were not updated upon deletion of files
@ -37,7 +29,6 @@ propaganda
- fixed double "Content-Length" header on compressed pages - fixed double "Content-Length" header on compressed pages
- fixed log text base color not matching system settings http://rejetto.com/forum/index.php?topic=13233.0 - fixed log text base color not matching system settings http://rejetto.com/forum/index.php?topic=13233.0
- fixed while renaming a file in the GUI, CTRL+C/V didn't work on the text - fixed while renaming a file in the GUI, CTRL+C/V didn't work on the text
- fixed diff tpl logic: an empty section will now override the inherited one
VER 2.3m VER 2.3m
propaganda propaganda