Package Archives:

- fix security arbitrary path
- fix linter

Package AWS:
- implement resolver v2

Package Cobra:
- fix linter

Package Config/component:
- fix linter

Package Context/Config:
- Add function to set context

Package Database/KV...:
- Fix error
- Fix collision pointer
- Fix models
- Fix circular dependencies
- Add function Delete on driver, table and item
- Add function new on drvier to prevent collision data when create item on table get / walk

Package Duration:
- Add type Duration based on time.Duration to allow transform duration to string instead of int64 nanosecond
- Add function to parse in json, yaml, toml, text, cbor
- Add function to allow convert type into mapstructure (spf13 viper, cobra...)

Package File/Perm:
- Add type Perm based on os.FileMode to allow marshall / unmashall it into octal form instead of string representation (-rwxrwxrwx)
- Add function to marshall / unmarshall in json, yaml, toml, text, cbor
- Add function to allow convert type into mapstructure (spf13 viper, cobra...)

Package File/progress:
- Fix linter

Package HTTPServer :
- Fix linter
- Fix security by adding a default value if not set on config

Package ioutils:
- Fix Linter

Package LDAP:
- Add Clone function

Package logger/hookfile:
- Fix linter

Package nats:
- Fix linter

Package Network/Protocol:
- Fix bug with quote / Dbl Quote on unmarshall

Package Password:
- Replace password with crypto rand instead of math rand

Package Size:
- Fix potential overflow
- Add function to format value into Int32, Int, Uint32, Uint, Float32
- Add function to parse Float64 into type Size

Package Socket:
- change config uint32 to golib Size, time.Duration to golib Duration
- add TLS managment to server TCP, discard for UDP & Unix file Local Domain
- add function Info Server to print information of server when listen is starting
This commit is contained in:
Nicolas JUHEL
2023-11-16 10:07:16 +01:00
committed by nabbar
parent b07fafb2f2
commit 97e70d063f
69 changed files with 1643 additions and 445 deletions

View File

@@ -96,17 +96,17 @@ jobs:
continue-on-error: false continue-on-error: false
run: | run: |
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"' | tr -d "'")" | tr '\n' '|') IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"' | tr -d "'")" | tr '\n' '|')
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 GOAMD64=v4 go build -a -v -race -installsuffix cgo -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1}) CGO_ENABLED=1 GOOS=linux GOARCH=amd64 GOAMD64=v4 go build -a -race -installsuffix cgo -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
- name: Test Build Windows/amd64 with CGO - name: Test Build Windows/amd64 with CGO
continue-on-error: false continue-on-error: false
run: | run: |
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"' | tr -d "'")" | tr '\n' '|') IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"' | tr -d "'")" | tr '\n' '|')
CC=/usr/bin/x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=amd64 GOAMD64=v4 go build -a -v -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1}) CC=/usr/bin/x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=amd64 GOAMD64=v4 go build -a -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
- name: Test Build Darwin/arm64 with suffix/CGO - name: Test Build Darwin/arm64 with suffix/CGO
continue-on-error: false continue-on-error: false
run: | run: |
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"' | tr -d "'")" | tr '\n' '|') IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"' | tr -d "'")" | tr '\n' '|')
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 GOAMD64=v1 go build -a -v -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1}) CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 GOAMD64=v1 go build -a -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})

View File

@@ -41,9 +41,10 @@ func GetFile(src io.ReadSeeker, dst io.WriteSeeker) errors.Error {
r := bzip2.NewReader(src) r := bzip2.NewReader(src)
//nolint #nosec // #nosec
/* #nosec */ _, e := io.Copy(dst, r)
if _, e := io.Copy(dst, r); e != nil {
if e != nil {
return ErrorIOCopy.Error(e) return ErrorIOCopy.Error(e)
} else if _, e = dst.Seek(0, io.SeekStart); e != nil { } else if _, e = dst.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.Error(e) return ErrorFileSeek.Error(e)

View File

@@ -29,9 +29,8 @@ import (
gz "compress/gzip" gz "compress/gzip"
"io" "io"
libfpg "github.com/nabbar/golib/file/progress"
"github.com/nabbar/golib/errors" "github.com/nabbar/golib/errors"
libfpg "github.com/nabbar/golib/file/progress"
) )
func GetFile(src io.ReadSeeker, dst io.WriteSeeker) errors.Error { func GetFile(src io.ReadSeeker, dst io.WriteSeeker) errors.Error {
@@ -50,9 +49,10 @@ func GetFile(src io.ReadSeeker, dst io.WriteSeeker) errors.Error {
_ = r.Close() _ = r.Close()
}() }()
//nolint #nosec // #nosec
/* #nosec */ _, e = io.Copy(dst, r)
if _, e = io.Copy(dst, r); e != nil {
if e != nil {
return ErrorIOCopy.Error(e) return ErrorIOCopy.Error(e)
} else if _, e = dst.Seek(0, io.SeekStart); e != nil { } else if _, e = dst.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.Error(e) return ErrorFileSeek.Error(e)
@@ -88,6 +88,7 @@ func GetGunZipSize(src io.ReadSeeker) int64 {
} }
var n int64 var n int64
// #nosec
n, e = io.Copy(io.Discard, r) n, e = io.Copy(io.Discard, r)
if e != nil { if e != nil {

View File

@@ -33,10 +33,9 @@ import (
"runtime" "runtime"
"strings" "strings"
libfpg "github.com/nabbar/golib/file/progress"
libarc "github.com/nabbar/golib/archive/archive" libarc "github.com/nabbar/golib/archive/archive"
liberr "github.com/nabbar/golib/errors" liberr "github.com/nabbar/golib/errors"
libfpg "github.com/nabbar/golib/file/progress"
) )
func GetFile(src, dst libfpg.Progress, filenameContain, filenameRegex string) liberr.Error { func GetFile(src, dst libfpg.Progress, filenameContain, filenameRegex string) liberr.Error {
@@ -93,9 +92,11 @@ func GetAll(src io.ReadSeeker, outputFolder string, defaultDirPerm os.FileMode)
return ErrorTarNext.Error(e) return ErrorTarNext.Error(e)
} }
dst := filepath.Join(outputFolder, libarc.CleanPath(strings.Replace(h.Name, ".."+string(filepath.Separator), "", -1)))
//nolint #nosec //nolint #nosec
/* #nosec */ /* #nosec */
if err := writeContent(r, h, filepath.Join(outputFolder, libarc.CleanPath(h.Name)), defaultDirPerm); err != nil { if err := writeContent(r, h, dst, defaultDirPerm); err != nil {
return err return err
} }
} }

View File

@@ -30,11 +30,11 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"strings"
libfpg "github.com/nabbar/golib/file/progress"
arcmod "github.com/nabbar/golib/archive/archive" arcmod "github.com/nabbar/golib/archive/archive"
liberr "github.com/nabbar/golib/errors" liberr "github.com/nabbar/golib/errors"
libfpg "github.com/nabbar/golib/file/progress"
) )
func GetFile(src, dst libfpg.Progress, filenameContain, filenameRegex string) liberr.Error { func GetFile(src, dst libfpg.Progress, filenameContain, filenameRegex string) liberr.Error {
@@ -119,9 +119,10 @@ func GetAll(src libfpg.Progress, outputFolder string, defaultDirPerm os.FileMode
continue continue
} }
//nolint #nosec dst := filepath.Join(outputFolder, arcmod.CleanPath(strings.Replace(f.Name, ".."+string(filepath.Separator), "..", -1)))
/* #nosec */
if err := writeContent(f, filepath.Join(outputFolder, arcmod.CleanPath(f.Name)), defaultDirPerm); err != nil { // #nosec
if err := writeContent(f, dst, defaultDirPerm); err != nil {
return err return err
} }
} }
@@ -175,9 +176,10 @@ func writeContent(f *zip.File, out string, defaultDirPerm os.FileMode) (err libe
return ErrorZipFileOpen.Error(e) return ErrorZipFileOpen.Error(e)
} }
//nolint #nosec // #nosec
/* #nosec */ _, e = io.Copy(dst, r)
if _, e = io.Copy(dst, r); e != nil {
if e != nil {
return ErrorIOCopy.Error(e) return ErrorIOCopy.Error(e)
} else if e = dst.Close(); e != nil { } else if e = dst.Close(); e != nil {
return ErrorFileClose.Error(e) return ErrorFileClose.Error(e)

View File

@@ -28,6 +28,7 @@ package bucket
import ( import (
"fmt" "fmt"
sdkaws "github.com/aws/aws-sdk-go-v2/aws"
sdksss "github.com/aws/aws-sdk-go-v2/service/s3" sdksss "github.com/aws/aws-sdk-go-v2/service/s3"
sdkstp "github.com/aws/aws-sdk-go-v2/service/s3/types" sdkstp "github.com/aws/aws-sdk-go-v2/service/s3/types"
libhlp "github.com/nabbar/golib/aws/helper" libhlp "github.com/nabbar/golib/aws/helper"
@@ -64,10 +65,12 @@ func (cli *client) _create(RegionConstraint string, lockEnable bool) error {
if RegionConstraint != "" { if RegionConstraint != "" {
in.CreateBucketConfiguration.LocationConstraint = sdkstp.BucketLocationConstraint(RegionConstraint) in.CreateBucketConfiguration.LocationConstraint = sdkstp.BucketLocationConstraint(RegionConstraint)
} else {
in.CreateBucketConfiguration.LocationConstraint = sdkstp.BucketLocationConstraint(cli.GetRegion())
} }
if lockEnable { if lockEnable {
in.ObjectLockEnabledForBucket = true in.ObjectLockEnabledForBucket = sdkaws.Bool(true)
} }
out, err := cli.s3.CreateBucket(cli.GetContext(), in) out, err := cli.s3.CreateBucket(cli.GetContext(), in)

View File

@@ -118,11 +118,13 @@ func (c *client) _NewClientIAM(ctx context.Context, httpClient *http.Client) (*s
EndpointOptions: sdkiam.EndpointResolverOptions{ EndpointOptions: sdkiam.EndpointResolverOptions{
DisableHTTPS: !c.c.IsHTTPs(), DisableHTTPS: !c.c.IsHTTPs(),
}, },
EndpointResolver: c._NewIAMResolver(cfg), BaseEndpoint: sdkaws.String(c.c.GetEndpoint().String()),
HTTPSignerV4: sig, EndpointResolver: c._NewIAMResolver(cfg),
Region: cfg.Region, EndpointResolverV2: c._NewIAMResolverV2(c.c),
Retryer: ret, HTTPSignerV4: sig,
HTTPClient: httpClient, Region: cfg.Region,
Retryer: ret,
HTTPClient: httpClient,
}) })
return iam, nil return iam, nil
@@ -161,12 +163,14 @@ func (c *client) _NewClientS3(ctx context.Context, httpClient *http.Client) (*sd
EndpointOptions: sdksss.EndpointResolverOptions{ EndpointOptions: sdksss.EndpointResolverOptions{
DisableHTTPS: !c.c.IsHTTPs(), DisableHTTPS: !c.c.IsHTTPs(),
}, },
EndpointResolver: c._NewS3Resolver(cfg), BaseEndpoint: sdkaws.String(c.c.GetEndpoint().String()),
HTTPSignerV4: sig, EndpointResolver: c._NewS3Resolver(cfg),
Region: cfg.Region, EndpointResolverV2: c._NewS3ResolverV2(c.c),
Retryer: ret, HTTPSignerV4: sig,
HTTPClient: httpClient, Region: cfg.Region,
UsePathStyle: c.p, Retryer: ret,
HTTPClient: httpClient,
UsePathStyle: c.p,
}) })
return sss, nil return sss, nil

View File

