mirror of
https://github.com/rejetto/hfs2.git
synced 2025-12-19 10:03:56 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ff458fb73 | ||
|
|
0d71b9946a | ||
|
|
140528bac8 | ||
|
|
29f6bac31c | ||
|
|
e233f6d29a | ||
|
|
6e4dcf5b56 |
@ -1,3 +1,9 @@
|
|||||||
|
# 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
|
## 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.
|
||||||
@ -11,6 +17,8 @@ Icons are generated at http://fontello.com/ . Use fontello.json for further modi
|
|||||||
|
|
||||||
For the default template we are targeting compatibility with Chrome 49 as it's the latest version running on Windows XP.
|
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
|
## Libs used
|
||||||
- [ICS v8.64](http://www.overbyte.be) by François PIETTE
|
- [ICS v8.64](http://www.overbyte.be) by François PIETTE
|
||||||
- [TRegExpr v0.952b](https://github.com/andgineer/TRegExpr/releases) by Andrey V. Sorokin
|
- [TRegExpr v0.952b](https://github.com/andgineer/TRegExpr/releases) by Andrey V. Sorokin
|
||||||
|
|||||||
@ -99,6 +99,7 @@ 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;
|
||||||
@ -524,6 +525,16 @@ 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;
|
||||||
|
|||||||
10
default.tpl
10
default.tpl
@ -227,6 +227,10 @@ $domReady(()=>{
|
|||||||
$on('#search-panel', { submit(ev) {
|
$on('#search-panel', { submit(ev) {
|
||||||
var f = $form(ev.target)
|
var f = $form(ev.target)
|
||||||
var s = f.search
|
var s = f.search
|
||||||
|
if (!s) {
|
||||||
|
showError(`{.!Search field is mandatory.}`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
var folder = ''
|
var folder = ''
|
||||||
var ps = []
|
var ps = []
|
||||||
switch (f.where) {
|
switch (f.where) {
|
||||||
@ -733,7 +737,7 @@ function $form(form, field) {
|
|||||||
return form.elements.namedItem(field).value
|
return form.elements.namedItem(field).value
|
||||||
let ret = {}
|
let ret = {}
|
||||||
for (let e of form.elements)
|
for (let e of form.elements)
|
||||||
if (e.name) {
|
if (e.name && (e.type !== 'radio' || e.checked)) {
|
||||||
let v = e.value
|
let v = e.value
|
||||||
if (field === false)
|
if (field === false)
|
||||||
v = v.trim()
|
v = v.trim()
|
||||||
@ -1081,7 +1085,7 @@ function toggleSelection() {
|
|||||||
$toggle('selection-panel')
|
$toggle('selection-panel')
|
||||||
if (multiSelection = !multiSelection) {
|
if (multiSelection = !multiSelection) {
|
||||||
let base = $create('input.selector', { a:{type:'checkbox'} })
|
let base = $create('input.selector', { a:{type:'checkbox'} })
|
||||||
$msel('.item-selectable a', e=> // having the checkbox inside the A element will put it on the same line of A even with long A, otherwise A will start on a new line.
|
$msel('.item-selectable .item-link a', e=> // having the checkbox inside the A element will put it on the same line of A even with long A, otherwise A will start on a new line.
|
||||||
e.append(base.cloneNode()) )
|
e.append(base.cloneNode()) )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1340,7 +1344,7 @@ $domReady(()=>{
|
|||||||
$toggle('delete-selection', $sel('.can-delete'))
|
$toggle('delete-selection', $sel('.can-delete'))
|
||||||
$click('#archive', ()=>
|
$click('#archive', ()=>
|
||||||
mustSelect() && ask("{.!Downloading many files as archive can be a lengthy operation, and the result is a TAR file. Continue?.}", ()=>
|
mustSelect() && ask("{.!Downloading many files as archive can be a lengthy operation, and the result is a TAR file. Continue?.}", ()=>
|
||||||
submit({ selection: getSelectedItemsName() }, "{.get|url|mode=archive|recursive.}") ))
|
submit({ selection: getSelectedItemsName() }, "?mode=archive") ))
|
||||||
|
|
||||||
$msel('#files .cannot-access .item-link img', x=>
|
$msel('#files .cannot-access .item-link img', x=>
|
||||||
x.insertAdjacentElement('afterend', $icon('lock', "{.!No access.}") ))
|
x.insertAdjacentElement('afterend', $icon('lock', "{.!No access.}") ))
|
||||||
|
|||||||
@ -104,7 +104,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
|
||||||
@ -423,7 +423,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
|
||||||
@ -1599,7 +1599,7 @@ end; // initInputStream
|
|||||||
|
|
||||||
function ThttpConn.sendNextChunk(max:integer=MAXINT):integer;
|
function ThttpConn.sendNextChunk(max:integer=MAXINT):integer;
|
||||||
var
|
var
|
||||||
n: int64;
|
n, toSend: int64;
|
||||||
buf: ansistring;
|
buf: ansistring;
|
||||||
begin
|
begin
|
||||||
result:=0;
|
result:=0;
|
||||||
@ -1611,7 +1611,8 @@ 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;
|
||||||
if n > bytesToSend then n:=bytesToSend;
|
toSend:=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);
|
||||||
|
|||||||
20
main.pas
20
main.pas
@ -35,8 +35,8 @@ uses
|
|||||||
HSlib, traylib, monoLib, progFrmLib, classesLib;
|
HSlib, traylib, monoLib, progFrmLib, classesLib;
|
||||||
|
|
||||||
const
|
const
|
||||||
VERSION = '2.4.0 RC7';
|
VERSION = '2.4.0 RC8';
|
||||||
VERSION_BUILD = '319';
|
VERSION_BUILD = '320';
|
||||||
VERSION_STABLE = {$IFDEF STABLE } TRUE {$ELSE} FALSE {$ENDIF};
|
VERSION_STABLE = {$IFDEF STABLE } TRUE {$ELSE} FALSE {$ENDIF};
|
||||||
CURRENT_VFS_FORMAT :integer = 1;
|
CURRENT_VFS_FORMAT :integer = 1;
|
||||||
CRLF = #13#10;
|
CRLF = #13#10;
|
||||||
@ -5024,6 +5024,12 @@ var
|
|||||||
tar: TtarStream;
|
tar: TtarStream;
|
||||||
nofolders, selection, itsAsearch: boolean;
|
nofolders, selection, itsAsearch: boolean;
|
||||||
|
|
||||||
|
procedure addToTar(src,dst:string);
|
||||||
|
begin
|
||||||
|
if not selection or not tar.contains(src) then
|
||||||
|
tar.addFile(src, dst);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure addFolder(f:Tfile; ignoreConnFilters:boolean=FALSE);
|
procedure addFolder(f:Tfile; ignoreConnFilters:boolean=FALSE);
|
||||||
var
|
var
|
||||||
i, ofs: integer;
|
i, ofs: integer;
|
||||||
@ -5058,7 +5064,7 @@ var
|
|||||||
else
|
else
|
||||||
s:=fi.pathTill(f.parent); // we want the path to include also f, so stop at f.parent
|
s:=fi.pathTill(f.parent); // we want the path to include also f, so stop at f.parent
|
||||||
|
|
||||||
tar.addFile(fi.resource, s);
|
addToTar(fi.resource, s);
|
||||||
end
|
end
|
||||||
finally listing.free end;
|
finally listing.free end;
|
||||||
end; // addFolder
|
end; // addFolder
|
||||||
@ -5093,7 +5099,7 @@ var
|
|||||||
t:=substr(s, lastDelimiter('\/', s)+1)
|
t:=substr(s, lastDelimiter('\/', s)+1)
|
||||||
else
|
else
|
||||||
t:=s;
|
t:=s;
|
||||||
tar.addFile(ft.resource, t);
|
addToTar(ft.resource, t);
|
||||||
finally freeIfTemp(ft) end;
|
finally freeIfTemp(ft) end;
|
||||||
end;
|
end;
|
||||||
end; // addSelection
|
end; // addSelection
|
||||||
@ -8112,10 +8118,10 @@ var
|
|||||||
|
|
||||||
if userSocketBuffer > 0 then
|
if userSocketBuffer > 0 then
|
||||||
data.conn.sndBuf:=userSocketBuffer
|
data.conn.sndBuf:=userSocketBuffer
|
||||||
else
|
else if highSpeedChk.checked then
|
||||||
begin
|
begin
|
||||||
size:=minmax(8192, MEGA, round(data.averageSpeed));
|
size:=minmax(8192, MEGA, round(data.averageSpeed));
|
||||||
if highSpeedChk.checked and (safeDiv(0.0+size, data.conn.sndbuf, 2) > 2) then
|
if safeDiv(0.0+size, data.conn.sndbuf, 2) > 2 then
|
||||||
data.conn.sndBuf:=size;
|
data.conn.sndBuf:=size;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -12118,7 +12124,7 @@ tray:=TmyTrayicon.create(self);
|
|||||||
DragAcceptFiles(handle, true);
|
DragAcceptFiles(handle, true);
|
||||||
caption:=format('HFS ~ HTTP File Server %s', [VERSION]);
|
caption:=format('HFS ~ HTTP File Server %s', [VERSION]);
|
||||||
application.Title:=format('HFS %s', [VERSION]);
|
application.Title:=format('HFS %s', [VERSION]);
|
||||||
setSpeedLimit(-1);
|
setSpeedLimit(50000);
|
||||||
setSpeedLimitIP(-1);
|
setSpeedLimitIP(-1);
|
||||||
setGraphRate(10);
|
setGraphRate(10);
|
||||||
setMaxConnections(0);
|
setMaxConnections(0);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user