From a507deaad03fbae517946fb501f2a8a9d06cd3e2 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Tue, 12 Dec 2023 23:37:29 +0700 Subject: cmd/httpdfs: implement [libhttp.Server] with [memfs.MemFS] The httpdfs accept single directory to be served under HTTP server, with the following options, -address Run the HTTP server on specific IP address and port. Default to ` + defAddress + `. -exclude Exclude the files matched by regex from being served. Default to empty, none of files is excluded. -help Print this usage. -include Serve only list of files matched with regex. Default to include CSS, HTML, JavaScript, ICO, JPG, PNG, and SVG files only. -version Print the program version. --- .gitignore | 1 + cmd/httpdfs/main.go | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 cmd/httpdfs/main.go diff --git a/.gitignore b/.gitignore index 9c0cad59..cc0c8329 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ /_bin/epoch /_bin/gofmtcomment /_bin/hexo +/_bin/httpdfs /_bin/ini /_bin/sendemail /_bin/smtpcli diff --git a/cmd/httpdfs/main.go b/cmd/httpdfs/main.go new file mode 100644 index 00000000..62f0c32b --- /dev/null +++ b/cmd/httpdfs/main.go @@ -0,0 +1,147 @@ +// Copyright 2023, Shulhan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Program httpdfs implement [libhttp.Server] with [memfs.MemFS]. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/signal" + + "github.com/shuLhan/share" + libhttp "github.com/shuLhan/share/lib/http" + "github.com/shuLhan/share/lib/memfs" +) + +const ( + defAddress = `127.0.0.1:28194` + defInclude = `.*\.(css|html|ico|js|jpg|png|svg)$` +) + +func main() { + var ( + flagAddress string + flagExclude string + flagInclude string + + flagHelp bool + flagVersion bool + ) + + flag.StringVar(&flagAddress, `address`, defAddress, `Listen address`) + flag.StringVar(&flagExclude, `exclude`, ``, `Regex to exclude files in base directory`) + flag.BoolVar(&flagHelp, `help`, false, `Print the command usage`) + flag.StringVar(&flagInclude, `include`, defInclude, `Regex to include files in base directory`) + flag.BoolVar(&flagVersion, `version`, false, `Print the program version`) + + flag.Parse() + + var cmdName = os.Args[0] + + if flagHelp { + usage(cmdName) + os.Exit(0) + } + if flagVersion { + fmt.Println(share.Version) + os.Exit(0) + } + + var ( + dirBase = flag.Arg(0) + err error + ) + if len(dirBase) == 0 { + dirBase, err = os.Getwd() + if err != nil { + log.Fatalf(`%s: %s`, cmdName, err) + } + } + + var ( + mfsOpts = memfs.Options{ + Root: dirBase, + Includes: []string{flagInclude}, + MaxFileSize: -1, + TryDirect: true, + } + mfs *memfs.MemFS + ) + if len(flagExclude) != 0 { + mfsOpts.Excludes = []string{flagExclude} + } + + mfs, err = memfs.New(&mfsOpts) + if err != nil { + log.Fatalf(`%s: %s`, cmdName, err) + } + + var ( + serverOpts = libhttp.ServerOptions{ + Memfs: mfs, + Address: flagAddress, + EnableIndexHtml: true, + } + httpd *libhttp.Server + ) + + httpd, err = libhttp.NewServer(&serverOpts) + if err != nil { + log.Fatalf(`%s: %s`, cmdName, err) + } + + var signalq = make(chan os.Signal, 1) + signal.Notify(signalq, os.Interrupt, os.Kill) + + go func() { + log.Printf(`%s: serving %q at http://%s`, cmdName, dirBase, flagAddress) + var errStart = httpd.Start() + if errStart != nil { + log.Printf(`%s: %s`, cmdName, errStart) + } + }() + + <-signalq + + err = httpd.Stop(0) + if err != nil { + log.Printf(`%s: %s`, cmdName, err) + } +} + +func usage(cmdName string) { + fmt.Println(`= ` + cmdName + ` - a simple HTTP server + + ` + cmdName + ` [options] + +== Options + + -address + Run the HTTP server on specific IP address and port. + Default to ` + defAddress + `. + + -exclude + Exclude the files matched by regex from being served. + Default to empty, none of files is excluded. + + -help + Print this usage. + + -include + Serve only list of files matched with regex. + Default to include CSS, HTML, JavaScript, ICO, JPG, PNG, and + SVG files only. + + -version + Print the program version. + +== Parameter + + + Directory to be served under HTTP. + If not set default to current directory.`) +} -- cgit v1.3