@@ -65,7 +65,7 @@ func (m *mpu) Copy(fromBucket, fromObject, fromVersionId string) error {
Bucket: sdkaws.String(bck), Bucket: sdkaws.String(bck),
CopySource: sdkaws.String(src), CopySource: sdkaws.String(src),
Key: sdkaws.String(obj), Key: sdkaws.String(obj),
PartNumber: m.Counter() + 1, PartNumber: sdkaws.Int32(m.Counter() + 1),
UploadId: sdkaws.String(mid), UploadId: sdkaws.String(mid),
CopySourceRange: sdkaws.String("bytes=" + p), CopySourceRange: sdkaws.String("bytes=" + p),
RequestPayer: sdktyp.RequestPayerRequester, RequestPayer: sdktyp.RequestPayerRequester,
@@ -121,7 +121,9 @@ func (m *mpu) getCopyPart(fromBucket, fromObject, fromVersionId string) []string
return res return res
} else if hdo == nil || hdo.ETag == nil || len(*hdo.ETag) < 1 { } else if hdo == nil || hdo.ETag == nil || len(*hdo.ETag) < 1 {
return res return res
} else if size := hdo.ContentLength; size < 1 { } else if s := hdo.ContentLength; s == nil {
return res
} else if size := *s; size < 1 {
return res return res
} else { } else {
var i int64 = 0 var i int64 = 0

View File

@@ -98,7 +98,7 @@ func (m *mpu) RegisterPart(etag string) {
m.n++ m.n++
m.l = append(m.l, sdktyp.CompletedPart{ m.l = append(m.l, sdktyp.CompletedPart{
ETag: sdkaws.String(strings.Replace(etag, "\"", "", -1)), ETag: sdkaws.String(strings.Replace(etag, "\"", "", -1)),
PartNumber: m.n, PartNumber: sdkaws.Int32(m.n),
}) })
} }
@@ -154,8 +154,8 @@ func (m *mpu) AddPart(r io.Reader) (n int64, e error) {
Bucket: sdkaws.String(bck), Bucket: sdkaws.String(bck),
Key: sdkaws.String(obj), Key: sdkaws.String(obj),
UploadId: sdkaws.String(mid), UploadId: sdkaws.String(mid),
PartNumber: m.Counter() + 1, PartNumber: sdkaws.Int32(m.Counter() + 1),
ContentLength: n, ContentLength: sdkaws.Int64(n),
Body: tmp, Body: tmp,
RequestPayer: sdktyp.RequestPayerRequester, RequestPayer: sdktyp.RequestPayerRequester,
ContentMD5: sdkaws.String(hss), ContentMD5: sdkaws.String(hss),

View File

@@ -75,7 +75,7 @@ func (cli *client) SetRetention(object, version string, bypass bool, until time.
} }
if bypass { if bypass {
in.BypassGovernanceRetention = true in.BypassGovernanceRetention = sdkaws.Bool(true)
} }
switch { switch {

View File

@@ -42,7 +42,7 @@ import (
func (cli *client) MultipartList(keyMarker, markerId string) (uploads []sdktyp.MultipartUpload, nextKeyMarker string, nextIdMarker string, count int64, e error) { func (cli *client) MultipartList(keyMarker, markerId string) (uploads []sdktyp.MultipartUpload, nextKeyMarker string, nextIdMarker string, count int64, e error) {
in := &sdksss.ListMultipartUploadsInput{ in := &sdksss.ListMultipartUploadsInput{
Bucket: sdkaws.String(cli.GetBucketName()), Bucket: sdkaws.String(cli.GetBucketName()),
MaxUploads: 1000, MaxUploads: sdkaws.Int32(1000),
} }
if keyMarker != "" && markerId != "" { if keyMarker != "" && markerId != "" {
@@ -54,10 +54,17 @@ func (cli *client) MultipartList(keyMarker, markerId string) (uploads []sdktyp.M
if err != nil { if err != nil {
return nil, "", "", 0, cli.GetError(err) return nil, "", "", 0, cli.GetError(err)
} else if out.IsTruncated { }
return out.Uploads, *out.NextKeyMarker, *out.NextUploadIdMarker, int64(out.MaxUploads), nil
var maxKeys int32
if out != nil && out.MaxUploads != nil {
maxKeys = *out.MaxUploads
}
if out != nil && out.IsTruncated != nil && *out.IsTruncated {
return out.Uploads, *out.NextKeyMarker, *out.NextUploadIdMarker, int64(maxKeys), nil
} else { } else {
return out.Uploads, "", "", int64(out.MaxUploads), nil return out.Uploads, "", "", int64(maxKeys), nil
} }
} }

View File

@@ -30,9 +30,8 @@ import (
"mime" "mime"
"path/filepath" "path/filepath"
sdksss "github.com/aws/aws-sdk-go-v2/service/s3"
sdkaws "github.com/aws/aws-sdk-go-v2/aws" sdkaws "github.com/aws/aws-sdk-go-v2/aws"
sdksss "github.com/aws/aws-sdk-go-v2/service/s3"
sdktps "github.com/aws/aws-sdk-go-v2/service/s3/types" sdktps "github.com/aws/aws-sdk-go-v2/service/s3/types"
libhlp "github.com/nabbar/golib/aws/helper" libhlp "github.com/nabbar/golib/aws/helper"
) )
@@ -58,10 +57,17 @@ func (cli *client) ListPrefix(continuationToken string, prefix string) ([]sdktps
if err != nil { if err != nil {
return nil, "", 0, cli.GetError(err) return nil, "", 0, cli.GetError(err)
} else if out.IsTruncated { }
return out.Contents, *out.NextContinuationToken, int64(out.KeyCount), nil
var maxKeys int32
if out != nil && out.MaxKeys != nil {
maxKeys = *out.MaxKeys
}
if out != nil && out.IsTruncated != nil && *out.IsTruncated {
return out.Contents, *out.NextContinuationToken, int64(maxKeys), nil
} else { } else {
return out.Contents, "", int64(out.KeyCount), nil return out.Contents, "", int64(maxKeys), nil
} }
} }
@@ -104,7 +110,7 @@ func (cli *client) WalkPrefix(prefix string, f WalkFunc) error {
} }
} }
if out.IsTruncated { if out != nil && out.IsTruncated != nil && *out.IsTruncated {
t = out.NextContinuationToken t = out.NextContinuationToken
} else { } else {
return e return e

View File

@@ -38,7 +38,7 @@ import (
func (cli *client) VersionList(prefix, keyMarker, markerId string) (version []sdktps.ObjectVersion, delMarker []sdktps.DeleteMarkerEntry, nextKeyMarker, nextMarkerId string, count int64, err error) { func (cli *client) VersionList(prefix, keyMarker, markerId string) (version []sdktps.ObjectVersion, delMarker []sdktps.DeleteMarkerEntry, nextKeyMarker, nextMarkerId string, count int64, err error) {
in := sdksss.ListObjectVersionsInput{ in := sdksss.ListObjectVersionsInput{
Bucket: cli.GetBucketAws(), Bucket: cli.GetBucketAws(),
MaxKeys: 1000, MaxKeys: sdkaws.Int32(1000),
} }
if prefix != "" { if prefix != "" {
@@ -54,10 +54,17 @@ func (cli *client) VersionList(prefix, keyMarker, markerId string) (version []sd
if e != nil { if e != nil {
return nil, nil, "", "", 0, cli.GetError(e) return nil, nil, "", "", 0, cli.GetError(e)
} else if out.IsTruncated { }
return out.Versions, out.DeleteMarkers, *out.NextKeyMarker, *out.NextVersionIdMarker, int64(out.MaxKeys), nil
var maxKeys int32
if out != nil && out.MaxKeys != nil {
maxKeys = *out.MaxKeys
}
if out != nil && out.IsTruncated != nil && *out.IsTruncated {
return out.Versions, out.DeleteMarkers, *out.NextKeyMarker, *out.NextVersionIdMarker, int64(maxKeys), nil
} else { } else {
return out.Versions, out.DeleteMarkers, "", "", int64(out.MaxKeys), nil return out.Versions, out.DeleteMarkers, "", "", int64(maxKeys), nil
} }
} }
@@ -68,7 +75,7 @@ func (cli *client) VersionWalk(fv VersionWalkFunc, fd DelMakWalkFunc) error {
func (cli *client) VersionWalkPrefix(prefix string, fv VersionWalkFunc, fd DelMakWalkFunc) error { func (cli *client) VersionWalkPrefix(prefix string, fv VersionWalkFunc, fd DelMakWalkFunc) error {
in := sdksss.ListObjectVersionsInput{ in := sdksss.ListObjectVersionsInput{
Bucket: cli.GetBucketAws(), Bucket: cli.GetBucketAws(),
MaxKeys: 1000, MaxKeys: sdkaws.Int32(1000),
} }
if prefix != "" { if prefix != "" {
@@ -117,7 +124,7 @@ func (cli *client) VersionWalkPrefix(prefix string, fv VersionWalkFunc, fd DelMa
} }
} }
if out.IsTruncated { if out != nil && out.IsTruncated != nil && *out.IsTruncated {
km = out.NextKeyMarker km = out.NextKeyMarker
mi = out.NextVersionIdMarker mi = out.NextVersionIdMarker
} else { } else {
@@ -181,8 +188,10 @@ func (cli *client) VersionSize(object, version string) (size int64, err error) {
if h, err = cli.VersionHead(object, version); err != nil { if h, err = cli.VersionHead(object, version); err != nil {
return return
} else if h != nil && h.ContentLength != nil {
return *h.ContentLength, nil
} else { } else {
return h.ContentLength, nil return 0, nil
} }
} }
@@ -207,7 +216,7 @@ func (cli *client) VersionDeleteLock(check bool, object, version string, byPassG
} }
if byPassGovernance { if byPassGovernance {
in.BypassGovernanceRetention = true in.BypassGovernanceRetention = sdkaws.Bool(true)
} }
_, err := cli.s3.DeleteObject(cli.GetContext(), &in) _, err := cli.s3.DeleteObject(cli.GetContext(), &in)

View File

@@ -26,9 +26,13 @@
package aws package aws
import ( import (
"context"
"net/url"
sdkaws "github.com/aws/aws-sdk-go-v2/aws" sdkaws "github.com/aws/aws-sdk-go-v2/aws"
sdkiam "github.com/aws/aws-sdk-go-v2/service/iam" sdkiam "github.com/aws/aws-sdk-go-v2/service/iam"
sdksss "github.com/aws/aws-sdk-go-v2/service/s3" sdksss "github.com/aws/aws-sdk-go-v2/service/s3"
awsedp "github.com/aws/smithy-go/endpoints"
) )
type resolverIam struct { type resolverIam struct {
@@ -39,6 +43,14 @@ func (r *resolverIam) ResolveEndpoint(region string, options sdkiam.EndpointReso
return r.r("iam", region) return r.r("iam", region)
} }
type resolverIamV2 struct {
r func(service, region string) (awsedp.Endpoint, error)
}
func (r *resolverIamV2) ResolveEndpoint(ctx context.Context, params sdkiam.EndpointParameters) (awsedp.Endpoint, error) {
return r.r("iam", *params.Region)
}
type resolverS3 struct { type resolverS3 struct {
r func(service, region string) (sdkaws.Endpoint, error) r func(service, region string) (sdkaws.Endpoint, error)
} }
@@ -47,14 +59,62 @@ func (r *resolverS3) ResolveEndpoint(region string, options sdksss.EndpointResol
return r.r("s3", region) return r.r("s3", region)
} }
type resolverS3V2 struct {
r func(service, region string) (awsedp.Endpoint, error)
}
func (r *resolverS3V2) ResolveEndpoint(ctx context.Context, params sdksss.EndpointParameters) (awsedp.Endpoint, error) {
return r.r("s3", *params.Region)
}
func (c *client) _NewIAMResolver(cfg *sdkaws.Config) sdkiam.EndpointResolver { func (c *client) _NewIAMResolver(cfg *sdkaws.Config) sdkiam.EndpointResolver {
return &resolverIam{ return &resolverIam{
r: cfg.EndpointResolver.ResolveEndpoint, r: cfg.EndpointResolver.ResolveEndpoint,
} }
} }
func (c *client) _NewIAMResolverV2(cfg Config) sdkiam.EndpointResolverV2 {
return &resolverIamV2{
r: func(service, region string) (awsedp.Endpoint, error) {
edp, err := cfg.ResolveEndpoint(service, region)
if err != nil {
return awsedp.Endpoint{}, err
}
uri, err := url.Parse(edp.URL)
if err != nil {
return awsedp.Endpoint{}, err
}
return awsedp.Endpoint{
URI: *uri,
}, nil
},
}
}
func (c *client) _NewS3Resolver(cfg *sdkaws.Config) sdksss.EndpointResolver { func (c *client) _NewS3Resolver(cfg *sdkaws.Config) sdksss.EndpointResolver {
return &resolverS3{ return &resolverS3{
r: cfg.EndpointResolver.ResolveEndpoint, r: cfg.EndpointResolver.ResolveEndpoint,
} }
} }
func (c *client) _NewS3ResolverV2(cfg Config) sdksss.EndpointResolverV2 {
return &resolverS3V2{
r: func(service, region string) (awsedp.Endpoint, error) {
edp, err := cfg.ResolveEndpoint(service, region)
if err != nil {
return awsedp.Endpoint{}, err
}
uri, err := url.Parse(edp.URL)
if err != nil {
return awsedp.Endpoint{}, err
}
return awsedp.Endpoint{
URI: *uri,
}, nil
},
}
}

View File

@@ -61,7 +61,9 @@ func (c *cobra) AddCommandCompletion() {
os.Exit(1) os.Exit(1)
} else if len(args) >= 2 { } else if len(args) >= 2 {
file = filepath.Clean(args[1]) file = filepath.Clean(args[1])
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "create file path", os.MkdirAll(filepath.Dir(file), 0755)) // #nosec
e := os.MkdirAll(filepath.Dir(file), 0755)
c.getLog().CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "create file path", e)
} }
switch strings.ToLower(args[0]) { switch strings.ToLower(args[0]) {

View File

@@ -110,6 +110,7 @@ func (c *cobra) ConfigureWriteConfig(basename string, defaultConfig func() io.Re
cfgFile = strings.TrimRight(cfgFile, ext) + ".json" cfgFile = strings.TrimRight(cfgFile, ext) + ".json"
} }
// #nosec
fs, err = os.OpenFile(cfgFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) fs, err = os.OpenFile(cfgFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil { if err != nil {
return err return err

View File

@@ -147,6 +147,7 @@ func (o *componentSmtp) _GetTLS() libtls.TLSConfig {
func (o *componentSmtp) _GetTLSConfig(cfg libtls.Config) *tls.Config { func (o *componentSmtp) _GetTLSConfig(cfg libtls.Config) *tls.Config {
if i, e := cfg.NewFrom(o._GetTLS()); e != nil { if i, e := cfg.NewFrom(o._GetTLS()); e != nil {
// #nosec
return &tls.Config{} return &tls.Config{}
} else { } else {
return i.TlsConfig("") return i.TlsConfig("")

View File

@@ -52,6 +52,7 @@ type Config[T comparable] interface {
MapManage[T] MapManage[T]
Context Context
SetContext(ctx FuncContext)
Clone(ctx context.Context) Config[T] Clone(ctx context.Context) Config[T]
Merge(cfg Config[T]) bool Merge(cfg Config[T]) bool
Walk(fct FuncWalk[T]) bool Walk(fct FuncWalk[T]) bool
@@ -81,6 +82,18 @@ type configContext[T comparable] struct {
x FuncContext x FuncContext
} }
func (c *configContext[T]) SetContext(ctx FuncContext) {
c.n.Lock()
defer c.n.Unlock()
if ctx == nil {
ctx = context.Background
}
c.Context = ctx()
c.x = ctx
}
func (c *configContext[T]) Delete(key T) { func (c *configContext[T]) Delete(key T) {
if c.Err() != nil { if c.Err() != nil {
c.Clean() c.Clean()

View File

@@ -39,6 +39,7 @@ const (
ErrorBadInstance ErrorBadInstance
ErrorGetFunction ErrorGetFunction
ErrorSetFunction ErrorSetFunction
ErrorDelFunction
ErrorListFunction ErrorListFunction
ErrorFunctionParams ErrorFunctionParams
) )
@@ -62,6 +63,8 @@ func getMessage(code liberr.CodeError) (message string) {
return "missing get function of " + pkgName return "missing get function of " + pkgName
case ErrorSetFunction: case ErrorSetFunction:
return "missing set function of " + pkgName return "missing set function of " + pkgName
case ErrorDelFunction:
return "missing del function of " + pkgName
case ErrorListFunction: case ErrorListFunction:
return "missing list function of " + pkgName return "missing list function of " + pkgName
case ErrorFunctionParams: case ErrorFunctionParams:

View File

@@ -26,25 +26,33 @@
package kvdriver package kvdriver
type FctWalk[K comparable, M any] func(key K, model M) bool import (
libkvt "github.com/nabbar/golib/database/kvtypes"
type KVDriver[K comparable, M any] interface { )
Get(key K, model *M) error
Set(key K, model M) error
List() ([]K, error)
Walk(fct FctWalk[K, M]) error
}
type FuncNew[K comparable, M any] func() libkvt.KVDriver[K, M]
type FuncGet[K comparable, M any] func(key K) (M, error) type FuncGet[K comparable, M any] func(key K) (M, error)
type FuncSet[K comparable, M any] func(key K, model M) error type FuncSet[K comparable, M any] func(key K, model M) error
type FuncDel[K comparable] func(key K) error
type FuncList[K comparable, M any] func() ([]K, error) type FuncList[K comparable, M any] func() ([]K, error)
type FuncWalk[K comparable, M any] func(fct FctWalk[K, M]) error type FuncWalk[K comparable, M any] func(fct libkvt.FctWalk[K, M]) error
type Driver[K comparable, M any] struct {
KVDriver[K, M]
type drv[K comparable, M any] struct {
FctNew FuncNew[K, M]
FctGet FuncGet[K, M] FctGet FuncGet[K, M]
FctSet FuncSet[K, M] FctSet FuncSet[K, M]
FctDel FuncDel[K]
FctList FuncList[K, M] FctList FuncList[K, M]
FctWalk FuncWalk[K, M] // optional FctWalk FuncWalk[K, M] // optional
} }
func New[K comparable, M any](fn FuncNew[K, M], fg FuncGet[K, M], fs FuncSet[K, M], fd FuncDel[K], fl FuncList[K, M], fw FuncWalk[K, M]) libkvt.KVDriver[K, M] {
return &drv[K, M]{
FctNew: fn,
FctGet: fg,
FctSet: fs,
FctDel: fd,
FctList: fl,
FctWalk: fw,
}
}

View File

@@ -26,7 +26,26 @@
package kvdriver package kvdriver
func (o *Driver[K, M]) Get(key K, model *M) error { import (
libkvt "github.com/nabbar/golib/database/kvtypes"
)
func (o *drv[K, M]) New() libkvt.KVDriver[K, M] {
if o.FctNew != nil {
return o.FctNew()
}
return &drv[K, M]{
FctNew: o.FctNew,
FctGet: o.FctGet,
FctSet: o.FctSet,
FctDel: o.FctDel,
FctList: o.FctList,
FctWalk: o.FctWalk,
}
}
func (o *drv[K, M]) Get(key K, model *M) error {
if o == nil { if o == nil {
return ErrorBadInstance.Error(nil) return ErrorBadInstance.Error(nil)
} else if o.FctGet == nil { } else if o.FctGet == nil {
@@ -38,7 +57,7 @@ func (o *Driver[K, M]) Get(key K, model *M) error {
} }
} }
func (o *Driver[K, M]) Set(key K, model M) error { func (o *drv[K, M]) Set(key K, model M) error {
if o == nil { if o == nil {
return ErrorBadInstance.Error(nil) return ErrorBadInstance.Error(nil)
} else if o.FctSet == nil { } else if o.FctSet == nil {
@@ -48,7 +67,17 @@ func (o *Driver[K, M]) Set(key K, model M) error {
} }
} }
func (o *Driver[K, M]) List() ([]K, error) { func (o *drv[K, M]) Del(key K) error {
if o == nil {
return ErrorBadInstance.Error(nil)
} else if o.FctDel == nil {
return ErrorSetFunction.Error(nil)
} else {
return o.FctDel(key)
}
}
func (o *drv[K, M]) List() ([]K, error) {
if o == nil { if o == nil {
return nil, ErrorBadInstance.Error(nil) return nil, ErrorBadInstance.Error(nil)
} else if o.FctList == nil { } else if o.FctList == nil {
@@ -58,7 +87,7 @@ func (o *Driver[K, M]) List() ([]K, error) {
} }
} }
func (o *Driver[K, M]) Walk(fct FctWalk[K, M]) error { func (o *drv[K, M]) Walk(fct libkvt.FctWalk[K, M]) error {
if o == nil { if o == nil {
return ErrorBadInstance.Error(nil) return ErrorBadInstance.Error(nil)
} else if fct == nil { } else if fct == nil {
@@ -70,7 +99,7 @@ func (o *Driver[K, M]) Walk(fct FctWalk[K, M]) error {
} }
} }
func (o *Driver[K, M]) fakeWalk(fct FctWalk[K, M]) error { func (o *drv[K, M]) fakeWalk(fct libkvt.FctWalk[K, M]) error {
if l, e := o.List(); e != nil { if l, e := o.List(); e != nil {
return e return e
} else { } else {

View File

@@ -38,6 +38,7 @@ const (
ErrorParamEmpty liberr.CodeError = iota + liberr.MinPkgDatabaseKVItm ErrorParamEmpty liberr.CodeError = iota + liberr.MinPkgDatabaseKVItm
ErrorLoadFunction ErrorLoadFunction
ErrorStoreFunction ErrorStoreFunction
ErrorRemoveFunction
) )
func init() { func init() {
@@ -57,6 +58,8 @@ func getMessage(code liberr.CodeError) (message string) {
return "missing load function of " + pkgName return "missing load function of " + pkgName
case ErrorStoreFunction: case ErrorStoreFunction:
return "missing store function of " + pkgName return "missing store function of " + pkgName
case ErrorRemoveFunction:
return "missing remove function of " + pkgName
} }
return liberr.NullMessage return liberr.NullMessage

View File

@@ -26,40 +26,21 @@
package kvitem package kvitem
import "sync/atomic" import (
"sync/atomic"
type FuncLoad[K comparable, M any] func(key K, model *M) error libkvt "github.com/nabbar/golib/database/kvtypes"
type FuncStore[K comparable, M any] func(key K, model M) error )
type KVItem[K comparable, M any] interface {
Set(model M)
Get() M
Load() error
Store(force bool) error
Clean()
HasChange() bool
RegisterFctLoad(fct FuncLoad[K, M])
RegisterFctStore(fct FuncStore[K, M])
}
func New[K comparable, M any](key K) KVItem[K, M] {
var (
ml = new(atomic.Value)
mw = new(atomic.Value)
)
ml.Store(nil)
mw.Store(nil)
func New[K comparable, M any](drv libkvt.KVDriver[K, M], key K) libkvt.KVItem[K, M] {
return &itm[K, M]{ return &itm[K, M]{
k: key, k: key,
ml: ml, d: drv,
ms: mw, ml: new(atomic.Value),
fl: nil, ms: new(atomic.Value),
fs: nil, fl: new(atomic.Value),
fs: new(atomic.Value),
fr: new(atomic.Value),
} }
} }

View File

@@ -29,9 +29,12 @@ package kvitem
import ( import (
"reflect" "reflect"
"sync/atomic" "sync/atomic"
libkvt "github.com/nabbar/golib/database/kvtypes"
) )
type itm[K comparable, M any] struct { type itm[K comparable, M any] struct {
d libkvt.KVDriver[K, M]
k K // key k K // key
ml *atomic.Value // model read ml *atomic.Value // model read
@@ -39,165 +42,145 @@ type itm[K comparable, M any] struct {
fl *atomic.Value fl *atomic.Value
fs *atomic.Value fs *atomic.Value
fr *atomic.Value
} }
func (o *itm[K, M]) RegisterFctLoad(fct FuncLoad[K, M]) { func (o *itm[K, M]) getDriver() libkvt.KVDriver[K, M] {
o.fl.Store(fct)
}
func (o *itm[K, M]) getFctLoad() FuncLoad[K, M] {
if o == nil { if o == nil {
return nil return nil
} }
i := o.fs.Load() return o.d
if i == nil {
return nil
} else if f, k := i.(FuncLoad[K, M]); !k {
return nil
} else {
return f
}
}
func (o *itm[K, M]) RegisterFctStore(fct FuncStore[K, M]) {
o.fs.Store(fct)
}
func (o *itm[K, M]) getFctStore() FuncStore[K, M] {
if o == nil {
return nil
}
i := o.fs.Load()
if i == nil {
return nil
} else if f, k := i.(FuncStore[K, M]); !k {
return nil
} else {
return f
}
} }
func (o *itm[K, M]) Set(model M) { func (o *itm[K, M]) Set(model M) {
if o == nil { var val = reflect.ValueOf(model)
return o.ms.Store(val.Interface())
} }
m := o.ml.Load() func (o *itm[K, M]) setModelLoad(mod M) {
var val = reflect.ValueOf(mod)
o.ml.Store(val.Interface())
}
// model not loaded, so store new model func (o *itm[K, M]) getModelLoad() M {
if m == nil { var mod M
o.ms.Store(model) if i := o.ml.Load(); i == nil {
// model loaded and new model given not same, so store new model return mod
} else if !reflect.DeepEqual(m.(M), model) { } else if v, k := i.(M); !k {
o.ms.Store(model) return mod
// model loaded and given model are same, so don't store new model
} else { } else {
o.ms.Store(nil) return v
} }
} }
func (o *itm[K, M]) getModelStore() M {
var mod M
if i := o.ms.Load(); i == nil {
return mod
} else if v, k := i.(M); !k {
return mod
} else {
return v
}
}
func (o *itm[K, M]) Key() K {
if o == nil {
var k K
return k
}
return o.k
}
func (o *itm[K, M]) Get() M { func (o *itm[K, M]) Get() M {
var (
tmp M
mod M
)
if o == nil { if o == nil {
return *(new(M)) return mod
} }
// update exist so latest fresh value mod = o.getModelStore()
m := o.ms.Load()
if m != nil {
if v, k := m.(M); k {
return v
}
}
// load model exist so return last model load if reflect.DeepEqual(mod, tmp) {
m = o.ml.Load() mod = o.getModelLoad()
if m != nil {
if v, k := m.(M); k {
return v
}
} }
// nothing load, so return new instance // nothing load, so return new instance
return *(new(M)) return mod
} }
func (o *itm[K, M]) Load() error { func (o *itm[K, M]) Load() error {
var fct FuncLoad[K, M] var (
mod M
drv = o.getDriver()
)
if fct = o.getFctLoad(); fct == nil { if drv == nil {
return ErrorLoadFunction.Error(nil) return ErrorLoadFunction.Error(nil)
} }
m := *(new(M)) if e := drv.Get(o.k, &mod); e == nil {
e := fct(o.k, &m) o.setModelLoad(mod)
} else {
if e == nil { return e
o.ml.Store(m)
} }
return e return nil
} }
func (o *itm[K, M]) Store(force bool) error { func (o *itm[K, M]) Store(force bool) error {
var fct FuncStore[K, M] var drv = o.getDriver()
if fct = o.getFctStore(); fct == nil { if drv == nil {
return ErrorStoreFunction.Error(nil) return ErrorStoreFunction.Error(nil)
} }
m := o.ms.Load() var (
if m != nil { lod M
return fct(o.k, m.(M)) str M
} else if !force { )
return nil
_ = o.Load()
str = o.getModelStore()
if reflect.DeepEqual(lod, str) {
str = o.getModelLoad()
} }
// no update, but force store, so use load model lod = o.getModelLoad()
m = o.ml.Load() if !reflect.DeepEqual(lod, str) {
if m != nil { return drv.Set(o.k, str)
return fct(o.k, m.(M)) } else if force {
return drv.Set(o.k, lod)
} }
// no update and no load, but force store, so use new instance of model return nil
m = *(new(M)) }
return fct(o.k, m.(M))
func (o *itm[K, M]) Remove() error {
drv := o.getDriver()
if drv == nil {
return ErrorStoreFunction.Error(nil)
}
return drv.Del(o.k)
} }
func (o *itm[K, M]) Clean() { func (o *itm[K, M]) Clean() {
o.ml.Store(nil) var tmp M
o.ms.Store(nil) o.setModelLoad(tmp)
o.Set(tmp)
} }
func (o *itm[K, M]) HasChange() bool { func (o *itm[K, M]) HasChange() bool {
r := o.ml.Load() r := o.getModelLoad()
w := o.ms.Load() w := o.getModelStore()
if r == nil && w == nil { return !reflect.DeepEqual(r, w)
// not loaded and not store, so no change
return false
} else if r == nil {
// not loaded but store is set, so has been updated
return true
} else if w == nil {
// loaded and not store, so no change
return false
}
mr, kr := r.(M)
mw, kw := w.(M)
if !kr && !kw {
// no valid model, so no change
return false
} else if !kr {
// not valid model for load, but valid for store, so has been updated
return true
} else if !kw {
// valid model for load, but not valid for store, so like no change
return false
}
return !reflect.DeepEqual(mr, mw)
} }

View File

@@ -39,6 +39,7 @@ const (
ErrorBadInstance ErrorBadInstance
ErrorGetFunction ErrorGetFunction
ErrorSetFunction ErrorSetFunction
ErrorDelFunction
ErrorListFunction ErrorListFunction
ErrorFunctionParams ErrorFunctionParams
) )
@@ -62,6 +63,8 @@ func getMessage(code liberr.CodeError) (message string) {
return "missing get function of " + pkgName return "missing get function of " + pkgName
case ErrorSetFunction: case ErrorSetFunction:
return "missing set function of " + pkgName return "missing set function of " + pkgName
case ErrorDelFunction:
return "missing del function of " + pkgName
case ErrorListFunction: case ErrorListFunction:
return "missing list function of " + pkgName return "missing list function of " + pkgName
case ErrorFunctionParams: case ErrorFunctionParams:

View File

@@ -27,17 +27,29 @@
package kvmap package kvmap
import ( import (
libkvd "github.com/nabbar/golib/database/kvdriver" libkvt "github.com/nabbar/golib/database/kvtypes"
) )
type FuncNew[K comparable, M any] func() libkvt.KVDriver[K, M]
type FuncGet[K comparable, MK comparable] func(key K) (map[MK]any, error) type FuncGet[K comparable, MK comparable] func(key K) (map[MK]any, error)
type FuncSet[K comparable, MK comparable] func(key K, model map[MK]any) error type FuncSet[K comparable, MK comparable] func(key K, model map[MK]any) error
type FuncDel[K comparable] func(key K) error
type FuncList[K comparable, MK comparable] func() ([]K, error) type FuncList[K comparable, MK comparable] func() ([]K, error)
type Driver[K comparable, MK comparable, M any] struct { type drv[K comparable, MK comparable, M any] struct {
libkvd.KVDriver[K, M] FctNew FuncNew[K, M]
FctGet FuncGet[K, MK] FctGet FuncGet[K, MK]
FctSet FuncSet[K, MK] FctSet FuncSet[K, MK]
FctDel FuncDel[K]
FctList FuncList[K, MK] FctList FuncList[K, MK]
} }
func New[K comparable, MK comparable, M any](fn FuncNew[K, M], fg FuncGet[K, MK], fs FuncSet[K, MK], fd FuncDel[K], fl FuncList[K, MK]) libkvt.KVDriver[K, M] {
return &drv[K, MK, M]{
FctNew: fn,
FctGet: fg,
FctSet: fs,
FctDel: fd,
FctList: fl,
}
}

View File

@@ -29,10 +29,10 @@ package kvmap
import ( import (
"encoding/json" "encoding/json"
libkvd "github.com/nabbar/golib/database/kvdriver" libkvt "github.com/nabbar/golib/database/kvtypes"
) )
func (o *Driver[K, MK, M]) serialize(model *M, modelMap *map[MK]any) error { func (o *drv[K, MK, M]) serialize(model *M, modelMap *map[MK]any) error {
if p, e := json.Marshal(model); e != nil { if p, e := json.Marshal(model); e != nil {
return e return e
} else { } else {
@@ -40,7 +40,7 @@ func (o *Driver[K, MK, M]) serialize(model *M, modelMap *map[MK]any) error {
} }
} }
func (o *Driver[K, MK, M]) unSerialize(modelMap *map[MK]any, model *M) error { func (o *drv[K, MK, M]) unSerialize(modelMap *map[MK]any, model *M) error {
if p, e := json.Marshal(modelMap); e != nil { if p, e := json.Marshal(modelMap); e != nil {
return e return e
} else { } else {
@@ -48,7 +48,16 @@ func (o *Driver[K, MK, M]) unSerialize(modelMap *map[MK]any, model *M) error {
} }
} }
func (o *Driver[K, MK, M]) Get(key K, model *M) error { func (o *drv[K, MK, M]) New() libkvt.KVDriver[K, M] {
return &drv[K, MK, M]{
FctGet: o.FctGet,
FctSet: o.FctSet,
FctDel: o.FctDel,
FctList: o.FctList,
}
}
func (o *drv[K, MK, M]) Get(key K, model *M) error {
if o == nil { if o == nil {
return ErrorBadInstance.Error(nil) return ErrorBadInstance.Error(nil)
} else if o.FctGet == nil { } else if o.FctGet == nil {
@@ -60,7 +69,7 @@ func (o *Driver[K, MK, M]) Get(key K, model *M) error {
} }
} }
func (o *Driver[K, MK, M]) Set(key K, model M) error { func (o *drv[K, MK, M]) Set(key K, model M) error {
var m = make(map[MK]any) var m = make(map[MK]any)
if o == nil { if o == nil {
@@ -74,7 +83,17 @@ func (o *Driver[K, MK, M]) Set(key K, model M) error {
} }
} }
func (o *Driver[K, MK, M]) List() ([]K, error) { func (o *drv[K, MK, M]) Del(key K) error {
if o == nil {
return ErrorBadInstance.Error(nil)
} else if o.FctDel == nil {
return ErrorDelFunction.Error(nil)
} else {
return o.FctDel(key)
}
}
func (o *drv[K, MK, M]) List() ([]K, error) {
if o == nil { if o == nil {
return nil, ErrorBadInstance.Error(nil) return nil, ErrorBadInstance.Error(nil)
} else if o.FctList == nil { } else if o.FctList == nil {
@@ -84,7 +103,7 @@ func (o *Driver[K, MK, M]) List() ([]K, error) {
} }
} }
func (o *Driver[K, MK, M]) Walk(fct libkvd.FctWalk[K, M]) error { func (o *drv[K, MK, M]) Walk(fct libkvt.FctWalk[K, M]) error {
if o == nil { if o == nil {
return ErrorBadInstance.Error(nil) return ErrorBadInstance.Error(nil)
} else if fct == nil { } else if fct == nil {

View File

@@ -27,25 +27,11 @@
package kvtable package kvtable
import ( import (
"sync/atomic" libkvt "github.com/nabbar/golib/database/kvtypes"
libkvd "github.com/nabbar/golib/database/kvdriver"
libkvi "github.com/nabbar/golib/database/kvitem"
) )
type FuncWalk[K comparable, M any] func(kv libkvi.KVItem[K, M]) bool func New[K comparable, M any](drv libkvt.KVDriver[K, M]) libkvt.KVTable[K, M] {
type KVTable[K comparable, M any] interface {
Get(key K) (libkvi.KVItem[K, M], error)
List() ([]libkvi.KVItem[K, M], error)
Walk(fct FuncWalk[K, M]) error
}
func New[K comparable, M any](drv libkvd.KVDriver[K, M]) KVTable[K, M] {
d := new(atomic.Value)
d.Store(drv)
return &tbl[K, M]{ return &tbl[K, M]{
d: d, d: drv,
} }
} }

View File

@@ -27,66 +27,58 @@
package kvtable package kvtable
import ( import (
"sync/atomic"
libkvd "github.com/nabbar/golib/database/kvdriver"
libkvs "github.com/nabbar/golib/database/kvitem" libkvs "github.com/nabbar/golib/database/kvitem"
libkvt "github.com/nabbar/golib/database/kvtypes"
) )
type tbl[K comparable, M any] struct { type tbl[K comparable, M any] struct {
d *atomic.Value d libkvt.KVDriver[K, M]
} }
func (o *tbl[K, M]) getDriver() libkvd.KVDriver[K, M] { func (o *tbl[K, M]) getDriver() libkvt.KVDriver[K, M] {
if o == nil { if o == nil {
return nil return nil
} }
i := o.d.Load() if o.d == nil {
if i == nil {
return nil
} else if d, k := i.(libkvd.KVDriver[K, M]); !k {
return nil return nil
} else { } else {
return d return o.d
} }
} }
func (o *tbl[K, M]) Get(key K) (libkvs.KVItem[K, M], error) { func (o *tbl[K, M]) Get(key K) (libkvt.KVItem[K, M], error) {
var kvs = libkvs.New[K, M](key)
if drv := o.getDriver(); drv == nil { if drv := o.getDriver(); drv == nil {
return nil, ErrorBadDriver.Error(nil) return nil, ErrorBadDriver.Error(nil)
} else { } else {
kvs.RegisterFctLoad(drv.Get) var kvi = libkvs.New[K, M](drv.New(), key)
kvs.RegisterFctStore(drv.Set) e := kvi.Load()
return kvi, e
} }
return kvs, kvs.Load()
} }
func (o *tbl[K, M]) Walk(fct FuncWalk[K, M]) error { func (o *tbl[K, M]) Del(key K) error {
if drv := o.getDriver(); drv == nil {
return ErrorBadDriver.Error(nil)
} else {
return drv.Del(key)
}
}
func (o *tbl[K, M]) Walk(fct libkvt.FuncWalk[K, M]) error {
if drv := o.getDriver(); drv == nil { if drv := o.getDriver(); drv == nil {
return ErrorBadDriver.Error(nil) return ErrorBadDriver.Error(nil)
} else { } else {
return drv.Walk(func(key K, model M) bool { return drv.Walk(func(key K, model M) bool {
var kvs = libkvs.New[K, M](key) kvi := libkvs.New[K, M](drv.New(), key)
kvi.Set(model)
kvs.RegisterFctStore(drv.Set) return fct(kvi)
kvs.RegisterFctLoad(func(k K, m *M) error {
*m = model
return nil
})
_ = kvs.Load()
kvs.RegisterFctLoad(drv.Get)
return fct(kvs)
}) })
} }
} }
func (o *tbl[K, M]) List() ([]libkvs.KVItem[K, M], error) { func (o *tbl[K, M]) List() ([]libkvt.KVItem[K, M], error) {
var res = make([]libkvs.KVItem[K, M], 0) var res = make([]libkvt.KVItem[K, M], 0)
if drv := o.getDriver(); drv == nil { if drv := o.getDriver(); drv == nil {
return nil, ErrorBadDriver.Error(nil) return nil, ErrorBadDriver.Error(nil)
@@ -94,12 +86,7 @@ func (o *tbl[K, M]) List() ([]libkvs.KVItem[K, M], error) {
return nil, e return nil, e
} else { } else {
for _, k := range l { for _, k := range l {
var kvs = libkvs.New[K, M](k) res = append(res, libkvs.New[K, M](drv.New(), k))
kvs.RegisterFctLoad(drv.Get)
kvs.RegisterFctStore(drv.Set)
res = append(res, kvs)
} }
return res, nil return res, nil

View File

@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2023 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
package kvtypes
type FctWalk[K comparable, M any] func(key K, model M) bool
type KVDriver[K comparable, M any] interface {
New() KVDriver[K, M]
Get(key K, model *M) error
Set(key K, model M) error
Del(key K) error
List() ([]K, error)
Walk(fct FctWalk[K, M]) error
}

40
database/kvtypes/item.go Normal file
View File

@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2023 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
package kvtypes
type KVItem[K comparable, M any] interface {
Set(model M)
Get() M
Key() K
Load() error
Store(force bool) error
Remove() error
Clean()
HasChange() bool
}

36
database/kvtypes/table.go Normal file
View File

@@ -0,0 +1,36 @@
/*
* MIT License
*
* Copyright (c) 2023 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
package kvtypes
type FuncWalk[K comparable, M any] func(kv KVItem[K, M]) bool
type KVTable[K comparable, M any] interface {
Get(key K) (KVItem[K, M], error)
Del(key K) error
List() ([]KVItem[K, M], error)
Walk(fct FuncWalk[K, M]) error
}

87
duration/encode.go Normal file
View File

@@ -0,0 +1,87 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package duration
import (
"fmt"
"gopkg.in/yaml.v3"
)
func (d Duration) MarshalJSON() ([]byte, error) {
t := d.String()
b := make([]byte, 0, len(t)+2)
b = append(b, '"')
b = append(b, []byte(t)...)
b = append(b, '"')
return b, nil
}
func (d *Duration) UnmarshalJSON(bytes []byte) error {
return d.unmarshall(bytes)
}
func (d Duration) MarshalYAML() (interface{}, error) {
return d.MarshalJSON()
}
func (d *Duration) UnmarshalYAML(value *yaml.Node) error {
return d.unmarshall([]byte(value.Value))
}
func (d Duration) MarshalTOML() ([]byte, error) {
return d.MarshalJSON()
}
func (d *Duration) UnmarshalTOML(i interface{}) error {
if b, k := i.([]byte); k {
return d.unmarshall(b)
}
if b, k := i.(string); k {
return d.parseString(b)
}
return fmt.Errorf("size: value not in valid format")
}
func (d Duration) MarshalText() ([]byte, error) {
return []byte(d.String()), nil
}
func (d *Duration) UnmarshalText(bytes []byte) error {
return d.unmarshall(bytes)
}
func (d Duration) MarshalCBOR() ([]byte, error) {
return []byte(d.String()), nil
}
func (d *Duration) UnmarshalCBOR(bytes []byte) error {
return d.unmarshall(bytes)
}

51
duration/format.go Normal file
View File

@@ -0,0 +1,51 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package duration
import (
"math"
"time"
)
func (d Duration) Time() time.Duration {
return time.Duration(d)
}
func (d Duration) String() string {
return time.Duration(d).String()
}
func (d Duration) Days() int64 {
t := math.Floor(d.Time().Hours())
if t > math.MaxInt64 {
return math.MaxInt64
}
return int64(t)
}

62
duration/interface.go Normal file
View File

@@ -0,0 +1,62 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package duration
import (
"time"
)
type Duration time.Duration
func Parse(s string) (Duration, error) {
return parseString(s)
}
func ParseByte(p []byte) (Duration, error) {
return parseString(string(p))
}
func Seconds(i int64) Duration {
return Duration(time.Duration(i) * time.Second)
}
func Minutes(i int64) Duration {
return Duration(time.Duration(i) * time.Minute)
}
func Hours(i int64) Duration {
return Duration(time.Duration(i) * time.Hour)
}
func Days(i int64) Duration {
return Duration(time.Duration(i) * time.Hour * 24)
}
func ParseDuration(d time.Duration) Duration {
return Duration(d)
}

59
duration/model.go Normal file
View File

@@ -0,0 +1,59 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package duration
import (
"reflect"
libmap "github.com/mitchellh/mapstructure"
)
func ViperDecoderHook() libmap.DecodeHookFuncType {
return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
var (
z = Duration(0)
t string
k bool
)
// Check if the data type matches the expected one
if from.Kind() != reflect.String {
return data, nil
} else if t, k = data.(string); !k {
return data, nil
}
// Check if the target type matches the expected one
if to != reflect.TypeOf(z) {
return data, nil
}
// Format/decode/parse the data and return the new value
return parseString(t)
}
}

61
duration/parse.go Normal file
View File

@@ -0,0 +1,61 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package duration
import (
"strings"
"time"
)
func parseString(s string) (Duration, error) {
s = strings.Replace(s, "\"", "", -1)
s = strings.Replace(s, "'", "", -1)
if v, e := time.ParseDuration(s); e != nil {
return 0, e
} else {
return Duration(v), nil
}
}
func (d *Duration) parseString(s string) error {
if v, e := parseString(s); e != nil {
return e
} else {
*d = v
return nil
}
}
func (d *Duration) unmarshall(val []byte) error {
if tmp, err := ParseByte(val); err != nil {
return err
} else {
*d = tmp
return nil
}
}

87
file/perm/encode.go Normal file
View File

@@ -0,0 +1,87 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package perm
import (
"fmt"
"gopkg.in/yaml.v3"
)
func (p Perm) MarshalJSON() ([]byte, error) {
t := p.String()
b := make([]byte, 0, len(t)+2)
b = append(b, '"')
b = append(b, []byte(t)...)
b = append(b, '"')
return b, nil
}
func (p *Perm) UnmarshalJSON(bytes []byte) error {
return p.unmarshall(bytes)
}
func (p Perm) MarshalYAML() (interface{}, error) {
return p.MarshalJSON()
}
func (p *Perm) UnmarshalYAML(value *yaml.Node) error {
return p.unmarshall([]byte(value.Value))
}
func (p Perm) MarshalTOML() ([]byte, error) {
return p.MarshalJSON()
}
func (p *Perm) UnmarshalTOML(i interface{}) error {
if b, k := i.([]byte); k {
return p.unmarshall(b)
}
if b, k := i.(string); k {
return p.parseString(b)
}
return fmt.Errorf("size: value not in valid format")
}
func (p Perm) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}
func (p *Perm) UnmarshalText(bytes []byte) error {
return p.unmarshall(bytes)
}
func (p Perm) MarshalCBOR() ([]byte, error) {
return []byte(p.String()), nil
}
func (p *Perm) UnmarshalCBOR(bytes []byte) error {
return p.unmarshall(bytes)
}

91
file/perm/format.go Normal file
View File

@@ -0,0 +1,91 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package perm
import (
"fmt"
"math"
"os"
)
func (p Perm) FileMode() os.FileMode {
return os.FileMode(p.Uint64())
}
func (p Perm) String() string {
return fmt.Sprintf("%#o", p.Uint64())
}
func (p Perm) Int64() int64 {
if uint64(p) > math.MaxInt64 {
// overflow
return math.MaxInt64
}
return int64(p)
}
func (p Perm) Int32() int32 {
if uint64(p) > math.MaxInt32 {
// overflow
return math.MaxInt32
}
return int32(p)
}
func (p Perm) Int() int {
if uint64(p) > math.MaxInt {
// overflow
return math.MaxInt
}
return int(p)
}
func (p Perm) Uint64() uint64 {
return uint64(p)
}
func (p Perm) Uint32() uint32 {
if uint64(p) > math.MaxUint32 {
// overflow
return math.MaxUint32
}
return uint32(p)
}
func (p Perm) Uint() uint {
if uint64(p) > math.MaxUint {
// overflow
return math.MaxUint
}
return uint(p)
}

51
file/perm/interface.go Normal file
View File

@@ -0,0 +1,51 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package perm
import (
"os"
"strconv"
)
type Perm os.FileMode
func Parse(s string) (Perm, error) {
return parseString(s)
}
func ParseInt(i int) (Perm, error) {
return parseString(strconv.FormatInt(int64(i), 8))
}
func ParseInt64(i int64) (Perm, error) {
return parseString(strconv.FormatInt(i, 8))
}
func ParseByte(p []byte) (Perm, error) {
return parseString(string(p))
}

59
file/perm/model.go Normal file
View File

@@ -0,0 +1,59 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package perm
import (
"reflect"
libmap "github.com/mitchellh/mapstructure"
)
func ViperDecoderHook() libmap.DecodeHookFuncType {
return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
var (
z = Perm(0)
t string
k bool
)
// Check if the data type matches the expected one
if from.Kind() != reflect.String {
return data, nil
} else if t, k = data.(string); !k {
return data, nil
}
// Check if the target type matches the expected one
if to != reflect.TypeOf(z) {
return data, nil
}
// Format/decode/parse the data and return the new value
return parseString(t)
}
}

66
file/perm/parse.go Normal file
View File

@@ -0,0 +1,66 @@
/***********************************************************************************************************************
*
* MIT License
*
* Copyright (c) 2022 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
**********************************************************************************************************************/
package perm
import (
"fmt"
"math"
"strconv"
"strings"
)
func parseString(s string) (Perm, error) {
s = strings.Replace(s, "\"", "", -1)
s = strings.Replace(s, "'", "", -1)
if v, e := strconv.ParseUint(s, 8, 32); e != nil {
return 0, e
} else if v > math.MaxUint32 {
return Perm(0), fmt.Errorf("invalid permission")
} else {
return Perm(v), nil
}
}
func (p *Perm) parseString(s string) error {
if v, e := parseString(s); e != nil {
return e
} else {
*p = v
return nil
}
}
func (p *Perm) unmarshall(val []byte) error {
if tmp, err := ParseByte(val); err != nil {
return err
} else {
*p = tmp
return nil
}
}

View File

@@ -85,7 +85,10 @@ type Progress interface {
} }
func New(name string, flags int, perm os.FileMode) (Progress, error) { func New(name string, flags int, perm os.FileMode) (Progress, error) {
if f, e := os.OpenFile(name, flags, perm); e != nil { // #nosec
f, e := os.OpenFile(name, flags, perm)
if e != nil {
return nil, e return nil, e
} else { } else {
return &progress{ return &progress{
@@ -99,7 +102,10 @@ func New(name string, flags int, perm os.FileMode) (Progress, error) {
} }
func Unique(basePath, pattern string) (Progress, error) { func Unique(basePath, pattern string) (Progress, error) {
if f, e := os.CreateTemp(basePath, pattern); e != nil { // #nosec
f, e := os.CreateTemp(basePath, pattern)
if e != nil {
return nil, e return nil, e
} else { } else {
return &progress{ return &progress{
@@ -113,7 +119,10 @@ func Unique(basePath, pattern string) (Progress, error) {
} }
func Temp(pattern string) (Progress, error) { func Temp(pattern string) (Progress, error) {
if f, e := os.CreateTemp("", pattern); e != nil { // #nosec
f, e := os.CreateTemp("", pattern)
if e != nil {
return nil, e return nil, e
} else { } else {
return &progress{ return &progress{
@@ -127,7 +136,10 @@ func Temp(pattern string) (Progress, error) {
} }
func Open(name string) (Progress, error) { func Open(name string) (Progress, error) {
if f, e := os.Open(name); e != nil { // #nosec
f, e := os.Open(name)
if e != nil {
return nil, e return nil, e
} else { } else {
return &progress{ return &progress{
@@ -141,7 +153,10 @@ func Open(name string) (Progress, error) {
} }
func Create(name string) (Progress, error) { func Create(name string) (Progress, error) {
if f, e := os.Create(name); e != nil { // #nosec
f, e := os.Create(name)
if e != nil {
return nil, e return nil, e
} else { } else {
return &progress{ return &progress{

132
go.mod
View File

@@ -2,25 +2,26 @@ module github.com/nabbar/golib
go 1.21 go 1.21
toolchain go1.21.1 toolchain go1.21.3
require ( require (
github.com/aws/aws-sdk-go-v2 v1.21.2 github.com/aws/aws-sdk-go-v2 v1.23.1
github.com/aws/aws-sdk-go-v2/config v1.18.45 github.com/aws/aws-sdk-go-v2/config v1.25.4
github.com/aws/aws-sdk-go-v2/credentials v1.13.43 github.com/aws/aws-sdk-go-v2/credentials v1.16.3
github.com/aws/aws-sdk-go-v2/service/iam v1.22.7 github.com/aws/aws-sdk-go-v2/service/iam v1.27.3
github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 github.com/aws/aws-sdk-go-v2/service/s3 v1.43.1
github.com/bits-and-blooms/bitset v1.10.0 github.com/aws/smithy-go v1.17.0
github.com/bits-and-blooms/bitset v1.11.0
github.com/c-bata/go-prompt v0.2.6 github.com/c-bata/go-prompt v0.2.6
github.com/fatih/color v1.15.0 github.com/fatih/color v1.16.0
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.7.0
github.com/fxamacker/cbor/v2 v2.5.0 github.com/fxamacker/cbor/v2 v2.5.0
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-playground/validator/v10 v10.15.5 github.com/go-playground/validator/v10 v10.16.0
github.com/google/go-github/v33 v33.0.0 github.com/google/go-github/v33 v33.0.0
github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-hclog v1.5.0
github.com/hashicorp/go-retryablehttp v0.7.4 github.com/hashicorp/go-retryablehttp v0.7.5
github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/go-version v1.6.0
github.com/jlaffaye/ftp v0.2.0 github.com/jlaffaye/ftp v0.2.0
@@ -29,34 +30,34 @@ require (
github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-colorable v0.1.13
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/nats-io/jwt/v2 v2.5.2 github.com/nats-io/jwt/v2 v2.5.3
github.com/nats-io/nats-server/v2 v2.10.3 github.com/nats-io/nats-server/v2 v2.10.5
github.com/nats-io/nats.go v1.30.2 github.com/nats-io/nats.go v1.31.0
github.com/nutsdb/nutsdb v0.14.1 github.com/nutsdb/nutsdb v0.14.3
github.com/onsi/ginkgo/v2 v2.13.0 github.com/onsi/ginkgo/v2 v2.13.1
github.com/onsi/gomega v1.28.0 github.com/onsi/gomega v1.30.0
github.com/pelletier/go-toml v1.9.5 github.com/pelletier/go-toml v1.9.5
github.com/prometheus/client_golang v1.17.0 github.com/prometheus/client_golang v1.17.0
github.com/shirou/gopsutil v3.21.11+incompatible github.com/shirou/gopsutil v3.21.11+incompatible
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.8.0
github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/viper v1.17.0 github.com/spf13/viper v1.17.0
github.com/ugorji/go/codec v1.2.11 github.com/ugorji/go/codec v1.2.11
github.com/vbauerster/mpb/v8 v8.6.2 github.com/vbauerster/mpb/v8 v8.6.2
github.com/xanzy/go-gitlab v0.93.1 github.com/xanzy/go-gitlab v0.94.0
github.com/xhit/go-simple-mail v2.2.2+incompatible github.com/xhit/go-simple-mail v2.2.2+incompatible
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235 github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235
golang.org/x/exp v0.0.0-20231006140011-7918f672742d golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/net v0.17.0 golang.org/x/net v0.18.0
golang.org/x/oauth2 v0.13.0 golang.org/x/oauth2 v0.14.0
golang.org/x/sync v0.4.0 golang.org/x/sync v0.5.0
golang.org/x/sys v0.13.0 golang.org/x/sys v0.14.0
golang.org/x/term v0.13.0 golang.org/x/term v0.14.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/clickhouse v0.5.1 gorm.io/driver/clickhouse v0.5.1
gorm.io/driver/mysql v1.5.2 gorm.io/driver/mysql v1.5.2
gorm.io/driver/postgres v1.5.3 gorm.io/driver/postgres v1.5.4
gorm.io/driver/sqlite v1.5.4 gorm.io/driver/sqlite v1.5.4
gorm.io/driver/sqlserver v1.5.2 gorm.io/driver/sqlserver v1.5.2
gorm.io/gorm v1.25.5 gorm.io/gorm v1.25.5
@@ -65,7 +66,7 @@ require (
require ( require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/ClickHouse/ch-go v0.58.2 // indirect github.com/ClickHouse/ch-go v0.58.2 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.14.3 // indirect github.com/ClickHouse/clickhouse-go/v2 v2.15.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect
@@ -78,38 +79,36 @@ require (
github.com/antlabs/stl v0.0.1 // indirect github.com/antlabs/stl v0.0.1 // indirect
github.com/antlabs/timer v0.0.11 // indirect github.com/antlabs/timer v0.0.11 // indirect
github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.17.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.20.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 // indirect
github.com/aws/smithy-go v1.15.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/bytedance/sonic v1.10.2 // indirect github.com/bytedance/sonic v1.10.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/errors v1.11.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20210331181633-27fc006b8bfb // indirect github.com/cockroachdb/pebble v0.0.0-20210331181633-27fc006b8bfb // indirect
github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/redact v1.1.5 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/getsentry/sentry-go v0.25.0 // indirect github.com/getsentry/sentry-go v0.25.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-faster/city v1.0.1 // indirect github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.6.1 // indirect github.com/go-faster/errors v0.7.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/logr v1.3.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
@@ -125,15 +124,15 @@ require (
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
github.com/google/uuid v1.3.1 // indirect github.com/google/uuid v1.4.0 // indirect
github.com/gorilla/css v1.0.0 // indirect github.com/gorilla/css v1.0.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-sockaddr v1.0.5 // indirect github.com/hashicorp/go-sockaddr v1.0.6 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/memberlist v0.5.0 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect
@@ -142,32 +141,33 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.4.3 // indirect github.com/jackc/pgx/v5 v5.5.0 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/juju/ratelimit v1.0.2 // indirect github.com/juju/ratelimit v1.0.2 // indirect
github.com/klauspost/compress v1.17.1 // indirect github.com/klauspost/compress v1.17.3 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/lni/goutils v1.3.0 // indirect github.com/lni/goutils v1.3.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mattn/go-sqlite3 v1.14.18 // indirect
github.com/mattn/go-tty v0.0.5 // indirect github.com/mattn/go-tty v0.0.5 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/microsoft/go-mssqldb v1.6.0 // indirect github.com/microsoft/go-mssqldb v1.6.0 // indirect
github.com/miekg/dns v1.1.56 // indirect github.com/miekg/dns v1.1.57 // indirect
github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nats-io/nkeys v0.4.5 // indirect github.com/nats-io/nkeys v0.4.6 // indirect
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/paulmach/orb v0.10.0 // indirect github.com/paulmach/orb v0.10.0 // indirect
@@ -176,7 +176,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/term v1.2.0-beta.2 // indirect github.com/pkg/term v1.2.0-beta.2 // indirect
github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect
@@ -201,15 +201,15 @@ require (
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xujiajun/mmap-go v1.0.1 // indirect github.com/xujiajun/mmap-go v1.0.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.5.0 // indirect golang.org/x/arch v0.6.0 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.15.0 // indirect
golang.org/x/mod v0.13.0 // indirect golang.org/x/mod v0.14.0 // indirect
golang.org/x/text v0.13.0 // indirect golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.4.0 // indirect
golang.org/x/tools v0.14.0 // indirect golang.org/x/tools v0.15.0 // indirect
google.golang.org/appengine v1.6.8 // indirect google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect

View File

@@ -93,6 +93,7 @@ func (o *srv) setServer(ctx context.Context) error {
var stdlog = o.logger() var stdlog = o.logger()
// #nosec
s := &http.Server{ s := &http.Server{
Addr: bind, Addr: bind,
Handler: o.HandlerLoadFct(), Handler: o.HandlerLoadFct(),

View File

@@ -56,6 +56,8 @@ func (o *optServer) initServer(s *http.Server) liberr.Error {
if o.ReadHeaderTimeout > 0 { if o.ReadHeaderTimeout > 0 {
s.ReadHeaderTimeout = o.ReadHeaderTimeout s.ReadHeaderTimeout = o.ReadHeaderTimeout
} else {
s.ReadHeaderTimeout = 30 * time.Second
} }
if o.WriteTimeout > 0 { if o.WriteTimeout > 0 {

View File

@@ -57,7 +57,11 @@ func PathCheckCreate(isFile bool, path string, permFile os.FileMode, permDir os.
return os.MkdirAll(path, permDir) return os.MkdirAll(path, permDir)
} else if err = PathCheckCreate(false, filepath.Dir(path), permFile, permDir); err != nil { } else if err = PathCheckCreate(false, filepath.Dir(path), permFile, permDir); err != nil {
return err return err
} else if hf, e := os.Create(path); e != nil { }
// #nosec
hf, e := os.Create(path)
if e != nil {
return e return e
} else { } else {
_ = hf.Close() _ = hf.Close()

View File

@@ -72,6 +72,23 @@ func NewLDAP(ctx context.Context, cnf *Config, attributes []string) (*HelperLDAP
}, nil }, nil
} }
func (lc *HelperLDAP) Clone() *HelperLDAP {
var att = make([]string, 0)
copy(att, lc.Attributes)
return &HelperLDAP{
Attributes: att,
conn: nil,
config: lc.config.Clone(),
tlsConfig: lc.tlsConfig.Clone(),
tlsMode: lc.tlsMode,
bindDN: lc.bindDN,
bindPass: lc.bindPass,
ctx: lc.ctx,
log: lc.log,
}
}
// SetLogger is used to specify the logger to be used for debug messgae // SetLogger is used to specify the logger to be used for debug messgae
func (lc *HelperLDAP) SetLogger(fct liblog.FuncLog) { func (lc *HelperLDAP) SetLogger(fct liblog.FuncLog) {
lc.log = fct lc.log = fct
@@ -242,7 +259,7 @@ func (lc *HelperLDAP) tryConnect() (TLSMode, liberr.Error) {
defer func() { defer func() {
if l != nil { if l != nil {
l.Close() _ = l.Close()
} }
}() }()
@@ -306,7 +323,7 @@ func (lc *HelperLDAP) connect() liberr.Error {
l, err = lc.dialTLS() l, err = lc.dialTLS()
if err != nil { if err != nil {
if l != nil { if l != nil {
l.Close() _ = l.Close()
} }
return err return err
} }
@@ -316,7 +333,7 @@ func (lc *HelperLDAP) connect() liberr.Error {
l, err = lc.dial() l, err = lc.dial()
if err != nil { if err != nil {
if l != nil { if l != nil {
l.Close() _ = l.Close()
} }
return err return err
} }
@@ -326,7 +343,7 @@ func (lc *HelperLDAP) connect() liberr.Error {
err = lc.starttls(l) err = lc.starttls(l)
if err != nil { if err != nil {
if l != nil { if l != nil {
l.Close() _ = l.Close()
} }
return err return err
} }
@@ -348,7 +365,7 @@ func (lc *HelperLDAP) Check() liberr.Error {
if lc.conn == nil { if lc.conn == nil {
defer func() { defer func() {
if lc.conn != nil { if lc.conn != nil {
lc.conn.Close() _ = lc.conn.Close()
lc.conn = nil lc.conn = nil
} }
}() }()
@@ -369,7 +386,7 @@ func (lc *HelperLDAP) Close() {
} }
if lc.conn != nil { if lc.conn != nil {
lc.conn.Close() _ = lc.conn.Close()
lc.conn = nil lc.conn = nil
} }
} }

View File

@@ -99,7 +99,10 @@ func New(opt logcfg.OptionsFile, format logrus.Formatter) (HookFile, error) {
} }
} }
if h, e := os.OpenFile(opt.Filepath, flags, opt.FileMode); e != nil { // #nosec
h, e := os.OpenFile(opt.Filepath, flags, opt.FileMode)
if e != nil {
return nil, e return nil, e
} else if _, e = h.Seek(0, io.SeekEnd); e != nil { } else if _, e = h.Seek(0, io.SeekEnd); e != nil {
_ = h.Close() _ = h.Close()

View File

@@ -74,7 +74,10 @@ func (o *hkf) writeBuffer(buf *bytes.Buffer) error {
} }
}() }()
if h, e = os.OpenFile(p, f, m); e != nil { // #nosec
h, e = os.OpenFile(p, f, m)
if e != nil {
return e return e
} else if _, e = h.Seek(0, io.SeekEnd); e != nil { } else if _, e = h.Seek(0, io.SeekEnd); e != nil {
return e return e

View File

@@ -104,6 +104,7 @@ func (c Config) LogConfigJson() liberr.Error {
return ErrorConfigInvalidFilePath.Error(e) return ErrorConfigInvalidFilePath.Error(e)
} }
// #nosec
f, e := os.OpenFile(c.Logs.LogFile, os.O_APPEND|os.O_WRONLY, permFile) f, e := os.OpenFile(c.Logs.LogFile, os.O_APPEND|os.O_WRONLY, permFile)
if e != nil { if e != nil {
return ErrorConfigInvalidFilePath.Error(e) return ErrorConfigInvalidFilePath.Error(e)
@@ -1054,6 +1055,7 @@ func (c ConfigWebsocket) makeOpt(defTls libtls.TLSConfig) (natsrv.WebsocketOpts,
} }
} else { } else {
cfg.NoTLS = true cfg.NoTLS = true
// #nosec
cfg.TLSConfig = &tls.Config{} cfg.TLSConfig = &tls.Config{}
cfg.HandshakeTimeout = 0 cfg.HandshakeTimeout = 0
} }
@@ -1092,6 +1094,7 @@ func (c ConfigMQTT) makeOpt(defTls libtls.TLSConfig) (natsrv.MQTTOpts, liberr.Er
cfg.TLSTimeout = float64(c.TLSTimeout) / float64(time.Second) cfg.TLSTimeout = float64(c.TLSTimeout) / float64(time.Second)
} }
} else { } else {
// #nosec
cfg.TLSConfig = &tls.Config{} cfg.TLSConfig = &tls.Config{}
cfg.TLSTimeout = 0 cfg.TLSTimeout = 0
} }

View File

@@ -28,12 +28,19 @@
package protocol package protocol
import ( import (
"bytes"
"fmt" "fmt"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
const (
dblQuote = "\""
smpQuote = "'"
)
func (s *NetworkProtocol) unmarshall(val []byte) error { func (s *NetworkProtocol) unmarshall(val []byte) error {
val = bytes.Trim(bytes.Trim(val, smpQuote), dblQuote)
*s = ParseBytes(val) *s = ParseBytes(val)
return nil return nil
} }

View File

@@ -26,8 +26,8 @@
package password package password
import ( import (
"math/rand" "crypto/rand"
"time" "math/big"
) )
const letterBytes = "abcdefghijklmnopqrstuvwxyz,;:!?./*%^$&\"'(-_)=+~#{[|`\\^@]}ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" const letterBytes = "abcdefghijklmnopqrstuvwxyz,;:!?./*%^$&\"'(-_)=+~#{[|`\\^@]}ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
@@ -41,36 +41,32 @@ const (
loopRandMaxLen = 10 loopRandMaxLen = 10
) )
func randStringBytesMaskImprSrc(n int) string { func randIdx() int {
var src = rand.NewSource(time.Now().UnixNano()) size := int64(len(letterBytes))
for n := 0; n < 100; n++ {
if i, e := rand.Int(rand.Reader, big.NewInt(size+1)); e != nil {
return 0
} else {
j := i.Int64()
if j > 0 && j < size {
return int(j)
}
}
}
return 0
}
func Generate(n int) string {
b := make([]byte, n) b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters! // A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { for i := n - 1; i >= 0; {
if remain == 0 { b[i] = letterBytes[randIdx()]
cache, remain = src.Int63(), letterIdxMax i--
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
} }
return string(b) return string(b)
} }
// Generate Generate a random string could be used as password.
// The len is defined by given 'n' parameters.
func Generate(n int) string {
if n > loopRandMaxLen {
var s = ""
for i := n; i > 0; i -= loopRandMaxLen {
s += randStringBytesMaskImprSrc(loopRandMaxLen)
}
return s[0 : n-1]
}
return randStringBytesMaskImprSrc(n)
}

View File

@@ -41,7 +41,8 @@ const (
) )
var ( var (
_maxFloat = uint64(math.Ceil(math.MaxFloat64)) _maxFloat64 = uint64(math.Ceil(math.MaxFloat64))
_maxFloat32 = uint64(math.Ceil(math.MaxFloat32))
) )
func (s Size) String() string { func (s Size) String() string {
@@ -63,12 +64,48 @@ func (s Size) Int64() int64 {
return int64(s) return int64(s)
} }
func (s Size) Int32() int32 {
if uint64(s) > math.MaxInt32 {
// overflow
return math.MaxInt32
}
return int32(s)
}
func (s Size) Int() int {
if uint64(s) > math.MaxInt {
// overflow
return math.MaxInt
}
return int(s)
}
func (s Size) Uint64() uint64 { func (s Size) Uint64() uint64 {
return uint64(s) return uint64(s)
} }
func (s Size) Uint32() uint32 {
if uint64(s) > math.MaxUint32 {
// overflow
return math.MaxUint32
}
return uint32(s)
}
func (s Size) Uint() uint {
if uint64(s) > math.MaxUint {
// overflow
return math.MaxUint
}
return uint(s)
}
func (s Size) Float64() float64 { func (s Size) Float64() float64 {
if uint64(s) > _maxFloat { if uint64(s) > _maxFloat64 {
// overflow // overflow
return math.MaxFloat64 return math.MaxFloat64
} }
@@ -76,6 +113,15 @@ func (s Size) Float64() float64 {
return float64(s) return float64(s)
} }
func (s Size) Float32() float32 {
if uint64(s) > _maxFloat32 {
// overflow
return math.MaxFloat32
}
return float32(s)
}
func (s Size) Format(format string) string { func (s Size) Format(format string) string {
switch { switch {
case SizeExa.isMax(s): case SizeExa.isMax(s):

View File

@@ -27,6 +27,8 @@
package bytes package bytes
import "math"
type Size uint64 type Size uint64
const ( const (
@@ -65,6 +67,18 @@ func SizeFromInt64(val int64) Size {
return Size(v) return Size(v)
} }
func SizeFromFloat64(val float64) Size {
val = math.Floor(val)
if val > math.MaxUint64 {
return Size(uint64(math.MaxUint64))
} else if -val > math.MaxUint64 {
return Size(uint64(math.MaxUint64))
} else {
return Size(uint64(val))
}
}
func Parse(s string) (Size, error) { func Parse(s string) (Size, error) {
return parseString(s) return parseString(s)
} }

View File

@@ -69,10 +69,10 @@ func (s Size) isMax(size Size) bool {
} }
func (s Size) sizeByUnit(unit Size) float64 { func (s Size) sizeByUnit(unit Size) float64 {
if s > 0 && uint64(s/unit) > _maxFloat { if s > 0 && uint64(s/unit) > _maxFloat64 {
// overflow // overflow
return math.MaxFloat64 return math.MaxFloat64
} else if s < 0 && uint64(-s/unit) > _maxFloat { } else if s < 0 && uint64(-s/unit) > _maxFloat64 {
// overflow // overflow
return -math.MaxFloat64 return -math.MaxFloat64
} else { } else {

View File

@@ -28,9 +28,10 @@ package config
import ( import (
"os" "os"
"time"
libdur "github.com/nabbar/golib/duration"
libptc "github.com/nabbar/golib/network/protocol" libptc "github.com/nabbar/golib/network/protocol"
libsiz "github.com/nabbar/golib/size"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
scksrv "github.com/nabbar/golib/socket/server" scksrv "github.com/nabbar/golib/socket/server"
) )
@@ -39,17 +40,17 @@ type ServerConfig struct {
Network libptc.NetworkProtocol `` Network libptc.NetworkProtocol ``
Address string Address string
PermFile os.FileMode PermFile os.FileMode
BuffSizeRead int32 BuffSizeRead libsiz.Size
TimeoutRead time.Duration TimeoutRead libdur.Duration
TimeoutWrite time.Duration TimeoutWrite libdur.Duration
} }
func (o ServerConfig) New(handler libsck.Handler) (libsck.Server, error) { func (o ServerConfig) New(handler libsck.Handler) (libsck.Server, error) {
s, e := scksrv.New(handler, o.Network, o.BuffSizeRead, o.Address, o.PermFile) s, e := scksrv.New(handler, o.Network, o.BuffSizeRead, o.Address, o.PermFile)
if e != nil { if e != nil {
s.SetReadTimeout(o.TimeoutRead) s.SetReadTimeout(o.TimeoutRead.Time())
s.SetWriteTimeout(o.TimeoutWrite) s.SetWriteTimeout(o.TimeoutWrite.Time())
} }
return s, e return s, e

View File

@@ -31,6 +31,8 @@ import (
"io" "io"
"net" "net"
"time" "time"
libtls "github.com/nabbar/golib/certificates"
) )
const DefaultBufferSize = 32 * 1024 const DefaultBufferSize = 32 * 1024
@@ -48,7 +50,31 @@ const (
ConnectionClose ConnectionClose
) )
func (c ConnState) String() string {
switch c {
case ConnectionDial:
return "Dial Connection"
case ConnectionNew:
return "New Connection"
case ConnectionRead:
return "Read Incoming Stream"
case ConnectionCloseRead:
return "Close Incoming Stream"
case ConnectionHandler:
return "Run Handler"
case ConnectionWrite:
return "Write Outgoing Steam"
case ConnectionCloseWrite:
return "Close Outgoing Stream"
case ConnectionClose:
return "Close Connection"
}
return "unknown connection state"
}
type FuncError func(e error) type FuncError func(e error)
type FuncInfoSrv func(msg string)
type FuncInfo func(local, remote net.Addr, state ConnState) type FuncInfo func(local, remote net.Addr, state ConnState)
type Handler func(request io.Reader, response io.Writer) type Handler func(request io.Reader, response io.Writer)
type Response func(r io.Reader) type Response func(r io.Reader)
@@ -56,10 +82,12 @@ type Response func(r io.Reader)
type Server interface { type Server interface {
RegisterFuncError(f FuncError) RegisterFuncError(f FuncError)
RegisterFuncInfo(f FuncInfo) RegisterFuncInfo(f FuncInfo)
RegisterFuncInfoServer(f FuncInfoSrv)
SetReadTimeout(d time.Duration) SetReadTimeout(d time.Duration)
SetWriteTimeout(d time.Duration) SetWriteTimeout(d time.Duration)
SetTLS(enable bool, config libtls.TLSConfig) error
Listen(ctx context.Context) error Listen(ctx context.Context) error
Shutdown() Shutdown()
Done() <-chan struct{} Done() <-chan struct{}

View File

@@ -36,13 +36,14 @@ import (
"strings" "strings"
libptc "github.com/nabbar/golib/network/protocol" libptc "github.com/nabbar/golib/network/protocol"
libsiz "github.com/nabbar/golib/size"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
scksrt "github.com/nabbar/golib/socket/server/tcp" scksrt "github.com/nabbar/golib/socket/server/tcp"
scksru "github.com/nabbar/golib/socket/server/udp" scksru "github.com/nabbar/golib/socket/server/udp"
scksrx "github.com/nabbar/golib/socket/server/unix" scksrx "github.com/nabbar/golib/socket/server/unix"
) )
func New(handler libsck.Handler, proto libptc.NetworkProtocol, sizeBufferRead int32, address string, perm os.FileMode) (libsck.Server, error) { func New(handler libsck.Handler, proto libptc.NetworkProtocol, sizeBufferRead libsiz.Size, address string, perm os.FileMode) (libsck.Server, error) {
switch proto { switch proto {
case libptc.NetworkUnix: case libptc.NetworkUnix:
if strings.EqualFold(runtime.GOOS, "linux") { if strings.EqualFold(runtime.GOOS, "linux") {

View File

@@ -34,12 +34,13 @@ import (
"os" "os"
libptc "github.com/nabbar/golib/network/protocol" libptc "github.com/nabbar/golib/network/protocol"
libsiz "github.com/nabbar/golib/size"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
scksrt "github.com/nabbar/golib/socket/server/tcp" scksrt "github.com/nabbar/golib/socket/server/tcp"
scksru "github.com/nabbar/golib/socket/server/udp" scksru "github.com/nabbar/golib/socket/server/udp"
) )
func New(handler libsck.Handler, proto libptc.NetworkProtocol, sizeBufferRead int32, address string, perm os.FileMode) (libsck.Server, error) { func New(handler libsck.Handler, proto libptc.NetworkProtocol, sizeBufferRead libsiz.Size, address string, perm os.FileMode) (libsck.Server, error) {
switch proto { switch proto {
case libptc.NetworkTCP, libptc.NetworkTCP4, libptc.NetworkTCP6: case libptc.NetworkTCP, libptc.NetworkTCP4, libptc.NetworkTCP6:
s := scksrt.New(handler, sizeBufferRead) s := scksrt.New(handler, sizeBufferRead)

View File

@@ -29,6 +29,7 @@ package tcp
import ( import (
"sync/atomic" "sync/atomic"
libsiz "github.com/nabbar/golib/size"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
) )
@@ -37,7 +38,7 @@ type ServerTcp interface {
RegisterServer(address string) error RegisterServer(address string) error
} }
func New(h libsck.Handler, sizeBuffRead int32) ServerTcp { func New(h libsck.Handler, sizeBuffRead libsiz.Size) ServerTcp {
c := new(atomic.Value) c := new(atomic.Value)
c.Store(make(chan []byte)) c.Store(make(chan []byte))
@@ -48,17 +49,20 @@ func New(h libsck.Handler, sizeBuffRead int32) ServerTcp {
f.Store(h) f.Store(h)
sr := new(atomic.Int32) sr := new(atomic.Int32)
sr.Store(sizeBuffRead) sr.Store(sizeBuffRead.Int32())
return &srv{ return &srv{
l: nil, l: nil,
t: new(atomic.Value),
h: f, h: f,
c: c, c: c,
s: s, s: s,
e: new(atomic.Value), fe: new(atomic.Value),
i: new(atomic.Value), fi: new(atomic.Value),
fs: new(atomic.Value),
tr: new(atomic.Value), tr: new(atomic.Value),
tw: new(atomic.Value), tw: new(atomic.Value),
sr: sr, sr: sr,
ad: new(atomic.Value),
} }
} }

View File

@@ -29,6 +29,7 @@ package tcp
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/tls"
"io" "io"
"net" "net"
"net/url" "net/url"
@@ -83,7 +84,16 @@ func (o *srv) Listen(ctx context.Context) error {
if a == nil { if a == nil {
return ErrInvalidAddress return ErrInvalidAddress
} else if l, e = net.Listen(libptc.NetworkTCP.Code(), a.Host); e != nil { } else if t := o.getTLS(); t == nil {
o.fctInfoSrv("starting listening socket '%s %s'", libptc.NetworkTCP.String(), a.Host)
l, e = net.Listen(libptc.NetworkTCP.Code(), a.Host)
} else {
o.fctInfoSrv("starting listening socket 'TLS %s %s'", libptc.NetworkTCP.String(), a.Host)
l, e = tls.Listen(libptc.NetworkTCP.Code(), a.Host, t)
}
if e != nil {
o.fctError(e)
return e return e
} }

View File

@@ -27,12 +27,15 @@
package tcp package tcp
import ( import (
"crypto/tls"
"fmt"
"net" "net"
"net/url" "net/url"
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"time" "time"
libtls "github.com/nabbar/golib/certificates"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
) )
@@ -45,14 +48,21 @@ func init() {
close(closedChanStruct) close(closedChanStruct)
} }
type data struct {
data any
}
type srv struct { type srv struct {
l net.Listener l net.Listener
t *atomic.Value // tls config
h *atomic.Value // handler h *atomic.Value // handler
c *atomic.Value // chan []byte c *atomic.Value // chan []byte
s *atomic.Value // chan struct{} s *atomic.Value // chan struct{}
e *atomic.Value // function error
i *atomic.Value // function info fe *atomic.Value // function error
fi *atomic.Value // function info
fs *atomic.Value // function info server
tr *atomic.Value // connection read timeout tr *atomic.Value // connection read timeout
tw *atomic.Value // connection write timeout tw *atomic.Value // connection write timeout
@@ -81,12 +91,31 @@ func (o *srv) Shutdown() {
} }
} }
func (o *srv) SetTLS(enable bool, config libtls.TLSConfig) error {
if !enable {
// #nosec
o.t.Store(&tls.Config{})
return nil
}
if config == nil {
return fmt.Errorf("invalid tls config")
} else if l := config.GetCertificatePair(); len(l) < 1 {
return fmt.Errorf("invalid tls config, missing certificates pair")
} else if t := config.TlsConfig(""); t == nil {
return fmt.Errorf("invalid tls config")
} else {
o.t.Store(t)
return nil
}
}
func (o *srv) RegisterFuncError(f libsck.FuncError) { func (o *srv) RegisterFuncError(f libsck.FuncError) {
if o == nil { if o == nil {
return return
} }
o.e.Store(f) o.fe.Store(f)
} }
func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) { func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) {
@@ -94,7 +123,15 @@ func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) {
return return
} }
o.i.Store(f) o.fi.Store(f)
}
func (o *srv) RegisterFuncInfoServer(f libsck.FuncInfoSrv) {
if o == nil {
return
}
o.fs.Store(f)
} }
func (o *srv) SetReadTimeout(d time.Duration) { func (o *srv) SetReadTimeout(d time.Duration) {
@@ -137,7 +174,7 @@ func (o *srv) fctError(e error) {
return return
} }
v := o.e.Load() v := o.fe.Load()
if v != nil { if v != nil {
v.(libsck.FuncError)(e) v.(libsck.FuncError)(e)
} }
@@ -148,12 +185,23 @@ func (o *srv) fctInfo(local, remote net.Addr, state libsck.ConnState) {
return return
} }
v := o.i.Load() v := o.fi.Load()
if v != nil { if v != nil {
v.(libsck.FuncInfo)(local, remote, state) v.(libsck.FuncInfo)(local, remote, state)
} }
} }
func (o *srv) fctInfoSrv(msg string, args ...interface{}) {
if o == nil {
return
}
v := o.fs.Load()
if v != nil {
v.(libsck.FuncInfoSrv)(fmt.Sprintf(msg, args...))
}
}
func (o *srv) handler() libsck.Handler { func (o *srv) handler() libsck.Handler {
if o == nil { if o == nil {
return nil return nil
@@ -166,3 +214,17 @@ func (o *srv) handler() libsck.Handler {
return nil return nil
} }
func (o *srv) getTLS() *tls.Config {
i := o.t.Load()
if i == nil {
return nil
} else if t, k := i.(*tls.Config); !k {
return nil
} else if len(t.Certificates) < 1 {
return nil
} else {
return t
}
}

View File

@@ -29,6 +29,7 @@ package udp
import ( import (
"sync/atomic" "sync/atomic"
libsiz "github.com/nabbar/golib/size"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
) )
@@ -37,7 +38,7 @@ type ServerTcp interface {
RegisterServer(address string) error RegisterServer(address string) error
} }
func New(h libsck.Handler, sizeBuffRead int32) ServerTcp { func New(h libsck.Handler, sizeBuffRead libsiz.Size) ServerTcp {
c := new(atomic.Value) c := new(atomic.Value)
c.Store(make(chan []byte)) c.Store(make(chan []byte))
@@ -48,17 +49,19 @@ func New(h libsck.Handler, sizeBuffRead int32) ServerTcp {
f.Store(h) f.Store(h)
sr := new(atomic.Int32) sr := new(atomic.Int32)
sr.Store(sizeBuffRead) sr.Store(sizeBuffRead.Int32())
return &srv{ return &srv{
l: nil, l: nil,
h: f, h: f,
c: c, c: c,
s: s, s: s,
e: new(atomic.Value), fe: new(atomic.Value),
i: new(atomic.Value), fi: new(atomic.Value),
fs: new(atomic.Value),
tr: new(atomic.Value), tr: new(atomic.Value),
tw: new(atomic.Value), tw: new(atomic.Value),
sr: sr, sr: sr,
ad: new(atomic.Value),
} }
} }

View File

@@ -93,6 +93,7 @@ func (o *srv) Listen(ctx context.Context) error {
} }
} }
o.fctInfoSrv("starting listening socket 'TLS %s %s'", libptc.NetworkUDP.String(), a.Host)
defer fctClose() defer fctClose()
// Accept new connection or stop if context or shutdown trigger // Accept new connection or stop if context or shutdown trigger

View File

@@ -27,12 +27,14 @@
package udp package udp
import ( import (
"fmt"
"net" "net"
"net/url" "net/url"
"strconv" "strconv"
"sync/atomic" "sync/atomic"
"time" "time"
libtls "github.com/nabbar/golib/certificates"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
) )
@@ -51,8 +53,10 @@ type srv struct {
h *atomic.Value // handler h *atomic.Value // handler
c *atomic.Value // chan []byte c *atomic.Value // chan []byte
s *atomic.Value // chan struct{} s *atomic.Value // chan struct{}
e *atomic.Value // function error
i *atomic.Value // function info fe *atomic.Value // function error
fi *atomic.Value // function info
fs *atomic.Value // function info server
tr *atomic.Value // connection read timeout tr *atomic.Value // connection read timeout
tw *atomic.Value // connection write timeout tw *atomic.Value // connection write timeout
@@ -81,12 +85,16 @@ func (o *srv) Shutdown() {
} }
} }
func (o *srv) SetTLS(enable bool, config libtls.TLSConfig) error {
return nil
}
func (o *srv) RegisterFuncError(f libsck.FuncError) { func (o *srv) RegisterFuncError(f libsck.FuncError) {
if o == nil { if o == nil {
return return
} }
o.e.Store(f) o.fe.Store(f)
} }
func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) { func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) {
@@ -94,7 +102,15 @@ func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) {
return return
} }
o.i.Store(f) o.fi.Store(f)
}
func (o *srv) RegisterFuncInfoServer(f libsck.FuncInfoSrv) {
if o == nil {
return
}
o.fs.Store(f)
} }
func (o *srv) SetReadTimeout(d time.Duration) { func (o *srv) SetReadTimeout(d time.Duration) {
@@ -137,7 +153,7 @@ func (o *srv) fctError(e error) {
return return
} }
v := o.e.Load() v := o.fe.Load()
if v != nil { if v != nil {
v.(libsck.FuncError)(e) v.(libsck.FuncError)(e)
} }
@@ -148,12 +164,23 @@ func (o *srv) fctInfo(local, remote net.Addr, state libsck.ConnState) {
return return
} }
v := o.i.Load() v := o.fi.Load()
if v != nil { if v != nil {
v.(libsck.FuncInfo)(local, remote, state) v.(libsck.FuncInfo)(local, remote, state)
} }
} }
func (o *srv) fctInfoSrv(msg string, args ...interface{}) {
if o == nil {
return
}
v := o.fs.Load()
if v != nil {
v.(libsck.FuncInfoSrv)(fmt.Sprintf(msg, args...))
}
}
func (o *srv) handler() libsck.Handler { func (o *srv) handler() libsck.Handler {
if o == nil { if o == nil {
return nil return nil

View File

@@ -33,6 +33,7 @@ import (
"os" "os"
"sync/atomic" "sync/atomic"
libsiz "github.com/nabbar/golib/size"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
) )
@@ -41,7 +42,7 @@ type ServerUnix interface {
RegisterSocket(unixFile string, perm os.FileMode) RegisterSocket(unixFile string, perm os.FileMode)
} }
func New(h libsck.Handler, sizeBuffRead int32) ServerUnix { func New(h libsck.Handler, sizeBuffRead libsiz.Size) ServerUnix {
c := new(atomic.Value) c := new(atomic.Value)
c.Store(make(chan []byte)) c.Store(make(chan []byte))
@@ -51,26 +52,30 @@ func New(h libsck.Handler, sizeBuffRead int32) ServerUnix {
f := new(atomic.Value) f := new(atomic.Value)
f.Store(h) f.Store(h)
// socket read buff size
sr := new(atomic.Int32) sr := new(atomic.Int32)
sr.Store(sizeBuffRead) sr.Store(sizeBuffRead.Int32())
fp := new(atomic.Value) // socket file
fp.Store("") sf := new(atomic.Value)
sf.Store("")
pe := new(atomic.Int64) // socket permission
pe.Store(0) sp := new(atomic.Int64)
sp.Store(0)
return &srv{ return &srv{
l: nil, l: nil,
h: f, h: f,
c: c, c: c,
s: s, s: s,
e: new(atomic.Value), fe: new(atomic.Value),
i: new(atomic.Value), fi: new(atomic.Value),
fs: new(atomic.Value),
tr: new(atomic.Value), tr: new(atomic.Value),
tw: new(atomic.Value), tw: new(atomic.Value),
sr: sr, sr: sr,
fs: fp, sf: sf,
fp: pe, sp: sp,
} }
} }

View File

@@ -82,7 +82,7 @@ func (o *srv) buffRead() *bytes.Buffer {
} }
func (o *srv) getSocketFile() (string, error) { func (o *srv) getSocketFile() (string, error) {
f := o.fs.Load() f := o.sf.Load()
if f != nil { if f != nil {
return o.checkFile(f.(string)) return o.checkFile(f.(string))
} }
@@ -91,7 +91,7 @@ func (o *srv) getSocketFile() (string, error) {
} }
func (o *srv) getSocketPerm() os.FileMode { func (o *srv) getSocketPerm() os.FileMode {
p := o.fp.Load() p := o.sp.Load()
if p > 0 { if p > 0 {
return os.FileMode(p) return os.FileMode(p)
} }
@@ -149,6 +149,7 @@ func (o *srv) Listen(ctx context.Context) error {
} }
} }
o.fctInfoSrv("starting listening socket 'TLS %s %s'", libptc.NetworkUnix.String(), unixFile)
defer fctClose() defer fctClose()
if i.Mode() != perm { if i.Mode() != perm {

View File

@@ -30,11 +30,13 @@
package unix package unix
import ( import (
"fmt"
"net" "net"
"os" "os"
"sync/atomic" "sync/atomic"
"time" "time"
libtls "github.com/nabbar/golib/certificates"
libsck "github.com/nabbar/golib/socket" libsck "github.com/nabbar/golib/socket"
) )
@@ -53,14 +55,17 @@ type srv struct {
h *atomic.Value // handler h *atomic.Value // handler
c *atomic.Value // chan []byte c *atomic.Value // chan []byte
s *atomic.Value // chan struct{} s *atomic.Value // chan struct{}
e *atomic.Value // function error
i *atomic.Value // function info fe *atomic.Value // function error
fi *atomic.Value // function info
fs *atomic.Value // function info server
tr *atomic.Value // connection read timeout tr *atomic.Value // connection read timeout
tw *atomic.Value // connection write timeout tw *atomic.Value // connection write timeout
sr *atomic.Int32 // read buffer size sr *atomic.Int32 // read buffer size
fs *atomic.Value // file unix socket
fp *atomic.Int64 // file unix perm sf *atomic.Value // file unix socket
sp *atomic.Int64 // file unix perm
} }
func (o *srv) Done() <-chan struct{} { func (o *srv) Done() <-chan struct{} {
@@ -83,12 +88,16 @@ func (o *srv) Shutdown() {
} }
} }
func (o *srv) SetTLS(enable bool, config libtls.TLSConfig) error {
return nil
}
func (o *srv) RegisterFuncError(f libsck.FuncError) { func (o *srv) RegisterFuncError(f libsck.FuncError) {
if o == nil { if o == nil {
return return
} }
o.e.Store(f) o.fe.Store(f)
} }
func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) { func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) {
@@ -96,7 +105,15 @@ func (o *srv) RegisterFuncInfo(f libsck.FuncInfo) {
return return
} }
o.i.Store(f) o.fi.Store(f)
}
func (o *srv) RegisterFuncInfoServer(f libsck.FuncInfoSrv) {
if o == nil {
return
}
o.fs.Store(f)
} }
func (o *srv) SetReadTimeout(d time.Duration) { func (o *srv) SetReadTimeout(d time.Duration) {
@@ -116,8 +133,8 @@ func (o *srv) SetWriteTimeout(d time.Duration) {
} }
func (o *srv) RegisterSocket(unixFile string, perm os.FileMode) { func (o *srv) RegisterSocket(unixFile string, perm os.FileMode) {
o.fs.Store(unixFile) o.sf.Store(unixFile)
o.fp.Store(int64(perm)) o.sp.Store(int64(perm))
} }
func (o *srv) fctError(e error) { func (o *srv) fctError(e error) {
@@ -125,7 +142,7 @@ func (o *srv) fctError(e error) {
return return
} }
v := o.e.Load() v := o.fe.Load()
if v != nil { if v != nil {
v.(libsck.FuncError)(e) v.(libsck.FuncError)(e)
} }
@@ -136,12 +153,23 @@ func (o *srv) fctInfo(local, remote net.Addr, state libsck.ConnState) {
return return
} }
v := o.i.Load() v := o.fi.Load()
if v != nil { if v != nil {
v.(libsck.FuncInfo)(local, remote, state) v.(libsck.FuncInfo)(local, remote, state)
} }
} }
func (o *srv) fctInfoSrv(msg string, args ...interface{}) {
if o == nil {
return
}
v := o.fs.Load()
if v != nil {
v.(libsck.FuncInfoSrv)(fmt.Sprintf(msg, args...))
}
}
func (o *srv) handler() libsck.Handler { func (o *srv) handler() libsck.Handler {
if o == nil { if o == nil {
return nil return nil