router代码 第一种
import (
"net/http"
"sync"
)
type Server struct {
mu sync.RWMutex
handlers map[string]http.Handler
}
func NewServer() *Server {
return &Server{
handlers: make(map[string]http.Handler),
}
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.mu.RLock()
handler, ok := s.handlers[r.URL.Path]
s.mu.RUnlock()
if !ok {
http.NotFound(w, r)
return
}
handler.ServeHTTP(w, r)
}
func (s *Server) Handle(path string, handler http.Handler) {
s.mu.Lock()
s.handlers[path] = handler
s.mu.Unlock()
}
应用
func main() {
mux := NewServer()
mux.Handle("/path", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Initial handler")
}))
go func() {
time.Sleep(10 * time.Second)
mux.Handle("/path", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Updated handler")
}))
}()
log.Fatal(http.ListenAndServe(":8080", mux))
}
router代码 第二种
package main
import (
"net/http"
"os"
"path/filepath"
"sync"
"regexp"
"github.com/mholt/archiver/v3"
)
type Server struct {
mux *http.ServeMux
lock sync.RWMutex
}
func NewServer() *Server {
return &Server{
mux: http.NewServeMux(),
}
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.lock.RLock()
defer s.lock.RUnlock()
s.mux.ServeHTTP(w, r)
}
var re = regexp.MustCompile(`^([^\.]*)`)
func (s *Server) LoadStaticWebHttpHandle(savePath, fixedPrefix string, urlPrefixAndFilepath map[string]string) error {
s.lock.Lock()
defer s.lock.Unlock()
newMux := http.NewServeMux()
pathA := filepath.Join(savePath, "A")
pathB := filepath.Join(savePath, "B")
if !util.Exists(pathA) {
savePath = pathA
} else {
savePath = pathB
}
for prefix, file_path := range urlPrefixAndFilepath {
err := archiver.Unarchive(file_path, savePath)
if err != nil {
return fmt.Errorf("archiveFile failed, err: %v", err)
}
newPrefix := fixedPrefix + prefix
prefix_archive_name := re.FindString(file_path)
newMux.Handle(newPrefix, http.StripPrefix(newPrefix, http.FileServer(http.Dir(filepath.Join(savePath, prefix_archive_name)))))
}
if savePath != pathA {
os.RemoveAll(pathA)
} else {
os.RemoveAll(pathB)
}
s.mux = newMux
return nil
}
应用
func main() {
s := NewServer()
s.LoadStaticWebHttpHandle("static-path", "/url_prefix", map[string]string{"static": "test.zip"})
laddr := "127.0.0.1:8080"
svr := http.Server{Addr: laddr, Handler: http.TimeoutHandler(http.DefaultServeMux, 600*time.Second, "server timeout"), ReadTimeout: 600 * time.Second, WriteTimeout: 600 * time.Second}
err = svr.ListenAndServe()
if err != nil {
log.Errorf("%v", err)
}
}