123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // package serv_http -- востроенный HTTP-сервер
- package serv_http
- import (
- "fmt"
- "log"
- "os"
- "sync"
- "time"
- "github.com/gofiber/fiber/v2"
- "github.com/gofiber/fiber/v2/middleware/cache"
- "github.com/gofiber/fiber/v2/middleware/compress"
- "github.com/gofiber/fiber/v2/utils"
- "github.com/gofiber/template/html/v2"
- "git.p78su.freemyip.com/svi/gostore/pkg/serv_http/router_anonym"
- "git.p78su.freemyip.com/svi/gostore/pkg/types"
- )
- // ServHttp -- встроенный HTTP-сервер
- type ServHttp struct {
- serv types.IService
- fiberApp *fiber.App
- port string
- store types.IStore
- anonym *router_anonym.RouterAnonym
- block sync.RWMutex
- isWork bool // Признак работы
- }
- var IsBad_ bool // Для тестов
- // NewServHttp -- возвращает новый HTTP-сервер
- func NewServHttp(serv types.IService) (types.IServHttp, error) {
- if IsBad_ {
- return nil, fmt.Errorf("NewServHttp(): IsBad_==true")
- }
- if serv == nil {
- return nil, fmt.Errorf("NewServHttp(): IService==nil")
- }
- port := os.Getenv("STORE_HTTP_PORT")
- if port == "" {
- return nil, fmt.Errorf("NewServHttp(): env STORE_HTTP_PORT not set")
- }
- engineTmpl := html.New("./static/tmpl", ".tmpl.html")
- appConf := fiber.Config{
- Prefork: false,
- ServerHeader: "GoStore",
- StrictRouting: false,
- CaseSensitive: false,
- Immutable: false,
- UnescapePath: false,
- ETag: false,
- BodyLimit: 10_000_000,
- Concurrency: 0,
- Views: engineTmpl,
- ViewsLayout: "",
- PassLocalsToViews: false,
- ReadTimeout: time.Second * 60,
- WriteTimeout: time.Second * 60,
- IdleTimeout: time.Second * 10,
- ReadBufferSize: 0,
- WriteBufferSize: 0,
- CompressedFileSuffix: ".fiber.gz",
- ProxyHeader: "",
- GETOnly: false,
- // ErrorHandler: func(*fiber.Ctx, error) error { panic("not implemented") },
- DisableKeepalive: false,
- DisableDefaultDate: false,
- DisableDefaultContentType: false,
- DisableHeaderNormalizing: false,
- DisableStartupMessage: false,
- AppName: "GoStore",
- StreamRequestBody: false,
- DisablePreParseMultipartForm: false,
- ReduceMemoryUsage: false,
- // JSONEncoder: func(interface{}) ([]byte, error) { panic("not implemented") },
- // JSONDecoder: func([]byte, interface{}) error { panic("not implemented") },
- // XMLEncoder: func(interface{}) ([]byte, error) { panic("not implemented") },
- Network: "tcp4",
- EnableTrustedProxyCheck: false,
- TrustedProxies: []string{},
- EnableIPValidation: false,
- EnablePrintRoutes: true,
- // ColorScheme: fiber.Colors{
- // Black: "",
- // Red: "",
- // Green: "",
- // Yellow: "",
- // Blue: "",
- // Magenta: "",
- // Cyan: "",
- // White: "",
- // Reset: "",
- // },
- // RequestMethods: []string{},
- EnableSplittingOnParsers: false,
- }
- app := fiber.New(appConf)
- app.Static("/static", "./static")
- compressConf := compress.Config{
- Level: compress.LevelBestCompression,
- }
- app.Use(compress.New(compressConf))
- cacheConf := cache.Config{
- Next: nil,
- Expiration: 30 * time.Minute,
- CacheHeader: "X-Cache",
- CacheControl: true,
- KeyGenerator: func(c *fiber.Ctx) string {
- return utils.CopyString(c.Path())
- },
- ExpirationGenerator: nil,
- StoreResponseHeaders: false,
- Storage: nil,
- MaxBytes: 0,
- Methods: []string{fiber.MethodGet, fiber.MethodHead},
- }
- app.Use(cache.New(cacheConf))
- sf := &ServHttp{
- serv: serv,
- fiberApp: app,
- port: port,
- store: serv.Store(),
- }
- var err error
- sf.anonym, err = router_anonym.NewRouterAnonym(sf)
- if err != nil {
- return nil, err
- }
- sf.fiberApp.Get("/", sf.get)
- sf.serv.Wg().Add(1)
- sf.isWork = true
- go sf.close()
- return sf, nil
- }
- // Возвращает индексную страницу хранилища
- func (sf *ServHttp) get(ctx *fiber.Ctx) error {
- return ctx.Render("index", fiber.Map{})
- }
- // Service -- возвращает сервис
- func (sf *ServHttp) Service() types.IService {
- return sf.serv
- }
- // FiberApp -- возвращает fiber-приложение
- func (sf *ServHttp) FiberApp() *fiber.App {
- return sf.fiberApp
- }
- // Run -- запускает веб-сервер в работу
- func (sf *ServHttp) Run() error {
- defer sf.serv.CancelApp()
- err := sf.fiberApp.Listen(":" + sf.port)
- if err != nil {
- return fmt.Errorf("ServHttp.Run(): in listen port(%q), err=\n\t%w", sf.port, err)
- }
- return nil
- }
- func (sf *ServHttp) close() {
- <-sf.serv.Ctx().Done()
- sf.block.Lock()
- defer sf.block.Unlock()
- if !sf.isWork {
- return
- }
- sf.isWork = false
- err := sf.fiberApp.Shutdown()
- if err != nil {
- log.Printf("ServHttp.close(): in shutdown fiberApp, err=\n\t%v\n", err)
- }
- sf.serv.Wg().Done()
- }
|