The best HTTP Static File Server, write with golang+vue

gohttpserver

Build Status Docker Automated build

  • Goal: Make the best HTTP File Server.
  • Features: Human-friendly UI, file uploading support, direct QR-code generation for Apple & Android install package.

Demo site

  • 目标: 做最好的HTTP文件服务器
  • 功能: 人性化的UI体验,文件的上传支持,安卓和苹果安装包的二维码直接生成。

Binaries can be downloaded from this repo releases

Requirements

Tested with go-1.16

Screenshots

screen

Features

  1. Support QRCode code generate
  2. Breadcrumb path quick change
  3. All assets package to Standalone binary
  4. Different file type different icon
  5. Support show or hide hidden files
  6. Upload support (auth by token or session)
  7. README.md preview
  8. HTTP Basic Auth
  9. Partial reload pages when directory change
  10. When only one dir under dir, path will combine two together
  11. Directory zip download
  12. Apple ipa auto generate .plist file, qrcode can be recognized by iphone (Require https)
  13. Plist proxy
  14. Download count statistics
  15. CORS enabled
  16. Offline download
  17. Code file preview
  18. Edit file support
  19. Global file search
  20. Hidden work download and qrcode in small screen
  21. Theme select support
  22. OK to working behide Nginx
  23. .ghs.yml support (like .htaccess)
  24. Calculate md5sum and sha
  25. Folder upload
  26. Support sort by size or modified time
  27. Add version info into index page
  28. Add api /-/info/some.(apk|ipa) to get detail info
  29. Add api /-/apk/info/some.apk to get android package info
  30. Auto tag version
  31. Custom title support
  32. Support setting from conf file
  33. Quick copy download link
  34. Show folder size
  35. Create folder
  36. Skip delete confirm when alt pressed
  37. Support unzip zip file when upload(with form: unzip=true)

Installation

go get -v github.com/codeskyblue/gohttpserver
cd $GOPATH/src/github.com/codeskyblue/gohttpserver
go build && ./gohttpserver

Or download binaries from github releases

If you are using Mac, simply run command

brew install codeskyblue/tap/gohttpserver

Usage

Listen on port 8000 of all interfaces, and enable file uploading.

./gohttpserver -r ./ --port 8000 --upload

Use command gohttpserver --help to see more usage.

Docker Usage

share current directory

docker run -it --rm -p 8000:8000 -v $PWD:/app/public --name gohttpserver codeskyblue/gohttpserver

Share current directory with http basic auth

docker run -it --rm -p 8000:8000 -v $PWD:/app/public --name gohttpserver \
  codeskyblue/gohttpserver \
  --auth-type http --auth-http username:password

Share current directory with openid auth. (Works only in netease company.)

docker run -it --rm -p 8000:8000 -v $PWD:/app/public --name gohttpserver \
  codeskyblue/gohttpserver \
  --auth-type openid

To build image yourself, please change the PWD to the root of this repo.

cd gohttpserver/
docker build -t codeskyblue/gohttpserver -f docker/Dockerfile .

Authentication options

  • Enable basic http authentication

    $ gohttpserver --auth-type http --auth-http username:password
  • Use openid auth

    $ gohttpserver --auth-type openid --auth-openid https://login.example-hostname.com/openid/
  • Use oauth2-proxy with

    $ gohttpserver --auth-type oauth2-proxy

    You can configure to let a http reverse proxy handling authentication. When using oauth2-proxy, the backend will use identification info from request headers X-Auth-Request-Email as userId and X-Auth-Request-Fullname as user's display name. Please config your oauth2 reverse proxy yourself. More about oauth2-proxy.

    All required headers list as following.

    header value
    X-Auth-Request-Email userId
    X-Auth-Request-Fullname user's display name(urlencoded)
    X-Auth-Request-User user's nickname (mostly email prefix)
  • Enable upload

    $ gohttpserver --upload
  • Enable delete and Create folder

    $ gohttpserver --delete

Advanced usage

Add access rule by creating a .ghs.yml file under a sub-directory. An example:

---
upload: false
delete: false
users:
- email: "[email protected]"
  delete: true
  upload: true
  token: 4567gf8asydhf293r23r

In this case, if openid auth is enabled and user "[email protected]" has logged in, he/she can delete/upload files under the directory where the .ghs.yml file exits.

