Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
|
a30d5783ae | |
|
bfc15136fd | |
|
b35a655414 | |
|
c072eac417 | |
|
24ad759c50 |
|
@ -0,0 +1,72 @@
|
||||||
|
package maps
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
type Map[K comparable, V any] struct {
|
||||||
|
m *sync.Map
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Store(key K, value V) {
|
||||||
|
gm.m.Store(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Load(key K) (V, bool) {
|
||||||
|
value, ok := gm.m.Load(key)
|
||||||
|
if !ok {
|
||||||
|
var zero V
|
||||||
|
return zero, false
|
||||||
|
}
|
||||||
|
return value.(V), true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Delete(key K) {
|
||||||
|
gm.m.Delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Range(f func(key K, value V) bool) {
|
||||||
|
gm.m.Range(func(key, value any) bool {
|
||||||
|
return f(key.(K), value.(V))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Swap(key K, value V) (previous V, loaded bool) {
|
||||||
|
actual, swapped := gm.m.Swap(key, value)
|
||||||
|
return actual.(V), swapped
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Len() int {
|
||||||
|
var n int
|
||||||
|
gm.m.Range(func(key, value any) bool {
|
||||||
|
n++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) Clear() {
|
||||||
|
gm.m.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) LoadOrStore(key K, value V) (V, bool) {
|
||||||
|
actual, loaded := gm.m.LoadOrStore(key, value)
|
||||||
|
return actual.(V), loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) LoadAndDelete(key K) (value V, loaded bool) {
|
||||||
|
actual, loaded := gm.m.LoadAndDelete(key)
|
||||||
|
return actual.(V), loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) CompareAndSwap(key K, old V, new V) (swapped bool) {
|
||||||
|
return gm.m.CompareAndSwap(key, old, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gm *Map[K, V]) CompareAndDelete(key K, old V) (deleted bool) {
|
||||||
|
return gm.m.CompareAndDelete(key, old)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New[K comparable, V any]() *Map[K, V] {
|
||||||
|
return &Map[K, V]{
|
||||||
|
m: new(sync.Map),
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,7 @@ type RestFieldOptions struct {
|
||||||
Description string `protobuf:"bytes,15,opt,name=description,proto3" json:"description,omitempty"`
|
Description string `protobuf:"bytes,15,opt,name=description,proto3" json:"description,omitempty"`
|
||||||
Readonly string `protobuf:"bytes,16,opt,name=readonly,proto3" json:"readonly,omitempty"`
|
Readonly string `protobuf:"bytes,16,opt,name=readonly,proto3" json:"readonly,omitempty"`
|
||||||
Endofnow string `protobuf:"bytes,17,opt,name=endofnow,proto3" json:"endofnow,omitempty"`
|
Endofnow string `protobuf:"bytes,17,opt,name=endofnow,proto3" json:"endofnow,omitempty"`
|
||||||
|
Condition string `protobuf:"bytes,18,opt,name=condition,proto3" json:"condition,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
@ -194,6 +195,13 @@ func (x *RestFieldOptions) GetEndofnow() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *RestFieldOptions) GetCondition() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Condition
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type RestMessageOptions struct {
|
type RestMessageOptions struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Table string `protobuf:"bytes,1,opt,name=table,proto3" json:"table,omitempty"`
|
Table string `protobuf:"bytes,1,opt,name=table,proto3" json:"table,omitempty"`
|
||||||
|
@ -278,7 +286,7 @@ var File_rest_proto protoreflect.FileDescriptor
|
||||||
const file_rest_proto_rawDesc = "" +
|
const file_rest_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"rest.proto\x12\x04aeus\x1a google/protobuf/descriptor.proto\"\xc6\x03\n" +
|
"rest.proto\x12\x04aeus\x1a google/protobuf/descriptor.proto\"\xe4\x03\n" +
|
||||||
"\x10RestFieldOptions\x12\x12\n" +
|
"\x10RestFieldOptions\x12\x12\n" +
|
||||||
"\x04gorm\x18\x01 \x01(\tR\x04gorm\x12\x18\n" +
|
"\x04gorm\x18\x01 \x01(\tR\x04gorm\x12\x18\n" +
|
||||||
"\acomment\x18\x02 \x01(\tR\acomment\x12\x1c\n" +
|
"\acomment\x18\x02 \x01(\tR\acomment\x12\x1c\n" +
|
||||||
|
@ -297,7 +305,8 @@ const file_rest_proto_rawDesc = "" +
|
||||||
"\tuploaduri\x18\x0e \x01(\tR\tuploaduri\x12 \n" +
|
"\tuploaduri\x18\x0e \x01(\tR\tuploaduri\x12 \n" +
|
||||||
"\vdescription\x18\x0f \x01(\tR\vdescription\x12\x1a\n" +
|
"\vdescription\x18\x0f \x01(\tR\vdescription\x12\x1a\n" +
|
||||||
"\breadonly\x18\x10 \x01(\tR\breadonly\x12\x1a\n" +
|
"\breadonly\x18\x10 \x01(\tR\breadonly\x12\x1a\n" +
|
||||||
"\bendofnow\x18\x11 \x01(\tR\bendofnow\"*\n" +
|
"\bendofnow\x18\x11 \x01(\tR\bendofnow\x12\x1c\n" +
|
||||||
|
"\tcondition\x18\x12 \x01(\tR\tcondition\"*\n" +
|
||||||
"\x12RestMessageOptions\x12\x14\n" +
|
"\x12RestMessageOptions\x12\x14\n" +
|
||||||
"\x05table\x18\x01 \x01(\tR\x05table:M\n" +
|
"\x05table\x18\x01 \x01(\tR\x05table:M\n" +
|
||||||
"\x05field\x12\x1d.google.protobuf.FieldOptions\x18\x96\x97\x03 \x01(\v2\x16.aeus.RestFieldOptionsR\x05field:O\n" +
|
"\x05field\x12\x1d.google.protobuf.FieldOptions\x18\x96\x97\x03 \x01(\v2\x16.aeus.RestFieldOptionsR\x05field:O\n" +
|
||||||
|
|
|
@ -31,6 +31,7 @@ message RestFieldOptions {
|
||||||
string description = 15;
|
string description = 15;
|
||||||
string readonly = 16;
|
string readonly = 16;
|
||||||
string endofnow = 17;
|
string endofnow = 17;
|
||||||
|
string condition = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend google.protobuf.MessageOptions {
|
extend google.protobuf.MessageOptions {
|
||||||
|
|
|
@ -37,6 +37,7 @@ type Server struct {
|
||||||
fs *filesystem
|
fs *filesystem
|
||||||
middlewares []middleware.Middleware
|
middlewares []middleware.Middleware
|
||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
|
autoCompress bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Endpoint(ctx context.Context) (string, error) {
|
func (s *Server) Endpoint(ctx context.Context) (string, error) {
|
||||||
|
@ -104,7 +105,8 @@ func (s *Server) Handle(method string, uri string, handler http.HandlerFunc) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Webroot(prefix string, fs http.FileSystem) {
|
func (s *Server) Webroot(prefix string, authCompress bool, fs http.FileSystem) {
|
||||||
|
s.autoCompress = authCompress
|
||||||
s.fs = newFS(time.Now(), fs)
|
s.fs = newFS(time.Now(), fs)
|
||||||
s.fs.SetPrefix(prefix)
|
s.fs.SetPrefix(prefix)
|
||||||
s.fs.DenyAccessDirectory()
|
s.fs.DenyAccessDirectory()
|
||||||
|
@ -112,6 +114,9 @@ func (s *Server) Webroot(prefix string, fs http.FileSystem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) shouldCompress(req *http.Request) bool {
|
func (s *Server) shouldCompress(req *http.Request) bool {
|
||||||
|
if !s.autoCompress {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if !strings.Contains(req.Header.Get(headerAcceptEncoding), "gzip") ||
|
if !strings.Contains(req.Header.Get(headerAcceptEncoding), "gzip") ||
|
||||||
strings.Contains(req.Header.Get("Connection"), "Upgrade") {
|
strings.Contains(req.Header.Get("Connection"), "Upgrade") {
|
||||||
return false
|
return false
|
||||||
|
@ -125,11 +130,11 @@ func (s *Server) shouldCompress(req *http.Request) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) staticHandle(ctx *gin.Context, fp http.File) {
|
func (s *Server) staticHandle(ctx *gin.Context, fp http.File) bool {
|
||||||
uri := path.Clean(ctx.Request.URL.Path)
|
uri := path.Clean(ctx.Request.URL.Path)
|
||||||
fi, err := fp.Stat()
|
fi, err := fp.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
if !fi.IsDir() {
|
if !fi.IsDir() {
|
||||||
//https://github.com/gin-contrib/gzip
|
//https://github.com/gin-contrib/gzip
|
||||||
|
@ -157,14 +162,25 @@ func (s *Server) staticHandle(ctx *gin.Context, fp http.File) {
|
||||||
}
|
}
|
||||||
http.ServeContent(ctx.Writer, ctx.Request, path.Base(uri), s.fs.modtime, fp)
|
http.ServeContent(ctx.Writer, ctx.Request, path.Base(uri), s.fs.modtime, fp)
|
||||||
ctx.Abort()
|
ctx.Abort()
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) notFoundHandle(ctx *gin.Context) {
|
func (s *Server) notFoundHandle(ctx *gin.Context) {
|
||||||
if s.fs != nil && ctx.Request.Method == http.MethodGet {
|
if s.fs != nil && ctx.Request.Method == http.MethodGet {
|
||||||
uri := path.Clean(ctx.Request.URL.Path)
|
uri := path.Clean(ctx.Request.URL.Path)
|
||||||
if fp, err := s.fs.Open(uri); err == nil {
|
if fp, err := s.fs.Open(uri); err == nil {
|
||||||
s.staticHandle(ctx, fp)
|
defer fp.Close()
|
||||||
fp.Close()
|
if s.staticHandle(ctx, fp) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//if found compress file
|
||||||
|
if fp, err := s.fs.Open(uri + ".gz"); err == nil {
|
||||||
|
defer fp.Close()
|
||||||
|
if s.staticHandle(ctx, fp) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.JSON(http.StatusNotFound, newResponse(errors.NotFound, "Not Found", nil))
|
ctx.JSON(http.StatusNotFound, newResponse(errors.NotFound, "Not Found", nil))
|
||||||
|
|
Loading…
Reference in New Issue