Skip to content

Unstable max ar workers #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: unstable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Will generate executable file "main" in current directory.
Start server on port 8080, root directory is current working directory:
```sh
ghfs -l 8080
```
```

Start server on port 8080, root directory is /usr/share/doc:
```sh
Expand Down Expand Up @@ -265,6 +265,10 @@ ghfs [options]
--archive-dir <fs-path> ...
--archive-dir-user <separator><fs-path>[<separator><allowed-username>...] ...
Similar to --archive, but use file system path instead of url path.
--archive-workers-max <number>
Maximum number of concurrent archive operations.
Set to 0 for unlimited (default).
When the limit is reached, new archive requests will be rejected with status code 429(Too Many Requests).

--global-cors
Allow CORS requests for all url path.
Expand Down Expand Up @@ -304,7 +308,7 @@ ghfs [options]
-S|--show <wildcard> ...
-SD|--show-dir <wildcard> ...
-SF|--show-file <wildcard> ...
If specified, files or directories match wildcards(except hidden by hide option) will be shown.
If specified, files or directories match wildcards(except hidden by hide option) will be shown.

-H|--hide <wildcard> ...
-HD|--hide-dir <wildcard> ...
Expand Down
6 changes: 5 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ go build main.go
在8080端口启动服务器,根目录为当前工作目录:
```sh
ghfs -l 8080
```
```

在8080端口启动服务器,根目录为 /usr/share/doc:
```sh
Expand Down Expand Up @@ -255,6 +255,10 @@ ghfs [选项]
--archive-dir <文件系统路径> ...
--archive-dir-user <分隔符><文件系统路径>[<分隔符><允许的用户名>...] ...
与--archive类似,但指定的是文件系统路径,而不是URL路径。
--archive-workers-max <数值>
指定打包下载的最大并发数。
设为0(默认)表示无限制。
达到并发上限后,会拒绝后续打包请求并返回状态码429(Too Many Requests)。

