mirror of
https://github.com/nabbar/golib.git
synced 2025-10-04 15:32:48 +08:00
Refactor package errors + packages names :
- Refactor ErrorType, list errors managment, codeError - Add interface Error with error interface implement - Add type CodeError assign typiclly to const that represent code of error - Add func to registry func to retrieve message from an uint16 codeError (typicaly a switch of each codeError const) - Add default errorCode with default errorMessage if no one code or message is found - Add modeError to manage how to manage compatibility between Error interface and error interface - Add Error interface that allow parent link (parent as error or Error interface), code and trace management - Add trace finder to allow find func/file/line caller when Error is call - Add http 2 transport in httpcli - Add http 2 transport in httpserver - Add function to get client http with timeout management in httpcli - Add function to get Error if occurs of http client in httpcli - Add test for smtp package - Chg return error by returning Error in all packages - Chg package njs-archive by archive - Chg package njs-certif by certificates - Chg package njs-console by console - Chg package njs-crypt by crypt - Chg package njs-errors by errors - Chg package njs-httpcli by httpcli - Chg package njs-httpserver by httpserver - Chg package njs-ioutils by ioutils - Chg package njs-ldap by ldap - Chg package njs-logger by logger - Chg package njs-password by password - Chg package njs-progress by progress - Chg package njs-router by router - Chg package njs-semaphore by semaphore - Chg package njs-smtp by smtp - Chg package njs-static by static - Chg package njs-status by status - Chg package njs-version by version - Fix dependancies gopkg by github/go-ldap for go module compatibility - Fix gin Abort call by gin Abort with Error in static package - Fix issue #18 in status package : replace partner by component - Fix go vet error - Del deprecated function - Del useless function & files - Bump dependancies - Apply CHG in README.md
This commit is contained in:
@@ -11,7 +11,7 @@ go get -u github.com/nabbar/golib/...
|
|||||||
|
|
||||||
second, import the needed lib in your code
|
second, import the needed lib in your code
|
||||||
```go
|
```go
|
||||||
import "github.com/nabbar/golib/njs-version"
|
import "github.com/nabbar/golib/version"
|
||||||
```
|
```
|
||||||
|
|
||||||
more information in each lib
|
more information in each lib
|
||||||
|
@@ -23,31 +23,30 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_archive
|
package archive
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/nabbar/golib/njs-archive/bz2"
|
"github.com/nabbar/golib/archive/bz2"
|
||||||
"github.com/nabbar/golib/njs-archive/gzip"
|
"github.com/nabbar/golib/archive/gzip"
|
||||||
"github.com/nabbar/golib/njs-archive/tar"
|
"github.com/nabbar/golib/archive/tar"
|
||||||
"github.com/nabbar/golib/njs-archive/zip"
|
"github.com/nabbar/golib/archive/zip"
|
||||||
|
|
||||||
//. "github.com/nabbar/golib/njs-logger"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
//. "github.com/nabbar/golib/logger"
|
||||||
|
|
||||||
iou "github.com/nabbar/golib/njs-ioutils"
|
iou "github.com/nabbar/golib/ioutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArchiveType uint8
|
type ArchiveType uint8
|
||||||
|
|
||||||
func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File, error) {
|
func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File, Error) {
|
||||||
var err error
|
|
||||||
|
|
||||||
loc := src.Name()
|
loc := src.Name()
|
||||||
|
|
||||||
if dst, err := bz2.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
if dst, err := bz2.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
||||||
//DebugLevel.Log("try deleting source archive...")
|
//DebugLevel.Log("try deleting source archive...")
|
||||||
if err = iou.DelTempFile(src, true); err != nil {
|
if err = iou.DelTempFile(src); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//DebugLevel.Log("try another archive...")
|
//DebugLevel.Log("try another archive...")
|
||||||
@@ -56,7 +55,7 @@ func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File,
|
|||||||
|
|
||||||
if dst, err := gzip.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
if dst, err := gzip.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
||||||
//DebugLevel.Log("try deleting source archive...")
|
//DebugLevel.Log("try deleting source archive...")
|
||||||
if err = iou.DelTempFile(src, true); err != nil {
|
if err = iou.DelTempFile(src); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//DebugLevel.Log("try another archive...")
|
//DebugLevel.Log("try another archive...")
|
||||||
@@ -65,7 +64,7 @@ func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File,
|
|||||||
|
|
||||||
if dst, err := tar.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
if dst, err := tar.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
||||||
//DebugLevel.Log("try deleting source archive...")
|
//DebugLevel.Log("try deleting source archive...")
|
||||||
if err = iou.DelTempFile(src, true); err != nil {
|
if err = iou.DelTempFile(src); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//DebugLevel.Log("try another archive...")
|
//DebugLevel.Log("try another archive...")
|
||||||
@@ -74,17 +73,24 @@ func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File,
|
|||||||
|
|
||||||
if dst, err := zip.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
if dst, err := zip.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
||||||
//DebugLevel.Log("try deleting source archive...")
|
//DebugLevel.Log("try deleting source archive...")
|
||||||
if err = iou.DelTempFile(src, true); err != nil {
|
if err = iou.DelTempFile(src); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//DebugLevel.Log("try another archive...")
|
//DebugLevel.Log("try another archive...")
|
||||||
return ExtractFile(dst, fileNameContain, fileNameRegex)
|
return ExtractFile(dst, fileNameContain, fileNameRegex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
if _, err = src.Seek(0, 0); err != nil {
|
if _, err = src.Seek(0, 0); err != nil {
|
||||||
|
e1 := FILE_SEEK.ErrorParent(err)
|
||||||
if src, err = os.Open(loc); err != nil {
|
if src, err = os.Open(loc); err != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "reopening file", err)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "reopening file", err)
|
||||||
return nil, err
|
e2 := FILE_OPEN.ErrorParent(err)
|
||||||
|
e2.AddParentError(e1)
|
||||||
|
return nil, e2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
52
archive/bz2/error.go
Normal file
52
archive/bz2/error.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 bz2
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Archive + 10
|
||||||
|
FILE_SEEK
|
||||||
|
IO_COPY
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case FILE_SEEK:
|
||||||
|
return "cannot seek into file"
|
||||||
|
case IO_COPY:
|
||||||
|
return "io copy occurs error"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -30,15 +30,16 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
//. "github.com/nabbar/golib/njs-logger"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
//. "github.com/nabbar/golib/logger"
|
||||||
|
|
||||||
iou "github.com/nabbar/golib/njs-ioutils"
|
iou "github.com/nabbar/golib/ioutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err error) {
|
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err Error) {
|
||||||
if _, e := src.Seek(0, 0); e != nil {
|
if _, e := src.Seek(0, 0); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
||||||
return nil, e
|
return nil, FILE_SEEK.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
r := bzip2.NewReader(src)
|
r := bzip2.NewReader(src)
|
||||||
@@ -46,12 +47,12 @@ func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File,
|
|||||||
if t, e := iou.NewTempFile(); e != nil {
|
if t, e := iou.NewTempFile(); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", e)
|
||||||
return nil, e
|
return nil, e
|
||||||
} else if _, e = io.Copy(t, r); e != nil {
|
} else if _, e := io.Copy(t, r); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", e)
|
||||||
return nil, e
|
return nil, IO_COPY.ErrorParent(e)
|
||||||
} else if _, e = t.Seek(0, 0); e != nil {
|
} else if _, e = t.Seek(0, 0); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
||||||
return nil, e
|
return nil, FILE_SEEK.ErrorParent(e)
|
||||||
} else {
|
} else {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
52
archive/error.go
Normal file
52
archive/error.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 archive
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Archive
|
||||||
|
FILE_SEEK
|
||||||
|
FILE_OPEN
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case FILE_SEEK:
|
||||||
|
return "cannot seek into file"
|
||||||
|
case FILE_OPEN:
|
||||||
|
return "cannot open file"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
55
archive/gzip/error.go
Normal file
55
archive/gzip/error.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 gzip
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Archive + 20
|
||||||
|
GZ_READER
|
||||||
|
FILE_SEEK
|
||||||
|
IO_COPY
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case GZ_READER:
|
||||||
|
return "cannot create new reader GZip"
|
||||||
|
case FILE_SEEK:
|
||||||
|
return "cannot seek into file"
|
||||||
|
case IO_COPY:
|
||||||
|
return "io copy occurs error"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -30,21 +30,22 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
//. "github.com/nabbar/golib/njs-logger"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
//. "github.com/nabbar/golib/logger"
|
||||||
|
|
||||||
iou "github.com/nabbar/golib/njs-ioutils"
|
iou "github.com/nabbar/golib/ioutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err error) {
|
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err Error) {
|
||||||
if _, e := src.Seek(0, 0); e != nil {
|
if _, e := src.Seek(0, 0); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
||||||
return nil, e
|
return nil, FILE_SEEK.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
r, e := gz.NewReader(src)
|
r, e := gz.NewReader(src)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init gzip reader", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "init gzip reader", e)
|
||||||
return nil, e
|
return nil, GZ_READER.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
@@ -52,12 +53,12 @@ func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File,
|
|||||||
if t, e := iou.NewTempFile(); e != nil {
|
if t, e := iou.NewTempFile(); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", e)
|
||||||
return nil, e
|
return nil, e
|
||||||
} else if _, e = io.Copy(t, r); e != nil {
|
} else if _, e := io.Copy(t, r); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", e)
|
||||||
return nil, e
|
return nil, IO_COPY.ErrorParent(e)
|
||||||
} else if _, e = t.Seek(0, 0); e != nil {
|
} else if _, e := t.Seek(0, 0); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
||||||
return nil, e
|
return nil, FILE_SEEK.ErrorParent(e)
|
||||||
} else {
|
} else {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
55
archive/tar/error.go
Normal file
55
archive/tar/error.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 tar
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Archive + 30
|
||||||
|
TAR_NEXT
|
||||||
|
FILE_SEEK
|
||||||
|
IO_COPY
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case TAR_NEXT:
|
||||||
|
return "cannot get next tar file"
|
||||||
|
case FILE_SEEK:
|
||||||
|
return "cannot seek into file"
|
||||||
|
case IO_COPY:
|
||||||
|
return "io copy occurs error"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -30,17 +30,18 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/nabbar/golib/njs-archive/archive"
|
"github.com/nabbar/golib/archive/archive"
|
||||||
|
|
||||||
//. "github.com/nabbar/golib/njs-logger"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
//. "github.com/nabbar/golib/logger"
|
||||||
|
|
||||||
iou "github.com/nabbar/golib/njs-ioutils"
|
iou "github.com/nabbar/golib/ioutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err error) {
|
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err Error) {
|
||||||
if _, e := src.Seek(0, 0); e != nil {
|
if _, e := src.Seek(0, 0); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
||||||
return nil, e
|
return nil, FILE_SEEK.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
r := tar.NewReader(src)
|
r := tar.NewReader(src)
|
||||||
@@ -52,7 +53,7 @@ func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File,
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
} else if e != nil {
|
} else if e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to read next file", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to read next file", e)
|
||||||
return nil, e
|
return nil, TAR_NEXT.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.FileInfo().Mode()&os.ModeType == os.ModeType {
|
if h.FileInfo().Mode()&os.ModeType == os.ModeType {
|
||||||
@@ -64,12 +65,12 @@ func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File,
|
|||||||
if t, e := iou.NewTempFile(); e != nil {
|
if t, e := iou.NewTempFile(); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", e)
|
||||||
return nil, e
|
return nil, e
|
||||||
} else if _, e = io.Copy(t, r); e != nil {
|
} else if _, e := io.Copy(t, r); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", e)
|
||||||
return nil, e
|
return nil, IO_COPY.ErrorParent(e)
|
||||||
} else if _, e = t.Seek(0, 0); e != nil {
|
} else if _, e := t.Seek(0, 0); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
||||||
return nil, e
|
return nil, FILE_SEEK.ErrorParent(e)
|
||||||
} else {
|
} else {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
61
archive/zip/error.go
Normal file
61
archive/zip/error.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 zip
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Archive + 40
|
||||||
|
FILE_OPEN
|
||||||
|
FILE_CLOSE
|
||||||
|
FILE_SEEK
|
||||||
|
IO_COPY
|
||||||
|
ZIP_OPEN
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case FILE_OPEN:
|
||||||
|
return "cannot open zipped file"
|
||||||
|
case FILE_CLOSE:
|
||||||
|
return "closing file occurs error"
|
||||||
|
case FILE_SEEK:
|
||||||
|
return "cannot seek into file"
|
||||||
|
case IO_COPY:
|
||||||
|
return "io copy occurs error"
|
||||||
|
case ZIP_OPEN:
|
||||||
|
return "cannot open zip file"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -30,25 +30,26 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
//. "github.com/nabbar/golib/njs-logger"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
//. "github.com/nabbar/golib/logger"
|
||||||
|
|
||||||
iou "github.com/nabbar/golib/njs-ioutils"
|
iou "github.com/nabbar/golib/ioutils"
|
||||||
|
|
||||||
"github.com/nabbar/golib/njs-archive/archive"
|
"github.com/nabbar/golib/archive/archive"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err error) {
|
func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File, err Error) {
|
||||||
location := iou.GetTempFilePath(src)
|
location := iou.GetTempFilePath(src)
|
||||||
|
|
||||||
if err = src.Close(); err != nil {
|
if e := src.Close(); err != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to close temp file", err)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to close temp file", err)
|
||||||
return
|
return dst, FILE_CLOSE.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFile(location, filenameContain, filenameRegex)
|
return getFile(location, filenameContain, filenameRegex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFile(src string, filenameContain, filenameRegex string) (dst *os.File, err error) {
|
func getFile(src string, filenameContain, filenameRegex string) (dst *os.File, err Error) {
|
||||||
var (
|
var (
|
||||||
r *zip.ReadCloser
|
r *zip.ReadCloser
|
||||||
e error
|
e error
|
||||||
@@ -56,10 +57,12 @@ func getFile(src string, filenameContain, filenameRegex string) (dst *os.File, e
|
|||||||
|
|
||||||
if r, e = zip.OpenReader(src); e != nil {
|
if r, e = zip.OpenReader(src); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to open zip file", e)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to open zip file", e)
|
||||||
return nil, e
|
return nil, ZIP_OPEN.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer r.Close()
|
defer func() {
|
||||||
|
_ = r.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
for _, f := range r.File {
|
for _, f := range r.File {
|
||||||
if f.Mode()&os.ModeType == os.ModeType {
|
if f.Mode()&os.ModeType == os.ModeType {
|
||||||
@@ -75,25 +78,30 @@ func getFile(src string, filenameContain, filenameRegex string) (dst *os.File, e
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extratFile(f *zip.File) (dst *os.File, err error) {
|
func extratFile(f *zip.File) (dst *os.File, err Error) {
|
||||||
var r io.ReadCloser
|
var (
|
||||||
|
r io.ReadCloser
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
if r, err = f.Open(); err != nil {
|
if r, e = f.Open(); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "open zipped file reader", err)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "open zipped file reader", err)
|
||||||
return
|
return dst, FILE_OPEN.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer r.Close()
|
defer func() {
|
||||||
|
_ = r.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
if dst, err = iou.NewTempFile(); err != nil {
|
if dst, err = iou.NewTempFile(); err != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", err)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", err)
|
||||||
return
|
return
|
||||||
} else if _, err = io.Copy(dst, r); err != nil {
|
} else if _, e = io.Copy(dst, r); e != nil {
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", err)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "copy buffer from archive reader", err)
|
||||||
return
|
return dst, IO_COPY.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dst.Seek(0, 0)
|
_, e = dst.Seek(0, 0)
|
||||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", err)
|
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", err)
|
||||||
return
|
return dst, FILE_SEEK.ErrorParent(e)
|
||||||
}
|
}
|
61
certificates/error.go
Normal file
61
certificates/error.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 certificates
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Certif
|
||||||
|
FILE_STAT_ERROR
|
||||||
|
FILE_READ_ERROR
|
||||||
|
CERT_APPEND_KO
|
||||||
|
CERT_LOAD_KEYPAIR
|
||||||
|
CERT_PARSE_KEYPAIR
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case FILE_STAT_ERROR:
|
||||||
|
return "cannot get file stat"
|
||||||
|
case FILE_READ_ERROR:
|
||||||
|
return "cannot read file"
|
||||||
|
case CERT_APPEND_KO:
|
||||||
|
return "cannot append PEM file"
|
||||||
|
case CERT_LOAD_KEYPAIR:
|
||||||
|
return "cannot X509 parsing certificate string"
|
||||||
|
case CERT_PARSE_KEYPAIR:
|
||||||
|
return "cannot x509 loading certificate file"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_certif
|
package certificates
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
logger "github.com/nabbar/golib/njs-logger"
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -40,6 +40,7 @@ var (
|
|||||||
certificates = make([]tls.Certificate, 0)
|
certificates = make([]tls.Certificate, 0)
|
||||||
caCertificates = x509.NewCertPool()
|
caCertificates = x509.NewCertPool()
|
||||||
tlsMinVersion uint16 = tls.VersionTLS12
|
tlsMinVersion uint16 = tls.VersionTLS12
|
||||||
|
tlsMaxVersion uint16 = tls.VersionTLS12
|
||||||
cipherList = []uint16{
|
cipherList = []uint16{
|
||||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||||
@@ -76,21 +77,26 @@ func AddRootCAContents(rootContent string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddRootCAFile(rootFile string) bool {
|
func AddRootCAFile(rootFile string) Error {
|
||||||
if rootFile == "" {
|
if rootFile == "" {
|
||||||
return false
|
return EMPTY_PARAMS.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, e := os.Stat(rootFile); logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "checking certificates file '%s'", e, rootFile) {
|
if _, e := os.Stat(rootFile); e != nil {
|
||||||
return false
|
return FILE_STAT_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
c, e := ioutil.ReadFile(rootFile) // #nosec
|
c, e := ioutil.ReadFile(rootFile) // #nosec
|
||||||
if !logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "loading certificates file '%s'", e, rootFile) {
|
|
||||||
return rootCA.AppendCertsFromPEM(c)
|
if e == nil {
|
||||||
|
if rootCA.AppendCertsFromPEM(c) {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return CERT_APPEND_KO.Error(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return FILE_READ_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddCACertificateContents(caContent string) bool {
|
func AddCACertificateContents(caContent string) bool {
|
||||||
@@ -101,61 +107,68 @@ func AddCACertificateContents(caContent string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddCACertificateFile(caFile string) bool {
|
func AddCACertificateFile(caFile string) Error {
|
||||||
if caFile == "" {
|
if caFile == "" {
|
||||||
return false
|
return EMPTY_PARAMS.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, e := os.Stat(caFile); logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "checking certificates file '%s'", e, caFile) {
|
if _, e := os.Stat(caFile); e != nil {
|
||||||
return false
|
return FILE_STAT_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
c, e := ioutil.ReadFile(caFile) // #nosec
|
c, e := ioutil.ReadFile(caFile) // #nosec
|
||||||
if !logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "loading certificates file '%s'", e, caFile) {
|
|
||||||
return caCertificates.AppendCertsFromPEM(c)
|
if e == nil {
|
||||||
|
if caCertificates.AppendCertsFromPEM(c) {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return CERT_APPEND_KO.Error(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return FILE_READ_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckCertificates() bool {
|
func CheckCertificates() bool {
|
||||||
return len(certificates) > 0
|
return len(certificates) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddCertificateContents(keyContents, certContents string) bool {
|
func AddCertificateContents(keyContents, certContents string) Error {
|
||||||
keyContents = strings.TrimSpace(keyContents)
|
keyContents = strings.TrimSpace(keyContents)
|
||||||
certContents = strings.TrimSpace(certContents)
|
certContents = strings.TrimSpace(certContents)
|
||||||
|
|
||||||
if keyContents != "" && keyContents != "\n" && certContents != "" && certContents != "\n" {
|
if keyContents != "" && keyContents != "\n" && certContents != "" && certContents != "\n" {
|
||||||
c, err := tls.X509KeyPair([]byte(certContents), []byte(keyContents))
|
c, err := tls.X509KeyPair([]byte(certContents), []byte(keyContents))
|
||||||
if !logger.ErrorLevel.LogErrorCtx(logger.InfoLevel, "loading certificates contents", err) {
|
if err == nil {
|
||||||
certificates = append(certificates, c)
|
certificates = append(certificates, c)
|
||||||
return true
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return CERT_PARSE_KEYPAIR.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddCertificateFile(keyFile, certFile string) bool {
|
return EMPTY_PARAMS.Error(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddCertificateFile(keyFile, certFile string) Error {
|
||||||
if keyFile == "" || certFile == "" {
|
if keyFile == "" || certFile == "" {
|
||||||
return false
|
return EMPTY_PARAMS.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, e := os.Stat(keyFile); logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "loading certificates file '%s'", e, keyFile) {
|
if _, e := os.Stat(keyFile); e != nil {
|
||||||
return false
|
return FILE_STAT_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, e := os.Stat(certFile); logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "loading certificates file '%s'", e, certFile) {
|
if _, e := os.Stat(certFile); e != nil {
|
||||||
return false
|
return FILE_STAT_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c, e := tls.LoadX509KeyPair(certFile, keyFile); !logger.ErrorLevel.LogErrorCtx(logger.InfoLevel, "loading X509 Pair file", e) {
|
if c, e := tls.LoadX509KeyPair(certFile, keyFile); e == nil {
|
||||||
certificates = append(certificates, c)
|
certificates = append(certificates, c)
|
||||||
return true
|
return nil
|
||||||
|
} else {
|
||||||
|
return CERT_LOAD_KEYPAIR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCertificates() []tls.Certificate {
|
func GetCertificates() []tls.Certificate {
|
||||||
@@ -178,29 +191,30 @@ func GetClientCA() *x509.CertPool {
|
|||||||
return caCertificates
|
return caCertificates
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetStringTlsVersion(tlsVersStr string) {
|
func SetVersionMin(vers uint16) {
|
||||||
|
tlsMinVersion = vers
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetVersionMax(vers uint16) {
|
||||||
|
tlsMaxVersion = vers
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetStringTlsVersion(tlsVersStr string) uint16 {
|
||||||
tlsVersStr = strings.ToLower(tlsVersStr)
|
tlsVersStr = strings.ToLower(tlsVersStr)
|
||||||
tlsVersStr = strings.Replace(tlsVersStr, "TLS", "", -1)
|
tlsVersStr = strings.Replace(tlsVersStr, "TLS", "", -1)
|
||||||
tlsVersStr = strings.TrimSpace(tlsVersStr)
|
tlsVersStr = strings.TrimSpace(tlsVersStr)
|
||||||
|
|
||||||
switch tlsVersStr {
|
switch tlsVersStr {
|
||||||
case "1", "1.0":
|
case "1", "1.0":
|
||||||
tlsMinVersion = tls.VersionTLS10
|
return tls.VersionTLS10
|
||||||
case "1.1":
|
case "1.1":
|
||||||
tlsMinVersion = tls.VersionTLS11
|
return tls.VersionTLS11
|
||||||
|
case "1.2":
|
||||||
|
return tls.VersionTLS12
|
||||||
|
case "1.3":
|
||||||
|
return tls.VersionTLS13
|
||||||
default:
|
default:
|
||||||
tlsMinVersion = tls.VersionTLS12
|
return tls.VersionTLS12
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetTlsVersion(tlsVers uint16) {
|
|
||||||
switch tlsVers {
|
|
||||||
case tls.VersionTLS10:
|
|
||||||
tlsMinVersion = tls.VersionTLS10
|
|
||||||
case tls.VersionTLS11:
|
|
||||||
tlsMinVersion = tls.VersionTLS11
|
|
||||||
default:
|
|
||||||
tlsMinVersion = tls.VersionTLS12
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,10 +301,17 @@ func GetTLSConfig(serverName string) *tls.Config {
|
|||||||
cnf := &tls.Config{
|
cnf := &tls.Config{
|
||||||
RootCAs: rootCA,
|
RootCAs: rootCA,
|
||||||
ClientCAs: caCertificates,
|
ClientCAs: caCertificates,
|
||||||
MinVersion: tlsMinVersion,
|
|
||||||
InsecureSkipVerify: false,
|
InsecureSkipVerify: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tlsMinVersion > 0 {
|
||||||
|
cnf.MinVersion = tlsMinVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
if tlsMaxVersion > 0 {
|
||||||
|
cnf.MaxVersion = tlsMaxVersion
|
||||||
|
}
|
||||||
|
|
||||||
if serverName != "" {
|
if serverName != "" {
|
||||||
cnf.ServerName = serverName
|
cnf.ServerName = serverName
|
||||||
}
|
}
|
||||||
@@ -326,8 +347,9 @@ func GetTlsConfigCertificates() *tls.Config {
|
|||||||
cnf.ClientAuth = clientAuth
|
cnf.ClientAuth = clientAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cnf.Certificates) > 0 {
|
||||||
cnf.Certificates = certificates
|
cnf.Certificates = certificates
|
||||||
cnf.BuildNameToCertificate()
|
}
|
||||||
|
|
||||||
return cnf
|
return cnf
|
||||||
}
|
}
|
@@ -23,13 +23,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_console
|
package console
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type colorType uint8
|
type colorType uint8
|
||||||
@@ -84,13 +86,28 @@ func (c colorType) Print(text string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c colorType) BuffPrintf(buff *bufio.ReadWriter, format string, args ...interface{}) (n int, err error) {
|
func (c colorType) BuffPrintf(buff *bufio.ReadWriter, format string, args ...interface{}) (n int, err Error) {
|
||||||
if colorList[c] != nil && buff != nil {
|
if colorList[c] != nil && buff != nil {
|
||||||
return colorList[c].Fprintf(buff, format, args...) // #nosec
|
|
||||||
|
i, e := colorList[c].Fprintf(buff, format, args...) // #nosec
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return i, COLOR_IO_FRINTF.ErrorParent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, nil
|
||||||
|
|
||||||
} else if buff != nil {
|
} else if buff != nil {
|
||||||
return buff.Write([]byte(fmt.Sprintf(format, args...)))
|
|
||||||
|
i, e := buff.Write([]byte(fmt.Sprintf(format, args...)))
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return i, COLOR_BUFF_WRITE.ErrorParent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, nil
|
||||||
} else {
|
} else {
|
||||||
return 0, fmt.Errorf("buffer is not defined")
|
return 0, COLOR_BUFF_UNDEFINED.Error(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
55
console/error.go
Normal file
55
console/error.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 console
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Console
|
||||||
|
COLOR_IO_FRINTF
|
||||||
|
COLOR_BUFF_WRITE
|
||||||
|
COLOR_BUFF_UNDEFINED
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case COLOR_IO_FRINTF:
|
||||||
|
return "cannot write on IO"
|
||||||
|
case COLOR_BUFF_WRITE:
|
||||||
|
return "cannot write on buffer"
|
||||||
|
case COLOR_BUFF_UNDEFINED:
|
||||||
|
return "buffer is not defined"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_console
|
package console
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_console
|
package console
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
@@ -23,15 +23,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_crypt
|
package crypt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
"io"
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -39,20 +41,22 @@ var (
|
|||||||
cryptNonce = make([]byte, 12)
|
cryptNonce = make([]byte, 12)
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetKeyHex(key, nonce string) error {
|
func SetKeyHex(key, nonce string) Error {
|
||||||
var err error
|
var err error
|
||||||
// Load your secret key from a safe place and reuse it across multiple
|
// Load your secret key from a safe place and reuse it across multiple
|
||||||
// Seal/Open calls. (Obviously don't use this example key for anything
|
// Seal/Open calls. (Obviously don't use this example key for anything
|
||||||
// real.) If you want to convert a passphrase to a key, use a suitable
|
// real.) If you want to convert a passphrase to a key, use a suitable
|
||||||
// package like bcrypt or scrypt.
|
// package like bcrypt or scrypt.
|
||||||
cryptKey, err = hex.DecodeString(key)
|
cryptKey, err = hex.DecodeString(key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("converting hexa key error : %v", err)
|
return HEXA_KEY.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cryptNonce, err = hex.DecodeString(nonce)
|
cryptNonce, err = hex.DecodeString(nonce)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("converting hexa nonce error : %v", err)
|
return HEXA_NONCE.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -63,51 +67,55 @@ func SetKeyByte(key [32]byte, nonce [12]byte) {
|
|||||||
cryptNonce = nonce[:]
|
cryptNonce = nonce[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenKeyByte() ([]byte, []byte, error) {
|
func GenKeyByte() ([]byte, []byte, Error) {
|
||||||
// Never use more than 2^32 random key with a given key because of the risk of a repeat.
|
// Never use more than 2^32 random key with a given key because of the risk of a repeat.
|
||||||
if _, err := io.ReadFull(rand.Reader, cryptKey); err != nil {
|
if _, err := io.ReadFull(rand.Reader, cryptKey); err != nil {
|
||||||
return make([]byte, 32), make([]byte, 12), fmt.Errorf("key generate error : %v", err)
|
return make([]byte, 32), make([]byte, 12), BYTE_KEYGEN.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never use more than 2^32 random nonces with a given key because of the risk of a repeat.
|
// Never use more than 2^32 random nonces with a given key because of the risk of a repeat.
|
||||||
if _, err := io.ReadFull(rand.Reader, cryptNonce); err != nil {
|
if _, err := io.ReadFull(rand.Reader, cryptNonce); err != nil {
|
||||||
return make([]byte, 32), make([]byte, 12), fmt.Errorf("nonce generate error : %v", err)
|
return make([]byte, 32), make([]byte, 12), BYTE_NONCEGEN.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cryptKey, cryptNonce, nil
|
return cryptKey, cryptNonce, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Encrypt(clearValue []byte) (string, error) {
|
func Encrypt(clearValue []byte) (string, Error) {
|
||||||
// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
|
// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
|
||||||
block, err := aes.NewCipher(cryptKey)
|
block, err := aes.NewCipher(cryptKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("init AES block error : %v", err)
|
return "", AES_BLOCK.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("AES GSM cipher init : %v", err)
|
return "", AES_GCM.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hex.EncodeToString(aesgcm.Seal(nil, cryptNonce, clearValue, nil)), nil
|
return hex.EncodeToString(aesgcm.Seal(nil, cryptNonce, clearValue, nil)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Decrypt(hexaVal string) ([]byte, error) {
|
func Decrypt(hexaVal string) ([]byte, Error) {
|
||||||
// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
|
// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
|
||||||
ciphertext, err := hex.DecodeString(hexaVal)
|
ciphertext, err := hex.DecodeString(hexaVal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("hexa decode crypted value error : %v", err)
|
return nil, HEXA_DECODE.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := aes.NewCipher(cryptKey)
|
block, err := aes.NewCipher(cryptKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("AES block init error : %v", err)
|
return nil, AES_BLOCK.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("AES GSM cipher init error : %v", err)
|
return nil, AES_GCM.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return aesgcm.Open(nil, cryptNonce, ciphertext, nil)
|
if res, err := aesgcm.Open(nil, cryptNonce, ciphertext, nil); err != nil {
|
||||||
|
return res, AES_DECRYPT.ErrorParent(err)
|
||||||
|
} else {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
}
|
}
|
70
crypt/error.go
Normal file
70
crypt/error.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 crypt
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Crypt
|
||||||
|
HEXA_DECODE
|
||||||
|
HEXA_KEY
|
||||||
|
HEXA_NONCE
|
||||||
|
BYTE_KEYGEN
|
||||||
|
BYTE_NONCEGEN
|
||||||
|
AES_BLOCK
|
||||||
|
AES_GCM
|
||||||
|
AES_DECRYPT
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case HEXA_DECODE:
|
||||||
|
return "hexa decode error"
|
||||||
|
case HEXA_KEY:
|
||||||
|
return "converting hexa key error"
|
||||||
|
case HEXA_NONCE:
|
||||||
|
return "converting hexa nonce error"
|
||||||
|
case BYTE_KEYGEN:
|
||||||
|
return "key generate error"
|
||||||
|
case BYTE_NONCEGEN:
|
||||||
|
return "nonce generate error"
|
||||||
|
case AES_BLOCK:
|
||||||
|
return "init AES block error"
|
||||||
|
case AES_GCM:
|
||||||
|
return "init AES GCM error"
|
||||||
|
case AES_DECRYPT:
|
||||||
|
return "decrypt AES GCM error"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
88
errors/code.go
Normal file
88
errors/code.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 errors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var msgfct = make([]Message, 0)
|
||||||
|
|
||||||
|
type Message func(code CodeError) (message string)
|
||||||
|
type CodeError uint16
|
||||||
|
|
||||||
|
const UNK_ERROR CodeError = 0
|
||||||
|
const UNK_MESSAGE = "unknown error"
|
||||||
|
|
||||||
|
func (c CodeError) GetUint16() uint16 {
|
||||||
|
return uint16(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) GetInt() int {
|
||||||
|
return int(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) GetString() string {
|
||||||
|
return strconv.Itoa(c.GetInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) GetMessage() string {
|
||||||
|
if c == UNK_ERROR {
|
||||||
|
return UNK_MESSAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range msgfct {
|
||||||
|
m := f(c)
|
||||||
|
if m != "" {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNK_MESSAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) Error(p Error) Error {
|
||||||
|
return NewError(c.GetUint16(), c.GetMessage(), p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) ErrorParent(p ...error) Error {
|
||||||
|
e := c.Error(nil)
|
||||||
|
e.AddParent(p...)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) IfError(e Error) Error {
|
||||||
|
return NewErrorIfError(c.GetUint16(), c.GetMessage(), e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CodeError) Iferror(e error) Error {
|
||||||
|
return NewErrorIferror(c.GetUint16(), c.GetMessage(), e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterFctMessage(fct Message) {
|
||||||
|
msgfct = append(msgfct, fct)
|
||||||
|
}
|
397
errors/errors.go
Normal file
397
errors/errors.go
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 errors
|
||||||
|
|
||||||
|
import (
|
||||||
|
errs "errors"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultGlue = ", "
|
||||||
|
defaultPattern = "[Error #%s] %s"
|
||||||
|
defaultPatternTrace = "[Error #%s] %s (%s)"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetDefaultGlue(glue string) {
|
||||||
|
defaultGlue = glue
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultGlue() string {
|
||||||
|
return defaultGlue
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDefaultPattern(pattern string) {
|
||||||
|
defaultPattern = pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultPattern() string {
|
||||||
|
return defaultPattern
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDefaultPatternTrace(patternTrace string) {
|
||||||
|
defaultPatternTrace = patternTrace
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultPatternTrace() string {
|
||||||
|
return defaultPatternTrace
|
||||||
|
}
|
||||||
|
|
||||||
|
type errors struct {
|
||||||
|
c uint16
|
||||||
|
e string
|
||||||
|
p []Error
|
||||||
|
t runtime.Frame
|
||||||
|
}
|
||||||
|
|
||||||
|
type Error interface {
|
||||||
|
IsCodeError(code CodeError) bool
|
||||||
|
HasCodeError(code CodeError) bool
|
||||||
|
|
||||||
|
IsError(e error) bool
|
||||||
|
HasError(err error) bool
|
||||||
|
|
||||||
|
AddParent(parent ...error)
|
||||||
|
SetParent(parent ...error)
|
||||||
|
AddParentError(parent ...Error)
|
||||||
|
SetParentError(parent ...Error)
|
||||||
|
|
||||||
|
Code() string
|
||||||
|
CodeFull(glue string) string
|
||||||
|
CodeSlice() []string
|
||||||
|
|
||||||
|
CodeError(pattern string) string
|
||||||
|
CodeErrorFull(pattern, glue string) string
|
||||||
|
CodeErrorSlice(pattern string) []string
|
||||||
|
|
||||||
|
CodeErrorTrace(pattern string) string
|
||||||
|
CodeErrorTraceFull(pattern, glue string) string
|
||||||
|
CodeErrorTraceSlice(pattern string) []string
|
||||||
|
|
||||||
|
Error() string
|
||||||
|
|
||||||
|
StringError() string
|
||||||
|
StringErrorFull(glue string) string
|
||||||
|
StringErrorSlice() []string
|
||||||
|
|
||||||
|
GetError() error
|
||||||
|
GetErrorFull(glue string) error
|
||||||
|
GetErrorSlice() []error
|
||||||
|
|
||||||
|
GetIError() Error
|
||||||
|
GetIErrorSlice() []Error
|
||||||
|
|
||||||
|
GetTrace() string
|
||||||
|
GetTraceSlice() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeErrorIfError(err ...Error) Error {
|
||||||
|
var e Error = nil
|
||||||
|
|
||||||
|
for _, p := range err {
|
||||||
|
if p == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if e == nil {
|
||||||
|
e = p
|
||||||
|
} else {
|
||||||
|
e.AddParentError(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewError(code uint16, message string, parent Error) Error {
|
||||||
|
if parent == nil {
|
||||||
|
parent = &errors{
|
||||||
|
c: 0,
|
||||||
|
e: "",
|
||||||
|
p: make([]Error, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &errors{
|
||||||
|
c: code,
|
||||||
|
e: message,
|
||||||
|
p: parent.GetIErrorSlice(),
|
||||||
|
t: getFrame(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrorIferror(code uint16, message string, parent error) Error {
|
||||||
|
if parent == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
p := make([]Error, 0)
|
||||||
|
p = append(p, &errors{
|
||||||
|
c: 0,
|
||||||
|
e: parent.Error(),
|
||||||
|
p: nil,
|
||||||
|
})
|
||||||
|
|
||||||
|
return &errors{
|
||||||
|
c: code,
|
||||||
|
e: message,
|
||||||
|
p: p,
|
||||||
|
t: getFrame(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrorIfError(code uint16, message string, parent Error) Error {
|
||||||
|
if parent == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &errors{
|
||||||
|
c: code,
|
||||||
|
e: message,
|
||||||
|
p: parent.GetIErrorSlice(),
|
||||||
|
t: getFrame(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) AddParent(parent ...error) {
|
||||||
|
for _, v := range parent {
|
||||||
|
|
||||||
|
if v == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
e.p = append(e.p, &errors{
|
||||||
|
c: 0,
|
||||||
|
e: v.Error(),
|
||||||
|
p: nil,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) IsCodeError(code CodeError) bool {
|
||||||
|
return e.c == code.GetUint16()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) IsError(err error) bool {
|
||||||
|
return e.e == err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) HasCodeError(code CodeError) bool {
|
||||||
|
if e.IsCodeError(code) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range e.p {
|
||||||
|
if p.IsCodeError(code) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) HasError(err error) bool {
|
||||||
|
if e.IsError(err) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range e.p {
|
||||||
|
if p.IsError(err) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) SetParent(parent ...error) {
|
||||||
|
e.p = make([]Error, 0)
|
||||||
|
e.AddParent(parent...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) AddParentError(parent ...Error) {
|
||||||
|
e.p = append(e.p, parent...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) SetParentError(parent ...Error) {
|
||||||
|
e.p = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) Code() string {
|
||||||
|
return strconv.Itoa(int(e.c))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeFull(glue string) string {
|
||||||
|
if glue == "" {
|
||||||
|
glue = defaultGlue
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(e.CodeSlice(), glue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeSlice() []string {
|
||||||
|
var r = []string{e.Code()}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
r = append(r, v.Code())
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) Error() string {
|
||||||
|
return modeError.error(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) StringError() string {
|
||||||
|
return e.e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) StringErrorFull(glue string) string {
|
||||||
|
if glue == "" {
|
||||||
|
glue = defaultGlue
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(e.StringErrorSlice(), glue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) StringErrorSlice() []string {
|
||||||
|
var r = []string{e.Error()}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
r = append(r, v.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetError() error {
|
||||||
|
return errs.New(e.e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetErrorFull(glue string) error {
|
||||||
|
return errs.New(e.StringErrorFull(glue))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetErrorSlice() []error {
|
||||||
|
var r = []error{e.GetError()}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
r = append(r, v.GetError())
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetIError() Error {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetIErrorSlice() []Error {
|
||||||
|
var r = []Error{e}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
r = append(r, v.GetIError())
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetTrace() string {
|
||||||
|
if e.t.File != "" {
|
||||||
|
return fmt.Sprintf("%s#%d", e.t.File, e.t.Line)
|
||||||
|
} else if e.t.Function != "" {
|
||||||
|
return fmt.Sprintf("%s#%d", e.t.Function, e.t.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) GetTraceSlice() []string {
|
||||||
|
var r = []string{e.GetTrace()}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
if t := v.GetTrace(); t != "" {
|
||||||
|
r = append(r, v.GetTrace())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeError(pattern string) string {
|
||||||
|
if pattern == "" {
|
||||||
|
pattern = defaultPattern
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(pattern, e.Code(), e.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeErrorFull(pattern, glue string) string {
|
||||||
|
if glue == "" {
|
||||||
|
glue = defaultGlue
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(e.CodeErrorSlice(pattern), glue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeErrorSlice(pattern string) []string {
|
||||||
|
var r = []string{e.CodeError(pattern)}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
r = append(r, v.CodeError(pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeErrorTrace(pattern string) string {
|
||||||
|
if pattern == "" {
|
||||||
|
pattern = defaultPatternTrace
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf(pattern, e.Code(), e.GetTrace(), e.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeErrorTraceFull(pattern, glue string) string {
|
||||||
|
if glue == "" {
|
||||||
|
glue = defaultGlue
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(e.CodeErrorTraceSlice(pattern), glue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *errors) CodeErrorTraceSlice(pattern string) []string {
|
||||||
|
var r = []string{e.CodeErrorTrace(pattern)}
|
||||||
|
|
||||||
|
for _, v := range e.p {
|
||||||
|
r = append(r, v.CodeErrorTrace(pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
99
errors/mode.go
Normal file
99
errors/mode.go
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 errors
|
||||||
|
|
||||||
|
var modeError = ERROR_RETURN_Default
|
||||||
|
|
||||||
|
func SetModeReturnError(mode ErrorMode) {
|
||||||
|
modeError = mode
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetModeReturnError() ErrorMode {
|
||||||
|
return modeError
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorMode uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
ERROR_RETURN_Default ErrorMode = iota
|
||||||
|
ERROR_RETURN_Code
|
||||||
|
ERROR_RETURN_CodeFull
|
||||||
|
ERROR_RETURN_CodeError
|
||||||
|
ERROR_RETURN_CodeErrorFull
|
||||||
|
ERROR_RETURN_CodeErrorTrace
|
||||||
|
ERROR_RETURN_CodeErrorTraceFull
|
||||||
|
ERROR_RETURN_StringError
|
||||||
|
ERROR_RETURN_StringErrorFull
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m ErrorMode) String() string {
|
||||||
|
switch m {
|
||||||
|
case ERROR_RETURN_Code:
|
||||||
|
return "Code"
|
||||||
|
case ERROR_RETURN_CodeFull:
|
||||||
|
return "CodeFull"
|
||||||
|
case ERROR_RETURN_CodeError:
|
||||||
|
return "CodeError"
|
||||||
|
case ERROR_RETURN_CodeErrorFull:
|
||||||
|
return "CodeErrorFull"
|
||||||
|
case ERROR_RETURN_CodeErrorTrace:
|
||||||
|
return "CodeErrorTrace"
|
||||||
|
case ERROR_RETURN_CodeErrorTraceFull:
|
||||||
|
return "CodeErrorTraceFull"
|
||||||
|
case ERROR_RETURN_StringError:
|
||||||
|
return "StringError"
|
||||||
|
case ERROR_RETURN_StringErrorFull:
|
||||||
|
return "StringErrorFull"
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m ErrorMode) error(e *errors) string {
|
||||||
|
switch m {
|
||||||
|
case ERROR_RETURN_Code:
|
||||||
|
return e.Code()
|
||||||
|
case ERROR_RETURN_CodeFull:
|
||||||
|
return e.CodeFull("")
|
||||||
|
case ERROR_RETURN_CodeError:
|
||||||
|
return e.CodeError("")
|
||||||
|
case ERROR_RETURN_CodeErrorFull:
|
||||||
|
return e.CodeErrorFull("", "")
|
||||||
|
case ERROR_RETURN_CodeErrorTrace:
|
||||||
|
return e.CodeErrorTrace("")
|
||||||
|
case ERROR_RETURN_CodeErrorTraceFull:
|
||||||
|
return e.CodeErrorTraceFull("", "")
|
||||||
|
case ERROR_RETURN_StringError:
|
||||||
|
return e.StringError()
|
||||||
|
case ERROR_RETURN_StringErrorFull:
|
||||||
|
return e.StringErrorFull("")
|
||||||
|
|
||||||
|
default:
|
||||||
|
return e.StringError()
|
||||||
|
}
|
||||||
|
}
|
51
errors/modules.go
Normal file
51
errors/modules.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 errors
|
||||||
|
|
||||||
|
const (
|
||||||
|
MIN_PKG_Archive = 100
|
||||||
|
// MIN_PKG_Artifact = 200 // unused
|
||||||
|
MIN_PKG_Certif = 300
|
||||||
|
MIN_PKG_Console = 400
|
||||||
|
MIN_PKG_Crypt = 500
|
||||||
|
MIN_PKG_Httpcli = 600
|
||||||
|
MIN_PKG_Httpserver = 700
|
||||||
|
MIN_PKG_IOUtils = 800
|
||||||
|
MIN_PKG_LDAP = 900
|
||||||
|
// MIN_PKG_Logger = 1000 // unused
|
||||||
|
// MIN_PKG_Password = 1100 // unused
|
||||||
|
// MIN_PKG_Progress = 1200 // unused
|
||||||
|
MIN_PKG_Router = 1300
|
||||||
|
MIN_PKG_Semaphore = 1400
|
||||||
|
MIN_PKG_SMTP = 1500
|
||||||
|
MIN_PKG_Static = 1600
|
||||||
|
// MIN_PKG_Status = 1700 // unused
|
||||||
|
// MIN_PKG_Update = 1800 // unused
|
||||||
|
MIN_PKG_Version = 1900
|
||||||
|
|
||||||
|
MIN_AVAILABLE = 2000
|
||||||
|
)
|
67
errors/trace.go
Normal file
67
errors/trace.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 errors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var currPkgs = path.Base(reflect.TypeOf(UNK_ERROR).PkgPath())
|
||||||
|
|
||||||
|
func getFrame() runtime.Frame {
|
||||||
|
// Set size to targetFrameIndex+2 to ensure we have room for one more caller than we need
|
||||||
|
programCounters := make([]uintptr, 0)
|
||||||
|
n := runtime.Callers(0, programCounters)
|
||||||
|
|
||||||
|
if n > 0 {
|
||||||
|
frames := runtime.CallersFrames(programCounters[:n])
|
||||||
|
more := true
|
||||||
|
|
||||||
|
for more {
|
||||||
|
var (
|
||||||
|
frame runtime.Frame
|
||||||
|
)
|
||||||
|
|
||||||
|
frame, more = frames.Next()
|
||||||
|
|
||||||
|
if strings.Contains(frame.Function, currPkgs) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getNilFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNilFrame() runtime.Frame {
|
||||||
|
return runtime.Frame{Function: "", File: "", Line: 0}
|
||||||
|
}
|
8
go.mod
8
go.mod
@@ -6,6 +6,7 @@ require (
|
|||||||
github.com/VividCortex/ewma v1.1.1 // indirect
|
github.com/VividCortex/ewma v1.1.1 // indirect
|
||||||
github.com/fatih/color v1.9.0
|
github.com/fatih/color v1.9.0
|
||||||
github.com/gin-gonic/gin v1.6.3
|
github.com/gin-gonic/gin v1.6.3
|
||||||
|
github.com/go-ldap/ldap/v3 v3.2.2
|
||||||
github.com/go-playground/validator/v10 v10.3.0 // indirect
|
github.com/go-playground/validator/v10 v10.3.0 // indirect
|
||||||
github.com/gobuffalo/envy v1.9.0 // indirect
|
github.com/gobuffalo/envy v1.9.0 // indirect
|
||||||
github.com/gobuffalo/packd v1.0.0 // indirect
|
github.com/gobuffalo/packd v1.0.0 // indirect
|
||||||
@@ -27,12 +28,13 @@ require (
|
|||||||
github.com/spf13/jwalterweatherman v1.1.0
|
github.com/spf13/jwalterweatherman v1.1.0
|
||||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||||
github.com/vbauerster/mpb v3.4.0+incompatible // indirect
|
github.com/vbauerster/mpb v3.4.0+incompatible // indirect
|
||||||
github.com/vbauerster/mpb/v5 v5.2.2
|
github.com/vbauerster/mpb/v5 v5.2.3
|
||||||
github.com/vjeantet/ldapserver v0.0.0-20170919170217-479fece7c5f1 // indirect
|
github.com/vjeantet/ldapserver v0.0.0-20170919170217-479fece7c5f1 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
||||||
|
golang.org/x/text v0.3.3 // indirect
|
||||||
google.golang.org/protobuf v1.25.0 // indirect
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||||
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
|
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
|
||||||
|
16
go.sum
16
go.sum
@@ -1,4 +1,6 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||||
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||||
@@ -26,6 +28,11 @@ github.com/gin-gonic/gin v1.6.2 h1:88crIK23zO6TqlQBt+f9FrPJNKm9ZEr7qjp9vl/d5TM=
|
|||||||
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
|
github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=
|
||||||
|
github.com/go-ldap/ldap/v3 v3.2.2 h1:XIXsu/Z2SbIMrh51WMAf0t7zWftlCKoZiLU6MS8KWm8=
|
||||||
|
github.com/go-ldap/ldap/v3 v3.2.2/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||||
@@ -176,6 +183,8 @@ github.com/vbauerster/mpb v3.4.0+incompatible h1:mfiiYw87ARaeRW6x5gWwYRUawxaW1tL
|
|||||||
github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
|
github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
|
||||||
github.com/vbauerster/mpb/v5 v5.2.2 h1:zIICVOm+XD+uV6crpSORaL6I0Q1WqOdvxZTp+r3L9cw=
|
github.com/vbauerster/mpb/v5 v5.2.2 h1:zIICVOm+XD+uV6crpSORaL6I0Q1WqOdvxZTp+r3L9cw=
|
||||||
github.com/vbauerster/mpb/v5 v5.2.2/go.mod h1:W5Fvgw4dm3/0NhqzV8j6EacfuTe5SvnzBRwiXxDR9ww=
|
github.com/vbauerster/mpb/v5 v5.2.2/go.mod h1:W5Fvgw4dm3/0NhqzV8j6EacfuTe5SvnzBRwiXxDR9ww=
|
||||||
|
github.com/vbauerster/mpb/v5 v5.2.3 h1:OfqncMAhUojApki4/AxW4Z14cpiYBw7+MVLOyGklBmM=
|
||||||
|
github.com/vbauerster/mpb/v5 v5.2.3/go.mod h1:K4iCHQp5sWnmAgEn+uW1sAxSilctb4JPAGXx49jV+Aw=
|
||||||
github.com/vjeantet/ldapserver v0.0.0-20170919170217-479fece7c5f1/go.mod h1:+KHPMCVmFBVXK3UAUom0AgP/IeOXH5C3ieEwA+JU3WE=
|
github.com/vjeantet/ldapserver v0.0.0-20170919170217-479fece7c5f1/go.mod h1:+KHPMCVmFBVXK3UAUom0AgP/IeOXH5C3ieEwA+JU3WE=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@@ -191,6 +200,8 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf
|
|||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||||
|
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
@@ -215,6 +226,8 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYc
|
|||||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||||
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -255,7 +268,10 @@ golang.org/x/sys v0.0.0-20200620081246-981b61492c35/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
92
httpcli/cli.go
Normal file
92
httpcli/cli.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 httpcli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
njs_certif "github.com/nabbar/golib/certificates"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TIMEOUT_30_SEC = 30 * time.Second
|
||||||
|
TIMEOUT_10_SEC = 10 * time.Second
|
||||||
|
TIMEOUT_5_SEC = 5 * time.Second
|
||||||
|
TIMEOUT_1_SEC = 1 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetClient(serverName string) *http.Client {
|
||||||
|
c, e := getClient(true, TIMEOUT_30_SEC, TIMEOUT_10_SEC, TIMEOUT_30_SEC, TIMEOUT_30_SEC, TIMEOUT_5_SEC, TIMEOUT_1_SEC, njs_certif.GetTLSConfig(serverName))
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
c, _ = getClient(false, TIMEOUT_30_SEC, TIMEOUT_10_SEC, TIMEOUT_30_SEC, TIMEOUT_30_SEC, TIMEOUT_5_SEC, TIMEOUT_1_SEC, njs_certif.GetTLSConfig(serverName))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetClientError(serverName string) (*http.Client, Error) {
|
||||||
|
return getClient(true, TIMEOUT_30_SEC, TIMEOUT_10_SEC, TIMEOUT_30_SEC, TIMEOUT_30_SEC, TIMEOUT_5_SEC, TIMEOUT_1_SEC, njs_certif.GetTLSConfig(serverName))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetClientTimeout(serverName string, GlobalTimeout, DialTimeOut, DialKeepAlive, IdleConnTimeout, TLSHandshakeTimeout, ExpectContinueTimeout time.Duration) (*http.Client, Error) {
|
||||||
|
return getClient(true, GlobalTimeout, DialTimeOut, DialKeepAlive, IdleConnTimeout, TLSHandshakeTimeout, ExpectContinueTimeout, njs_certif.GetTLSConfig(serverName))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getClient(http2Transport bool, GlobalTimeout, DialTimeOut, DialKeepAlive, IdleConnTimeout, TLSHandshakeTimeout, ExpectContinueTimeout time.Duration, tlsConfig *tls.Config) (*http.Client, Error) {
|
||||||
|
tr := &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
DialContext: (&net.Dialer{
|
||||||
|
Timeout: DialTimeOut,
|
||||||
|
KeepAlive: DialKeepAlive,
|
||||||
|
}).DialContext,
|
||||||
|
MaxIdleConns: 100,
|
||||||
|
IdleConnTimeout: IdleConnTimeout,
|
||||||
|
TLSHandshakeTimeout: TLSHandshakeTimeout,
|
||||||
|
ExpectContinueTimeout: ExpectContinueTimeout,
|
||||||
|
DisableCompression: true,
|
||||||
|
TLSClientConfig: tlsConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
if http2Transport {
|
||||||
|
if e := http2.ConfigureTransport(tr); e != nil {
|
||||||
|
return nil, HTTP2_CONFIGURE.ErrorParent(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &http.Client{
|
||||||
|
Transport: tr,
|
||||||
|
Timeout: GlobalTimeout,
|
||||||
|
}, nil
|
||||||
|
}
|
67
httpcli/error.go
Normal file
67
httpcli/error.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 httpcli
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Httpcli
|
||||||
|
URL_PARSE
|
||||||
|
HTTP_CLIENT
|
||||||
|
HTTP_REQUEST
|
||||||
|
HTTP_DO
|
||||||
|
IO_READ
|
||||||
|
BUFFER_WRITE
|
||||||
|
HTTP2_CONFIGURE
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case URL_PARSE:
|
||||||
|
return "uri/url parse error"
|
||||||
|
case HTTP_CLIENT:
|
||||||
|
return "error on creating a new http/http2 client"
|
||||||
|
case HTTP_REQUEST:
|
||||||
|
return "error on creating a new http/http2 request"
|
||||||
|
case HTTP_DO:
|
||||||
|
return "error on sending a http/http2 request"
|
||||||
|
case IO_READ:
|
||||||
|
return "error on reading i/o stream"
|
||||||
|
case BUFFER_WRITE:
|
||||||
|
return "error on writing bytes on buffer"
|
||||||
|
case HTTP2_CONFIGURE:
|
||||||
|
return "error while configure http2 transport for client"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,21 +23,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_httpcli
|
package httpcli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
njs_certif "github.com/nabbar/golib/njs-certif"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
. "github.com/nabbar/golib/logger"
|
||||||
njs_logger "github.com/nabbar/golib/njs-logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type httpClient struct {
|
type httpClient struct {
|
||||||
@@ -46,11 +42,11 @@ type httpClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HTTP interface {
|
type HTTP interface {
|
||||||
Check() bool
|
Check() Error
|
||||||
Call(file *bytes.Buffer) (bool, *bytes.Buffer)
|
Call(file *bytes.Buffer) (bool, *bytes.Buffer, Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(uri string) HTTP {
|
func NewClient(uri string) (HTTP, Error) {
|
||||||
var (
|
var (
|
||||||
pUri *url.URL
|
pUri *url.URL
|
||||||
err error
|
err error
|
||||||
@@ -59,85 +55,100 @@ func NewClient(uri string) HTTP {
|
|||||||
|
|
||||||
if uri != "" {
|
if uri != "" {
|
||||||
pUri, err = url.Parse(uri)
|
pUri, err = url.Parse(uri)
|
||||||
njs_logger.PanicLevel.LogErrorCtx(njs_logger.NilLevel, fmt.Sprintf("parsing url '%s'", uri), err)
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, URL_PARSE.ErrorParent(err)
|
||||||
|
}
|
||||||
|
|
||||||
host = pUri.Host
|
host = pUri.Host
|
||||||
} else {
|
} else {
|
||||||
pUri = nil
|
pUri = nil
|
||||||
host = ""
|
host = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, e := GetClientError(host)
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return nil, HTTP_CLIENT.Error(e)
|
||||||
|
}
|
||||||
|
|
||||||
return &httpClient{
|
return &httpClient{
|
||||||
url: pUri,
|
url: pUri,
|
||||||
cli: GetClient(host),
|
cli: c,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetClient(serverName string) *http.Client {
|
func (obj *httpClient) Check() Error {
|
||||||
return &http.Client{
|
req, e := obj.newRequest(http.MethodHead, nil)
|
||||||
Transport: &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
if e != nil {
|
||||||
DialContext: (&net.Dialer{
|
return e
|
||||||
Timeout: 10 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
DualStack: true,
|
|
||||||
}).DialContext,
|
|
||||||
MaxIdleConns: 100,
|
|
||||||
IdleConnTimeout: 30 * time.Second,
|
|
||||||
TLSHandshakeTimeout: 5 * time.Second,
|
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
|
||||||
DisableCompression: true,
|
|
||||||
TLSClientConfig: njs_certif.GetTLSConfig(serverName),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *httpClient) Check() bool {
|
_, e = obj.doRequest(req)
|
||||||
obj.doRequest(obj.newRequest(http.MethodHead, nil))
|
|
||||||
return true
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *httpClient) Call(body *bytes.Buffer) (bool, *bytes.Buffer) {
|
func (obj *httpClient) Call(body *bytes.Buffer) (bool, *bytes.Buffer, Error) {
|
||||||
return obj.checkResponse(
|
req, e := obj.newRequest(http.MethodPost, body)
|
||||||
obj.doRequest(
|
|
||||||
obj.newRequest(http.MethodPost, body),
|
if e != nil {
|
||||||
),
|
return false, nil, e
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *httpClient) newRequest(method string, body *bytes.Buffer) *http.Request {
|
res, e := obj.doRequest(req)
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return false, nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj.checkResponse(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (obj *httpClient) newRequest(method string, body *bytes.Buffer) (*http.Request, Error) {
|
||||||
var reader *bytes.Reader
|
var reader *bytes.Reader
|
||||||
|
|
||||||
if body != nil && body.Len() > 0 {
|
if body != nil && body.Len() > 0 {
|
||||||
reader = bytes.NewReader(body.Bytes())
|
reader = bytes.NewReader(body.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(method, obj.url.String(), reader)
|
req, e := http.NewRequest(method, obj.url.String(), reader)
|
||||||
njs_logger.PanicLevel.LogErrorCtx(njs_logger.NilLevel, fmt.Sprintf("creating '%s' request to '%s'", method, obj.url.Host), err)
|
if e != nil {
|
||||||
|
return req, HTTP_REQUEST.ErrorParent(e)
|
||||||
return req
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *httpClient) doRequest(req *http.Request) *http.Response {
|
return req, nil
|
||||||
res, err := obj.cli.Do(req)
|
|
||||||
njs_logger.PanicLevel.LogErrorCtx(njs_logger.NilLevel, fmt.Sprintf("running request '%s:%s'", req.Method, req.URL.Host), err)
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *httpClient) checkResponse(res *http.Response) (bool, *bytes.Buffer) {
|
func (obj *httpClient) doRequest(req *http.Request) (*http.Response, Error) {
|
||||||
|
res, e := obj.cli.Do(req)
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
return res, HTTP_DO.ErrorParent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (obj *httpClient) checkResponse(res *http.Response) (bool, *bytes.Buffer, Error) {
|
||||||
var buf *bytes.Buffer
|
var buf *bytes.Buffer
|
||||||
|
|
||||||
if res.Body != nil {
|
if res.Body != nil {
|
||||||
bdy, err := ioutil.ReadAll(res.Body)
|
bdy, err := ioutil.ReadAll(res.Body)
|
||||||
|
|
||||||
if err == nil {
|
if err != nil {
|
||||||
|
return false, nil, IO_READ.ErrorParent(err)
|
||||||
|
}
|
||||||
|
|
||||||
_, err = buf.Write(bdy)
|
_, err = buf.Write(bdy)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, BUFFER_WRITE.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.LogError(err)
|
DebugLevel.LogError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.InfoLevel.Logf("Calling '%s:%s' result %s (Body : %d bytes)", res.Request.Method, res.Request.URL.Host, res.Status, buf.Len())
|
return strings.HasPrefix(res.Status, "2"), buf, nil
|
||||||
|
|
||||||
return strings.HasPrefix(res.Status, "2"), buf
|
|
||||||
}
|
}
|
46
httpserver/error.go
Normal file
46
httpserver/error.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 httpserver
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Httpserver
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_httpserver
|
package httpserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -40,8 +40,18 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
njs_certif "github.com/nabbar/golib/njs-certif"
|
"golang.org/x/net/http2"
|
||||||
njs_logger "github.com/nabbar/golib/njs-logger"
|
|
||||||
|
njs_certif "github.com/nabbar/golib/certificates"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TIMEOUT_30_SEC = 30 * time.Second
|
||||||
|
TIMEOUT_10_SEC = 10 * time.Second
|
||||||
|
TIMEOUT_5_SEC = 5 * time.Second
|
||||||
|
TIMEOUT_1_SEC = 1 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
type modelServer struct {
|
type modelServer struct {
|
||||||
@@ -169,22 +179,36 @@ func (srv *modelServer) Listen() {
|
|||||||
|
|
||||||
srv.srv = &http.Server{
|
srv.srv = &http.Server{
|
||||||
Addr: srv.GetBindable(),
|
Addr: srv.GetBindable(),
|
||||||
ErrorLog: njs_logger.GetLogger(njs_logger.ErrorLevel, log.LstdFlags | log.LstdFlags | log.Lmicroseconds, "server '%s'", srv.GetBindable()),
|
ErrorLog: GetLogger(ErrorLevel, log.LstdFlags|log.Lmicroseconds, "[http/http2 server '%s']", srv.GetBindable()),
|
||||||
Handler: srv.hdl,
|
Handler: srv.hdl,
|
||||||
TLSConfig: srv.ssl,
|
TLSConfig: srv.ssl,
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.InfoLevel.Logf("Server starting with bindable: %s", srv.GetBindable())
|
cnf := &http2.Server{
|
||||||
|
//MaxHandlers: 0,
|
||||||
|
//MaxConcurrentStreams: 0,
|
||||||
|
//MaxReadFrameSize: 0,
|
||||||
|
//PermitProhibitedCipherSuites: false,
|
||||||
|
IdleTimeout: TIMEOUT_30_SEC,
|
||||||
|
//MaxUploadBufferPerConnection: 0,
|
||||||
|
//MaxUploadBufferPerStream: 0,
|
||||||
|
//NewWriteScheduler: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := http2.ConfigureServer(srv.srv, cnf)
|
||||||
|
FatalLevel.Logf("Configuring Server '%s' Error: %v", srv.host, err)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if srv.ssl == nil || !njs_certif.CheckCertificates() {
|
if srv.ssl == nil || !njs_certif.CheckCertificates() {
|
||||||
|
InfoLevel.Logf("Server '%s' is starting with bindable: %s", srv.host, srv.GetBindable())
|
||||||
if err := srv.srv.ListenAndServe(); err != nil {
|
if err := srv.srv.ListenAndServe(); err != nil {
|
||||||
njs_logger.FatalLevel.Logf("Listen Error: %v", err)
|
FatalLevel.Logf("Listen Server '%s' Error: %v", srv.host, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
InfoLevel.Logf("TLS Server '%s' is starting with bindable: %s", srv.host, srv.GetBindable())
|
||||||
if err := srv.srv.ListenAndServeTLS("", ""); err != nil {
|
if err := srv.srv.ListenAndServeTLS("", ""); err != nil {
|
||||||
njs_logger.FatalLevel.Logf("Listen config Error: %v", err)
|
FatalLevel.Logf("Listen TLS Server '%s' Error: %v", srv.host, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +237,7 @@ func (srv *modelServer) Restart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (srv *modelServer) Shutdown() {
|
func (srv *modelServer) Shutdown() {
|
||||||
njs_logger.InfoLevel.Logf("Shutdown Server ...")
|
InfoLevel.Logf("Shutdown Server '%s'...", srv.addr.Host)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -223,7 +247,7 @@ func (srv *modelServer) Shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := srv.srv.Shutdown(ctx); err != nil {
|
if err := srv.srv.Shutdown(ctx); err != nil {
|
||||||
njs_logger.FatalLevel.Logf("Server Shutdown Error: %v", err)
|
FatalLevel.Logf("Shutdown Server '%s' Error: %v", srv.host, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
srv.srv = nil
|
srv.srv = nil
|
61
ioutils/error.go
Normal file
61
ioutils/error.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 ioutils
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_IOUtils
|
||||||
|
SYSCALL_RLIMIT_GET
|
||||||
|
SYSCALL_RLIMIT_SET
|
||||||
|
IO_TEMP_FILE_NEW
|
||||||
|
IO_TEMP_FILE_CLOSE
|
||||||
|
IO_TEMP_FILE_REMOVE
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case SYSCALL_RLIMIT_GET:
|
||||||
|
return "error on retrieve value in syscall rlimit"
|
||||||
|
case SYSCALL_RLIMIT_SET:
|
||||||
|
return "error on changing value in syscall rlimit"
|
||||||
|
case IO_TEMP_FILE_NEW:
|
||||||
|
return "error occur while trying to create new temporary file"
|
||||||
|
case IO_TEMP_FILE_CLOSE:
|
||||||
|
return "closing temporary file occurs error"
|
||||||
|
case IO_TEMP_FILE_REMOVE:
|
||||||
|
return "error occurs on removing temporary file"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,7 +23,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ioutils
|
package ioutils
|
||||||
|
|
||||||
|
import . "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SystemFileDescriptor is returning current Limit & max system limit for file descriptor (open file or I/O resource) currently set in the system
|
* SystemFileDescriptor is returning current Limit & max system limit for file descriptor (open file or I/O resource) currently set in the system
|
||||||
@@ -49,6 +51,6 @@ package njs_ioutils
|
|||||||
* Normally no problem will be result in the build
|
* Normally no problem will be result in the build
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
func SystemFileDescriptor(newValue int) (current int, max int, err error) {
|
func SystemFileDescriptor(newValue int) (current int, max int, err Error) {
|
||||||
return systemFileDescriptor(newValue)
|
return systemFileDescriptor(newValue)
|
||||||
}
|
}
|
@@ -25,13 +25,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ioutils
|
package ioutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nabbar/golib/njs-ioutils/maxstdio"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
"github.com/nabbar/golib/ioutils/maxstdio"
|
||||||
)
|
)
|
||||||
|
|
||||||
func systemFileDescriptor(newValue int) (current int, max int, err error) {
|
func systemFileDescriptor(newValue int) (current int, max int, err Error) {
|
||||||
rLimit := maxstdio.GetMaxStdio()
|
rLimit := maxstdio.GetMaxStdio()
|
||||||
|
|
||||||
if rLimit < 0 {
|
if rLimit < 0 {
|
@@ -25,14 +25,22 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ioutils
|
package ioutils
|
||||||
|
|
||||||
import "syscall"
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
func systemFileDescriptor(newValue int) (current int, max int, err error) {
|
. "github.com/nabbar/golib/errors"
|
||||||
var rLimit syscall.Rlimit
|
)
|
||||||
|
|
||||||
if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil {
|
func systemFileDescriptor(newValue int) (current int, max int, err Error) {
|
||||||
|
var (
|
||||||
|
rLimit syscall.Rlimit
|
||||||
|
e error
|
||||||
|
)
|
||||||
|
|
||||||
|
if e = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit); e != nil {
|
||||||
|
err = SYSCALL_RLIMIT_GET.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +64,8 @@ func systemFileDescriptor(newValue int) (current int, max int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if chg {
|
if chg {
|
||||||
if err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil {
|
if e = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit); e != nil {
|
||||||
|
err = SYSCALL_RLIMIT_SET.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ioutils
|
package ioutils
|
||||||
|
|
||||||
import "io"
|
import "io"
|
||||||
|
|
@@ -23,21 +23,19 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ioutils
|
package ioutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTempFile() (*os.File, error) {
|
func NewTempFile() (*os.File, Error) {
|
||||||
if f, e := ioutil.TempFile(os.TempDir(), ""); e != nil {
|
f, e := ioutil.TempFile(os.TempDir(), "")
|
||||||
return nil, e
|
return f, IO_TEMP_FILE_NEW.Iferror(e)
|
||||||
} else {
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTempFilePath(f *os.File) string {
|
func GetTempFilePath(f *os.File) string {
|
||||||
@@ -48,24 +46,18 @@ func GetTempFilePath(f *os.File) string {
|
|||||||
return path.Join(os.TempDir(), path.Base(f.Name()))
|
return path.Join(os.TempDir(), path.Base(f.Name()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func DelTempFile(f *os.File, ignoreErrClose bool) error {
|
func DelTempFile(f *os.File) Error {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
n := GetTempFilePath(f)
|
n := GetTempFilePath(f)
|
||||||
|
|
||||||
a := f.Close()
|
a := f.Close()
|
||||||
|
e1 := IO_TEMP_FILE_CLOSE.Iferror(a)
|
||||||
|
|
||||||
b := os.Remove(n)
|
b := os.Remove(n)
|
||||||
|
e2 := IO_TEMP_FILE_REMOVE.Iferror(b)
|
||||||
|
|
||||||
if ignoreErrClose {
|
return MakeErrorIfError(e2, e1)
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
if a != nil && b != nil {
|
|
||||||
return fmt.Errorf("%v, %v", a, b)
|
|
||||||
} else if a != nil {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
}
|
70
ldap/error.go
Normal file
70
ldap/error.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 ldap
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_LDAP
|
||||||
|
LDAP_SERVER_CONFIG
|
||||||
|
LDAP_SERVER_DIAL
|
||||||
|
LDAP_SERVER_TLS
|
||||||
|
LDAP_SERVER_STARTTLS
|
||||||
|
LDAP_BIND
|
||||||
|
LDAP_SEARCH
|
||||||
|
LDAP_USER_NOT_UNIQ
|
||||||
|
LDAP_USER_NOT_FOUND
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case LDAP_SERVER_CONFIG:
|
||||||
|
return "LDAP server config is not well defined"
|
||||||
|
case LDAP_SERVER_DIAL:
|
||||||
|
return "dialing server occurs error "
|
||||||
|
case LDAP_SERVER_TLS:
|
||||||
|
return "cannot start dial to server with TLS Mode"
|
||||||
|
case LDAP_SERVER_STARTTLS:
|
||||||
|
return "cannot init starttls mode on opening server connection"
|
||||||
|
case LDAP_BIND:
|
||||||
|
return "error on binding user/pass"
|
||||||
|
case LDAP_SEARCH:
|
||||||
|
return "error on calling search on connected server"
|
||||||
|
case LDAP_USER_NOT_UNIQ:
|
||||||
|
return "user uid is not uniq"
|
||||||
|
case LDAP_USER_NOT_FOUND:
|
||||||
|
return "user uid is not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,17 +23,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/go-ldap/ldap/v3"
|
||||||
"github.com/nabbar/golib/njs-certif"
|
|
||||||
"github.com/nabbar/golib/njs-logger"
|
njs_certif "github.com/nabbar/golib/certificates"
|
||||||
"gopkg.in/ldap.v3"
|
. "github.com/nabbar/golib/errors"
|
||||||
|
. "github.com/nabbar/golib/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
//HelperLDAP struct use to manage connection to server and request it
|
//HelperLDAP struct use to manage connection to server and request it
|
||||||
@@ -48,9 +49,9 @@ type HelperLDAP struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//NewLDAP build a new LDAP helper based on config struct given
|
//NewLDAP build a new LDAP helper based on config struct given
|
||||||
func NewLDAP(cnf *Config, attributes []string) *HelperLDAP {
|
func NewLDAP(cnf *Config, attributes []string) (*HelperLDAP, Error) {
|
||||||
if cnf == nil {
|
if cnf == nil {
|
||||||
panic("given config is a nil struct")
|
return nil, EMPTY_PARAMS.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &HelperLDAP{
|
return &HelperLDAP{
|
||||||
@@ -58,7 +59,7 @@ func NewLDAP(cnf *Config, attributes []string) *HelperLDAP {
|
|||||||
tlsConfig: njs_certif.GetTLSConfig(cnf.Uri),
|
tlsConfig: njs_certif.GetTLSConfig(cnf.Uri),
|
||||||
tlsMode: tlsmode_init,
|
tlsMode: tlsmode_init,
|
||||||
config: cnf.Clone(),
|
config: cnf.Clone(),
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//SetCredentials used to defined the BindDN and password for connection
|
//SetCredentials used to defined the BindDN and password for connection
|
||||||
@@ -79,45 +80,45 @@ func (lc *HelperLDAP) ForceTLSMode(tlsMode TLSMode, tlsConfig *tls.Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *HelperLDAP) tryConnect() (TLSMode, error) {
|
func (lc *HelperLDAP) tryConnect() (TLSMode, Error) {
|
||||||
var (
|
var (
|
||||||
l *ldap.Conn
|
l *ldap.Conn
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
defer func(l *ldap.Conn) {
|
defer func() {
|
||||||
if l != nil {
|
if l != nil {
|
||||||
l.Close()
|
l.Close()
|
||||||
}
|
}
|
||||||
}(l)
|
}()
|
||||||
|
|
||||||
if lc.config.Portldaps != 0 {
|
if lc.config.Portldaps != 0 {
|
||||||
l, err = ldap.DialTLS("tcp", lc.config.ServerAddr(true), lc.tlsConfig)
|
l, err = ldap.DialTLS("tcp", lc.config.ServerAddr(true), lc.tlsConfig)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
njs_logger.DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
||||||
return TLSMODE_TLS, nil
|
return TLSMODE_TLS, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if lc.config.PortLdap == 0 {
|
if lc.config.PortLdap == 0 {
|
||||||
return 0, fmt.Errorf("ldap server not well defined")
|
return tlsmode_init, LDAP_SERVER_CONFIG.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
l, err = ldap.Dial("tcp", lc.config.ServerAddr(false))
|
l, err = ldap.Dial("tcp", lc.config.ServerAddr(false))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, LDAP_SERVER_DIAL.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e := l.StartTLS(lc.tlsConfig); e == nil {
|
if err = l.StartTLS(lc.tlsConfig); err == nil {
|
||||||
njs_logger.DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
||||||
return TLSMODE_STARTTLS, nil
|
return TLSMODE_STARTTLS, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
||||||
return TLSMODE_NONE, nil
|
return TLSMODE_NONE, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *HelperLDAP) connect() error {
|
func (lc *HelperLDAP) connect() Error {
|
||||||
if lc.conn == nil {
|
if lc.conn == nil {
|
||||||
var (
|
var (
|
||||||
l *ldap.Conn
|
l *ldap.Conn
|
||||||
@@ -137,25 +138,25 @@ func (lc *HelperLDAP) connect() error {
|
|||||||
if lc.tlsMode == TLSMODE_TLS {
|
if lc.tlsMode == TLSMODE_TLS {
|
||||||
l, err = ldap.DialTLS("tcp", lc.config.ServerAddr(true), lc.tlsConfig)
|
l, err = ldap.DialTLS("tcp", lc.config.ServerAddr(true), lc.tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ldap connection error with tls mode '%s': %v", lc.tlsMode.String(), err)
|
return LDAP_SERVER_TLS.ErrorParent(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if lc.tlsMode == TLSMODE_NONE || lc.tlsMode == TLSMODE_STARTTLS {
|
if lc.tlsMode == TLSMODE_NONE || lc.tlsMode == TLSMODE_STARTTLS {
|
||||||
l, err = ldap.Dial("tcp", lc.config.ServerAddr(false))
|
l, err = ldap.Dial("tcp", lc.config.ServerAddr(false))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ldap connection error with tls mode '%s': %v", lc.tlsMode.String(), err)
|
return LDAP_SERVER_DIAL.ErrorParent(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if lc.tlsMode == TLSMODE_STARTTLS {
|
if lc.tlsMode == TLSMODE_STARTTLS {
|
||||||
err = l.StartTLS(lc.tlsConfig)
|
err = l.StartTLS(lc.tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ldap connection error with tls mode '%s': %v", lc.tlsMode.String(), err)
|
return LDAP_SERVER_STARTTLS.ErrorParent(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
||||||
lc.conn = l
|
lc.conn = l
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +164,7 @@ func (lc *HelperLDAP) connect() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check used to check if connection success (without any bind)
|
//Check used to check if connection success (without any bind)
|
||||||
func (lc *HelperLDAP) Check() error {
|
func (lc *HelperLDAP) Check() Error {
|
||||||
if err := lc.connect(); err != nil {
|
if err := lc.connect(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -181,37 +182,39 @@ func (lc *HelperLDAP) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//AuthUser used to test bind given user uid and password
|
//AuthUser used to test bind given user uid and password
|
||||||
func (lc *HelperLDAP) AuthUser(username, password string) error {
|
func (lc *HelperLDAP) AuthUser(username, password string) Error {
|
||||||
|
|
||||||
if err := lc.connect(); err != nil {
|
if err := lc.connect(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if username == "" || password == "" {
|
if username == "" || password == "" {
|
||||||
return errors.New("Cannot bind with partial credentials, bindDN or bind password is empty string")
|
return EMPTY_PARAMS.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return lc.conn.Bind(username, password)
|
err := lc.conn.Bind(username, password)
|
||||||
|
|
||||||
|
return LDAP_BIND.Iferror(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Connect used to connect and bind to server
|
//Connect used to connect and bind to server
|
||||||
func (lc *HelperLDAP) Connect() error {
|
func (lc *HelperLDAP) Connect() Error {
|
||||||
if err := lc.AuthUser(lc.bindDN, lc.bindPass); err != nil {
|
if err := lc.AuthUser(lc.bindDN, lc.bindPass); err != nil {
|
||||||
return fmt.Errorf("error while trying to bind on LDAP server %s with tls mode '%s': %v", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("Bind success on LDAP server %s with tls mode '%s'", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String())
|
DebugLevel.Logf("Bind success on LDAP server %s with tls mode '%s'", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *HelperLDAP) runSearch(filter string, attributes []string) (*ldap.SearchResult, error) {
|
func (lc *HelperLDAP) runSearch(filter string, attributes []string) (*ldap.SearchResult, Error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
src *ldap.SearchResult
|
src *ldap.SearchResult
|
||||||
)
|
)
|
||||||
|
|
||||||
if err = lc.Connect(); err != nil {
|
if e := lc.Connect(); e != nil {
|
||||||
return nil, err
|
return nil, e
|
||||||
}
|
}
|
||||||
|
|
||||||
defer lc.Close()
|
defer lc.Close()
|
||||||
@@ -227,17 +230,17 @@ func (lc *HelperLDAP) runSearch(filter string, attributes []string) (*ldap.Searc
|
|||||||
)
|
)
|
||||||
|
|
||||||
if src, err = lc.conn.Search(searchRequest); err != nil {
|
if src, err = lc.conn.Search(searchRequest); err != nil {
|
||||||
return nil, fmt.Errorf("error while looking for '%s' on ldap server %s with tls mode '%s': %v", filter, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), err)
|
return nil, LDAP_SEARCH.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("Search success on server '%s' with tls mode '%s', with filter [%s] and attribute %v", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), filter, attributes)
|
DebugLevel.Logf("Search success on server '%s' with tls mode '%s', with filter [%s] and attribute %v", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), filter, attributes)
|
||||||
return src, nil
|
return src, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//UserInfo used to retrieve the information of a given username
|
//UserInfo used to retrieve the information of a given username
|
||||||
func (lc *HelperLDAP) UserInfo(username string) (map[string]string, error) {
|
func (lc *HelperLDAP) UserInfo(username string) (map[string]string, Error) {
|
||||||
var (
|
var (
|
||||||
err error
|
e Error
|
||||||
src *ldap.SearchResult
|
src *ldap.SearchResult
|
||||||
userRes map[string]string
|
userRes map[string]string
|
||||||
)
|
)
|
||||||
@@ -250,18 +253,18 @@ func (lc *HelperLDAP) UserInfo(username string) (map[string]string, error) {
|
|||||||
userRes = make(map[string]string)
|
userRes = make(map[string]string)
|
||||||
attributes := append(lc.Attributes, "cn")
|
attributes := append(lc.Attributes, "cn")
|
||||||
|
|
||||||
if src, err = lc.runSearch(fmt.Sprintf(lc.config.FilterUser, username), attributes); err != nil {
|
src, e = lc.runSearch(fmt.Sprintf(lc.config.FilterUser, username), attributes)
|
||||||
return userRes, err
|
|
||||||
|
if e != nil {
|
||||||
|
return userRes, e
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(src.Entries) != 1 {
|
if len(src.Entries) != 1 {
|
||||||
if len(src.Entries) > 1 {
|
if len(src.Entries) > 1 {
|
||||||
err = errors.New("Username not unique")
|
return userRes, LDAP_USER_NOT_UNIQ.Error(nil)
|
||||||
} else {
|
} else {
|
||||||
err = errors.New("Username not found")
|
return userRes, LDAP_USER_NOT_FOUND.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return userRes, fmt.Errorf("error while looking for username '%s' on ldap server '%s' with tls mode '%s': %v", username, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, attr := range attributes {
|
for _, attr := range attributes {
|
||||||
@@ -272,14 +275,14 @@ func (lc *HelperLDAP) UserInfo(username string) (map[string]string, error) {
|
|||||||
userRes["DN"] = src.Entries[0].DN
|
userRes["DN"] = src.Entries[0].DN
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("Map info retrieve in ldap server '%s' with tls mode '%s' about user [%s] : %v", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), username, userRes)
|
DebugLevel.Logf("Map info retrieve in ldap server '%s' with tls mode '%s' about user [%s] : %v", lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), username, userRes)
|
||||||
return userRes, nil
|
return userRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//UserMemberOf returns the group list of a given user.
|
//UserMemberOf returns the group list of a given user.
|
||||||
func (lc *HelperLDAP) UserMemberOf(username string) ([]string, error) {
|
func (lc *HelperLDAP) UserMemberOf(username string) ([]string, Error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err Error
|
||||||
src *ldap.SearchResult
|
src *ldap.SearchResult
|
||||||
grp []string
|
grp []string
|
||||||
)
|
)
|
||||||
@@ -291,26 +294,27 @@ func (lc *HelperLDAP) UserMemberOf(username string) ([]string, error) {
|
|||||||
|
|
||||||
grp = make([]string, 0)
|
grp = make([]string, 0)
|
||||||
|
|
||||||
if src, err = lc.runSearch(fmt.Sprintf(lc.config.FilterUser, username), []string{"memberOf"}); err != nil {
|
src, err = lc.runSearch(fmt.Sprintf(lc.config.FilterUser, username), []string{"memberOf"})
|
||||||
|
if err != nil {
|
||||||
return grp, err
|
return grp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, entry := range src.Entries {
|
for _, entry := range src.Entries {
|
||||||
for _, mmb := range entry.GetAttributeValues("memberOf") {
|
for _, mmb := range entry.GetAttributeValues("memberOf") {
|
||||||
njs_logger.DebugLevel.Logf("Group find for uid '%s' on server '%s' with tls mode '%s' : %v", username, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), mmb)
|
DebugLevel.Logf("Group find for uid '%s' on server '%s' with tls mode '%s' : %v", username, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), mmb)
|
||||||
mmo := lc.ParseEntries(mmb)
|
mmo := lc.ParseEntries(mmb)
|
||||||
grp = append(grp, mmo["cn"]...)
|
grp = append(grp, mmo["cn"]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("Groups find for uid '%s' on server '%s' with tls mode '%s' : %v", username, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), grp)
|
DebugLevel.Logf("Groups find for uid '%s' on server '%s' with tls mode '%s' : %v", username, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), grp)
|
||||||
return grp, nil
|
return grp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//UserIsInGroup used to check if a given username is a group member of a list of reference group name
|
//UserIsInGroup used to check if a given username is a group member of a list of reference group name
|
||||||
func (lc *HelperLDAP) UserIsInGroup(username string, groupname []string) (bool, error) {
|
func (lc *HelperLDAP) UserIsInGroup(username string, groupname []string) (bool, Error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err Error
|
||||||
grpMmbr []string
|
grpMmbr []string
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -319,13 +323,14 @@ func (lc *HelperLDAP) UserIsInGroup(username string, groupname []string) (bool,
|
|||||||
username = usr["uid"][0]
|
username = usr["uid"][0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if grpMmbr, err = lc.UserMemberOf(username); err != nil {
|
grpMmbr, err = lc.UserMemberOf(username)
|
||||||
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, grpSrch := range groupname {
|
for _, grpSrch := range groupname {
|
||||||
for _, grpItem := range grpMmbr {
|
for _, grpItem := range grpMmbr {
|
||||||
if strings.ToUpper(grpSrch) == strings.ToUpper(grpItem) {
|
if strings.EqualFold(grpSrch, grpItem) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,16 +340,17 @@ func (lc *HelperLDAP) UserIsInGroup(username string, groupname []string) (bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//UsersOfGroup used to retrieve the member list of a given group name
|
//UsersOfGroup used to retrieve the member list of a given group name
|
||||||
func (lc *HelperLDAP) UsersOfGroup(groupname string) ([]string, error) {
|
func (lc *HelperLDAP) UsersOfGroup(groupname string) ([]string, Error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err Error
|
||||||
src *ldap.SearchResult
|
src *ldap.SearchResult
|
||||||
grp []string
|
grp []string
|
||||||
)
|
)
|
||||||
|
|
||||||
grp = make([]string, 0)
|
grp = make([]string, 0)
|
||||||
|
|
||||||
if src, err = lc.runSearch(fmt.Sprintf(lc.config.FilterGroup, groupname), []string{"member"}); err != nil {
|
src, err = lc.runSearch(fmt.Sprintf(lc.config.FilterGroup, groupname), []string{"member"})
|
||||||
|
if err != nil {
|
||||||
return grp, err
|
return grp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +361,7 @@ func (lc *HelperLDAP) UsersOfGroup(groupname string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
njs_logger.DebugLevel.Logf("Member of groups [%s] find on server '%s' with tls mode '%s' : %v", groupname, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), grp)
|
DebugLevel.Logf("Member of groups [%s] find on server '%s' with tls mode '%s' : %v", groupname, lc.config.ServerAddr(lc.tlsMode == TLSMODE_TLS), lc.tlsMode.String(), grp)
|
||||||
return grp, nil
|
return grp, nil
|
||||||
}
|
}
|
||||||
|
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@@ -22,12 +22,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Format a uint8 type customized with function to manage the result logger format
|
// Format a uint8 type customized with function to manage the result logger format
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -341,7 +341,7 @@ func (level Level) logDetails(message string, data interface{}, err error, field
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var tags = make(map[string]interface{}, 0)
|
var tags = make(map[string]interface{})
|
||||||
|
|
||||||
if enableGID {
|
if enableGID {
|
||||||
tags[tagStack] = getGID()
|
tags[tagStack] = getGID()
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
@@ -40,7 +40,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
tagStack = "stack"
|
tagStack = "stack"
|
||||||
tagTime = "time"
|
tagTime = "time"
|
||||||
tagLevel = "level"
|
//tagLevel = "level" //unused
|
||||||
tagCaller = "func"
|
tagCaller = "func"
|
||||||
tagFile = "file"
|
tagFile = "file"
|
||||||
tagLine = "line"
|
tagLine = "line"
|
@@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 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 njs_errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ErrorCode interface {
|
|
||||||
Error() error
|
|
||||||
ErrorFull() error
|
|
||||||
|
|
||||||
String() string
|
|
||||||
StringFull() string
|
|
||||||
|
|
||||||
Code() string
|
|
||||||
Trace() runtime.Frame
|
|
||||||
}
|
|
||||||
|
|
||||||
type errorCode struct {
|
|
||||||
code string
|
|
||||||
err ErrorType
|
|
||||||
ori error
|
|
||||||
trace runtime.Frame
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error return an error type of the current error code, with no code in reference
|
|
||||||
func (e errorCode) Error() error {
|
|
||||||
return e.err.Error(e.ori)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String return a string of the current error code, with no code in reference
|
|
||||||
func (e errorCode) String() string {
|
|
||||||
return e.err.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code return a string of the current code, with no error in reference
|
|
||||||
func (e errorCode) Code() string {
|
|
||||||
return e.code
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trace return a runtime frame of the current error
|
|
||||||
func (e errorCode) Trace() runtime.Frame {
|
|
||||||
return e.trace
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringFull return a error type of the current code, with error and origin in reference
|
|
||||||
func (e errorCode) StringFull() string {
|
|
||||||
return e.ErrorFull().Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrorFull return a error type of the current code, with error and origin in reference
|
|
||||||
func (e errorCode) ErrorFull() error {
|
|
||||||
|
|
||||||
if e.trace != getNilFrame() {
|
|
||||||
var t = make([]string, 0)
|
|
||||||
|
|
||||||
if e.trace.File != "" {
|
|
||||||
t = append(t, path.Base(e.trace.File))
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.trace.Function != "" {
|
|
||||||
t = append(t, e.trace.Function)
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.trace.Line > 0 {
|
|
||||||
t = append(t, fmt.Sprintf("%v", e.trace.Line))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t) > 0 {
|
|
||||||
return fmt.Errorf("(%s) [%s] %v", e.code, strings.Join(t, "|"), e.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("(%s) %v", e.code, e.Error())
|
|
||||||
}
|
|
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 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 njs_errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
currPkgs = path.Base(reflect.TypeOf(ERR_UNKNOWN).PkgPath())
|
|
||||||
_listCodeErrors = make(map[string]ErrorType, 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetErrorCode Register a new error with code and an error string as ErrorType
|
|
||||||
func SetErrorCode(code string, err ErrorType) {
|
|
||||||
if _listCodeErrors == nil || len(_listCodeErrors) < 1 {
|
|
||||||
_listCodeErrors = make(map[string]ErrorType, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
_listCodeErrors[code] = err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetErrorCodeString Register a new error with code and an error string as string
|
|
||||||
func SetErrorCodeString(code, err string) {
|
|
||||||
SetErrorCode(code, ErrorType(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelErrorCode Remove an error with code from the register list
|
|
||||||
func DelErrorCode(code string) {
|
|
||||||
var _lst = _listCodeErrors
|
|
||||||
|
|
||||||
DelAllErrorCode()
|
|
||||||
|
|
||||||
for k, v := range _lst {
|
|
||||||
if k != code {
|
|
||||||
_listCodeErrors[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelAllErrorCode Clean the complete list of couple code - error
|
|
||||||
func DelAllErrorCode() {
|
|
||||||
_listCodeErrors = make(map[string]ErrorType, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetErrorCode return an ErrorCode interface mapped to code given in parameters.
|
|
||||||
// If the code is not found an 'ERR_UNKNOWN' will be used instead of the awaiting error
|
|
||||||
// If an origin error is given in params, this origin error will be used in the reference of generated error or string
|
|
||||||
func GetErrorCode(code string, origin error) ErrorCode {
|
|
||||||
return getErrorCode(code, origin, getNilFrame())
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTraceErrorCode return an ErrorCode interface mapped to given params code.
|
|
||||||
// If the code is not found an 'ERR_UNKNOWN' will be used instead of the awaiting error
|
|
||||||
// If an origin error is given in params, this origin error will be used in the reference of generated error or string
|
|
||||||
// This function add a trace of error generated
|
|
||||||
func GetTraceErrorCode(code string, origin error) ErrorCode {
|
|
||||||
return getErrorCode(code, origin, getFrame())
|
|
||||||
}
|
|
||||||
|
|
||||||
func getErrorCode(code string, origin error, trace runtime.Frame) ErrorCode {
|
|
||||||
var (
|
|
||||||
e ErrorType
|
|
||||||
ok bool
|
|
||||||
)
|
|
||||||
|
|
||||||
if e, ok = _listCodeErrors[code]; !ok {
|
|
||||||
e = ERR_UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
return &errorCode{
|
|
||||||
code: code,
|
|
||||||
err: e,
|
|
||||||
ori: origin,
|
|
||||||
trace: trace,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFrame() runtime.Frame {
|
|
||||||
// Set size to targetFrameIndex+2 to ensure we have room for one more caller than we need
|
|
||||||
programCounters := make([]uintptr, 0)
|
|
||||||
n := runtime.Callers(0, programCounters)
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
frames := runtime.CallersFrames(programCounters[:n])
|
|
||||||
more := true
|
|
||||||
|
|
||||||
for more {
|
|
||||||
var (
|
|
||||||
frame runtime.Frame
|
|
||||||
)
|
|
||||||
|
|
||||||
frame, more = frames.Next()
|
|
||||||
|
|
||||||
if strings.Contains(frame.Function, currPkgs) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return frame
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getNilFrame()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNilFrame() runtime.Frame {
|
|
||||||
return runtime.Frame{Function: "", File: "", Line: 0}
|
|
||||||
}
|
|
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2019 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 njs_smtp
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
func cleanMergeSlice(str []string, args ...string) []string {
|
|
||||||
for _, s := range args {
|
|
||||||
if s != "" {
|
|
||||||
str = append(str, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func unicSliceString(str []string) []string {
|
|
||||||
var new = make([]string, 0)
|
|
||||||
|
|
||||||
for _, s := range str {
|
|
||||||
if !existSliceString(new, s) {
|
|
||||||
new = append(new, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new
|
|
||||||
}
|
|
||||||
|
|
||||||
func existSliceString(slc []string, str string) bool {
|
|
||||||
for _, s := range slc {
|
|
||||||
if s == str {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanJoin(str []string, glue string) string {
|
|
||||||
var new = make([]string, 0)
|
|
||||||
|
|
||||||
for _, s := range str {
|
|
||||||
if s != "" {
|
|
||||||
new = append(new, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(new, glue)
|
|
||||||
}
|
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_password
|
package password
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
@@ -23,20 +23,23 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_progress
|
package progress
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
njs_semaphore "github.com/nabbar/golib/njs-semaphore"
|
|
||||||
"github.com/vbauerster/mpb/v5"
|
"github.com/vbauerster/mpb/v5"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
sem "github.com/nabbar/golib/semaphore"
|
||||||
)
|
)
|
||||||
|
|
||||||
type bar struct {
|
type bar struct {
|
||||||
u bool
|
u bool
|
||||||
t int64
|
t int64
|
||||||
b *mpb.Bar
|
b *mpb.Bar
|
||||||
s njs_semaphore.Sem
|
s sem.Sem
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bar interface {
|
type Bar interface {
|
||||||
@@ -45,19 +48,19 @@ type Bar interface {
|
|||||||
Increment(n int)
|
Increment(n int)
|
||||||
Refill(amount int64)
|
Refill(amount int64)
|
||||||
|
|
||||||
NewWorker() error
|
NewWorker() Error
|
||||||
NewWorkerTry() bool
|
NewWorkerTry() bool
|
||||||
DeferWorker()
|
DeferWorker()
|
||||||
DeferMain(dropBar bool)
|
DeferMain(dropBar bool)
|
||||||
|
|
||||||
WaitAll() error
|
WaitAll() Error
|
||||||
Context() context.Context
|
Context() context.Context
|
||||||
Cancel()
|
Cancel()
|
||||||
|
|
||||||
GetBarMPB() *mpb.Bar
|
GetBarMPB() *mpb.Bar
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBar(b *mpb.Bar, s njs_semaphore.Sem, total int64) Bar {
|
func newBar(b *mpb.Bar, s sem.Sem, total int64) Bar {
|
||||||
return &bar{
|
return &bar{
|
||||||
u: total > 0,
|
u: total > 0,
|
||||||
t: total,
|
t: total,
|
||||||
@@ -89,7 +92,7 @@ func (b *bar) Refill(amount int64) {
|
|||||||
b.b.SetRefill(amount)
|
b.b.SetRefill(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bar) NewWorker() error {
|
func (b *bar) NewWorker() Error {
|
||||||
if !b.u {
|
if !b.u {
|
||||||
b.t++
|
b.t++
|
||||||
b.b.SetTotal(b.t, false)
|
b.b.SetTotal(b.t, false)
|
||||||
@@ -112,7 +115,7 @@ func (b *bar) DeferMain(dropBar bool) {
|
|||||||
b.s.DeferMain()
|
b.s.DeferMain()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bar) WaitAll() error {
|
func (b *bar) WaitAll() Error {
|
||||||
return b.s.WaitAll()
|
return b.s.WaitAll()
|
||||||
}
|
}
|
||||||
|
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_progress
|
package progress
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -31,7 +31,7 @@ import (
|
|||||||
|
|
||||||
"github.com/vbauerster/mpb/v5/decor"
|
"github.com/vbauerster/mpb/v5/decor"
|
||||||
|
|
||||||
njs_semaphore "github.com/nabbar/golib/njs-semaphore"
|
njs_semaphore "github.com/nabbar/golib/semaphore"
|
||||||
|
|
||||||
"github.com/vbauerster/mpb/v5"
|
"github.com/vbauerster/mpb/v5"
|
||||||
)
|
)
|
@@ -23,15 +23,16 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
njs_logger "github.com/nabbar/golib/njs-logger"
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
|
. "github.com/nabbar/golib/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthCode uint8
|
type AuthCode uint8
|
||||||
@@ -71,7 +72,7 @@ func AuthForbidden(c *gin.Context, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type authorization struct {
|
type authorization struct {
|
||||||
check func(AuthHeader string) (AuthCode, error)
|
check func(AuthHeader string) (AuthCode, Error)
|
||||||
router []gin.HandlerFunc
|
router []gin.HandlerFunc
|
||||||
authType string
|
authType string
|
||||||
}
|
}
|
||||||
@@ -82,7 +83,7 @@ type Authorization interface {
|
|||||||
Append(router ...gin.HandlerFunc)
|
Append(router ...gin.HandlerFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthorization(HeadAuthType string, authCheckFunc func(AuthHeader string) (AuthCode, error)) Authorization {
|
func NewAuthorization(HeadAuthType string, authCheckFunc func(AuthHeader string) (AuthCode, Error)) Authorization {
|
||||||
return &authorization{
|
return &authorization{
|
||||||
check: authCheckFunc,
|
check: authCheckFunc,
|
||||||
authType: HeadAuthType,
|
authType: HeadAuthType,
|
||||||
@@ -104,7 +105,7 @@ func (a authorization) Handler(c *gin.Context) {
|
|||||||
auth := c.Request.Header.Get(HEAD_AUTH_SEND)
|
auth := c.Request.Header.Get(HEAD_AUTH_SEND)
|
||||||
|
|
||||||
if auth == "" {
|
if auth == "" {
|
||||||
AuthRequire(c, fmt.Errorf("header '%s' is missing", HEAD_AUTH_SEND))
|
AuthRequire(c, HEADER_AUTH_MISSING.Error(nil).GetErrorFull(""))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ func (a authorization) Handler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if authValue == "" {
|
if authValue == "" {
|
||||||
AuthRequire(c, fmt.Errorf("reading authorization error : auth string is empty"))
|
AuthRequire(c, HEADER_AUTH_EMPTY.Error(nil).GetErrorFull(""))
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
code, err := a.check(authValue)
|
code, err := a.check(authValue)
|
||||||
@@ -126,17 +127,16 @@ func (a authorization) Handler(c *gin.Context) {
|
|||||||
switch code {
|
switch code {
|
||||||
case AUTH_CODE_SUCCESS:
|
case AUTH_CODE_SUCCESS:
|
||||||
for _, r := range a.router {
|
for _, r := range a.router {
|
||||||
njs_logger.DebugLevel.Logf("Calling router '%s=%s'", c.Request.Method, c.Request.URL.RawPath)
|
DebugLevel.Logf("Calling router '%s=%s'", c.Request.Method, c.Request.URL.RawPath)
|
||||||
r(c)
|
r(c)
|
||||||
}
|
}
|
||||||
case AUTH_CODE_REQUIRE:
|
case AUTH_CODE_REQUIRE:
|
||||||
AuthRequire(c, fmt.Errorf("authorization error : %v", err))
|
AuthRequire(c, HEADER_AUTH_REQUIRE.Error(err).GetErrorFull(""))
|
||||||
case AUTH_CODE_FORBIDDEN:
|
case AUTH_CODE_FORBIDDEN:
|
||||||
AuthForbidden(c, fmt.Errorf("authorization error : %v", err))
|
AuthForbidden(c, HEADER_AUTH_FORBIDDEN.Error(err).GetErrorFull(""))
|
||||||
default:
|
default:
|
||||||
err := fmt.Errorf("auth response code is not valid")
|
|
||||||
c.Errors = append(c.Errors, &gin.Error{
|
c.Errors = append(c.Errors, &gin.Error{
|
||||||
Err: err,
|
Err: HEADER_AUTH_ERROR.Error(err).GetErrorFull(""),
|
||||||
Type: gin.ErrorTypePrivate,
|
Type: gin.ErrorTypePrivate,
|
||||||
})
|
})
|
||||||
c.AbortWithStatus(http.StatusInternalServerError)
|
c.AbortWithStatus(http.StatusInternalServerError)
|
61
router/error.go
Normal file
61
router/error.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 router
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Router
|
||||||
|
HEADER_AUTH_MISSING
|
||||||
|
HEADER_AUTH_EMPTY
|
||||||
|
HEADER_AUTH_REQUIRE
|
||||||
|
HEADER_AUTH_FORBIDDEN
|
||||||
|
HEADER_AUTH_ERROR
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case HEADER_AUTH_MISSING:
|
||||||
|
return "missing authorization header"
|
||||||
|
case HEADER_AUTH_EMPTY:
|
||||||
|
return "authorization header is empty"
|
||||||
|
case HEADER_AUTH_REQUIRE:
|
||||||
|
return "authorization check failed, authorization still require"
|
||||||
|
case HEADER_AUTH_FORBIDDEN:
|
||||||
|
return "authorization check success but unauthorized client"
|
||||||
|
case HEADER_AUTH_ERROR:
|
||||||
|
return "authorization check return an invalid response code"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -50,7 +50,7 @@ type Headers interface {
|
|||||||
|
|
||||||
func NewHeaders() Headers {
|
func NewHeaders() Headers {
|
||||||
return &headers{
|
return &headers{
|
||||||
head: make(http.Header, 0),
|
head: make(http.Header),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ func (h headers) Handler(c *gin.Context) {
|
|||||||
// It appends to any existing values associated with key.
|
// It appends to any existing values associated with key.
|
||||||
func (h *headers) Add(key, value string) {
|
func (h *headers) Add(key, value string) {
|
||||||
if h.head == nil {
|
if h.head == nil {
|
||||||
h.head = make(http.Header, 0)
|
h.head = make(http.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.head.Add(key, value)
|
h.head.Add(key, value)
|
||||||
@@ -107,7 +107,7 @@ func (h *headers) Add(key, value string) {
|
|||||||
// values associated with key.
|
// values associated with key.
|
||||||
func (h *headers) Set(key, value string) {
|
func (h *headers) Set(key, value string) {
|
||||||
if h.head == nil {
|
if h.head == nil {
|
||||||
h.head = make(http.Header, 0)
|
h.head = make(http.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.head.Set(key, value)
|
h.head.Set(key, value)
|
||||||
@@ -121,7 +121,7 @@ func (h *headers) Set(key, value string) {
|
|||||||
// access the map directly.
|
// access the map directly.
|
||||||
func (h headers) Get(key string) string {
|
func (h headers) Get(key string) string {
|
||||||
if h.head == nil {
|
if h.head == nil {
|
||||||
h.head = make(http.Header, 0)
|
h.head = make(http.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.head.Get(key)
|
return h.head.Get(key)
|
||||||
@@ -130,7 +130,7 @@ func (h headers) Get(key string) string {
|
|||||||
// Del deletes the values associated with key.
|
// Del deletes the values associated with key.
|
||||||
func (h *headers) Del(key string) {
|
func (h *headers) Del(key string) {
|
||||||
if h.head == nil {
|
if h.head == nil {
|
||||||
h.head = make(http.Header, 0)
|
h.head = make(http.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.head.Del(key)
|
h.head.Del(key)
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -68,7 +68,7 @@ func RoutersHandler(engine *gin.Engine) {
|
|||||||
|
|
||||||
func NewRouterList() RouterList {
|
func NewRouterList() RouterList {
|
||||||
return &routerList{
|
return &routerList{
|
||||||
list: make(map[string][]routerItem, 0),
|
list: make(map[string][]routerItem),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -38,16 +38,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Compatibility
|
|
||||||
// @TODO: clean this func
|
|
||||||
|
|
||||||
// deprecated
|
|
||||||
// SetGinHnadler func that return given func as ginTonic HandlerFunc interface type
|
|
||||||
// use SetGinHandler instead of SetGinHnadler
|
|
||||||
func SetGinHnadler(fct func(c *gin.Context)) gin.HandlerFunc {
|
|
||||||
return SetGinHandler(fct)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGinHandler func that return given func as ginTonic HandlerFunc interface type
|
// SetGinHandler func that return given func as ginTonic HandlerFunc interface type
|
||||||
func SetGinHandler(fct func(c *gin.Context)) gin.HandlerFunc {
|
func SetGinHandler(fct func(c *gin.Context)) gin.HandlerFunc {
|
||||||
return fct
|
return fct
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_semaphore
|
package semaphore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Nicolas JUHEL
|
* Copyright (c) 2020 Nicolas JUHEL
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -21,27 +21,32 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_errors
|
package semaphore
|
||||||
|
|
||||||
import "fmt"
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
type ErrorType string
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Semaphore
|
||||||
|
NEW_WORKER
|
||||||
|
WAITALL
|
||||||
|
)
|
||||||
|
|
||||||
const ERR_UNKNOWN ErrorType = "unknown error"
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
// String return the string form of the current ErrorType
|
|
||||||
func (e ErrorType) String() string {
|
|
||||||
return string(e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error return an error type of the current ErrorType
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
// If an origin error is given (and not nil), this origin error will be append of the string (comma separated)
|
switch code {
|
||||||
func (e ErrorType) Error(origin error) error {
|
case EMPTY_PARAMS:
|
||||||
if origin != nil {
|
return "given parameters is empty"
|
||||||
return fmt.Errorf("%s, %v", e.String(), origin)
|
case NEW_WORKER:
|
||||||
|
return "error on acquire one new semaphore worker"
|
||||||
|
case WAITALL:
|
||||||
|
return "error on acquire to wait all pending thread"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("%s", e.String())
|
return ""
|
||||||
}
|
}
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_semaphore
|
package semaphore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -31,6 +31,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/sync/semaphore"
|
"golang.org/x/sync/semaphore"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sem struct {
|
type sem struct {
|
||||||
@@ -41,12 +43,12 @@ type sem struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Sem interface {
|
type Sem interface {
|
||||||
NewWorker() error
|
NewWorker() Error
|
||||||
NewWorkerTry() bool
|
NewWorkerTry() bool
|
||||||
DeferWorker()
|
DeferWorker()
|
||||||
DeferMain()
|
DeferMain()
|
||||||
|
|
||||||
WaitAll() error
|
WaitAll() Error
|
||||||
Context() context.Context
|
Context() context.Context
|
||||||
Cancel()
|
Cancel()
|
||||||
}
|
}
|
||||||
@@ -70,20 +72,18 @@ func NewSemaphore(maxSimultaneous int, timeout time.Duration, deadline time.Time
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sem) NewWorker() error {
|
func (s *sem) NewWorker() Error {
|
||||||
if e := s.s.Acquire(s.x, 1); e != nil {
|
e := s.s.Acquire(s.x, 1)
|
||||||
return e
|
return NEW_WORKER.Iferror(e)
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sem) NewWorkerTry() bool {
|
func (s *sem) NewWorkerTry() bool {
|
||||||
return s.s.TryAcquire(1)
|
return s.s.TryAcquire(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sem) WaitAll() error {
|
func (s *sem) WaitAll() Error {
|
||||||
return s.s.Acquire(s.Context(), s.m)
|
e := s.s.Acquire(s.Context(), s.m)
|
||||||
|
return WAITALL.Iferror(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sem) DeferWorker() {
|
func (s *sem) DeferWorker() {
|
||||||
@@ -102,6 +102,7 @@ func (s *sem) Cancel() {
|
|||||||
|
|
||||||
func (s *sem) Context() context.Context {
|
func (s *sem) Context() context.Context {
|
||||||
if s.x == nil {
|
if s.x == nil {
|
||||||
|
s.x, s.c = GetContext(0, GetEmptyTime(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.x
|
return s.x
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/mail"
|
"net/mail"
|
@@ -22,13 +22,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type attachment struct {
|
type attachment struct {
|
||||||
@@ -86,15 +88,15 @@ func NewAttachment(name string) Attachment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAttachmentFile(name string, filepath string) (Attachment, error) {
|
func NewAttachmentFile(name string, filepath string) (Attachment, Error) {
|
||||||
var b = bytes.NewBuffer([]byte{})
|
var b = bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
if _, e := os.Stat(filepath); e != nil {
|
if _, e := os.Stat(filepath); e != nil {
|
||||||
return nil, e
|
return nil, FILE_STAT.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bb, e := ioutil.ReadFile(filepath); e != nil {
|
if bb, e := ioutil.ReadFile(filepath); e != nil {
|
||||||
return nil, e
|
return nil, FILE_READ.ErrorParent(e)
|
||||||
} else {
|
} else {
|
||||||
b.Write(bb)
|
b.Write(bb)
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -34,8 +34,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
njs_certif "github.com/nabbar/golib/njs-certif"
|
njs_certif "github.com/nabbar/golib/certificates"
|
||||||
. "github.com/nabbar/golib/njs-logger"
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type smtpConfig struct {
|
type smtpConfig struct {
|
||||||
@@ -58,9 +59,9 @@ type smtpClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SMTP interface {
|
type SMTP interface {
|
||||||
Client() (*smtp.Client, error)
|
Client() (*smtp.Client, Error)
|
||||||
Close()
|
Close()
|
||||||
Check() error
|
Check() Error
|
||||||
Clone() SMTP
|
Clone() SMTP
|
||||||
|
|
||||||
ForceHost(host string)
|
ForceHost(host string)
|
||||||
@@ -141,7 +142,7 @@ func (n NETMode) string() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseDSN parses the DSN string to a Config
|
// ParseDSN parses the DSN string to a Config
|
||||||
func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
func newSMTPConfig(dsn string) (*smtpConfig, Error) {
|
||||||
var (
|
var (
|
||||||
smtpcnf = &smtpConfig{
|
smtpcnf = &smtpConfig{
|
||||||
DSN: dsn,
|
DSN: dsn,
|
||||||
@@ -191,9 +192,9 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
|||||||
// dsn[i-1] must be == ')' if an address is specified
|
// dsn[i-1] must be == ')' if an address is specified
|
||||||
if dsn[i-1] != ')' {
|
if dsn[i-1] != ')' {
|
||||||
if strings.ContainsRune(dsn[k+1:i], ')') {
|
if strings.ContainsRune(dsn[k+1:i], ')') {
|
||||||
return nil, fmt.Errorf("invalid DSN: did you forget to escape a param value")
|
return nil, CONFIG_INVALID_DSN.Error(nil)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("invalid DSN: network address not terminated (missing closing brace)")
|
return nil, CONFIG_INVALID_NETWORK.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.ContainsRune(dsn[k+1:i-1], ':') {
|
if strings.ContainsRune(dsn[k+1:i-1], ':') {
|
||||||
@@ -225,7 +226,7 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
|||||||
if dsn[j] == '?' {
|
if dsn[j] == '?' {
|
||||||
|
|
||||||
if val, err := url.ParseQuery(dsn[j+1:]); err != nil {
|
if val, err := url.ParseQuery(dsn[j+1:]); err != nil {
|
||||||
return nil, err
|
return nil, CONFIG_INVALID_PARAMS.ErrorParent(err)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if val.Get("ServerName") != "" {
|
if val.Get("ServerName") != "" {
|
||||||
@@ -250,7 +251,7 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !foundSlash && len(dsn) > 0 {
|
if !foundSlash && len(dsn) > 0 {
|
||||||
return nil, fmt.Errorf("invalid DSN: missing the slash ending the host")
|
return nil, CONFIG_INVALID_HOST.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return smtpcnf, nil
|
return smtpcnf, nil
|
||||||
@@ -261,7 +262,7 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
|||||||
// - params available are : ServerName (string), SkipVerify (boolean)
|
// - params available are : ServerName (string), SkipVerify (boolean)
|
||||||
// - tls mode acceptable are : starttls, tls, <any other value to no tls/startls>
|
// - tls mode acceptable are : starttls, tls, <any other value to no tls/startls>
|
||||||
// - net aceeptable are : tcp4, tcp6, unix
|
// - net aceeptable are : tcp4, tcp6, unix
|
||||||
func NewSMTP(dsn string, tlsConfig *tls.Config) (SMTP, error) {
|
func NewSMTP(dsn string, tlsConfig *tls.Config) (SMTP, Error) {
|
||||||
if tlsConfig == nil {
|
if tlsConfig == nil {
|
||||||
tlsConfig = njs_certif.GetTLSConfig("")
|
tlsConfig = njs_certif.GetTLSConfig("")
|
||||||
}
|
}
|
||||||
@@ -277,7 +278,7 @@ func NewSMTP(dsn string, tlsConfig *tls.Config) (SMTP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Client Get SMTP Client interface
|
// Client Get SMTP Client interface
|
||||||
func (s *smtpClient) Client() (*smtp.Client, error) {
|
func (s *smtpClient) Client() (*smtp.Client, Error) {
|
||||||
if s.cli == nil {
|
if s.cli == nil {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
@@ -299,35 +300,34 @@ func (s *smtpClient) Client() (*smtp.Client, error) {
|
|||||||
|
|
||||||
if s.cfg.TLS == TLS_TLS {
|
if s.cfg.TLS == TLS_TLS {
|
||||||
s.con, err = tls.Dial(s.cfg.Net.string(), addr, tlsc)
|
s.con, err = tls.Dial(s.cfg.Net.string(), addr, tlsc)
|
||||||
if ErrorLevel.LogErrorCtxf(DebugLevel, "trying to intialize SMTP '%s' over tls connection to '%s'", err, s.cfg.Net.string(), addr) {
|
if err != nil {
|
||||||
s.cfg.TLS = TLS_STARTTLS
|
s.cfg.TLS = TLS_STARTTLS
|
||||||
err = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.cfg.TLS != TLS_TLS {
|
if s.cfg.TLS != TLS_TLS {
|
||||||
s.con, err = net.Dial(s.cfg.Net.string(), addr)
|
s.con, err = net.Dial(s.cfg.Net.string(), addr)
|
||||||
if ErrorLevel.LogErrorCtxf(DebugLevel, "Dial initiated to server '%s' over '%s'", err, addr, s.cfg.Net.string()) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, SMTP_DIAL.ErrorParent(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.cli, err = smtp.NewClient(s.con, addr)
|
s.cli, err = smtp.NewClient(s.con, addr)
|
||||||
if ErrorLevel.LogErrorCtxf(DebugLevel, "SMTP Client initiated to server '%s' over '%s'", err, addr, s.cfg.Net.string()) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, SMTP_CLIENT_INIT.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.cfg.TLS == TLS_STARTTLS {
|
if s.cfg.TLS == TLS_STARTTLS {
|
||||||
err = s.cli.StartTLS(tlsc)
|
err = s.cli.StartTLS(tlsc)
|
||||||
if ErrorLevel.LogErrorCtxf(DebugLevel, "SMTP Client STARTTLS initiated to server '%s' over '%s'", err, addr, s.cfg.Net.string()) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, SMTP_CLIENT_STARTTLS.ErrorParent(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.cfg.User != "" || s.cfg.Pass != "" {
|
if s.cfg.User != "" || s.cfg.Pass != "" {
|
||||||
err = s.cli.Auth(smtp.PlainAuth("", s.cfg.User, s.cfg.Pass, addr))
|
err = s.cli.Auth(smtp.PlainAuth("", s.cfg.User, s.cfg.Pass, addr))
|
||||||
if ErrorLevel.LogErrorCtxf(DebugLevel, "SMTP Client authentificate user '%s' with server '%s' over '%s'", err, s.cfg.User, addr, s.cfg.Net.string()) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, SMTP_CLIENT_AUTH.ErrorParent(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,25 +341,25 @@ func (s *smtpClient) Client() (*smtp.Client, error) {
|
|||||||
func (s *smtpClient) Close() {
|
func (s *smtpClient) Close() {
|
||||||
if s.cli != nil {
|
if s.cli != nil {
|
||||||
if e := s.cli.Quit(); e != nil {
|
if e := s.cli.Quit(); e != nil {
|
||||||
s.cli.Close()
|
_ = s.cli.Close()
|
||||||
}
|
}
|
||||||
s.cli = nil
|
s.cli = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.con != nil {
|
if s.con != nil {
|
||||||
s.con.Close()
|
_ = s.con.Close()
|
||||||
s.con = nil
|
s.con = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Try to initiate SMTP dial and negotiation and try to close connection
|
// Check Try to initiate SMTP dial and negotiation and try to close connection
|
||||||
func (s *smtpClient) Check() error {
|
func (s *smtpClient) Check() Error {
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
if c, e := s.Client(); e != nil {
|
if c, e := s.Client(); e != nil {
|
||||||
return e
|
return e
|
||||||
} else if e = c.Noop(); e != nil {
|
} else if e := c.Noop(); e != nil {
|
||||||
return e
|
return SMTP_CLIENT_NOOP.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
145
smtp/error.go
Normal file
145
smtp/error.go
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 smtp
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_SMTP
|
||||||
|
FILE_STAT
|
||||||
|
FILE_READ
|
||||||
|
CONFIG_INVALID_DSN
|
||||||
|
CONFIG_INVALID_NETWORK
|
||||||
|
CONFIG_INVALID_PARAMS
|
||||||
|
CONFIG_INVALID_HOST
|
||||||
|
SMTP_DIAL
|
||||||
|
SMTP_SEND
|
||||||
|
SMTP_CLIENT_INIT
|
||||||
|
SMTP_CLIENT_STARTTLS
|
||||||
|
SMTP_CLIENT_AUTH
|
||||||
|
SMTP_CLIENT_NOOP
|
||||||
|
SMTP_CLIENT_MAIL
|
||||||
|
SMTP_CLIENT_RCPT
|
||||||
|
SMTP_CLIENT_DATA
|
||||||
|
SMTP_CLIENT_EMPTY
|
||||||
|
SMTP_CLIENT_SEND_RECOVERED
|
||||||
|
SMTP_CLIENT_FROM_EMPTY
|
||||||
|
SMTP_CLIENT_TO_EMPTY
|
||||||
|
SMTP_CLIENT_SUBJECT_EMPTY
|
||||||
|
SMTP_CLIENT_MAILER_EMPTY
|
||||||
|
RAND_READER
|
||||||
|
BUFFER_EMPTY
|
||||||
|
BUFFER_WRITE_STRING
|
||||||
|
BUFFER_WRITE_BYTES
|
||||||
|
IO_WRITER_MISSING
|
||||||
|
IO_WRITER_ERROR
|
||||||
|
EMPTY_HTML
|
||||||
|
EMPTY_CONTENTS
|
||||||
|
TEMPLATE_PARSING
|
||||||
|
TEMPLATE_EXECUTE
|
||||||
|
TEMPLATE_CLONE
|
||||||
|
TEMPLATE_HTML2TEXT
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case FILE_STAT:
|
||||||
|
return "error occurs on getting stat of file"
|
||||||
|
case FILE_READ:
|
||||||
|
return "error occurs on reading file"
|
||||||
|
case CONFIG_INVALID_DSN:
|
||||||
|
return "invalid DSN: did you forget to escape a param value"
|
||||||
|
case CONFIG_INVALID_NETWORK:
|
||||||
|
return "invalid DSN: network address not terminated (missing closing brace)"
|
||||||
|
case CONFIG_INVALID_PARAMS:
|
||||||
|
return "invalid DSN: parsing uri parameters occurs an error"
|
||||||
|
case CONFIG_INVALID_HOST:
|
||||||
|
return "invalid DSN: missing the slash ending the host"
|
||||||
|
case SMTP_DIAL:
|
||||||
|
return "error while trying to dial with SMTP server"
|
||||||
|
case SMTP_SEND:
|
||||||
|
return "error while sending mail to SMTP server"
|
||||||
|
case SMTP_CLIENT_INIT:
|
||||||
|
return "error while trying to initialize new client for dial connection to SMTP Server"
|
||||||
|
case SMTP_CLIENT_STARTTLS:
|
||||||
|
return "error while trying to starttls on SMTP server"
|
||||||
|
case SMTP_CLIENT_AUTH:
|
||||||
|
return "error while trying to authenticate to SMTP server"
|
||||||
|
case SMTP_CLIENT_NOOP:
|
||||||
|
return "error on sending noop command to check connection with SMTP server"
|
||||||
|
case SMTP_CLIENT_MAIL:
|
||||||
|
return "error on sending mail command to initialize new mail transaction with SMTP server"
|
||||||
|
case SMTP_CLIENT_RCPT:
|
||||||
|
return "error on sending rcpt command to specify add recipient email for the new mail"
|
||||||
|
case SMTP_CLIENT_DATA:
|
||||||
|
return "error on opening io writer to send data on client"
|
||||||
|
case SMTP_CLIENT_EMPTY:
|
||||||
|
return "cannot send email without any attachment and contents"
|
||||||
|
case SMTP_CLIENT_SEND_RECOVERED:
|
||||||
|
return "recovered error while client sending mail"
|
||||||
|
case SMTP_CLIENT_FROM_EMPTY:
|
||||||
|
return "sender From address cannot be empty"
|
||||||
|
case SMTP_CLIENT_TO_EMPTY:
|
||||||
|
return "list of recipient To address cannot be empty"
|
||||||
|
case SMTP_CLIENT_SUBJECT_EMPTY:
|
||||||
|
return "subject of the new mail cannot be empty"
|
||||||
|
case SMTP_CLIENT_MAILER_EMPTY:
|
||||||
|
return "mailer of the new mail cannot be empty"
|
||||||
|
case RAND_READER:
|
||||||
|
return "error on reading on random reader io"
|
||||||
|
case BUFFER_EMPTY:
|
||||||
|
return "buffer is empty"
|
||||||
|
case BUFFER_WRITE_STRING:
|
||||||
|
return "error on write string into buffer"
|
||||||
|
case BUFFER_WRITE_BYTES:
|
||||||
|
return "error on write bytes into buffer"
|
||||||
|
case IO_WRITER_MISSING:
|
||||||
|
return "io writer is not defined"
|
||||||
|
case IO_WRITER_ERROR:
|
||||||
|
return "error occur on write on io writer"
|
||||||
|
case EMPTY_HTML:
|
||||||
|
return "text/html content is empty"
|
||||||
|
case EMPTY_CONTENTS:
|
||||||
|
return "mail content is empty"
|
||||||
|
case TEMPLATE_PARSING:
|
||||||
|
return "error occur on parsing template"
|
||||||
|
case TEMPLATE_EXECUTE:
|
||||||
|
return "error occur on execute template"
|
||||||
|
case TEMPLATE_CLONE:
|
||||||
|
return "error occur while cloning template"
|
||||||
|
case TEMPLATE_HTML2TEXT:
|
||||||
|
return "error occur on reading io reader html and convert it to text"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -31,6 +31,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContentType uint8
|
type ContentType uint8
|
||||||
@@ -63,14 +65,14 @@ type ioData struct {
|
|||||||
b string
|
b string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) getBoundary() (string, error) {
|
func (i *ioData) getBoundary() (string, Error) {
|
||||||
if i.b == "" {
|
if i.b == "" {
|
||||||
var buf [30]byte
|
var buf [30]byte
|
||||||
|
|
||||||
_, err := io.ReadFull(rand.Reader, buf[:])
|
_, err := io.ReadFull(rand.Reader, buf[:])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", RAND_READER.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bnd := fmt.Sprintf("%x", buf[:])
|
bnd := fmt.Sprintf("%x", buf[:])
|
||||||
@@ -85,11 +87,11 @@ func (i ioData) GetBuffer() *bytes.Buffer {
|
|||||||
return i.p
|
return i.p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) CRLF() error {
|
func (i *ioData) CRLF() Error {
|
||||||
return i.String("\r\n")
|
return i.String("\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) ContentType(ct ContentType, charset string) error {
|
func (i *ioData) ContentType(ct ContentType, charset string) Error {
|
||||||
if charset != "" {
|
if charset != "" {
|
||||||
return i.Header("Content-Type", fmt.Sprintf("\"%s\"; charset=%s", ct.String(), charset))
|
return i.Header("Content-Type", fmt.Sprintf("\"%s\"; charset=%s", ct.String(), charset))
|
||||||
} else {
|
} else {
|
||||||
@@ -97,7 +99,7 @@ func (i *ioData) ContentType(ct ContentType, charset string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) BoundaryStart(ct ContentType) error {
|
func (i *ioData) BoundaryStart(ct ContentType) Error {
|
||||||
if b, err := i.getBoundary(); err != nil {
|
if b, err := i.getBoundary(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err = i.Header("Content-Type", fmt.Sprintf("%s; boundary=\"%s\"", ct.String(), b)); err != nil {
|
} else if err = i.Header("Content-Type", fmt.Sprintf("%s; boundary=\"%s\"", ct.String(), b)); err != nil {
|
||||||
@@ -107,7 +109,7 @@ func (i *ioData) BoundaryStart(ct ContentType) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) BoundaryPart() error {
|
func (i *ioData) BoundaryPart() Error {
|
||||||
if i.b == "" {
|
if i.b == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -121,7 +123,7 @@ func (i *ioData) BoundaryPart() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) BoundaryEnd() error {
|
func (i *ioData) BoundaryEnd() Error {
|
||||||
if b, err := i.getBoundary(); err != nil {
|
if b, err := i.getBoundary(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err = i.CRLF(); err != nil {
|
} else if err = i.CRLF(); err != nil {
|
||||||
@@ -133,23 +135,23 @@ func (i *ioData) BoundaryEnd() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) Header(key, value string) error {
|
func (i *ioData) Header(key, value string) Error {
|
||||||
return i.String(fmt.Sprintf("%s: %s\r\n", key, value))
|
return i.String(fmt.Sprintf("%s: %s\r\n", key, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) String(value string) error {
|
func (i *ioData) String(value string) Error {
|
||||||
if i.p == nil {
|
if i.p == nil {
|
||||||
i.p = bytes.NewBuffer(make([]byte, 0))
|
i.p = bytes.NewBuffer(make([]byte, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, e := i.p.WriteString(value); e != nil {
|
if _, e := i.p.WriteString(value); e != nil {
|
||||||
return e
|
return BUFFER_WRITE_STRING.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) Bytes(value []byte) error {
|
func (i *ioData) Bytes(value []byte) Error {
|
||||||
if i.p == nil {
|
if i.p == nil {
|
||||||
i.p = bytes.NewBuffer(make([]byte, 0))
|
i.p = bytes.NewBuffer(make([]byte, 0))
|
||||||
}
|
}
|
||||||
@@ -161,7 +163,7 @@ func (i *ioData) Bytes(value []byte) error {
|
|||||||
|
|
||||||
if (n+1)%76 == 0 {
|
if (n+1)%76 == 0 {
|
||||||
if _, e := i.p.Write(tmp); e != nil {
|
if _, e := i.p.Write(tmp); e != nil {
|
||||||
return e
|
return BUFFER_WRITE_BYTES.ErrorParent(e)
|
||||||
} else if e := i.CRLF(); e != nil {
|
} else if e := i.CRLF(); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@@ -172,7 +174,7 @@ func (i *ioData) Bytes(value []byte) error {
|
|||||||
|
|
||||||
if len(tmp) != 0 {
|
if len(tmp) != 0 {
|
||||||
if _, e := i.p.Write(tmp); e != nil {
|
if _, e := i.p.Write(tmp); e != nil {
|
||||||
return e
|
return BUFFER_WRITE_BYTES.ErrorParent(e)
|
||||||
} else if e := i.CRLF(); e != nil {
|
} else if e := i.CRLF(); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@@ -181,28 +183,27 @@ func (i *ioData) Bytes(value []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) Send() error {
|
func (i *ioData) Send() Error {
|
||||||
if i.w == nil {
|
if i.w == nil {
|
||||||
return fmt.Errorf("empty writer")
|
return IO_WRITER_MISSING.Error(nil)
|
||||||
}
|
}
|
||||||
if i.p == nil || i.p.Len() < 1 {
|
if i.p == nil || i.p.Len() < 1 {
|
||||||
return fmt.Errorf("empty buffer")
|
return BUFFER_EMPTY.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, e := i.w.Write(i.p.Bytes()); e != nil {
|
if _, e := i.w.Write(i.p.Bytes()); e != nil {
|
||||||
return e
|
return IO_WRITER_ERROR.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) AttachmentStart(c ContentType) error {
|
func (i *ioData) AttachmentStart(c ContentType) Error {
|
||||||
return i.BoundaryStart(c)
|
return i.BoundaryStart(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) AttachmentAddFile(contentType, attachmentName string, attachment *bytes.Buffer) error {
|
func (i *ioData) AttachmentAddFile(contentType, attachmentName string, attachment *bytes.Buffer) Error {
|
||||||
var (
|
var (
|
||||||
e error
|
|
||||||
c = make([]byte, base64.StdEncoding.EncodedLen(attachment.Len()))
|
c = make([]byte, base64.StdEncoding.EncodedLen(attachment.Len()))
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -210,10 +211,10 @@ func (i *ioData) AttachmentAddFile(contentType, attachmentName string, attachmen
|
|||||||
base64.StdEncoding.Encode(c, attachment.Bytes())
|
base64.StdEncoding.Encode(c, attachment.Bytes())
|
||||||
|
|
||||||
if len(c) < 1 {
|
if len(c) < 1 {
|
||||||
return fmt.Errorf("encoded buffer is empty")
|
return BUFFER_EMPTY.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e = i.BoundaryPart(); e != nil {
|
if e := i.BoundaryPart(); e != nil {
|
||||||
return e
|
return e
|
||||||
} else if e = i.Header("Content-Type", contentType); e != nil {
|
} else if e = i.Header("Content-Type", contentType); e != nil {
|
||||||
return e
|
return e
|
||||||
@@ -234,14 +235,14 @@ func (i *ioData) AttachmentAddFile(contentType, attachmentName string, attachmen
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) AttachmentAddBody(m MailTemplate, ct ContentType) error {
|
func (i *ioData) AttachmentAddBody(m MailTemplate, ct ContentType) Error {
|
||||||
var (
|
var (
|
||||||
e error
|
e Error
|
||||||
p *bytes.Buffer
|
p *bytes.Buffer
|
||||||
)
|
)
|
||||||
|
|
||||||
if m.IsEmpty() {
|
if m.IsEmpty() {
|
||||||
return fmt.Errorf("text/html content is empty")
|
return EMPTY_HTML.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ct {
|
switch ct {
|
||||||
@@ -280,7 +281,7 @@ func (i *ioData) AttachmentAddBody(m MailTemplate, ct ContentType) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ioData) AttachmentEnd() error {
|
func (i *ioData) AttachmentEnd() Error {
|
||||||
if e := i.BoundaryEnd(); e != nil {
|
if e := i.BoundaryEnd(); e != nil {
|
||||||
return e
|
return e
|
||||||
} else if e = i.BoundaryEnd(); e != nil {
|
} else if e = i.BoundaryEnd(); e != nil {
|
||||||
@@ -291,24 +292,24 @@ func (i *ioData) AttachmentEnd() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IOData interface {
|
type IOData interface {
|
||||||
ContentType(ct ContentType, charset string) error
|
ContentType(ct ContentType, charset string) Error
|
||||||
Header(key, value string) error
|
Header(key, value string) Error
|
||||||
String(value string) error
|
String(value string) Error
|
||||||
Bytes(value []byte) error
|
Bytes(value []byte) Error
|
||||||
CRLF() error
|
CRLF() Error
|
||||||
|
|
||||||
Send() error
|
Send() Error
|
||||||
GetBuffer() *bytes.Buffer
|
GetBuffer() *bytes.Buffer
|
||||||
|
|
||||||
AttachmentStart(c ContentType) error
|
AttachmentStart(c ContentType) Error
|
||||||
AttachmentAddFile(contentType, attachmentName string, attachment *bytes.Buffer) error
|
AttachmentAddFile(contentType, attachmentName string, attachment *bytes.Buffer) Error
|
||||||
AttachmentAddBody(m MailTemplate, ct ContentType) error
|
AttachmentAddBody(m MailTemplate, ct ContentType) Error
|
||||||
AttachmentEnd() error
|
AttachmentEnd() Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIOData(cli *smtp.Client) (IOData, error) {
|
func NewIOData(cli *smtp.Client) (IOData, Error) {
|
||||||
if w, e := cli.Data(); e != nil {
|
if w, e := cli.Data(); e != nil {
|
||||||
return nil, e
|
return nil, SMTP_CLIENT_DATA.ErrorParent(e)
|
||||||
} else {
|
} else {
|
||||||
return &ioData{
|
return &ioData{
|
||||||
w: w,
|
w: w,
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ func (lst listMailAddress) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (lst listMailAddress) Clone() ListMailAddress {
|
func (lst listMailAddress) Clone() ListMailAddress {
|
||||||
var l = make(listMailAddress, 0)
|
var l = make(listMailAddress)
|
||||||
|
|
||||||
for _, a := range lst {
|
for _, a := range lst {
|
||||||
l.Add(a.Clone())
|
l.Add(a.Clone())
|
||||||
@@ -125,5 +125,5 @@ type ListMailAddress interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewListMailAddress() ListMailAddress {
|
func NewListMailAddress() ListMailAddress {
|
||||||
return make(listMailAddress, 0)
|
return make(listMailAddress)
|
||||||
}
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -6,9 +6,10 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/jaytaylor/html2text"
|
||||||
"github.com/olekukonko/tablewriter"
|
"github.com/olekukonko/tablewriter"
|
||||||
|
|
||||||
"github.com/jaytaylor/html2text"
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mailTemplate struct {
|
type mailTemplate struct {
|
||||||
@@ -34,7 +35,7 @@ func (m mailTemplate) GetTextOption() html2text.Options {
|
|||||||
return m.opt
|
return m.opt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mailTemplate) GetBufferHtml(data interface{}) (*bytes.Buffer, error) {
|
func (m mailTemplate) GetBufferHtml(data interface{}) (*bytes.Buffer, Error) {
|
||||||
var res = bytes.NewBuffer(make([]byte, 0))
|
var res = bytes.NewBuffer(make([]byte, 0))
|
||||||
|
|
||||||
if data == nil {
|
if data == nil {
|
||||||
@@ -42,30 +43,31 @@ func (m mailTemplate) GetBufferHtml(data interface{}) (*bytes.Buffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := m.tpl.Execute(res, data); err != nil {
|
if err := m.tpl.Execute(res, data); err != nil {
|
||||||
return nil, err
|
return nil, TEMPLATE_EXECUTE.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mailTemplate) GetBufferText(data interface{}) (*bytes.Buffer, error) {
|
func (m mailTemplate) GetBufferText(data interface{}) (*bytes.Buffer, Error) {
|
||||||
var (
|
var (
|
||||||
res = bytes.NewBuffer(make([]byte, 0))
|
res = bytes.NewBuffer(make([]byte, 0))
|
||||||
str string
|
str string
|
||||||
|
e error
|
||||||
)
|
)
|
||||||
|
|
||||||
if buf, err := m.GetBufferHtml(data); err != nil {
|
if buf, err := m.GetBufferHtml(data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if str, err = html2text.FromReader(buf, m.opt); err != nil {
|
} else if str, e = html2text.FromReader(buf, m.opt); e != nil {
|
||||||
return nil, err
|
return nil, TEMPLATE_HTML2TEXT.ErrorParent(e)
|
||||||
} else if _, err = res.WriteString(str); err != nil {
|
} else if _, e = res.WriteString(str); e != nil {
|
||||||
return nil, err
|
return nil, BUFFER_WRITE_STRING.ErrorParent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mailTemplate) GetBufferRich(data interface{}) (*bytes.Buffer, error) {
|
func (m mailTemplate) GetBufferRich(data interface{}) (*bytes.Buffer, Error) {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +87,7 @@ func (m mailTemplate) IsEmpty() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m mailTemplate) Clone() (MailTemplate, error) {
|
func (m mailTemplate) Clone() (MailTemplate, Error) {
|
||||||
res := &mailTemplate{
|
res := &mailTemplate{
|
||||||
data: nil,
|
data: nil,
|
||||||
char: m.char,
|
char: m.char,
|
||||||
@@ -94,7 +96,7 @@ func (m mailTemplate) Clone() (MailTemplate, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tpl, err := m.tpl.Clone(); err != nil {
|
if tpl, err := m.tpl.Clone(); err != nil {
|
||||||
return nil, err
|
return nil, TEMPLATE_CLONE.ErrorParent(err)
|
||||||
} else {
|
} else {
|
||||||
res.tpl = tpl
|
res.tpl = tpl
|
||||||
}
|
}
|
||||||
@@ -103,7 +105,7 @@ func (m mailTemplate) Clone() (MailTemplate, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MailTemplate interface {
|
type MailTemplate interface {
|
||||||
Clone() (MailTemplate, error)
|
Clone() (MailTemplate, Error)
|
||||||
|
|
||||||
IsEmpty() bool
|
IsEmpty() bool
|
||||||
|
|
||||||
@@ -113,14 +115,14 @@ type MailTemplate interface {
|
|||||||
SetTextOption(opt html2text.Options)
|
SetTextOption(opt html2text.Options)
|
||||||
GetTextOption() html2text.Options
|
GetTextOption() html2text.Options
|
||||||
|
|
||||||
GetBufferHtml(data interface{}) (*bytes.Buffer, error)
|
GetBufferHtml(data interface{}) (*bytes.Buffer, Error)
|
||||||
GetBufferText(data interface{}) (*bytes.Buffer, error)
|
GetBufferText(data interface{}) (*bytes.Buffer, Error)
|
||||||
GetBufferRich(data interface{}) (*bytes.Buffer, error)
|
GetBufferRich(data interface{}) (*bytes.Buffer, Error)
|
||||||
|
|
||||||
RegisterData(data interface{})
|
RegisterData(data interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMailTemplate(name, tpl string, isFile bool) (MailTemplate, error) {
|
func NewMailTemplate(name, tpl string, isFile bool) (MailTemplate, Error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
res = &mailTemplate{
|
res = &mailTemplate{
|
||||||
@@ -154,17 +156,17 @@ func NewMailTemplate(name, tpl string, isFile bool) (MailTemplate, error) {
|
|||||||
if isFile {
|
if isFile {
|
||||||
var fs []byte
|
var fs []byte
|
||||||
if _, err = os.Stat(tpl); err != nil {
|
if _, err = os.Stat(tpl); err != nil {
|
||||||
return nil, err
|
return nil, FILE_STAT.ErrorParent(err)
|
||||||
} else if fs, err = ioutil.ReadFile(tpl); err != nil {
|
} else if fs, err = ioutil.ReadFile(tpl); err != nil {
|
||||||
return nil, err
|
return nil, FILE_READ.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl = string(fs)
|
tpl = string(fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.tpl, err = res.tpl.Parse(tpl); err != nil {
|
if res.tpl, err = res.tpl.Parse(tpl); err != nil {
|
||||||
return nil, err
|
return nil, TEMPLATE_PARSING.ErrorParent(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, err
|
return res, nil
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_smtp
|
package smtp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -31,7 +31,9 @@ import (
|
|||||||
"net/smtp"
|
"net/smtp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
njs_version "github.com/nabbar/golib/njs-version"
|
vers "github.com/nabbar/golib/version"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sendmail struct {
|
type sendmail struct {
|
||||||
@@ -136,7 +138,7 @@ func (s *sendmail) SetMailer(mailer string) {
|
|||||||
s.mailer = mailer
|
s.mailer = mailer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sendmail) NJSMailer(version njs_version.Version) {
|
func (s *sendmail) NJSMailer(version vers.Version) {
|
||||||
s.mailer = version.GetHeader()
|
s.mailer = version.GetHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +146,7 @@ func (s *sendmail) SetTestMode(enable bool) {
|
|||||||
s.testMode = enable
|
s.testMode = enable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sendmail) Clone() (SendMail, error) {
|
func (s sendmail) Clone() (SendMail, Error) {
|
||||||
var (
|
var (
|
||||||
la = make([]Attachment, 0)
|
la = make([]Attachment, 0)
|
||||||
)
|
)
|
||||||
@@ -208,42 +210,43 @@ func (s sendmail) Clone() (SendMail, error) {
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sendmail) SendSMTP(cli SMTP) (err error, buff *bytes.Buffer) {
|
func (s sendmail) SendSMTP(cli SMTP) (err Error, buff *bytes.Buffer) {
|
||||||
var c *smtp.Client
|
var (
|
||||||
|
e error
|
||||||
|
c *smtp.Client
|
||||||
|
)
|
||||||
|
|
||||||
defer func(cli *smtp.Client) {
|
defer func(cli *smtp.Client) {
|
||||||
if cli != nil {
|
if cli != nil {
|
||||||
cli.Quit()
|
_ = cli.Quit()
|
||||||
cli.Close()
|
_ = cli.Close()
|
||||||
}
|
}
|
||||||
}(c)
|
}(c)
|
||||||
|
|
||||||
if c, err = cli.Client(); err != nil {
|
if c, err = cli.Client(); err != nil {
|
||||||
return
|
return
|
||||||
} else if err, buff = s.Send(c); err != nil {
|
} else if e, buff = s.Send(c); e != nil {
|
||||||
c.Reset()
|
_ = c.Reset()
|
||||||
return err, buff
|
return SMTP_SEND.ErrorParent(e), buff
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
func (s sendmail) Send(cli *smtp.Client) (err Error, buff *bytes.Buffer) {
|
||||||
var (
|
var (
|
||||||
iod IOData
|
iod IOData
|
||||||
)
|
)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil && err != nil {
|
if r := recover(); r != nil {
|
||||||
err = fmt.Errorf("%v, %v", err, r)
|
err = SMTP_CLIENT_SEND_RECOVERED.ErrorParent(err, fmt.Errorf("%v", r))
|
||||||
} else if r != nil {
|
|
||||||
err = fmt.Errorf("%v", r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cli != nil {
|
if cli != nil {
|
||||||
cli.Reset()
|
_ = cli.Reset()
|
||||||
cli.Quit()
|
_ = cli.Quit()
|
||||||
cli.Close()
|
_ = cli.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -260,38 +263,44 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
|||||||
} else if s.msgText.Len() > 0 {
|
} else if s.msgText.Len() > 0 {
|
||||||
ctBody = CONTENTTYPE_TEXT
|
ctBody = CONTENTTYPE_TEXT
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("no attachment & no contents"), nil
|
return SMTP_CLIENT_EMPTY.Error(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s.from.AddressOnly()) < 7 {
|
if len(s.from.AddressOnly()) < 7 {
|
||||||
return fmt.Errorf("from address is empty"), nil
|
return SMTP_CLIENT_FROM_EMPTY.Error(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = cli.Noop(); err != nil {
|
if e := cli.Noop(); e != nil {
|
||||||
|
err = SMTP_CLIENT_NOOP.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = cli.Mail(s.from.String()); err != nil {
|
if e := cli.Mail(s.from.String()); e != nil {
|
||||||
|
err = SMTP_CLIENT_MAIL.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.testMode {
|
if s.testMode {
|
||||||
if err = cli.Rcpt(s.from.String()); err != nil {
|
if e := cli.Rcpt(s.from.String()); e != nil {
|
||||||
|
err = SMTP_CLIENT_RCPT.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, a := range s.to.Slice() {
|
for _, a := range s.to.Slice() {
|
||||||
if err = cli.Rcpt(a.String()); err != nil {
|
if e := cli.Rcpt(a.String()); e != nil {
|
||||||
|
err = SMTP_CLIENT_RCPT.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, a := range s.cc.Slice() {
|
for _, a := range s.cc.Slice() {
|
||||||
if err = cli.Rcpt(a.String()); err != nil {
|
if e := cli.Rcpt(a.String()); e != nil {
|
||||||
|
err = SMTP_CLIENT_RCPT.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, a := range s.bcc.Slice() {
|
for _, a := range s.bcc.Slice() {
|
||||||
if err = cli.Rcpt(a.String()); err != nil {
|
if e := cli.Rcpt(a.String()); e != nil {
|
||||||
|
err = SMTP_CLIENT_RCPT.ErrorParent(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +315,7 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.to.IsEmpty() {
|
if s.to.IsEmpty() {
|
||||||
return fmt.Errorf("to address is empty"), nil
|
return SMTP_CLIENT_TO_EMPTY.Error(nil), nil
|
||||||
} else if err = iod.Header("To", s.to.String()); err != nil {
|
} else if err = iod.Header("To", s.to.String()); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -334,7 +343,7 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(s.subject) < 1 {
|
if len(s.subject) < 1 {
|
||||||
return fmt.Errorf("subjetc is empty"), nil
|
return SMTP_CLIENT_SUBJECT_EMPTY.Error(nil), nil
|
||||||
} else {
|
} else {
|
||||||
var (
|
var (
|
||||||
b = []byte(s.subject)
|
b = []byte(s.subject)
|
||||||
@@ -349,7 +358,7 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(s.mailer) < 1 {
|
if len(s.mailer) < 1 {
|
||||||
return fmt.Errorf("mailer is empty"), nil
|
return SMTP_CLIENT_MAILER_EMPTY.Error(nil), nil
|
||||||
} else {
|
} else {
|
||||||
if err = iod.Header("X-Mailer", s.mailer); err != nil {
|
if err = iod.Header("X-Mailer", s.mailer); err != nil {
|
||||||
return
|
return
|
||||||
@@ -376,13 +385,13 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if s.msgHtml.IsEmpty() {
|
} else if s.msgHtml.IsEmpty() {
|
||||||
return fmt.Errorf("empty content mail"), nil
|
return EMPTY_CONTENTS.Error(nil), nil
|
||||||
} else if err = iod.AttachmentAddBody(s.msgHtml, CONTENTTYPE_TEXT); err != nil {
|
} else if err = iod.AttachmentAddBody(s.msgHtml, CONTENTTYPE_TEXT); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if ctBody == CONTENTTYPE_HTML {
|
} else if ctBody == CONTENTTYPE_HTML {
|
||||||
if s.msgHtml.IsEmpty() {
|
if s.msgHtml.IsEmpty() {
|
||||||
return fmt.Errorf("empty content mail"), nil
|
return EMPTY_CONTENTS.Error(nil), nil
|
||||||
} else if err = iod.AttachmentAddBody(s.msgHtml, CONTENTTYPE_HTML); err != nil {
|
} else if err = iod.AttachmentAddBody(s.msgHtml, CONTENTTYPE_HTML); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -442,13 +451,13 @@ type SendMail interface {
|
|||||||
|
|
||||||
SetMessageId(id string)
|
SetMessageId(id string)
|
||||||
SetMailer(mailer string)
|
SetMailer(mailer string)
|
||||||
NJSMailer(version njs_version.Version)
|
NJSMailer(version vers.Version)
|
||||||
|
|
||||||
SetTestMode(enable bool)
|
SetTestMode(enable bool)
|
||||||
|
|
||||||
Clone() (SendMail, error)
|
Clone() (SendMail, Error)
|
||||||
Send(cli *smtp.Client) (err error, buff *bytes.Buffer)
|
Send(cli *smtp.Client) (err Error, buff *bytes.Buffer)
|
||||||
SendSMTP(cli SMTP) (err error, buff *bytes.Buffer)
|
SendSMTP(cli SMTP) (err Error, buff *bytes.Buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSendMail() SendMail {
|
func NewSendMail() SendMail {
|
58
static/error.go
Normal file
58
static/error.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 static
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Static
|
||||||
|
EMPTY_PACKED
|
||||||
|
INDEX_NOT_FOUND
|
||||||
|
INDEX_REQUESTED_NOT_SET
|
||||||
|
FILE_NOT_FOUND
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case EMPTY_PACKED:
|
||||||
|
return "packed file is empty"
|
||||||
|
case INDEX_NOT_FOUND:
|
||||||
|
return "mode index is defined but index.(html|htm) is not found"
|
||||||
|
case INDEX_REQUESTED_NOT_SET:
|
||||||
|
return "request call index but mode index is false"
|
||||||
|
case FILE_NOT_FOUND:
|
||||||
|
return "requested packed file is not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_static
|
package static
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -33,14 +33,14 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
njs_router "github.com/nabbar/golib/njs-router"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin/render"
|
|
||||||
|
|
||||||
njs_logger "github.com/nabbar/golib/njs-logger"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/render"
|
||||||
"github.com/gobuffalo/packr"
|
"github.com/gobuffalo/packr"
|
||||||
|
|
||||||
|
. "github.com/nabbar/golib/errors"
|
||||||
|
. "github.com/nabbar/golib/logger"
|
||||||
|
|
||||||
|
njs_router "github.com/nabbar/golib/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -68,7 +68,7 @@ type Static interface {
|
|||||||
Has(file string) bool
|
Has(file string) bool
|
||||||
Find(file string) ([]byte, error)
|
Find(file string) ([]byte, error)
|
||||||
|
|
||||||
Health() error
|
Health() Error
|
||||||
Get(c *gin.Context)
|
Get(c *gin.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,21 +119,21 @@ func (s staticHandler) print() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range s.box.List() {
|
for _, f := range s.box.List() {
|
||||||
njs_logger.DebugLevel.Logf("Embedded file : %s", f)
|
DebugLevel.Logf("Embedded file : %s", f)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.debug = true
|
s.debug = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s staticHandler) Health() error {
|
func (s staticHandler) Health() Error {
|
||||||
s.print()
|
s.print()
|
||||||
|
|
||||||
if len(s.box.List()) < 1 {
|
if len(s.box.List()) < 1 {
|
||||||
return fmt.Errorf("empty packed file stored")
|
return EMPTY_PACKED.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.index && !s.box.Has("index.html") && !s.box.Has("index.htm") {
|
if s.index && !s.box.Has("index.html") && !s.box.Has("index.htm") {
|
||||||
return fmt.Errorf("cannot find 'index.html' file")
|
return INDEX_NOT_FOUND.Error(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -160,12 +160,12 @@ func (s staticHandler) Get(c *gin.Context) {
|
|||||||
calledFile = FileIndex
|
calledFile = FileIndex
|
||||||
requestPath = FileIndex
|
requestPath = FileIndex
|
||||||
} else {
|
} else {
|
||||||
c.Abort()
|
_ = c.AbortWithError(http.StatusNotFound, INDEX_REQUESTED_NOT_SET.Error(nil))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj, err := s.box.Find(requestPath); !njs_logger.ErrorLevel.LogErrorCtxf(njs_logger.NilLevel, "find file '%s' error for request '%s%s' :", err, calledFile, s.prefix, requestPath) {
|
if obj, err := s.box.Find(requestPath); !ErrorLevel.LogErrorCtxf(DebugLevel, "find file '%s' error for request '%s%s' :", err, calledFile, s.prefix, requestPath) {
|
||||||
head := s.head()
|
head := s.head()
|
||||||
|
|
||||||
if s.allDwnld || s.IsDownload(requestPath) {
|
if s.allDwnld || s.IsDownload(requestPath) {
|
||||||
@@ -179,7 +179,7 @@ func (s staticHandler) Get(c *gin.Context) {
|
|||||||
Reader: bytes.NewReader(obj),
|
Reader: bytes.NewReader(obj),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
c.Abort()
|
_ = c.AbortWithError(http.StatusNotFound, FILE_NOT_FOUND.Error(nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -23,7 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_status
|
package status
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -31,13 +31,15 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
njs_router "github.com/nabbar/golib/njs-router"
|
njs_router "github.com/nabbar/golib/router"
|
||||||
|
|
||||||
njs_version "github.com/nabbar/golib/njs-version"
|
njs_version "github.com/nabbar/golib/version"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @TODO : see compliant with https://tools.ietf.org/html/draft-inadarei-api-health-check-02
|
||||||
|
|
||||||
type StatusItemResponse struct {
|
type StatusItemResponse struct {
|
||||||
Name string
|
Name string
|
||||||
Status string
|
Status string
|
||||||
@@ -48,7 +50,7 @@ type StatusItemResponse struct {
|
|||||||
|
|
||||||
type StatusResponse struct {
|
type StatusResponse struct {
|
||||||
StatusItemResponse
|
StatusItemResponse
|
||||||
Partner []StatusItemResponse
|
Component []StatusItemResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusOK = "OK"
|
const statusOK = "OK"
|
||||||
@@ -63,7 +65,7 @@ type statusItem struct {
|
|||||||
release string
|
release string
|
||||||
}
|
}
|
||||||
|
|
||||||
type statusPartner struct {
|
type statusComponent struct {
|
||||||
statusItem
|
statusItem
|
||||||
WarnIfErr bool
|
WarnIfErr bool
|
||||||
later *initLater
|
later *initLater
|
||||||
@@ -71,8 +73,8 @@ type statusPartner struct {
|
|||||||
|
|
||||||
type mainPackage struct {
|
type mainPackage struct {
|
||||||
statusItem
|
statusItem
|
||||||
ptn []statusPartner
|
cpt []statusComponent
|
||||||
header func(c *gin.Context)
|
header gin.HandlerFunc
|
||||||
later *initLater
|
later *initLater
|
||||||
init bool
|
init bool
|
||||||
}
|
}
|
||||||
@@ -87,18 +89,18 @@ type initLater struct {
|
|||||||
type Status interface {
|
type Status interface {
|
||||||
Register(prefix string, register njs_router.RegisterRouter)
|
Register(prefix string, register njs_router.RegisterRouter)
|
||||||
|
|
||||||
AddPartner(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error)
|
AddComponent(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error)
|
||||||
AddVersionPartner(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error)
|
AddVersionComponent(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error)
|
||||||
|
|
||||||
LaterAddPartner(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool)
|
LaterAddComponent(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool)
|
||||||
LaterAddVersionPartner(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool)
|
LaterAddVersionComponent(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool)
|
||||||
|
|
||||||
Get(c *gin.Context)
|
Get(c *gin.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStatusLater(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, Header func(c *gin.Context)) Status {
|
func NewStatusLater(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, Header gin.HandlerFunc) Status {
|
||||||
return &mainPackage{
|
return &mainPackage{
|
||||||
ptn: make([]statusPartner, 0),
|
cpt: make([]statusComponent, 0),
|
||||||
header: Header,
|
header: Header,
|
||||||
later: &initLater{
|
later: &initLater{
|
||||||
version: nil,
|
version: nil,
|
||||||
@@ -110,19 +112,19 @@ func NewStatusLater(info func() (name, release, build string), msg func() (ok st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStatus(name, msgOK, msgKO, release, build string, health func() error, Header func(c *gin.Context)) Status {
|
func NewStatus(name, msgOK, msgKO, release, build string, health func() error, Header gin.HandlerFunc) Status {
|
||||||
return &mainPackage{
|
return &mainPackage{
|
||||||
statusItem: newItem(name, msgOK, msgKO, release, build, health),
|
statusItem: newItem(name, msgOK, msgKO, release, build, health),
|
||||||
ptn: make([]statusPartner, 0),
|
cpt: make([]statusComponent, 0),
|
||||||
header: Header,
|
header: Header,
|
||||||
later: nil,
|
later: nil,
|
||||||
init: false,
|
init: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVersionStatusLater(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, Header func(c *gin.Context)) Status {
|
func NewVersionStatusLater(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, Header gin.HandlerFunc) Status {
|
||||||
return &mainPackage{
|
return &mainPackage{
|
||||||
ptn: make([]statusPartner, 0),
|
cpt: make([]statusComponent, 0),
|
||||||
header: Header,
|
header: Header,
|
||||||
later: &initLater{
|
later: &initLater{
|
||||||
version: vers,
|
version: vers,
|
||||||
@@ -134,7 +136,7 @@ func NewVersionStatusLater(vers func() njs_version.Version, msg func() (ok strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVersionStatus(vers njs_version.Version, msgOK, msgKO string, health func() error, Header func(c *gin.Context)) Status {
|
func NewVersionStatus(vers njs_version.Version, msgOK, msgKO string, health func() error, Header gin.HandlerFunc) Status {
|
||||||
return NewStatus(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), health, Header)
|
return NewStatus(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), health, Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,16 +151,16 @@ func newItem(name, msgOK, msgKO, release, build string, health func() error) sta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mainPackage) AddPartner(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error) {
|
func (p *mainPackage) AddComponent(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error) {
|
||||||
p.ptn = append(p.ptn, statusPartner{
|
p.cpt = append(p.cpt, statusComponent{
|
||||||
statusItem: newItem(name, msgOK, msgKO, release, build, health),
|
statusItem: newItem(name, msgOK, msgKO, release, build, health),
|
||||||
WarnIfErr: WarnIfError,
|
WarnIfErr: WarnIfError,
|
||||||
later: nil,
|
later: nil,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mainPackage) LaterAddPartner(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
func (p *mainPackage) LaterAddComponent(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
||||||
p.ptn = append(p.ptn, statusPartner{
|
p.cpt = append(p.cpt, statusComponent{
|
||||||
WarnIfErr: WarnIfError,
|
WarnIfErr: WarnIfError,
|
||||||
later: &initLater{
|
later: &initLater{
|
||||||
version: nil,
|
version: nil,
|
||||||
@@ -169,12 +171,12 @@ func (p *mainPackage) LaterAddPartner(info func() (name, release, build string),
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mainPackage) AddVersionPartner(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error) {
|
func (p *mainPackage) AddVersionComponent(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error) {
|
||||||
p.AddPartner(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), WarnIfError, health)
|
p.AddComponent(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), WarnIfError, health)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mainPackage) LaterAddVersionPartner(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
func (p *mainPackage) LaterAddVersionComponent(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
||||||
p.ptn = append(p.ptn, statusPartner{
|
p.cpt = append(p.cpt, statusComponent{
|
||||||
WarnIfErr: WarnIfError,
|
WarnIfErr: WarnIfError,
|
||||||
later: &initLater{
|
later: &initLater{
|
||||||
version: vers,
|
version: vers,
|
||||||
@@ -204,14 +206,14 @@ func (p *mainPackage) initStatus() {
|
|||||||
p.later = nil
|
p.later = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var ptn = make([]statusPartner, 0)
|
var cpt = make([]statusComponent, 0)
|
||||||
|
|
||||||
for _, part := range p.ptn {
|
for _, part := range p.cpt {
|
||||||
if part.later != nil {
|
if part.later != nil {
|
||||||
if part.later.info != nil {
|
if part.later.info != nil {
|
||||||
name, release, build := part.later.info()
|
name, release, build := part.later.info()
|
||||||
ok, ko := part.later.msg()
|
ok, ko := part.later.msg()
|
||||||
part = statusPartner{
|
part = statusComponent{
|
||||||
statusItem: newItem(name, ok, ko, release, build, part.health),
|
statusItem: newItem(name, ok, ko, release, build, part.health),
|
||||||
WarnIfErr: part.WarnIfErr,
|
WarnIfErr: part.WarnIfErr,
|
||||||
later: nil,
|
later: nil,
|
||||||
@@ -219,7 +221,7 @@ func (p *mainPackage) initStatus() {
|
|||||||
} else if p.later.version != nil {
|
} else if p.later.version != nil {
|
||||||
v := p.later.version()
|
v := p.later.version()
|
||||||
ok, ko := p.later.msg()
|
ok, ko := p.later.msg()
|
||||||
part = statusPartner{
|
part = statusComponent{
|
||||||
statusItem: newItem(v.GetPackage(), ok, ko, v.GetRelease(), v.GetBuild(), part.health),
|
statusItem: newItem(v.GetPackage(), ok, ko, v.GetRelease(), v.GetBuild(), part.health),
|
||||||
WarnIfErr: part.WarnIfErr,
|
WarnIfErr: part.WarnIfErr,
|
||||||
later: nil,
|
later: nil,
|
||||||
@@ -231,11 +233,11 @@ func (p *mainPackage) initStatus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptn = append(ptn, part)
|
cpt = append(cpt, part)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.init = true
|
p.init = true
|
||||||
p.ptn = ptn
|
p.cpt = cpt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mainPackage) cleanPrefix(prefix string) string {
|
func (p *mainPackage) cleanPrefix(prefix string) string {
|
||||||
@@ -302,20 +304,20 @@ func (p *mainPackage) Get(c *gin.Context) {
|
|||||||
make([]StatusItemResponse, 0),
|
make([]StatusItemResponse, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pkg := range p.ptn {
|
for _, pkg := range p.cpt {
|
||||||
pres := pkg.GetStatusResponse(c)
|
pres := pkg.GetStatusResponse(c)
|
||||||
if res.Status == statusOK && pres.Status == statusKO && !pkg.WarnIfErr {
|
if res.Status == statusOK && pres.Status == statusKO && !pkg.WarnIfErr {
|
||||||
res.Status = statusKO
|
res.Status = statusKO
|
||||||
} else if pres.Status == statusKO {
|
} else if pres.Status == statusKO {
|
||||||
hasError = true
|
hasError = true
|
||||||
}
|
}
|
||||||
res.Partner = append(res.Partner, pres)
|
res.Component = append(res.Component, pres)
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Status != statusOK {
|
if res.Status != statusOK {
|
||||||
c.AbortWithStatusJSON(http.StatusInternalServerError, &res)
|
c.AbortWithStatusJSON(http.StatusInternalServerError, &res)
|
||||||
} else if hasError {
|
} else if hasError {
|
||||||
c.JSON(http.StatusMultiStatus, &res)
|
c.JSON(http.StatusAccepted, &res)
|
||||||
} else {
|
} else {
|
||||||
c.JSON(http.StatusOK, &res)
|
c.JSON(http.StatusOK, &res)
|
||||||
}
|
}
|
@@ -30,16 +30,16 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
njs_archive "github.com/nabbar/golib/njs-archive"
|
njs_archive "github.com/nabbar/golib/archive"
|
||||||
|
|
||||||
iou "github.com/nabbar/golib/njs-ioutils"
|
iou "github.com/nabbar/golib/ioutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// git archive --format=tar --output=git.tar HEAD
|
// git archive --format=tar --output=git.tar HEAD
|
||||||
//const fileName = "./git.tar"
|
//const fileName = "./git.tar"
|
||||||
const fileName = "./vendor.zip"
|
const fileName = "./vendor.zip"
|
||||||
|
|
||||||
//const contain = "njs-version/license_mit.go"
|
//const contain = "version/license_mit.go"
|
||||||
const contain = "vendor/github.com/gin-gonic/gin/internal/json/json.go"
|
const contain = "vendor/github.com/gin-gonic/gin/internal/json/json.go"
|
||||||
|
|
||||||
//const regex = ""
|
//const regex = ""
|
||||||
@@ -57,13 +57,17 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer src.Close()
|
defer func() {
|
||||||
|
_ = src.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
if tmp, err = iou.NewTempFile(); err != nil {
|
if tmp, err = iou.NewTempFile(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer iou.DelTempFile(tmp, true)
|
defer func() {
|
||||||
|
_ = iou.DelTempFile(tmp)
|
||||||
|
}()
|
||||||
|
|
||||||
if _, err = io.Copy(tmp, src); err != nil {
|
if _, err = io.Copy(tmp, src); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -73,7 +77,9 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer rio.Close()
|
defer func() {
|
||||||
|
_ = rio.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
if _, err = rio.Seek(0, 0); err != nil {
|
if _, err = rio.Seek(0, 0); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@@ -29,21 +29,21 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
njs_progress "github.com/nabbar/golib/njs-progress"
|
npb "github.com/nabbar/golib/progress"
|
||||||
"github.com/vbauerster/mpb/v5"
|
"github.com/vbauerster/mpb/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pb njs_progress.ProgressBar
|
pb npb.ProgressBar
|
||||||
br njs_progress.Bar
|
br npb.Bar
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
println("Starting...")
|
println("Starting...")
|
||||||
|
|
||||||
pb = njs_progress.NewProgressBar(0, time.Time{}, nil, mpb.WithWidth(64))
|
pb = npb.NewProgressBar(0, time.Time{}, nil, mpb.WithWidth(64))
|
||||||
pb.SetSemaphoreOption(0, 0)
|
pb.SetSemaphoreOption(0, 0)
|
||||||
br = pb.NewBarSimple("test bar")
|
br = pb.NewBarSimpleETA("test bar")
|
||||||
|
|
||||||
defer br.DeferMain(false)
|
defer br.DeferMain(false)
|
||||||
|
|
||||||
|
101
test/test-smtp/main.go
Normal file
101
test/test-smtp/main.go
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/jaytaylor/html2text"
|
||||||
|
"github.com/olekukonko/tablewriter"
|
||||||
|
|
||||||
|
"github.com/nabbar/golib/logger"
|
||||||
|
"github.com/nabbar/golib/smtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CONFIG_SMTP_DSN = "user@example.com:test_password@tcp4(mail.example.com:25)/starttls?ServerName=mail.example.com"
|
||||||
|
CONFIG_EMAIL_FROM = "sender@example.com"
|
||||||
|
CONFIG_EMAIL_TO = "recipient@example.com"
|
||||||
|
CONFIG_MAILER = "Nabbar SMTP Tester"
|
||||||
|
CONFIG_SUBJECT = "Testing Send Mail"
|
||||||
|
CONFIG_TESTMODE = false
|
||||||
|
CONFIG_TEMPLATE_TEST = `<html><head></head><body><b>Hello {{.Name}}</b>, this is a test e-mail sent by <i>Go</i> with package nabbar/golib/smtp.</body></html>`
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
cfg smtp.SMTP
|
||||||
|
tpl smtp.MailTemplate
|
||||||
|
snd smtp.SendMail
|
||||||
|
err error
|
||||||
|
buff = bytes.NewBuffer(make([]byte, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.EnableColor()
|
||||||
|
logger.AddGID(true)
|
||||||
|
logger.FileTrace(true)
|
||||||
|
logger.SetFormat(logger.TextFormat)
|
||||||
|
logger.SetLevel(logger.DebugLevel)
|
||||||
|
|
||||||
|
tpl, err = smtp.NewMailTemplate("mail", CONFIG_TEMPLATE_TEST, false)
|
||||||
|
logger.FatalLevel.LogErrorCtxf(logger.InfoLevel, "mail template parsing", err)
|
||||||
|
tpl.SetCharset("utf-8")
|
||||||
|
tpl.RegisterData(struct {
|
||||||
|
Name string
|
||||||
|
}{Name: "éloïse"})
|
||||||
|
tpl.SetTextOption(html2text.Options{
|
||||||
|
PrettyTables: true,
|
||||||
|
PrettyTablesOptions: &html2text.PrettyTablesOptions{
|
||||||
|
AutoFormatHeader: true,
|
||||||
|
AutoWrapText: true,
|
||||||
|
ReflowDuringAutoWrap: true,
|
||||||
|
ColWidth: tablewriter.MAX_ROW_WIDTH,
|
||||||
|
ColumnSeparator: tablewriter.COLUMN,
|
||||||
|
RowSeparator: tablewriter.ROW,
|
||||||
|
CenterSeparator: tablewriter.CENTER,
|
||||||
|
HeaderAlignment: tablewriter.ALIGN_DEFAULT,
|
||||||
|
FooterAlignment: tablewriter.ALIGN_DEFAULT,
|
||||||
|
Alignment: tablewriter.ALIGN_DEFAULT,
|
||||||
|
ColumnAlignment: []int{},
|
||||||
|
NewLine: tablewriter.NEWLINE,
|
||||||
|
HeaderLine: true,
|
||||||
|
RowLine: false,
|
||||||
|
AutoMergeCells: false,
|
||||||
|
Borders: tablewriter.Border{Left: true, Right: true, Bottom: true, Top: true},
|
||||||
|
},
|
||||||
|
OmitLinks: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if p, e := tpl.GetBufferHtml(nil); e == nil {
|
||||||
|
fmt.Printf("\n\n\n\t >> HTML Mail : \n")
|
||||||
|
print(p.String())
|
||||||
|
fmt.Printf("\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if p, e := tpl.GetBufferText(nil); e == nil {
|
||||||
|
fmt.Printf("\n\n\n\t >> Text Mail : \n")
|
||||||
|
print(p.String())
|
||||||
|
fmt.Printf("\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
snd = smtp.NewSendMail()
|
||||||
|
snd.SetTo(smtp.MailAddressParser(CONFIG_EMAIL_TO))
|
||||||
|
snd.SetFrom(smtp.MailAddressParser(CONFIG_EMAIL_FROM))
|
||||||
|
snd.SetMailer(CONFIG_MAILER)
|
||||||
|
snd.SetSubject(CONFIG_SUBJECT)
|
||||||
|
snd.SetTestMode(CONFIG_TESTMODE)
|
||||||
|
snd.SetForceOnly(smtp.CONTENTTYPE_HTML)
|
||||||
|
snd.SetHtml(tpl)
|
||||||
|
|
||||||
|
cfg, err = smtp.NewSMTP(CONFIG_SMTP_DSN, &tls.Config{})
|
||||||
|
logger.FatalLevel.LogErrorCtxf(logger.InfoLevel, "smtp config parsing", err)
|
||||||
|
logger.FatalLevel.LogErrorCtxf(logger.InfoLevel, "smtp checking working", cfg.Check())
|
||||||
|
|
||||||
|
err, buff = snd.SendSMTP(cfg)
|
||||||
|
logger.FatalLevel.LogErrorCtxf(logger.InfoLevel, "Sending Mail", err)
|
||||||
|
|
||||||
|
fmt.Printf("\n\n\n\t >> Buff Mail : \n")
|
||||||
|
print(buff.String())
|
||||||
|
fmt.Printf("\n\n")
|
||||||
|
|
||||||
|
}
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
njs_ioutils "github.com/nabbar/golib/njs-ioutils"
|
njs_ioutils "github.com/nabbar/golib/ioutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
55
version/error.go
Normal file
55
version/error.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 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 version
|
||||||
|
|
||||||
|
import errors "github.com/nabbar/golib/errors"
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMPTY_PARAMS errors.CodeError = iota + errors.MIN_PKG_Version
|
||||||
|
GOVERSION_INIT
|
||||||
|
GOVERSION_RUNTIME
|
||||||
|
GOVERSION_CONTRAINT
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
errors.RegisterFctMessage(getMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMessage(code errors.CodeError) (message string) {
|
||||||
|
switch code {
|
||||||
|
case EMPTY_PARAMS:
|
||||||
|
return "given parameters is empty"
|
||||||
|
case GOVERSION_INIT:
|
||||||
|
return "init GoVersion contraint error"
|
||||||
|
case GOVERSION_RUNTIME:
|
||||||
|
return "extract GoVersion runtime error"
|
||||||
|
case GOVERSION_CONTRAINT:
|
||||||
|
return "current binary is build with a non-compatible version of Go"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func licence_agpl_v3() string {
|
func licence_agpl_v3() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func licence_apache2() string {
|
func licence_apache2() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func license_cc_by_4() string {
|
func license_cc_by_4() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func license_cc_sa_4() string {
|
func license_cc_sa_4() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func licence_cc0_v1() string {
|
func licence_cc0_v1() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func licence_gpl_v3() string {
|
func licence_gpl_v3() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func licence_lgpl_v3() string {
|
func licence_lgpl_v3() string {
|
||||||
return `
|
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package njs_version
|
package version
|
||||||
|
|
||||||
func license_mit() string {
|
func license_mit() string {
|
||||||
return `
|
return `
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user