token is used for upload. see upload with curl

For example, in the following directory hierarchy, users can delete/uploade files in directory foo, but he/she cannot do this in directory bar.

root -
  |-- foo
  |    |-- .ghs.yml
  |    `-- world.txt 
  `-- bar
       `-- hello.txt

User can specify config file name with --conf, see example config.yml.

To specify which files is hidden and which file is visible, add the following lines to .ghs.yml

accessTables:
- regex: block.file
  allow: false
- regex: visual.file
  allow: true

ipa plist proxy

This is used for server on which https is enabled. default use https://plistproxy.herokuapp.com/plist

./gohttpserver --plistproxy=https://someproxyhost.com/

Test if proxy works:

$ http POST https://someproxyhost.com/plist < app.plist
{
	"key": "18f99211"
}
$ http GET https://someproxyhost.com/plist/18f99211
# show the app.plist content

If your ghs running behide nginx server and have https configed. plistproxy will be disabled automaticly.

Upload with CURL

For example, upload a file named foo.txt to directory somedir

$ curl -F [email protected] localhost:8000/somedir
{"destination":"somedir/foo.txt","success":true}
# upload with token
$ curl -F [email protected] -F token=12312jlkjafs localhost:8000/somedir
{"destination":"somedir/foo.txt","success":true}

# upload and change filename
$ curl -F [email protected] -F filename=hi.txt localhost:8000/somedir
{"destination":"somedir/hi.txt","success":true}

Upload zip file and unzip it (zip file will be delete when finished unzip)

$ curl -F [email protected] -F unzip=true localhost:8000/somedir
{"success": true}

Note: \/:*<>| are not allowed in filenames.

Deploy with nginx

Recommended configuration, assume your gohttpserver listening on 127.0.0.1:8200

server {
  listen 80;
  server_name your-domain-name.com;

  location / {
    proxy_pass http://127.0.0.1:8200; # here need to change
    proxy_redirect off;
    proxy_set_header  Host    $host;
    proxy_set_header  X-Real-IP $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;

    client_max_body_size 0; # disable upload limit
  }
}

gohttpserver should started with --xheaders argument when behide nginx.

Refs: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size

FAQ

How the query is formated

The search query follows common format rules just like Google. Keywords are seperated with space(s), keywords with prefix - will be excluded in search results.

  1. hello world means must contains hello and world
  2. hello -world means must contains hello but not contains world

Developer Guide

Depdencies are managed by govendor

  1. Build develop version. assets directory must exists
go build
./gohttpserver
  1. Build single binary release
go generate .
go build -tags vfs

Theme are defined in assets/themes directory. Now only two themes are available, "black" and "green".

Reference Web sites

Go Libraries

History

The old version is hosted at https://github.com/codeskyblue/gohttp

LICENSE

This project is licensed under MIT.

Comments
  • cannot use apkf.Manifest().VersionCode

    cannot use apkf.Manifest().VersionCode

    Hi, when building Docker image, the error stop occurs:

    # github.com/codeskyblue/gohttpserver
    ./httpstaticserver.go:291:18: cannot use apkf.Manifest().VersionCode (type androidbinary.Int32) as type int in assignment
    ./httpstaticserver.go:292:18: cannot use apkf.Manifest().VersionName (type androidbinary.String) as type string in assignment
    The command '/bin/sh -c go get -v' returned a non-zero code: 2
    

    Steps to reproduce:

    1. git clone https://github.com/codeskyblue/gohttpserver.git
    2. cd gohttpserver/
    3. docker build -t codeskyblue/gohttpserver -f docker/Dockerfile

    Full output on the steps above:

    [user@lp-user tmp]$ git clone https://github.com/codeskyblue/gohttpserver.git
    Cloning into 'gohttpserver'...
    remote: Enumerating objects: 2321, done.
    remote: Total 2321 (delta 0), reused 0 (delta 0), pack-reused 2321
    Receiving objects: 100% (2321/2321), 3.56 MiB | 3.86 MiB/s, done.
    Resolving deltas: 100% (1087/1087), done.
    [user@lp-user tmp]$ cd gohttpserver/
    [user@lp-user gohttpserver]$ ls -la
    total 116K
    drwxr-sr-x 1 user cdrom   516 Aug 28 17:16 .
    drwxr-s--- 1 user cdrom    82 Aug 28 17:16 ..
    drwxr-sr-x 1 user cdrom   170 Aug 28 17:16 assets
    -rw-r--r-- 1 user cdrom   172 Aug 28 17:16 assets_dev.go
    -rw-r--r-- 1 user cdrom   316 Aug 28 17:16 assets_generate.go
    -rwxr-xr-x 1 user cdrom   809 Aug 28 17:16 build.sh
    drwxr-sr-x 1 user cdrom   100 Aug 28 17:16 docker
    -rw-r--r-- 1 user cdrom   282 Aug 28 17:16 .fsw.yml
    -rw-r--r-- 1 user cdrom    27 Aug 28 17:16 .ghs.yml
    drwxr-sr-x 1 user cdrom   138 Aug 28 17:16 .git
    -rw-r--r-- 1 user cdrom   330 Aug 28 17:16 .gitignore
    -rw-r--r-- 1 user cdrom  1374 Aug 28 17:16 go.mod
    -rw-r--r-- 1 user cdrom   821 Aug 28 17:16 .goreleaser.yml
    -rw-r--r-- 1 user cdrom 18518 Aug 28 17:16 httpstaticserver.go
    -rw-r--r-- 1 user cdrom  3456 Aug 28 17:16 ipa.go
    -rw-r--r-- 1 user cdrom  1077 Aug 28 17:16 LICENSE
    -rw-r--r-- 1 user cdrom  6641 Aug 28 17:16 main.go
    -rw-r--r-- 1 user cdrom   593 Aug 28 17:16 oauth2-proxy.go
    -rw-r--r-- 1 user cdrom  2893 Aug 28 17:16 openid-login.go
    -rw-r--r-- 1 user cdrom    71 Aug 28 17:16 Procfile
    -rw-r--r-- 1 user cdrom  9248 Aug 28 17:16 README.md
    -rw-r--r-- 1 user cdrom   458 Aug 28 17:16 res.go
    drwxr-sr-x 1 user cdrom    34 Aug 28 17:16 scripts
    drwxr-sr-x 1 user cdrom   144 Aug 28 17:16 testdata
    -rw-r--r-- 1 user cdrom   468 Aug 28 17:16 .travis.yml
    -rw-r--r-- 1 user cdrom  1375 Aug 28 17:16 utils.go
    -rw-r--r-- 1 user cdrom   543 Aug 28 17:16 utils_test.go
    -rw-r--r-- 1 user cdrom  3798 Aug 28 17:16 zip.go
    -rw-r--r-- 1 user cdrom   380 Aug 28 17:16 zip_test.go
    [user@lp-user gohttpserver]$ docker build --no-cache -t codeskyblue/gohttpserver -f docker/Dockerfile .
    Sending build context to Docker daemon  7.335MB
    Step 1/15 : FROM golang:1.10
     ---> 6fd1f7edb6ab
    Step 2/15 : WORKDIR /go/src/github.com/codeskyblue/gohttpserver
     ---> Running in fde824fcd582
    Removing intermediate container fde824fcd582
     ---> 02230697b6a8
    Step 3/15 : ADD . /go/src/github.com/codeskyblue/gohttpserver/
     ---> c38419cb8284
    Step 4/15 : RUN go get -v
     ---> Running in a814305425ec
    github.com/alecthomas/kingpin (download)
    github.com/alecthomas/template (download)
    github.com/alecthomas/units (download)
    github.com/codeskyblue/dockerignore (download)
    github.com/codeskyblue/go-accesslog (download)
    github.com/codeskyblue/openid-go (download)
    Fetching https://golang.org/x/net/html?go-get=1
    Parsing meta tags from https://golang.org/x/net/html?go-get=1 (status code 200)
    get "golang.org/x/net/html": found meta tag get.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at https://golang.org/x/net/html?go-get=1
    get "golang.org/x/net/html": verifying non-authoritative meta tag
    Fetching https://golang.org/x/net?go-get=1
    Parsing meta tags from https://golang.org/x/net?go-get=1 (status code 200)
    golang.org/x/net (download)
    github.com/fork2fix/go-plist (download)
    github.com/go-yaml/yaml (download)
    github.com/goji/httpauth (download)
    github.com/gorilla/handlers (download)
    github.com/gorilla/mux (download)
    github.com/gorilla/sessions (download)
    github.com/gorilla/securecookie (download)
    github.com/shogo82148/androidbinary (download)
    github.com/pkg/errors (download)
    github.com/shurcooL/vfsgen (download)
    github.com/shurcooL/httpfs (download)
    Fetching https://golang.org/x/text/encoding/simplifiedchinese?go-get=1
    Parsing meta tags from https://golang.org/x/text/encoding/simplifiedchinese?go-get=1 (status code 200)
    get "golang.org/x/text/encoding/simplifiedchinese": found meta tag get.metaImport{Prefix:"golang.org/x/text", VCS:"git", RepoRoot:"https://go.googlesource.com/text"} at https://golang.org/x/text/encoding/simplifiedchinese?go-get=1
    get "golang.org/x/text/encoding/simplifiedchinese": verifying non-authoritative meta tag
    Fetching https://golang.org/x/text?go-get=1
    Parsing meta tags from https://golang.org/x/text?go-get=1 (status code 200)
    golang.org/x/text (download)
    golang.org/x/text/encoding/internal/identifier
    golang.org/x/net/html/atom
    golang.org/x/text/transform
    github.com/alecthomas/template/parse
    github.com/alecthomas/units
    github.com/codeskyblue/dockerignore
    golang.org/x/net/html
    github.com/fork2fix/go-plist
    github.com/codeskyblue/go-accesslog
    github.com/go-yaml/yaml
    github.com/alecthomas/template
    github.com/goji/httpauth
    github.com/codeskyblue/openid-go
    github.com/gorilla/handlers
    github.com/gorilla/mux
    github.com/alecthomas/kingpin
    github.com/gorilla/securecookie
    github.com/pkg/errors
    github.com/gorilla/sessions
    github.com/shogo82148/androidbinary
    github.com/shurcooL/httpfs/vfsutil
    golang.org/x/text/encoding
    github.com/shurcooL/vfsgen
    golang.org/x/text/encoding/internal
    github.com/shogo82148/androidbinary/apk
    golang.org/x/text/encoding/simplifiedchinese
    github.com/codeskyblue/gohttpserver
    # github.com/codeskyblue/gohttpserver
    ./httpstaticserver.go:291:18: cannot use apkf.Manifest().VersionCode (type androidbinary.Int32) as type int in assignment
    ./httpstaticserver.go:292:18: cannot use apkf.Manifest().VersionName (type androidbinary.String) as type string in assignment
    The command '/bin/sh -c go get -v' returned a non-zero code: 2
    

    Could you please advise how to success with the image build?

    Thanks, Vladimir.

  • Run on android & ios

    Run on android & ios

    Could you provide some releases for windows, linux, mac or android & ios? And also, you can provide a qr code to help mobile phone to visit your file server.

  • why search file does not works for me?

    why search file does not works for me?

    I try the demon https://gohttpserver.herokuapp.com

    on right top corner, search text box, I type 'readme' it only works one time.

    then it stop working.

    Then I try type 'image.jpg' in search box right top corner, then nothing. This file is under 'filetypes' folder, why it not find?

    Can you advise, why, this happen to me?

  • 请问后退按钮是如何做到的?

    请问后退按钮是如何做到的?

     <button class="btn btn-xs btn-default" onclick="history.back()">
                                    Back <i class="fa fa-arrow-left"></i>
                                </button>
    

    我没有找到back函数。谢谢

  • rest api feature?

    rest api feature?

    Is it possible add new feature as rest api?

    for example:

    http://localhost:8000/xxx?f=json

    this url will response as a json instead of html.

    ` { subfolder: { { folder: xxxx1},
    { folder: xxxx1}
    },

    file: { {file: yyy1}, {file: yyy2} ..... }

    }`

    you also can add other meta data info into this json.

    Why do this, is because if you have this rest api, I can write page easy search file name(since all file name, file info are in Json format.)

    I mean, you have build the website, if you add rest api for this web site, will be very useful for third party wrote apps to communicate with your site.

    For example, twitter rest api, facebook rest api, flickr rest api. etc......

  • How to setup https(ssl)?

    How to setup https(ssl)?

    I see your code support https, but I am not sure, how and where, can you write more details how and where on README? I know this is go and https question, should not be here, but since your code already support https, your simple a few words will helps alot.

    What I don't know is where to setup gcfg.Cert, gcfg.Key?

    I have 2 files "public.cert" and "private.key" where should I put these 2 files for https,

    And does config.yml need to update? how to connect gcfg.Cert, gcfg.Key to those 2 files?

    I also try

        gcfg.Cert = "./public.cert"
    gcfg.Key = "./private.key"
    

    and put those 2 files at ./ , failed.

       var err error
    if gcfg.Key != "" && gcfg.Cert != "" {
    	err = http.ListenAndServeTLS(gcfg.Addr, gcfg.Cert, gcfg.Key, nil)
    } else {
    	err = http.ListenAndServe(gcfg.Addr, nil)
    }
    log.Fatal(err)
    
  • can I search file by name?

    can I search file by name?

    I try to search file by file name, (NOT text contend inside file). I want to find all file name, that have "xxxx", but nothing return.

    How to use the search box on top right corner?

    Can you wrote some details in READ ME, teach us how to use search function?

  • Need user login sign up

    Need user login sign up

    Anybody can upload? That is huge risk. Can you add user sign up and user login?
    Only logined user can upload!

    Add user management is MUST have feature, for it to be useful. Super admin can disable other user, add, delete other users.

  • How to get in touch regarding a security concern?

    How to get in touch regarding a security concern?

    Hello 👋

    I found a potential security issue in gohttpserver, how can I get in touch with you in a private way and submit my security report?

    Could you add a SECURITY.md file with an e-mail address for me to send further details to? GitHub recommends a security policy to ensure issues are responsibly disclosed, and it would help direct researchers in the future.

  • Add support for strict TLS protocol version and cipher-suites

    Add support for strict TLS protocol version and cipher-suites

    This is a very poorly written patch that adds the following:

    --strong-tls - Sets the TLS configuration to TLS1.3 only and sets ciphers to a list that excludes problematic cipher-suites (e.g. those with CBC-mode symmetric ciphers) --tls1_2 - When used with --strong-tls, this enables TLS1.2, but still excludes cipher-suites with CBC-mode symmetric ciphers

    I don't necessarily expect you to accept this for a few reasons:

    1. It's poorly written- I don't write go very often, you'll notice (for example) that the instantiation of http.Server now can take place in one of two places. This seems clunky, it would make more sense to conditionally set the TLSConfig and and TLSNextProto parameters. If you have an interest in accepting this I can look into how to do that properly
    2. It may be the case that gohttpserver is intended to be placed behind a reverse-proxy for TLS termination when the strength of the TLS configuration is a concern
    3. There are not any _practically exploitable issues with the default configuration

    I included a few references as comments regarding the choice of cipher-suites, but the primary issue is the avoidance of CBC-mode symmetric algorithms. Historically, CBC-mode ciphers haven't fared well and many vulnerability scanners do not like finding them (particularly when TLS versions < TLS1.2 offer them) making this change mostly useful for compliance reasons within certain environments

    Please feel free to reject this or suggest improvements. I'm going to keep my fork as I need it for a specific use

    Thanks for your work on this project!

    EDIT: As the caveat in the command-line output says- enabling this can have an impact on portability- Internet Explorer in particular may have trouble with this, as well as some older mobile/embedded devices

go-fastdfs 是一个简单的分布式文件系统(私有云存储),具有无中心、高性能,高可靠,免维护等优点,支持断点续传,分块上传,小文件合并,自动同步,自动修复。Go-fastdfs is a simple distributed file system (private cloud storage), with no center, high performance, high reliability, maintenance free and other advantages, support breakpoint continuation, block upload, small file merge, automatic synchronization, automatic repair.(similar fastdfs).
go-fastdfs 是一个简单的分布式文件系统(私有云存储),具有无中心、高性能,高可靠,免维护等优点,支持断点续传,分块上传,小文件合并,自动同步,自动修复。Go-fastdfs is a simple distributed file system (private cloud storage), with no center, high performance, high reliability, maintenance free and other advantages, support breakpoint continuation, block upload, small file merge, automatic synchronization, automatic repair.(similar fastdfs).

中文 English 愿景:为用户提供最简单、可靠、高效的分布式文件系统。 go-fastdfs是一个基于http协议的分布式文件系统,它基于大道至简的设计理念,一切从简设计,使得它的运维及扩展变得更加简单,它具有高性能、高可靠、无中心、免维护等优点。 大家担心的是这么简单的文件系统,靠不靠谱,可不

Jan 8, 2023
Bigfile -- a file transfer system that supports http, rpc and ftp protocol https://bigfile.site
Bigfile -- a file transfer system that supports http, rpc and ftp protocol   https://bigfile.site

Bigfile ———— a file transfer system that supports http, rpc and ftp protocol 简体中文 ∙ English Bigfile is a file transfer system, supports http, ftp and

Dec 31, 2022
A basic file server automatically generates self certificates and serves the given folder.

A basic file server automatically generates self certificates and serves the given folder.

Jul 20, 2022
A very light-weight file sharing platform, including server and client

file-transporter A very light-weight file sharing platform, including server and client Installation git clone https://github.com/vence722/file-transp

Jan 12, 2022
Plik is a scalable & friendly temporary file upload system ( wetransfer like ) in golang.

Want to chat with us ? Telegram channel : https://t.me/plik_root_gg Plik Plik is a scalable & friendly temporary file upload system ( wetransfer like

Jan 2, 2023
File Processor in Concurrency Pattern using Golang goroutine.
 File Processor in Concurrency Pattern using Golang goroutine.

File Processor in Concurrency Pattern Implement a file processor solution in concurrency pattern using Golang goroutine. Get Started Run docker-compos

Sep 16, 2022
Get a binary file directly from the Golang source project.

This project aims to provide a way to get binary file from a Golang project easily. Users don't need to have a Golang environment. Server Usage: docke

Nov 18, 2021
searchHIBP is a golang tool that implements binary search over a hash ordered binary file.

searchHIBP is a golang tool that implements binary search over a hash ordered binary file.

Nov 9, 2021
ZAR File (Zip-Archiv) Archive Extractor in Golang

unzar - extractor for Zip-Archiv (ZAR) files A proprietary format by Peter Troxler. These files are DCL imploded with some basic header. Requires To b

Jan 8, 2022
RtxTest - Extract this zip file into your golang development environment

Documentation 1. Clone or extract file extract this zip file into your golang de

May 12, 2022
Abstract File Storage

afs - abstract file storage Please refer to CHANGELOG.md if you encounter breaking changes. Motivation Introduction Usage Matchers Content modifiers S

Dec 30, 2022
a tool for handling file uploads simple

baraka a tool for handling file uploads for http servers makes it easier to make operations with files from the http request. Contents Install Simple

Nov 30, 2022
Go file operations library chasing GNU APIs.
Go file operations library chasing GNU APIs.

flop flop aims to make copying files easier in Go, and is modeled after GNU cp. Most administrators and engineers interact with GNU utilities every da

Nov 10, 2022
Read csv file from go using tags

go-csv-tag Read csv file from Go using tags The project is in maintenance mode. It is kept compatible with changes in the Go ecosystem but no new feat

Nov 16, 2022
File system event notification library on steroids.

notify Filesystem event notification library on steroids. (under active development) Documentation godoc.org/github.com/rjeczalik/notify Installation

Dec 31, 2022
Pluggable, extensible virtual file system for Go

vfs Package vfs provides a pluggable, extensible, and opinionated set of file system functionality for Go across a number of file system types such as

Jan 3, 2023
An epoll(7)-based file-descriptor multiplexer.

poller Package poller is a file-descriptor multiplexer. Download: go get github.com/npat-efault/poller Package poller is a file-descriptor multiplexer

Sep 25, 2022
QueryCSV enables you to load CSV files and manipulate them using SQL queries then after you finish you can export the new values to a CSV file
QueryCSV enables you to load CSV files and manipulate them using SQL queries then after you finish you can export the new values to a CSV file

QueryCSV enable you to load CSV files and manipulate them using SQL queries then after you finish you can export the new values to CSV file

Dec 22, 2021
Goful is a CUI file manager written in Go.
Goful is a CUI file manager written in Go.

Goful Goful is a CUI file manager written in Go. Works on cross-platform such as gnome-terminal and cmd.exe. Displays multiple windows and workspaces.

Dec 28, 2022