--global-cors
接受所有URL路径的CORS跨域请求。
Expand Down
6 changes: 6 additions & 0 deletions src/param/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ func NewCliCmd() *goNixArgParser.Command {
err = options.AddFlagValues("archivedirsusers", "--archive-dir-user", "", nil, "file system path that allow archive files for specific users, <sep><fs-path>[<sep><user>...]")
serverError.CheckFatal(err)

err = options.AddFlagValue("archiveworkersmax", "--archive-workers-max", "", "0", "maximum number of concurrent archive operations (0 for unlimited)")
serverError.CheckFatal(err)

err = options.AddFlag("globalcors", "--global-cors", "GHFS_GLOBAL_CORS", "enable CORS headers for all directories")
serverError.CheckFatal(err)

Expand Down Expand Up @@ -436,6 +439,8 @@ func CmdResultsToParams(results []*goNixArgParser.ParseResult) (params Params, e
archiveDirsUsers, _ := result.GetStrings("archivedirsusers")
param.ArchiveDirsUsers = SplitAllKeyValues(archiveDirsUsers)

param.ArchiveWorkersMax, _ = result.GetUint32("archiveworkersmax")

// global restrict access
if result.HasKey("globalrestrictaccess") {
param.GlobalRestrictAccess, _ = result.GetStrings("globalrestrictaccess")
Expand Down Expand Up @@ -465,6 +470,7 @@ func CmdResultsToParams(results []*goNixArgParser.ParseResult) (params Params, e
certFiles, _ := result.GetStrings("certs")
keyFiles, _ := result.GetStrings("keys")
param.CertKeyPaths, es = goVirtualHost.CertsKeysToPairs(certFiles, keyFiles)
errs = append(errs, es...)

// listen
listens, _ := result.GetStrings("listens")
Expand Down
11 changes: 6 additions & 5 deletions src/param/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ type Param struct {
DeleteDirs []string
DeleteDirsUsers [][]string // [][path, user...]

GlobalArchive bool
ArchiveUrls []string
ArchiveUrlsUsers [][]string // [][path, user...]
ArchiveDirs []string
ArchiveDirsUsers [][]string // [][path, user...]
GlobalArchive bool
ArchiveUrls []string
ArchiveUrlsUsers [][]string // [][path, user...]
ArchiveDirs []string
ArchiveDirsUsers [][]string // [][path, user...]
ArchiveWorkersMax uint32

GlobalCors bool
CorsUrls []string
Expand Down
23 changes: 8 additions & 15 deletions src/serverHandler/aliasHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type aliasHandler struct {
archive *hierarchyAvailability
cors *hierarchyAvailability

archiveWorkersMax uint32
archivingWorkers *uint32

globalRestrictAccess []string
restrictAccessUrls pathStringsList
restrictAccessDirs pathStringsList
Expand Down Expand Up @@ -120,21 +123,8 @@ func (h *aliasHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

if session.isMutate && h.mutate(w, r, session, data) {
return
} else if session.isArchive {
switch session.archiveFormat {
case tarFmt:
if h.tar(w, r, session, data) {
return
}
case tgzFmt:
if h.tgz(w, r, session, data) {
return
}
case zipFmt:
if h.zip(w, r, session, data) {
return
}
}
} else if session.isArchive && h.tryArchive(w, r, session, data) {
return
}
}

Expand Down Expand Up @@ -179,6 +169,9 @@ func newAliasHandler(
toHttpsPort: p.ToHttpsPort,
defaultSort: p.DefaultSort,

archiveWorkersMax: p.ArchiveWorkersMax,
archivingWorkers: vhostCtx.archivingWorkers,

users: vhostCtx.users,
theme: vhostCtx.theme,
logger: vhostCtx.logger,
Expand Down
35 changes: 35 additions & 0 deletions src/serverHandler/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path"
"strings"
"sync/atomic"
)

type archiveCallback func(f *os.File, fInfo os.FileInfo, relPath string) error
Expand Down Expand Up @@ -210,3 +211,37 @@ func (h *aliasHandler) normalizeArchiveSelections(r *http.Request) ([]string, bo

return selections, true
}

func (h *aliasHandler) startArchive(w http.ResponseWriter, r *http.Request, session *sessionContext, data *responseData) (ok bool) {
switch session.archiveFormat {
case tarFmt:
return h.tar(w, r, session, data)
case tgzFmt:
return h.tgz(w, r, session, data)
case zipFmt:
return h.zip(w, r, session, data)
}

return
}

func (h *aliasHandler) tryArchive(w http.ResponseWriter, r *http.Request, session *sessionContext, data *responseData) (ok bool) {
if h.archivingWorkers == nil {
return h.startArchive(w, r, session, data)
}

if *h.archivingWorkers >= h.archiveWorkersMax {
data.Status = http.StatusTooManyRequests
return
}

archiving := atomic.AddUint32(h.archivingWorkers, 1)
ok = archiving <= h.archiveWorkersMax
if ok {
ok = h.startArchive(w, r, session, data)
} else {
data.Status = http.StatusTooManyRequests
}
atomic.AddUint32(h.archivingWorkers, ^uint32(0)) // archiveWorkers -= 1
Copy link

@OlegChuev OlegChuev May 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can ^uint32(0) cause uint underflow? (0 - 1 -> 4294967295)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this case, this would never happened since it always added by 1 first.

return
}
9 changes: 9 additions & 0 deletions src/serverHandler/vhostHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type vhostContext struct {
archiveUrlsUsers pathIntsList
archiveDirsUsers pathIntsList

archivingWorkers *uint32

shows *regexp.Regexp
showDirs *regexp.Regexp
showFiles *regexp.Regexp
Expand Down Expand Up @@ -95,6 +97,11 @@ func NewVhostHandler(
theme = defaultTheme.DefaultTheme
}

var archivingWorkers *uint32
if p.ArchiveWorkersMax > 0 {
archivingWorkers = new(uint32)
}

// alias param
vhostCtx := &vhostContext{
logger: logger,
Expand All @@ -114,6 +121,8 @@ func NewVhostHandler(
archiveUrlsUsers: pathUsernamesToPathUids(users, p.ArchiveUrlsUsers),
archiveDirsUsers: pathUsernamesToPathUids(users, p.ArchiveDirsUsers),

archivingWorkers: archivingWorkers,

shows: shows,
showDirs: showDirs,
showFiles: showFiles,
Expand Down