mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-03 06:07:20 +02:00
Static web server
- Fixed arm64 build bug in Make file - Added wip static web server
This commit is contained in:
parent
c65f780613
commit
a692ec818d
@ -19,7 +19,8 @@ clean:
|
||||
|
||||
$(PLATFORMS):
|
||||
@echo "Building $(os)/$(arch)"
|
||||
GOROOT_FINAL=Git/ GOOS=$(os) GOARCH=$(arch) GOARM=6 go build -o './dist/zoraxy_$(os)_$(arch)' -ldflags "-s -w" -trimpath
|
||||
GOROOT_FINAL=Git/ GOOS=$(os) GOARCH=$(arch) $(if $(filter linux/arm,$(os)/$(arch)),GOARM=6,) go build -o './dist/zoraxy_$(os)_$(arch)' -ldflags "-s -w" -trimpath
|
||||
# GOROOT_FINAL=Git/ GOOS=$(os) GOARCH=$(arch) GOARM=6 go build -o './dist/zoraxy_$(os)_$(arch)' -ldflags "-s -w" -trimpath
|
||||
|
||||
|
||||
fixwindows:
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"imuslab.com/zoraxy/mod/tlscert"
|
||||
"imuslab.com/zoraxy/mod/uptime"
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
"imuslab.com/zoraxy/mod/webserv"
|
||||
)
|
||||
|
||||
// General flags
|
||||
@ -41,6 +42,8 @@ var ztAuthToken = flag.String("ztauth", "", "ZeroTier authtoken for the local no
|
||||
var ztAPIPort = flag.Int("ztport", 9993, "ZeroTier controller API port")
|
||||
var acmeAutoRenewInterval = flag.Int("autorenew", 86400, "ACME auto TLS/SSL certificate renew check interval (seconds)")
|
||||
var enableHighSpeedGeoIPLookup = flag.Bool("fastgeoip", false, "Enable high speed geoip lookup, require 1GB extra memory (Not recommend for low end devices)")
|
||||
var staticWebServerRoot = flag.String("webroot", "./www", "Static web server root folder. Only allow chnage in start paramters")
|
||||
|
||||
var (
|
||||
name = "Zoraxy"
|
||||
version = "2.6.7"
|
||||
@ -73,6 +76,7 @@ var (
|
||||
tcpProxyManager *tcpprox.Manager //TCP Proxy Manager
|
||||
acmeHandler *acme.ACMEHandler //Handler for ACME Certificate renew
|
||||
acmeAutoRenewer *acme.AutoRenewer //Handler for ACME auto renew ticking
|
||||
staticWebServer *webserv.WebServer //Static web server for hosting simple stuffs
|
||||
|
||||
//Helper modules
|
||||
EmailSender *email.Sender //Email sender that handle email sending
|
||||
|
9
src/mod/webserv/handler.go
Normal file
9
src/mod/webserv/handler.go
Normal file
@ -0,0 +1,9 @@
|
||||
package webserv
|
||||
|
||||
/*
|
||||
Handler.go
|
||||
|
||||
Handler for web server options change
|
||||
web server is directly listening to the TCP port
|
||||
handlers in this script are for setting change only
|
||||
*/
|
41
src/mod/webserv/middleware.go
Normal file
41
src/mod/webserv/middleware.go
Normal file
@ -0,0 +1,41 @@
|
||||
package webserv
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
// Convert a request path (e.g. /index.html) into physical path on disk
|
||||
func (ws *WebServer) resolveFileDiskPath(requestPath string) string {
|
||||
fileDiskpath := filepath.Join(ws.option.WebRoot, "html", requestPath)
|
||||
|
||||
//Force convert it to slash even if the host OS is on Windows
|
||||
fileDiskpath = filepath.Clean(fileDiskpath)
|
||||
fileDiskpath = strings.ReplaceAll(fileDiskpath, "\\", "/")
|
||||
return fileDiskpath
|
||||
|
||||
}
|
||||
|
||||
// File server middleware to handle directory listing (and future expansion)
|
||||
func (ws *WebServer) fsMiddleware(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if ws.option.EnableDirectoryListing {
|
||||
if strings.HasSuffix(r.URL.Path, "/") {
|
||||
//This is a folder. Let check if index exists
|
||||
if utils.FileExists(filepath.Join(ws.resolveFileDiskPath(r.URL.Path), "index.html")) {
|
||||
|
||||
} else if utils.FileExists(filepath.Join(ws.resolveFileDiskPath(r.URL.Path), "index.htm")) {
|
||||
|
||||
} else {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
18
src/mod/webserv/utils.go
Normal file
18
src/mod/webserv/utils.go
Normal file
@ -0,0 +1,18 @@
|
||||
package webserv
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// IsPortInUse checks if a port is in use.
|
||||
func IsPortInUse(port string) bool {
|
||||
listener, err := net.Listen("tcp", "localhost:"+port)
|
||||
if err != nil {
|
||||
// If there was an error, the port is in use.
|
||||
return true
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
// No error means the port is available.
|
||||
return false
|
||||
}
|
137
src/mod/webserv/webserv.go
Normal file
137
src/mod/webserv/webserv.go
Normal file
@ -0,0 +1,137 @@
|
||||
package webserv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
/*
|
||||
Static Web Server package
|
||||
|
||||
This module host a static web server
|
||||
*/
|
||||
|
||||
type WebServerOptions struct {
|
||||
Port string //Port for listening
|
||||
EnableDirectoryListing bool //Enable listing of directory
|
||||
WebRoot string //Folder for stroing the static web folders
|
||||
}
|
||||
type WebServer struct {
|
||||
mux *http.ServeMux
|
||||
server *http.Server
|
||||
option *WebServerOptions
|
||||
isRunning bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// NewWebServer creates a new WebServer instance.
|
||||
func NewWebServer(options *WebServerOptions) *WebServer {
|
||||
if !utils.FileExists(options.WebRoot) {
|
||||
//Web root folder not exists. Create one
|
||||
os.MkdirAll(filepath.Join(options.WebRoot, "html"), 0775)
|
||||
os.MkdirAll(filepath.Join(options.WebRoot, "templates"), 0775)
|
||||
}
|
||||
return &WebServer{
|
||||
mux: http.NewServeMux(),
|
||||
option: options,
|
||||
isRunning: false,
|
||||
mu: sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// ChangePort changes the server's port.
|
||||
func (ws *WebServer) ChangePort(port string) error {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
|
||||
if ws.isRunning {
|
||||
if err := ws.Stop(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ws.option.Port = port
|
||||
ws.server.Addr = ":" + port
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start starts the web server.
|
||||
func (ws *WebServer) Start() error {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
|
||||
//Check if server already running
|
||||
if ws.isRunning {
|
||||
return fmt.Errorf("web server is already running")
|
||||
}
|
||||
|
||||
//Check if the port is usable
|
||||
if IsPortInUse(ws.option.Port) {
|
||||
return errors.New("Port already in use or access denied by host OS")
|
||||
}
|
||||
|
||||
//Dispose the old mux and create a new one
|
||||
ws.mux = http.NewServeMux()
|
||||
|
||||
//Create a static web server
|
||||
fs := http.FileServer(http.Dir(filepath.Join(ws.option.WebRoot, "html")))
|
||||
ws.mux.Handle("/", ws.fsMiddleware(fs))
|
||||
|
||||
ws.server = &http.Server{
|
||||
Addr: ":" + ws.option.Port,
|
||||
Handler: ws.mux,
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := ws.server.ListenAndServe(); err != nil {
|
||||
if err != http.ErrServerClosed {
|
||||
fmt.Printf("Web server error: %v\n", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
log.Println("Static Web Server started. Listeing on :" + ws.option.Port)
|
||||
ws.isRunning = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops the web server.
|
||||
func (ws *WebServer) Stop() error {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
|
||||
if !ws.isRunning {
|
||||
return fmt.Errorf("web server is not running")
|
||||
}
|
||||
|
||||
if err := ws.server.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ws.isRunning = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateDirectoryListing enables or disables directory listing.
|
||||
func (ws *WebServer) UpdateDirectoryListing(enable bool) {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
|
||||
ws.option.EnableDirectoryListing = enable
|
||||
|
||||
}
|
||||
|
||||
// Close stops the web server without returning an error.
|
||||
func (ws *WebServer) Close() {
|
||||
ws.Stop()
|
||||
}
|
16
src/start.go
16
src/start.go
@ -22,6 +22,7 @@ import (
|
||||
"imuslab.com/zoraxy/mod/statistic/analytic"
|
||||
"imuslab.com/zoraxy/mod/tcpprox"
|
||||
"imuslab.com/zoraxy/mod/tlscert"
|
||||
"imuslab.com/zoraxy/mod/webserv"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -208,6 +209,21 @@ func startupSequence() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
/*
|
||||
Static Web Server
|
||||
|
||||
Start the static web server
|
||||
*/
|
||||
|
||||
staticWebServer = webserv.NewWebServer(&webserv.WebServerOptions{
|
||||
Port: "8081",
|
||||
WebRoot: *staticWebServerRoot,
|
||||
EnableDirectoryListing: true,
|
||||
})
|
||||
|
||||
//TODO: Connect UI element to static web server
|
||||
staticWebServer.Start()
|
||||
}
|
||||
|
||||
// This sequence start after everything is initialized
|
||||
|
Loading…
x
Reference in New Issue
Block a user