mirror of
https://github.com/nabbar/golib.git
synced 2025-09-26 20:01:15 +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
|
||||
```go
|
||||
import "github.com/nabbar/golib/njs-version"
|
||||
import "github.com/nabbar/golib/version"
|
||||
```
|
||||
|
||||
more information in each lib
|
||||
|
@@ -23,31 +23,30 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_archive
|
||||
package archive
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/nabbar/golib/njs-archive/bz2"
|
||||
"github.com/nabbar/golib/njs-archive/gzip"
|
||||
"github.com/nabbar/golib/njs-archive/tar"
|
||||
"github.com/nabbar/golib/njs-archive/zip"
|
||||
"github.com/nabbar/golib/archive/bz2"
|
||||
"github.com/nabbar/golib/archive/gzip"
|
||||
"github.com/nabbar/golib/archive/tar"
|
||||
"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
|
||||
|
||||
func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File, error) {
|
||||
var err error
|
||||
|
||||
func ExtractFile(src *os.File, fileNameContain, fileNameRegex string) (*os.File, Error) {
|
||||
loc := src.Name()
|
||||
|
||||
if dst, err := bz2.GetFile(src, fileNameContain, fileNameRegex); err == nil {
|
||||
//DebugLevel.Log("try deleting source archive...")
|
||||
if err = iou.DelTempFile(src, true); err != nil {
|
||||
if err = iou.DelTempFile(src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//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 {
|
||||
//DebugLevel.Log("try deleting source archive...")
|
||||
if err = iou.DelTempFile(src, true); err != nil {
|
||||
if err = iou.DelTempFile(src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//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 {
|
||||
//DebugLevel.Log("try deleting source archive...")
|
||||
if err = iou.DelTempFile(src, true); err != nil {
|
||||
if err = iou.DelTempFile(src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//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 {
|
||||
//DebugLevel.Log("try deleting source archive...")
|
||||
if err = iou.DelTempFile(src, true); err != nil {
|
||||
if err = iou.DelTempFile(src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//DebugLevel.Log("try another archive...")
|
||||
return ExtractFile(dst, fileNameContain, fileNameRegex)
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
if _, err = src.Seek(0, 0); err != nil {
|
||||
e1 := FILE_SEEK.ErrorParent(err)
|
||||
if src, err = os.Open(loc); err != nil {
|
||||
//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"
|
||||
"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 {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
||||
return nil, e
|
||||
return nil, FILE_SEEK.ErrorParent(e)
|
||||
}
|
||||
|
||||
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 {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", 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)
|
||||
return nil, e
|
||||
return nil, IO_COPY.ErrorParent(e)
|
||||
} else if _, e = t.Seek(0, 0); e != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
||||
return nil, e
|
||||
return nil, FILE_SEEK.ErrorParent(e)
|
||||
} else {
|
||||
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"
|
||||
"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 {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
||||
return nil, e
|
||||
return nil, FILE_SEEK.ErrorParent(e)
|
||||
}
|
||||
|
||||
r, e := gz.NewReader(src)
|
||||
if e != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init gzip reader", e)
|
||||
return nil, e
|
||||
return nil, GZ_READER.ErrorParent(e)
|
||||
}
|
||||
|
||||
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 {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", 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)
|
||||
return nil, e
|
||||
} else if _, e = t.Seek(0, 0); e != nil {
|
||||
return nil, IO_COPY.ErrorParent(e)
|
||||
} else if _, e := t.Seek(0, 0); e != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
||||
return nil, e
|
||||
return nil, FILE_SEEK.ErrorParent(e)
|
||||
} else {
|
||||
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"
|
||||
"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 {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking buffer", e)
|
||||
return nil, e
|
||||
return nil, FILE_SEEK.ErrorParent(e)
|
||||
}
|
||||
|
||||
r := tar.NewReader(src)
|
||||
@@ -52,7 +53,7 @@ func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File,
|
||||
return nil, nil
|
||||
} else if e != nil {
|
||||
//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 {
|
||||
@@ -64,12 +65,12 @@ func GetFile(src *os.File, filenameContain, filenameRegex string) (dst *os.File,
|
||||
if t, e := iou.NewTempFile(); e != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", 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)
|
||||
return nil, e
|
||||
} else if _, e = t.Seek(0, 0); e != nil {
|
||||
return nil, IO_COPY.ErrorParent(e)
|
||||
} else if _, e := t.Seek(0, 0); e != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "seeking temp file", e)
|
||||
return nil, e
|
||||
return nil, FILE_SEEK.ErrorParent(e)
|
||||
} else {
|
||||
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"
|
||||
"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)
|
||||
|
||||
if err = src.Close(); err != nil {
|
||||
if e := src.Close(); err != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "trying to close temp file", err)
|
||||
return
|
||||
return dst, FILE_CLOSE.ErrorParent(e)
|
||||
}
|
||||
|
||||
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 (
|
||||
r *zip.ReadCloser
|
||||
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 {
|
||||
//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 {
|
||||
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
|
||||
}
|
||||
|
||||
func extratFile(f *zip.File) (dst *os.File, err error) {
|
||||
var r io.ReadCloser
|
||||
func extratFile(f *zip.File) (dst *os.File, err Error) {
|
||||
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)
|
||||
return
|
||||
return dst, FILE_OPEN.ErrorParent(e)
|
||||
}
|
||||
|
||||
defer r.Close()
|
||||
defer func() {
|
||||
_ = r.Close()
|
||||
}()
|
||||
|
||||
if dst, err = iou.NewTempFile(); err != nil {
|
||||
//ErrorLevel.LogErrorCtx(DebugLevel, "init new temporary buffer", err)
|
||||
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)
|
||||
return
|
||||
return dst, IO_COPY.ErrorParent(e)
|
||||
}
|
||||
|
||||
_, err = dst.Seek(0, 0)
|
||||
_, e = dst.Seek(0, 0)
|
||||
//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.
|
||||
*/
|
||||
|
||||
package njs_certif
|
||||
package certificates
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
logger "github.com/nabbar/golib/njs-logger"
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -40,6 +40,7 @@ var (
|
||||
certificates = make([]tls.Certificate, 0)
|
||||
caCertificates = x509.NewCertPool()
|
||||
tlsMinVersion uint16 = tls.VersionTLS12
|
||||
tlsMaxVersion uint16 = tls.VersionTLS12
|
||||
cipherList = []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
@@ -76,21 +77,26 @@ func AddRootCAContents(rootContent string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func AddRootCAFile(rootFile string) bool {
|
||||
func AddRootCAFile(rootFile string) Error {
|
||||
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) {
|
||||
return false
|
||||
if _, e := os.Stat(rootFile); e != nil {
|
||||
return FILE_STAT_ERROR.ErrorParent(e)
|
||||
}
|
||||
|
||||
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 CERT_APPEND_KO.Error(nil)
|
||||
}
|
||||
|
||||
return false
|
||||
return FILE_READ_ERROR.ErrorParent(e)
|
||||
}
|
||||
|
||||
func AddCACertificateContents(caContent string) bool {
|
||||
@@ -101,61 +107,68 @@ func AddCACertificateContents(caContent string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func AddCACertificateFile(caFile string) bool {
|
||||
func AddCACertificateFile(caFile string) Error {
|
||||
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) {
|
||||
return false
|
||||
if _, e := os.Stat(caFile); e != nil {
|
||||
return FILE_STAT_ERROR.ErrorParent(e)
|
||||
}
|
||||
|
||||
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 CERT_APPEND_KO.Error(nil)
|
||||
}
|
||||
|
||||
return false
|
||||
return FILE_READ_ERROR.ErrorParent(e)
|
||||
}
|
||||
|
||||
func CheckCertificates() bool {
|
||||
return len(certificates) > 0
|
||||
}
|
||||
|
||||
func AddCertificateContents(keyContents, certContents string) bool {
|
||||
func AddCertificateContents(keyContents, certContents string) Error {
|
||||
keyContents = strings.TrimSpace(keyContents)
|
||||
certContents = strings.TrimSpace(certContents)
|
||||
|
||||
if keyContents != "" && keyContents != "\n" && certContents != "" && certContents != "\n" {
|
||||
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)
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
|
||||
return CERT_PARSE_KEYPAIR.ErrorParent(err)
|
||||
}
|
||||
|
||||
return false
|
||||
return EMPTY_PARAMS.Error(nil)
|
||||
}
|
||||
|
||||
func AddCertificateFile(keyFile, certFile string) bool {
|
||||
func AddCertificateFile(keyFile, certFile string) Error {
|
||||
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) {
|
||||
return false
|
||||
if _, e := os.Stat(keyFile); e != nil {
|
||||
return FILE_STAT_ERROR.ErrorParent(e)
|
||||
}
|
||||
|
||||
if _, e := os.Stat(certFile); logger.ErrorLevel.LogErrorCtxf(logger.InfoLevel, "loading certificates file '%s'", e, certFile) {
|
||||
return false
|
||||
if _, e := os.Stat(certFile); e != nil {
|
||||
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)
|
||||
return true
|
||||
return nil
|
||||
} else {
|
||||
return CERT_LOAD_KEYPAIR.ErrorParent(e)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func GetCertificates() []tls.Certificate {
|
||||
@@ -178,29 +191,30 @@ func GetClientCA() *x509.CertPool {
|
||||
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.Replace(tlsVersStr, "TLS", "", -1)
|
||||
tlsVersStr = strings.TrimSpace(tlsVersStr)
|
||||
|
||||
switch tlsVersStr {
|
||||
case "1", "1.0":
|
||||
tlsMinVersion = tls.VersionTLS10
|
||||
return tls.VersionTLS10
|
||||
case "1.1":
|
||||
tlsMinVersion = tls.VersionTLS11
|
||||
return tls.VersionTLS11
|
||||
case "1.2":
|
||||
return tls.VersionTLS12
|
||||
case "1.3":
|
||||
return tls.VersionTLS13
|
||||
default:
|
||||
tlsMinVersion = tls.VersionTLS12
|
||||
}
|
||||
}
|
||||
|
||||
func SetTlsVersion(tlsVers uint16) {
|
||||
switch tlsVers {
|
||||
case tls.VersionTLS10:
|
||||
tlsMinVersion = tls.VersionTLS10
|
||||
case tls.VersionTLS11:
|
||||
tlsMinVersion = tls.VersionTLS11
|
||||
default:
|
||||
tlsMinVersion = tls.VersionTLS12
|
||||
return tls.VersionTLS12
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,10 +301,17 @@ func GetTLSConfig(serverName string) *tls.Config {
|
||||
cnf := &tls.Config{
|
||||
RootCAs: rootCA,
|
||||
ClientCAs: caCertificates,
|
||||
MinVersion: tlsMinVersion,
|
||||
InsecureSkipVerify: false,
|
||||
}
|
||||
|
||||
if tlsMinVersion > 0 {
|
||||
cnf.MinVersion = tlsMinVersion
|
||||
}
|
||||
|
||||
if tlsMaxVersion > 0 {
|
||||
cnf.MaxVersion = tlsMaxVersion
|
||||
}
|
||||
|
||||
if serverName != "" {
|
||||
cnf.ServerName = serverName
|
||||
}
|
||||
@@ -326,8 +347,9 @@ func GetTlsConfigCertificates() *tls.Config {
|
||||
cnf.ClientAuth = clientAuth
|
||||
}
|
||||
|
||||
cnf.Certificates = certificates
|
||||
cnf.BuildNameToCertificate()
|
||||
if len(cnf.Certificates) > 0 {
|
||||
cnf.Certificates = certificates
|
||||
}
|
||||
|
||||
return cnf
|
||||
}
|
@@ -23,13 +23,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_console
|
||||
package console
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 (
|
||||
"strings"
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_console
|
||||
package console
|
||||
|
||||
import (
|
||||
"bufio"
|
@@ -23,15 +23,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_crypt
|
||||
package crypt
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -39,20 +41,22 @@ var (
|
||||
cryptNonce = make([]byte, 12)
|
||||
)
|
||||
|
||||
func SetKeyHex(key, nonce string) error {
|
||||
func SetKeyHex(key, nonce string) Error {
|
||||
var err error
|
||||
// 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
|
||||
// real.) If you want to convert a passphrase to a key, use a suitable
|
||||
// package like bcrypt or scrypt.
|
||||
cryptKey, err = hex.DecodeString(key)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting hexa key error : %v", err)
|
||||
return HEXA_KEY.ErrorParent(err)
|
||||
}
|
||||
|
||||
cryptNonce, err = hex.DecodeString(nonce)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting hexa nonce error : %v", err)
|
||||
return HEXA_NONCE.ErrorParent(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -63,51 +67,55 @@ func SetKeyByte(key [32]byte, nonce [12]byte) {
|
||||
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.
|
||||
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.
|
||||
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
|
||||
}
|
||||
|
||||
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).
|
||||
block, err := aes.NewCipher(cryptKey)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("init AES block error : %v", err)
|
||||
return "", AES_BLOCK.ErrorParent(err)
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
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
|
||||
}
|
||||
|
||||
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).
|
||||
ciphertext, err := hex.DecodeString(hexaVal)
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AES block init error : %v", err)
|
||||
return nil, AES_BLOCK.ErrorParent(err)
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
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/fatih/color v1.9.0
|
||||
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/gobuffalo/envy v1.9.0 // indirect
|
||||
github.com/gobuffalo/packd v1.0.0 // indirect
|
||||
@@ -27,12 +28,13 @@ require (
|
||||
github.com/spf13/jwalterweatherman v1.1.0
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // 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
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
|
||||
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
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // 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=
|
||||
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/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
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.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
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/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
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/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.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/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=
|
||||
@@ -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-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
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/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=
|
||||
@@ -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-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-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/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=
|
||||
@@ -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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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.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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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 (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
njs_certif "github.com/nabbar/golib/njs-certif"
|
||||
|
||||
njs_logger "github.com/nabbar/golib/njs-logger"
|
||||
. "github.com/nabbar/golib/errors"
|
||||
. "github.com/nabbar/golib/logger"
|
||||
)
|
||||
|
||||
type httpClient struct {
|
||||
@@ -46,11 +42,11 @@ type httpClient struct {
|
||||
}
|
||||
|
||||
type HTTP interface {
|
||||
Check() bool
|
||||
Call(file *bytes.Buffer) (bool, *bytes.Buffer)
|
||||
Check() Error
|
||||
Call(file *bytes.Buffer) (bool, *bytes.Buffer, Error)
|
||||
}
|
||||
|
||||
func NewClient(uri string) HTTP {
|
||||
func NewClient(uri string) (HTTP, Error) {
|
||||
var (
|
||||
pUri *url.URL
|
||||
err error
|
||||
@@ -59,85 +55,100 @@ func NewClient(uri string) HTTP {
|
||||
|
||||
if 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
|
||||
} else {
|
||||
pUri = nil
|
||||
host = ""
|
||||
}
|
||||
|
||||
c, e := GetClientError(host)
|
||||
|
||||
if e != nil {
|
||||
return nil, HTTP_CLIENT.Error(e)
|
||||
}
|
||||
|
||||
return &httpClient{
|
||||
url: pUri,
|
||||
cli: GetClient(host),
|
||||
cli: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (obj *httpClient) Check() Error {
|
||||
req, e := obj.newRequest(http.MethodHead, nil)
|
||||
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
_, e = obj.doRequest(req)
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func GetClient(serverName string) *http.Client {
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
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) Call(body *bytes.Buffer) (bool, *bytes.Buffer, Error) {
|
||||
req, e := obj.newRequest(http.MethodPost, body)
|
||||
|
||||
if e != nil {
|
||||
return false, nil, e
|
||||
}
|
||||
|
||||
res, e := obj.doRequest(req)
|
||||
|
||||
if e != nil {
|
||||
return false, nil, e
|
||||
}
|
||||
|
||||
return obj.checkResponse(res)
|
||||
}
|
||||
|
||||
func (obj *httpClient) Check() bool {
|
||||
obj.doRequest(obj.newRequest(http.MethodHead, nil))
|
||||
return true
|
||||
}
|
||||
|
||||
func (obj *httpClient) Call(body *bytes.Buffer) (bool, *bytes.Buffer) {
|
||||
return obj.checkResponse(
|
||||
obj.doRequest(
|
||||
obj.newRequest(http.MethodPost, body),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (obj *httpClient) newRequest(method string, body *bytes.Buffer) *http.Request {
|
||||
func (obj *httpClient) newRequest(method string, body *bytes.Buffer) (*http.Request, Error) {
|
||||
var reader *bytes.Reader
|
||||
|
||||
if body != nil && body.Len() > 0 {
|
||||
reader = bytes.NewReader(body.Bytes())
|
||||
}
|
||||
|
||||
req, err := 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)
|
||||
req, e := http.NewRequest(method, obj.url.String(), reader)
|
||||
if e != nil {
|
||||
return req, HTTP_REQUEST.ErrorParent(e)
|
||||
}
|
||||
|
||||
return req
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (obj *httpClient) doRequest(req *http.Request) *http.Response {
|
||||
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)
|
||||
func (obj *httpClient) doRequest(req *http.Request) (*http.Response, Error) {
|
||||
res, e := obj.cli.Do(req)
|
||||
|
||||
return res
|
||||
if e != nil {
|
||||
return res, HTTP_DO.ErrorParent(e)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (obj *httpClient) checkResponse(res *http.Response) (bool, *bytes.Buffer) {
|
||||
func (obj *httpClient) checkResponse(res *http.Response) (bool, *bytes.Buffer, Error) {
|
||||
var buf *bytes.Buffer
|
||||
|
||||
if res.Body != nil {
|
||||
bdy, err := ioutil.ReadAll(res.Body)
|
||||
|
||||
if err == nil {
|
||||
_, err = buf.Write(bdy)
|
||||
if err != nil {
|
||||
return false, nil, IO_READ.ErrorParent(err)
|
||||
}
|
||||
|
||||
njs_logger.DebugLevel.LogError(err)
|
||||
_, err = buf.Write(bdy)
|
||||
|
||||
if err != nil {
|
||||
return false, nil, BUFFER_WRITE.ErrorParent(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
|
||||
return strings.HasPrefix(res.Status, "2"), buf, nil
|
||||
}
|
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 (
|
||||
"context"
|
||||
@@ -40,8 +40,18 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
njs_certif "github.com/nabbar/golib/njs-certif"
|
||||
njs_logger "github.com/nabbar/golib/njs-logger"
|
||||
"golang.org/x/net/http2"
|
||||
|
||||
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 {
|
||||
@@ -169,22 +179,36 @@ func (srv *modelServer) Listen() {
|
||||
|
||||
srv.srv = &http.Server{
|
||||
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,
|
||||
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() {
|
||||
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 {
|
||||
njs_logger.FatalLevel.Logf("Listen Error: %v", err)
|
||||
FatalLevel.Logf("Listen Server '%s' Error: %v", srv.host, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
InfoLevel.Logf("TLS Server '%s' is starting with bindable: %s", srv.host, srv.GetBindable())
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -213,7 +237,7 @@ func (srv *modelServer) Restart() {
|
||||
}
|
||||
|
||||
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)
|
||||
defer cancel()
|
||||
@@ -223,7 +247,7 @@ func (srv *modelServer) Shutdown() {
|
||||
}
|
||||
|
||||
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
|
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
|
||||
@@ -49,6 +51,6 @@ package njs_ioutils
|
||||
* 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)
|
||||
}
|
@@ -25,13 +25,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_ioutils
|
||||
package ioutils
|
||||
|
||||
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()
|
||||
|
||||
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) {
|
||||
var rLimit syscall.Rlimit
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -56,7 +64,8 @@ func systemFileDescriptor(newValue int) (current int, max int, err error) {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_ioutils
|
||||
package ioutils
|
||||
|
||||
import "io"
|
||||
|
@@ -23,21 +23,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_ioutils
|
||||
package ioutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
func NewTempFile() (*os.File, error) {
|
||||
if f, e := ioutil.TempFile(os.TempDir(), ""); e != nil {
|
||||
return nil, e
|
||||
} else {
|
||||
return f, nil
|
||||
}
|
||||
func NewTempFile() (*os.File, Error) {
|
||||
f, e := ioutil.TempFile(os.TempDir(), "")
|
||||
return f, IO_TEMP_FILE_NEW.Iferror(e)
|
||||
}
|
||||
|
||||
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()))
|
||||
}
|
||||
|
||||
func DelTempFile(f *os.File, ignoreErrClose bool) error {
|
||||
func DelTempFile(f *os.File) Error {
|
||||
if f == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := GetTempFilePath(f)
|
||||
|
||||
a := f.Close()
|
||||
e1 := IO_TEMP_FILE_CLOSE.Iferror(a)
|
||||
|
||||
b := os.Remove(n)
|
||||
e2 := IO_TEMP_FILE_REMOVE.Iferror(b)
|
||||
|
||||
if ignoreErrClose {
|
||||
return b
|
||||
}
|
||||
|
||||
if a != nil && b != nil {
|
||||
return fmt.Errorf("%v, %v", a, b)
|
||||
} else if a != nil {
|
||||
return a
|
||||
}
|
||||
|
||||
return b
|
||||
return MakeErrorIfError(e2, e1)
|
||||
}
|
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 (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/nabbar/golib/njs-certif"
|
||||
"github.com/nabbar/golib/njs-logger"
|
||||
"gopkg.in/ldap.v3"
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
|
||||
njs_certif "github.com/nabbar/golib/certificates"
|
||||
. "github.com/nabbar/golib/errors"
|
||||
. "github.com/nabbar/golib/logger"
|
||||
)
|
||||
|
||||
//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
|
||||
func NewLDAP(cnf *Config, attributes []string) *HelperLDAP {
|
||||
func NewLDAP(cnf *Config, attributes []string) (*HelperLDAP, Error) {
|
||||
if cnf == nil {
|
||||
panic("given config is a nil struct")
|
||||
return nil, EMPTY_PARAMS.Error(nil)
|
||||
}
|
||||
|
||||
return &HelperLDAP{
|
||||
@@ -58,7 +59,7 @@ func NewLDAP(cnf *Config, attributes []string) *HelperLDAP {
|
||||
tlsConfig: njs_certif.GetTLSConfig(cnf.Uri),
|
||||
tlsMode: tlsmode_init,
|
||||
config: cnf.Clone(),
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
//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 (
|
||||
l *ldap.Conn
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(l *ldap.Conn) {
|
||||
defer func() {
|
||||
if l != nil {
|
||||
l.Close()
|
||||
}
|
||||
}(l)
|
||||
}()
|
||||
|
||||
if lc.config.Portldaps != 0 {
|
||||
l, err = ldap.DialTLS("tcp", lc.config.ServerAddr(true), lc.tlsConfig)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, LDAP_SERVER_DIAL.ErrorParent(err)
|
||||
}
|
||||
|
||||
if e := l.StartTLS(lc.tlsConfig); e == nil {
|
||||
njs_logger.DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
||||
if err = l.StartTLS(lc.tlsConfig); err == nil {
|
||||
DebugLevel.Logf("ldap connected with tls mode '%s'", lc.tlsMode.String())
|
||||
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
|
||||
}
|
||||
|
||||
func (lc *HelperLDAP) connect() error {
|
||||
func (lc *HelperLDAP) connect() Error {
|
||||
if lc.conn == nil {
|
||||
var (
|
||||
l *ldap.Conn
|
||||
@@ -137,25 +138,25 @@ func (lc *HelperLDAP) connect() error {
|
||||
if lc.tlsMode == TLSMODE_TLS {
|
||||
l, err = ldap.DialTLS("tcp", lc.config.ServerAddr(true), lc.tlsConfig)
|
||||
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 {
|
||||
l, err = ldap.Dial("tcp", lc.config.ServerAddr(false))
|
||||
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 {
|
||||
err = l.StartTLS(lc.tlsConfig)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -163,7 +164,7 @@ func (lc *HelperLDAP) connect() error {
|
||||
}
|
||||
|
||||
//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 {
|
||||
return err
|
||||
}
|
||||
@@ -181,37 +182,39 @@ func (lc *HelperLDAP) Close() {
|
||||
}
|
||||
|
||||
//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 {
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
func (lc *HelperLDAP) Connect() error {
|
||||
func (lc *HelperLDAP) Connect() Error {
|
||||
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
|
||||
}
|
||||
|
||||
func (lc *HelperLDAP) runSearch(filter string, attributes []string) (*ldap.SearchResult, error) {
|
||||
func (lc *HelperLDAP) runSearch(filter string, attributes []string) (*ldap.SearchResult, Error) {
|
||||
var (
|
||||
err error
|
||||
src *ldap.SearchResult
|
||||
)
|
||||
|
||||
if err = lc.Connect(); err != nil {
|
||||
return nil, err
|
||||
if e := lc.Connect(); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
//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 (
|
||||
err error
|
||||
e Error
|
||||
src *ldap.SearchResult
|
||||
userRes map[string]string
|
||||
)
|
||||
@@ -250,18 +253,18 @@ func (lc *HelperLDAP) UserInfo(username string) (map[string]string, error) {
|
||||
userRes = make(map[string]string)
|
||||
attributes := append(lc.Attributes, "cn")
|
||||
|
||||
if src, err = lc.runSearch(fmt.Sprintf(lc.config.FilterUser, username), attributes); err != nil {
|
||||
return userRes, err
|
||||
src, e = lc.runSearch(fmt.Sprintf(lc.config.FilterUser, username), attributes)
|
||||
|
||||
if e != nil {
|
||||
return userRes, e
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
@@ -272,14 +275,14 @@ func (lc *HelperLDAP) UserInfo(username string) (map[string]string, error) {
|
||||
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
|
||||
}
|
||||
|
||||
//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 (
|
||||
err error
|
||||
err Error
|
||||
src *ldap.SearchResult
|
||||
grp []string
|
||||
)
|
||||
@@ -291,26 +294,27 @@ func (lc *HelperLDAP) UserMemberOf(username string) ([]string, error) {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
for _, entry := range src.Entries {
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
//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 (
|
||||
err error
|
||||
err Error
|
||||
grpMmbr []string
|
||||
)
|
||||
|
||||
@@ -319,13 +323,14 @@ func (lc *HelperLDAP) UserIsInGroup(username string, groupname []string) (bool,
|
||||
username = usr["uid"][0]
|
||||
}
|
||||
|
||||
if grpMmbr, err = lc.UserMemberOf(username); err != nil {
|
||||
grpMmbr, err = lc.UserMemberOf(username)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, grpSrch := range groupname {
|
||||
for _, grpItem := range grpMmbr {
|
||||
if strings.ToUpper(grpSrch) == strings.ToUpper(grpItem) {
|
||||
if strings.EqualFold(grpSrch, grpItem) {
|
||||
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
|
||||
func (lc *HelperLDAP) UsersOfGroup(groupname string) ([]string, error) {
|
||||
func (lc *HelperLDAP) UsersOfGroup(groupname string) ([]string, Error) {
|
||||
var (
|
||||
err error
|
||||
err Error
|
||||
src *ldap.SearchResult
|
||||
grp []string
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_ldap
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"fmt"
|
@@ -22,12 +22,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_logger
|
||||
package logger
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// 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.
|
||||
*/
|
||||
|
||||
package njs_logger
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_logger
|
||||
package logger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -341,7 +341,7 @@ func (level Level) logDetails(message string, data interface{}, err error, field
|
||||
return
|
||||
}
|
||||
|
||||
var tags = make(map[string]interface{}, 0)
|
||||
var tags = make(map[string]interface{})
|
||||
|
||||
if enableGID {
|
||||
tags[tagStack] = getGID()
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_logger
|
||||
package logger
|
||||
|
||||
import (
|
||||
"log"
|
||||
@@ -38,9 +38,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tagStack = "stack"
|
||||
tagTime = "time"
|
||||
tagLevel = "level"
|
||||
tagStack = "stack"
|
||||
tagTime = "time"
|
||||
//tagLevel = "level" //unused
|
||||
tagCaller = "func"
|
||||
tagFile = "file"
|
||||
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 (
|
||||
"math/rand"
|
@@ -23,20 +23,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_progress
|
||||
package progress
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
njs_semaphore "github.com/nabbar/golib/njs-semaphore"
|
||||
"github.com/vbauerster/mpb/v5"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
|
||||
sem "github.com/nabbar/golib/semaphore"
|
||||
)
|
||||
|
||||
type bar struct {
|
||||
u bool
|
||||
t int64
|
||||
b *mpb.Bar
|
||||
s njs_semaphore.Sem
|
||||
s sem.Sem
|
||||
}
|
||||
|
||||
type Bar interface {
|
||||
@@ -45,19 +48,19 @@ type Bar interface {
|
||||
Increment(n int)
|
||||
Refill(amount int64)
|
||||
|
||||
NewWorker() error
|
||||
NewWorker() Error
|
||||
NewWorkerTry() bool
|
||||
DeferWorker()
|
||||
DeferMain(dropBar bool)
|
||||
|
||||
WaitAll() error
|
||||
WaitAll() Error
|
||||
Context() context.Context
|
||||
Cancel()
|
||||
|
||||
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{
|
||||
u: total > 0,
|
||||
t: total,
|
||||
@@ -89,7 +92,7 @@ func (b *bar) Refill(amount int64) {
|
||||
b.b.SetRefill(amount)
|
||||
}
|
||||
|
||||
func (b *bar) NewWorker() error {
|
||||
func (b *bar) NewWorker() Error {
|
||||
if !b.u {
|
||||
b.t++
|
||||
b.b.SetTotal(b.t, false)
|
||||
@@ -112,7 +115,7 @@ func (b *bar) DeferMain(dropBar bool) {
|
||||
b.s.DeferMain()
|
||||
}
|
||||
|
||||
func (b *bar) WaitAll() error {
|
||||
func (b *bar) WaitAll() Error {
|
||||
return b.s.WaitAll()
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_progress
|
||||
package progress
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
|
||||
"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"
|
||||
)
|
@@ -23,15 +23,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_router
|
||||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"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
|
||||
@@ -71,7 +72,7 @@ func AuthForbidden(c *gin.Context, err error) {
|
||||
}
|
||||
|
||||
type authorization struct {
|
||||
check func(AuthHeader string) (AuthCode, error)
|
||||
check func(AuthHeader string) (AuthCode, Error)
|
||||
router []gin.HandlerFunc
|
||||
authType string
|
||||
}
|
||||
@@ -82,7 +83,7 @@ type Authorization interface {
|
||||
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{
|
||||
check: authCheckFunc,
|
||||
authType: HeadAuthType,
|
||||
@@ -104,7 +105,7 @@ func (a authorization) Handler(c *gin.Context) {
|
||||
auth := c.Request.Header.Get(HEAD_AUTH_SEND)
|
||||
|
||||
if auth == "" {
|
||||
AuthRequire(c, fmt.Errorf("header '%s' is missing", HEAD_AUTH_SEND))
|
||||
AuthRequire(c, HEADER_AUTH_MISSING.Error(nil).GetErrorFull(""))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -118,7 +119,7 @@ func (a authorization) Handler(c *gin.Context) {
|
||||
}
|
||||
|
||||
if authValue == "" {
|
||||
AuthRequire(c, fmt.Errorf("reading authorization error : auth string is empty"))
|
||||
AuthRequire(c, HEADER_AUTH_EMPTY.Error(nil).GetErrorFull(""))
|
||||
return
|
||||
} else {
|
||||
code, err := a.check(authValue)
|
||||
@@ -126,17 +127,16 @@ func (a authorization) Handler(c *gin.Context) {
|
||||
switch code {
|
||||
case AUTH_CODE_SUCCESS:
|
||||
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)
|
||||
}
|
||||
case AUTH_CODE_REQUIRE:
|
||||
AuthRequire(c, fmt.Errorf("authorization error : %v", err))
|
||||
AuthRequire(c, HEADER_AUTH_REQUIRE.Error(err).GetErrorFull(""))
|
||||
case AUTH_CODE_FORBIDDEN:
|
||||
AuthForbidden(c, fmt.Errorf("authorization error : %v", err))
|
||||
AuthForbidden(c, HEADER_AUTH_FORBIDDEN.Error(err).GetErrorFull(""))
|
||||
default:
|
||||
err := fmt.Errorf("auth response code is not valid")
|
||||
c.Errors = append(c.Errors, &gin.Error{
|
||||
Err: err,
|
||||
Err: HEADER_AUTH_ERROR.Error(err).GetErrorFull(""),
|
||||
Type: gin.ErrorTypePrivate,
|
||||
})
|
||||
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 (
|
||||
"net/http"
|
||||
@@ -50,7 +50,7 @@ type Headers interface {
|
||||
|
||||
func NewHeaders() 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.
|
||||
func (h *headers) Add(key, value string) {
|
||||
if h.head == nil {
|
||||
h.head = make(http.Header, 0)
|
||||
h.head = make(http.Header)
|
||||
}
|
||||
|
||||
h.head.Add(key, value)
|
||||
@@ -107,7 +107,7 @@ func (h *headers) Add(key, value string) {
|
||||
// values associated with key.
|
||||
func (h *headers) Set(key, value string) {
|
||||
if h.head == nil {
|
||||
h.head = make(http.Header, 0)
|
||||
h.head = make(http.Header)
|
||||
}
|
||||
|
||||
h.head.Set(key, value)
|
||||
@@ -121,7 +121,7 @@ func (h *headers) Set(key, value string) {
|
||||
// access the map directly.
|
||||
func (h headers) Get(key string) string {
|
||||
if h.head == nil {
|
||||
h.head = make(http.Header, 0)
|
||||
h.head = make(http.Header)
|
||||
}
|
||||
|
||||
return h.head.Get(key)
|
||||
@@ -130,7 +130,7 @@ func (h headers) Get(key string) string {
|
||||
// Del deletes the values associated with key.
|
||||
func (h *headers) Del(key string) {
|
||||
if h.head == nil {
|
||||
h.head = make(http.Header, 0)
|
||||
h.head = make(http.Header)
|
||||
}
|
||||
|
||||
h.head.Del(key)
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_router
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -68,7 +68,7 @@ func RoutersHandler(engine *gin.Engine) {
|
||||
|
||||
func NewRouterList() RouterList {
|
||||
return &routerList{
|
||||
list: make(map[string][]routerItem, 0),
|
||||
list: make(map[string][]routerItem),
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_router
|
||||
package router
|
||||
|
||||
import (
|
||||
"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
|
||||
func SetGinHandler(fct func(c *gin.Context)) gin.HandlerFunc {
|
||||
return fct
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_semaphore
|
||||
package semaphore
|
||||
|
||||
import (
|
||||
"context"
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
* 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"
|
||||
|
||||
// String return the string form of the current ErrorType
|
||||
func (e ErrorType) String() string {
|
||||
return string(e)
|
||||
func init() {
|
||||
errors.RegisterFctMessage(getMessage)
|
||||
}
|
||||
|
||||
// Error return an error type of the current ErrorType
|
||||
// If an origin error is given (and not nil), this origin error will be append of the string (comma separated)
|
||||
func (e ErrorType) Error(origin error) error {
|
||||
if origin != nil {
|
||||
return fmt.Errorf("%s, %v", e.String(), origin)
|
||||
func getMessage(code errors.CodeError) (message string) {
|
||||
switch code {
|
||||
case EMPTY_PARAMS:
|
||||
return "given parameters is empty"
|
||||
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 (
|
||||
"context"
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/semaphore"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
type sem struct {
|
||||
@@ -41,12 +43,12 @@ type sem struct {
|
||||
}
|
||||
|
||||
type Sem interface {
|
||||
NewWorker() error
|
||||
NewWorker() Error
|
||||
NewWorkerTry() bool
|
||||
DeferWorker()
|
||||
DeferMain()
|
||||
|
||||
WaitAll() error
|
||||
WaitAll() Error
|
||||
Context() context.Context
|
||||
Cancel()
|
||||
}
|
||||
@@ -70,20 +72,18 @@ func NewSemaphore(maxSimultaneous int, timeout time.Duration, deadline time.Time
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sem) NewWorker() error {
|
||||
if e := s.s.Acquire(s.x, 1); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
func (s *sem) NewWorker() Error {
|
||||
e := s.s.Acquire(s.x, 1)
|
||||
return NEW_WORKER.Iferror(e)
|
||||
}
|
||||
|
||||
func (s *sem) NewWorkerTry() bool {
|
||||
return s.s.TryAcquire(1)
|
||||
}
|
||||
|
||||
func (s *sem) WaitAll() error {
|
||||
return s.s.Acquire(s.Context(), s.m)
|
||||
func (s *sem) WaitAll() Error {
|
||||
e := s.s.Acquire(s.Context(), s.m)
|
||||
return WAITALL.Iferror(e)
|
||||
}
|
||||
|
||||
func (s *sem) DeferWorker() {
|
||||
@@ -102,6 +102,7 @@ func (s *sem) Cancel() {
|
||||
|
||||
func (s *sem) Context() context.Context {
|
||||
if s.x == nil {
|
||||
s.x, s.c = GetContext(0, GetEmptyTime(), nil)
|
||||
}
|
||||
|
||||
return s.x
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"net/mail"
|
@@ -22,13 +22,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
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{})
|
||||
|
||||
if _, e := os.Stat(filepath); e != nil {
|
||||
return nil, e
|
||||
return nil, FILE_STAT.ErrorParent(e)
|
||||
}
|
||||
|
||||
if bb, e := ioutil.ReadFile(filepath); e != nil {
|
||||
return nil, e
|
||||
return nil, FILE_READ.ErrorParent(e)
|
||||
} else {
|
||||
b.Write(bb)
|
||||
}
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -34,8 +34,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
njs_certif "github.com/nabbar/golib/njs-certif"
|
||||
. "github.com/nabbar/golib/njs-logger"
|
||||
njs_certif "github.com/nabbar/golib/certificates"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
type smtpConfig struct {
|
||||
@@ -58,9 +59,9 @@ type smtpClient struct {
|
||||
}
|
||||
|
||||
type SMTP interface {
|
||||
Client() (*smtp.Client, error)
|
||||
Client() (*smtp.Client, Error)
|
||||
Close()
|
||||
Check() error
|
||||
Check() Error
|
||||
Clone() SMTP
|
||||
|
||||
ForceHost(host string)
|
||||
@@ -141,7 +142,7 @@ func (n NETMode) string() string {
|
||||
}
|
||||
|
||||
// ParseDSN parses the DSN string to a Config
|
||||
func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
||||
func newSMTPConfig(dsn string) (*smtpConfig, Error) {
|
||||
var (
|
||||
smtpcnf = &smtpConfig{
|
||||
DSN: dsn,
|
||||
@@ -191,9 +192,9 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
||||
// dsn[i-1] must be == ')' if an address is specified
|
||||
if dsn[i-1] != ')' {
|
||||
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], ':') {
|
||||
@@ -225,7 +226,7 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
||||
if dsn[j] == '?' {
|
||||
|
||||
if val, err := url.ParseQuery(dsn[j+1:]); err != nil {
|
||||
return nil, err
|
||||
return nil, CONFIG_INVALID_PARAMS.ErrorParent(err)
|
||||
} else {
|
||||
|
||||
if val.Get("ServerName") != "" {
|
||||
@@ -250,7 +251,7 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -261,7 +262,7 @@ func newSMTPConfig(dsn string) (*smtpConfig, error) {
|
||||
// - params available are : ServerName (string), SkipVerify (boolean)
|
||||
// - tls mode acceptable are : starttls, tls, <any other value to no tls/startls>
|
||||
// - 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 {
|
||||
tlsConfig = njs_certif.GetTLSConfig("")
|
||||
}
|
||||
@@ -277,7 +278,7 @@ func NewSMTP(dsn string, tlsConfig *tls.Config) (SMTP, error) {
|
||||
}
|
||||
|
||||
// Client Get SMTP Client interface
|
||||
func (s *smtpClient) Client() (*smtp.Client, error) {
|
||||
func (s *smtpClient) Client() (*smtp.Client, Error) {
|
||||
if s.cli == nil {
|
||||
var (
|
||||
err error
|
||||
@@ -299,35 +300,34 @@ func (s *smtpClient) Client() (*smtp.Client, error) {
|
||||
|
||||
if s.cfg.TLS == TLS_TLS {
|
||||
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
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
|
||||
if s.cfg.TLS != TLS_TLS {
|
||||
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()) {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return nil, SMTP_DIAL.ErrorParent(err)
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return nil, SMTP_CLIENT_INIT.ErrorParent(err)
|
||||
}
|
||||
|
||||
if s.cfg.TLS == TLS_STARTTLS {
|
||||
err = s.cli.StartTLS(tlsc)
|
||||
if ErrorLevel.LogErrorCtxf(DebugLevel, "SMTP Client STARTTLS initiated to server '%s' over '%s'", err, addr, s.cfg.Net.string()) {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return nil, SMTP_CLIENT_STARTTLS.ErrorParent(err)
|
||||
}
|
||||
}
|
||||
|
||||
if s.cfg.User != "" || s.cfg.Pass != "" {
|
||||
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()) {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return nil, SMTP_CLIENT_AUTH.ErrorParent(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,25 +341,25 @@ func (s *smtpClient) Client() (*smtp.Client, error) {
|
||||
func (s *smtpClient) Close() {
|
||||
if s.cli != nil {
|
||||
if e := s.cli.Quit(); e != nil {
|
||||
s.cli.Close()
|
||||
_ = s.cli.Close()
|
||||
}
|
||||
s.cli = nil
|
||||
}
|
||||
|
||||
if s.con != nil {
|
||||
s.con.Close()
|
||||
_ = s.con.Close()
|
||||
s.con = nil
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
if c, e := s.Client(); e != nil {
|
||||
return e
|
||||
} else if e = c.Noop(); e != nil {
|
||||
return e
|
||||
} else if e := c.Noop(); e != nil {
|
||||
return SMTP_CLIENT_NOOP.ErrorParent(e)
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/smtp"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
type ContentType uint8
|
||||
@@ -63,14 +65,14 @@ type ioData struct {
|
||||
b string
|
||||
}
|
||||
|
||||
func (i *ioData) getBoundary() (string, error) {
|
||||
func (i *ioData) getBoundary() (string, Error) {
|
||||
if i.b == "" {
|
||||
var buf [30]byte
|
||||
|
||||
_, err := io.ReadFull(rand.Reader, buf[:])
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", RAND_READER.ErrorParent(err)
|
||||
}
|
||||
|
||||
bnd := fmt.Sprintf("%x", buf[:])
|
||||
@@ -85,11 +87,11 @@ func (i ioData) GetBuffer() *bytes.Buffer {
|
||||
return i.p
|
||||
}
|
||||
|
||||
func (i *ioData) CRLF() error {
|
||||
func (i *ioData) CRLF() Error {
|
||||
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 != "" {
|
||||
return i.Header("Content-Type", fmt.Sprintf("\"%s\"; charset=%s", ct.String(), charset))
|
||||
} 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 {
|
||||
return err
|
||||
} 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 == "" {
|
||||
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 {
|
||||
return err
|
||||
} 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))
|
||||
}
|
||||
|
||||
func (i *ioData) String(value string) error {
|
||||
func (i *ioData) String(value string) Error {
|
||||
if i.p == nil {
|
||||
i.p = bytes.NewBuffer(make([]byte, 0))
|
||||
}
|
||||
|
||||
if _, e := i.p.WriteString(value); e != nil {
|
||||
return e
|
||||
return BUFFER_WRITE_STRING.ErrorParent(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ioData) Bytes(value []byte) error {
|
||||
func (i *ioData) Bytes(value []byte) Error {
|
||||
if i.p == nil {
|
||||
i.p = bytes.NewBuffer(make([]byte, 0))
|
||||
}
|
||||
@@ -161,7 +163,7 @@ func (i *ioData) Bytes(value []byte) error {
|
||||
|
||||
if (n+1)%76 == 0 {
|
||||
if _, e := i.p.Write(tmp); e != nil {
|
||||
return e
|
||||
return BUFFER_WRITE_BYTES.ErrorParent(e)
|
||||
} else if e := i.CRLF(); e != nil {
|
||||
return e
|
||||
}
|
||||
@@ -172,7 +174,7 @@ func (i *ioData) Bytes(value []byte) error {
|
||||
|
||||
if len(tmp) != 0 {
|
||||
if _, e := i.p.Write(tmp); e != nil {
|
||||
return e
|
||||
return BUFFER_WRITE_BYTES.ErrorParent(e)
|
||||
} else if e := i.CRLF(); e != nil {
|
||||
return e
|
||||
}
|
||||
@@ -181,28 +183,27 @@ func (i *ioData) Bytes(value []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ioData) Send() error {
|
||||
func (i *ioData) Send() Error {
|
||||
if i.w == nil {
|
||||
return fmt.Errorf("empty writer")
|
||||
return IO_WRITER_MISSING.Error(nil)
|
||||
}
|
||||
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 {
|
||||
return e
|
||||
return IO_WRITER_ERROR.ErrorParent(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ioData) AttachmentStart(c ContentType) error {
|
||||
func (i *ioData) AttachmentStart(c ContentType) Error {
|
||||
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 (
|
||||
e error
|
||||
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())
|
||||
|
||||
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
|
||||
} else if e = i.Header("Content-Type", contentType); e != nil {
|
||||
return e
|
||||
@@ -234,14 +235,14 @@ func (i *ioData) AttachmentAddFile(contentType, attachmentName string, attachmen
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ioData) AttachmentAddBody(m MailTemplate, ct ContentType) error {
|
||||
func (i *ioData) AttachmentAddBody(m MailTemplate, ct ContentType) Error {
|
||||
var (
|
||||
e error
|
||||
e Error
|
||||
p *bytes.Buffer
|
||||
)
|
||||
|
||||
if m.IsEmpty() {
|
||||
return fmt.Errorf("text/html content is empty")
|
||||
return EMPTY_HTML.Error(nil)
|
||||
}
|
||||
|
||||
switch ct {
|
||||
@@ -280,7 +281,7 @@ func (i *ioData) AttachmentAddBody(m MailTemplate, ct ContentType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ioData) AttachmentEnd() error {
|
||||
func (i *ioData) AttachmentEnd() Error {
|
||||
if e := i.BoundaryEnd(); e != nil {
|
||||
return e
|
||||
} else if e = i.BoundaryEnd(); e != nil {
|
||||
@@ -291,24 +292,24 @@ func (i *ioData) AttachmentEnd() error {
|
||||
}
|
||||
|
||||
type IOData interface {
|
||||
ContentType(ct ContentType, charset string) error
|
||||
Header(key, value string) error
|
||||
String(value string) error
|
||||
Bytes(value []byte) error
|
||||
CRLF() error
|
||||
ContentType(ct ContentType, charset string) Error
|
||||
Header(key, value string) Error
|
||||
String(value string) Error
|
||||
Bytes(value []byte) Error
|
||||
CRLF() Error
|
||||
|
||||
Send() error
|
||||
Send() Error
|
||||
GetBuffer() *bytes.Buffer
|
||||
|
||||
AttachmentStart(c ContentType) error
|
||||
AttachmentAddFile(contentType, attachmentName string, attachment *bytes.Buffer) error
|
||||
AttachmentAddBody(m MailTemplate, ct ContentType) error
|
||||
AttachmentEnd() error
|
||||
AttachmentStart(c ContentType) Error
|
||||
AttachmentAddFile(contentType, attachmentName string, attachment *bytes.Buffer) Error
|
||||
AttachmentAddBody(m MailTemplate, ct ContentType) Error
|
||||
AttachmentEnd() Error
|
||||
}
|
||||
|
||||
func NewIOData(cli *smtp.Client) (IOData, error) {
|
||||
func NewIOData(cli *smtp.Client) (IOData, Error) {
|
||||
if w, e := cli.Data(); e != nil {
|
||||
return nil, e
|
||||
return nil, SMTP_CLIENT_DATA.ErrorParent(e)
|
||||
} else {
|
||||
return &ioData{
|
||||
w: w,
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import "strings"
|
||||
|
||||
@@ -99,7 +99,7 @@ func (lst listMailAddress) String() string {
|
||||
}
|
||||
|
||||
func (lst listMailAddress) Clone() ListMailAddress {
|
||||
var l = make(listMailAddress, 0)
|
||||
var l = make(listMailAddress)
|
||||
|
||||
for _, a := range lst {
|
||||
l.Add(a.Clone())
|
||||
@@ -125,5 +125,5 @@ type ListMailAddress interface {
|
||||
}
|
||||
|
||||
func NewListMailAddress() ListMailAddress {
|
||||
return make(listMailAddress, 0)
|
||||
return make(listMailAddress)
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -6,9 +6,10 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/jaytaylor/html2text"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
"github.com/jaytaylor/html2text"
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
type mailTemplate struct {
|
||||
@@ -34,7 +35,7 @@ func (m mailTemplate) GetTextOption() html2text.Options {
|
||||
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))
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
return nil, TEMPLATE_EXECUTE.ErrorParent(err)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (m mailTemplate) GetBufferText(data interface{}) (*bytes.Buffer, error) {
|
||||
func (m mailTemplate) GetBufferText(data interface{}) (*bytes.Buffer, Error) {
|
||||
var (
|
||||
res = bytes.NewBuffer(make([]byte, 0))
|
||||
str string
|
||||
e error
|
||||
)
|
||||
|
||||
if buf, err := m.GetBufferHtml(data); err != nil {
|
||||
return nil, err
|
||||
} else if str, err = html2text.FromReader(buf, m.opt); err != nil {
|
||||
return nil, err
|
||||
} else if _, err = res.WriteString(str); err != nil {
|
||||
return nil, err
|
||||
} else if str, e = html2text.FromReader(buf, m.opt); e != nil {
|
||||
return nil, TEMPLATE_HTML2TEXT.ErrorParent(e)
|
||||
} else if _, e = res.WriteString(str); e != nil {
|
||||
return nil, BUFFER_WRITE_STRING.ErrorParent(e)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (m mailTemplate) GetBufferRich(data interface{}) (*bytes.Buffer, error) {
|
||||
func (m mailTemplate) GetBufferRich(data interface{}) (*bytes.Buffer, Error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -85,7 +87,7 @@ func (m mailTemplate) IsEmpty() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m mailTemplate) Clone() (MailTemplate, error) {
|
||||
func (m mailTemplate) Clone() (MailTemplate, Error) {
|
||||
res := &mailTemplate{
|
||||
data: nil,
|
||||
char: m.char,
|
||||
@@ -94,7 +96,7 @@ func (m mailTemplate) Clone() (MailTemplate, error) {
|
||||
}
|
||||
|
||||
if tpl, err := m.tpl.Clone(); err != nil {
|
||||
return nil, err
|
||||
return nil, TEMPLATE_CLONE.ErrorParent(err)
|
||||
} else {
|
||||
res.tpl = tpl
|
||||
}
|
||||
@@ -103,7 +105,7 @@ func (m mailTemplate) Clone() (MailTemplate, error) {
|
||||
}
|
||||
|
||||
type MailTemplate interface {
|
||||
Clone() (MailTemplate, error)
|
||||
Clone() (MailTemplate, Error)
|
||||
|
||||
IsEmpty() bool
|
||||
|
||||
@@ -113,14 +115,14 @@ type MailTemplate interface {
|
||||
SetTextOption(opt html2text.Options)
|
||||
GetTextOption() html2text.Options
|
||||
|
||||
GetBufferHtml(data interface{}) (*bytes.Buffer, error)
|
||||
GetBufferText(data interface{}) (*bytes.Buffer, error)
|
||||
GetBufferRich(data interface{}) (*bytes.Buffer, error)
|
||||
GetBufferHtml(data interface{}) (*bytes.Buffer, Error)
|
||||
GetBufferText(data interface{}) (*bytes.Buffer, Error)
|
||||
GetBufferRich(data interface{}) (*bytes.Buffer, Error)
|
||||
|
||||
RegisterData(data interface{})
|
||||
}
|
||||
|
||||
func NewMailTemplate(name, tpl string, isFile bool) (MailTemplate, error) {
|
||||
func NewMailTemplate(name, tpl string, isFile bool) (MailTemplate, Error) {
|
||||
var (
|
||||
err error
|
||||
res = &mailTemplate{
|
||||
@@ -154,17 +156,17 @@ func NewMailTemplate(name, tpl string, isFile bool) (MailTemplate, error) {
|
||||
if isFile {
|
||||
var fs []byte
|
||||
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 {
|
||||
return nil, err
|
||||
return nil, FILE_READ.ErrorParent(err)
|
||||
}
|
||||
|
||||
tpl = string(fs)
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package njs_smtp
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -31,7 +31,9 @@ import (
|
||||
"net/smtp"
|
||||
"time"
|
||||
|
||||
njs_version "github.com/nabbar/golib/njs-version"
|
||||
vers "github.com/nabbar/golib/version"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
type sendmail struct {
|
||||
@@ -136,7 +138,7 @@ func (s *sendmail) SetMailer(mailer string) {
|
||||
s.mailer = mailer
|
||||
}
|
||||
|
||||
func (s *sendmail) NJSMailer(version njs_version.Version) {
|
||||
func (s *sendmail) NJSMailer(version vers.Version) {
|
||||
s.mailer = version.GetHeader()
|
||||
}
|
||||
|
||||
@@ -144,7 +146,7 @@ func (s *sendmail) SetTestMode(enable bool) {
|
||||
s.testMode = enable
|
||||
}
|
||||
|
||||
func (s sendmail) Clone() (SendMail, error) {
|
||||
func (s sendmail) Clone() (SendMail, Error) {
|
||||
var (
|
||||
la = make([]Attachment, 0)
|
||||
)
|
||||
@@ -208,42 +210,43 @@ func (s sendmail) Clone() (SendMail, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s sendmail) SendSMTP(cli SMTP) (err error, buff *bytes.Buffer) {
|
||||
var c *smtp.Client
|
||||
func (s sendmail) SendSMTP(cli SMTP) (err Error, buff *bytes.Buffer) {
|
||||
var (
|
||||
e error
|
||||
c *smtp.Client
|
||||
)
|
||||
|
||||
defer func(cli *smtp.Client) {
|
||||
if cli != nil {
|
||||
cli.Quit()
|
||||
cli.Close()
|
||||
_ = cli.Quit()
|
||||
_ = cli.Close()
|
||||
}
|
||||
}(c)
|
||||
|
||||
if c, err = cli.Client(); err != nil {
|
||||
return
|
||||
} else if err, buff = s.Send(c); err != nil {
|
||||
c.Reset()
|
||||
return err, buff
|
||||
} else if e, buff = s.Send(c); e != nil {
|
||||
_ = c.Reset()
|
||||
return SMTP_SEND.ErrorParent(e), buff
|
||||
} else {
|
||||
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 (
|
||||
iod IOData
|
||||
)
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil && err != nil {
|
||||
err = fmt.Errorf("%v, %v", err, r)
|
||||
} else if r != nil {
|
||||
err = fmt.Errorf("%v", r)
|
||||
if r := recover(); r != nil {
|
||||
err = SMTP_CLIENT_SEND_RECOVERED.ErrorParent(err, fmt.Errorf("%v", r))
|
||||
}
|
||||
|
||||
if cli != nil {
|
||||
cli.Reset()
|
||||
cli.Quit()
|
||||
cli.Close()
|
||||
_ = cli.Reset()
|
||||
_ = cli.Quit()
|
||||
_ = cli.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -260,38 +263,44 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
||||
} else if s.msgText.Len() > 0 {
|
||||
ctBody = CONTENTTYPE_TEXT
|
||||
} else {
|
||||
return fmt.Errorf("no attachment & no contents"), nil
|
||||
return SMTP_CLIENT_EMPTY.Error(nil), nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
} else {
|
||||
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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -306,7 +315,7 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
||||
}
|
||||
|
||||
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 {
|
||||
return
|
||||
}
|
||||
@@ -334,7 +343,7 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
||||
}
|
||||
|
||||
if len(s.subject) < 1 {
|
||||
return fmt.Errorf("subjetc is empty"), nil
|
||||
return SMTP_CLIENT_SUBJECT_EMPTY.Error(nil), nil
|
||||
} else {
|
||||
var (
|
||||
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 {
|
||||
return fmt.Errorf("mailer is empty"), nil
|
||||
return SMTP_CLIENT_MAILER_EMPTY.Error(nil), nil
|
||||
} else {
|
||||
if err = iod.Header("X-Mailer", s.mailer); err != nil {
|
||||
return
|
||||
@@ -376,13 +385,13 @@ func (s sendmail) Send(cli *smtp.Client) (err error, buff *bytes.Buffer) {
|
||||
return
|
||||
}
|
||||
} 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 {
|
||||
return
|
||||
}
|
||||
} else if ctBody == CONTENTTYPE_HTML {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
@@ -442,13 +451,13 @@ type SendMail interface {
|
||||
|
||||
SetMessageId(id string)
|
||||
SetMailer(mailer string)
|
||||
NJSMailer(version njs_version.Version)
|
||||
NJSMailer(version vers.Version)
|
||||
|
||||
SetTestMode(enable bool)
|
||||
|
||||
Clone() (SendMail, error)
|
||||
Send(cli *smtp.Client) (err error, buff *bytes.Buffer)
|
||||
SendSMTP(cli SMTP) (err error, buff *bytes.Buffer)
|
||||
Clone() (SendMail, Error)
|
||||
Send(cli *smtp.Client) (err Error, buff *bytes.Buffer)
|
||||
SendSMTP(cli SMTP) (err Error, buff *bytes.Buffer)
|
||||
}
|
||||
|
||||
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 (
|
||||
"bytes"
|
||||
@@ -33,14 +33,14 @@ import (
|
||||
"path/filepath"
|
||||
"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/render"
|
||||
"github.com/gobuffalo/packr"
|
||||
|
||||
. "github.com/nabbar/golib/errors"
|
||||
. "github.com/nabbar/golib/logger"
|
||||
|
||||
njs_router "github.com/nabbar/golib/router"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,11 +64,11 @@ type Static interface {
|
||||
SetDownloadAll()
|
||||
SetDownload(file string)
|
||||
IsDownload(file string) bool
|
||||
|
||||
|
||||
Has(file string) bool
|
||||
Find(file string) ([]byte, error)
|
||||
|
||||
Health() error
|
||||
Health() Error
|
||||
Get(c *gin.Context)
|
||||
}
|
||||
|
||||
@@ -119,21 +119,21 @@ func (s staticHandler) print() {
|
||||
}
|
||||
|
||||
for _, f := range s.box.List() {
|
||||
njs_logger.DebugLevel.Logf("Embedded file : %s", f)
|
||||
DebugLevel.Logf("Embedded file : %s", f)
|
||||
}
|
||||
|
||||
s.debug = true
|
||||
}
|
||||
|
||||
func (s staticHandler) Health() error {
|
||||
func (s staticHandler) Health() Error {
|
||||
s.print()
|
||||
|
||||
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") {
|
||||
return fmt.Errorf("cannot find 'index.html' file")
|
||||
return INDEX_NOT_FOUND.Error(nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -160,12 +160,12 @@ func (s staticHandler) Get(c *gin.Context) {
|
||||
calledFile = FileIndex
|
||||
requestPath = FileIndex
|
||||
} else {
|
||||
c.Abort()
|
||||
_ = c.AbortWithError(http.StatusNotFound, INDEX_REQUESTED_NOT_SET.Error(nil))
|
||||
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()
|
||||
|
||||
if s.allDwnld || s.IsDownload(requestPath) {
|
||||
@@ -179,7 +179,7 @@ func (s staticHandler) Get(c *gin.Context) {
|
||||
Reader: bytes.NewReader(obj),
|
||||
})
|
||||
} else {
|
||||
c.Abort()
|
||||
_ = c.AbortWithError(http.StatusNotFound, FILE_NOT_FOUND.Error(nil))
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package njs_status
|
||||
package status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -31,13 +31,15 @@ import (
|
||||
"path"
|
||||
"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"
|
||||
)
|
||||
|
||||
// @TODO : see compliant with https://tools.ietf.org/html/draft-inadarei-api-health-check-02
|
||||
|
||||
type StatusItemResponse struct {
|
||||
Name string
|
||||
Status string
|
||||
@@ -48,7 +50,7 @@ type StatusItemResponse struct {
|
||||
|
||||
type StatusResponse struct {
|
||||
StatusItemResponse
|
||||
Partner []StatusItemResponse
|
||||
Component []StatusItemResponse
|
||||
}
|
||||
|
||||
const statusOK = "OK"
|
||||
@@ -63,7 +65,7 @@ type statusItem struct {
|
||||
release string
|
||||
}
|
||||
|
||||
type statusPartner struct {
|
||||
type statusComponent struct {
|
||||
statusItem
|
||||
WarnIfErr bool
|
||||
later *initLater
|
||||
@@ -71,8 +73,8 @@ type statusPartner struct {
|
||||
|
||||
type mainPackage struct {
|
||||
statusItem
|
||||
ptn []statusPartner
|
||||
header func(c *gin.Context)
|
||||
cpt []statusComponent
|
||||
header gin.HandlerFunc
|
||||
later *initLater
|
||||
init bool
|
||||
}
|
||||
@@ -87,18 +89,18 @@ type initLater struct {
|
||||
type Status interface {
|
||||
Register(prefix string, register njs_router.RegisterRouter)
|
||||
|
||||
AddPartner(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error)
|
||||
AddVersionPartner(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error)
|
||||
AddComponent(name, msgOK, msgKO, release, build 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)
|
||||
LaterAddVersionPartner(vers func() njs_version.Version, 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)
|
||||
LaterAddVersionComponent(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool)
|
||||
|
||||
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{
|
||||
ptn: make([]statusPartner, 0),
|
||||
cpt: make([]statusComponent, 0),
|
||||
header: Header,
|
||||
later: &initLater{
|
||||
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{
|
||||
statusItem: newItem(name, msgOK, msgKO, release, build, health),
|
||||
ptn: make([]statusPartner, 0),
|
||||
cpt: make([]statusComponent, 0),
|
||||
header: Header,
|
||||
later: nil,
|
||||
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{
|
||||
ptn: make([]statusPartner, 0),
|
||||
cpt: make([]statusComponent, 0),
|
||||
header: Header,
|
||||
later: &initLater{
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
p.ptn = append(p.ptn, statusPartner{
|
||||
func (p *mainPackage) AddComponent(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error) {
|
||||
p.cpt = append(p.cpt, statusComponent{
|
||||
statusItem: newItem(name, msgOK, msgKO, release, build, health),
|
||||
WarnIfErr: WarnIfError,
|
||||
later: nil,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *mainPackage) LaterAddPartner(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
||||
p.ptn = append(p.ptn, statusPartner{
|
||||
func (p *mainPackage) LaterAddComponent(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
||||
p.cpt = append(p.cpt, statusComponent{
|
||||
WarnIfErr: WarnIfError,
|
||||
later: &initLater{
|
||||
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) {
|
||||
p.AddPartner(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), WarnIfError, health)
|
||||
func (p *mainPackage) AddVersionComponent(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error) {
|
||||
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) {
|
||||
p.ptn = append(p.ptn, statusPartner{
|
||||
func (p *mainPackage) LaterAddVersionComponent(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool) {
|
||||
p.cpt = append(p.cpt, statusComponent{
|
||||
WarnIfErr: WarnIfError,
|
||||
later: &initLater{
|
||||
version: vers,
|
||||
@@ -204,14 +206,14 @@ func (p *mainPackage) initStatus() {
|
||||
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.info != nil {
|
||||
name, release, build := part.later.info()
|
||||
ok, ko := part.later.msg()
|
||||
part = statusPartner{
|
||||
part = statusComponent{
|
||||
statusItem: newItem(name, ok, ko, release, build, part.health),
|
||||
WarnIfErr: part.WarnIfErr,
|
||||
later: nil,
|
||||
@@ -219,7 +221,7 @@ func (p *mainPackage) initStatus() {
|
||||
} else if p.later.version != nil {
|
||||
v := p.later.version()
|
||||
ok, ko := p.later.msg()
|
||||
part = statusPartner{
|
||||
part = statusComponent{
|
||||
statusItem: newItem(v.GetPackage(), ok, ko, v.GetRelease(), v.GetBuild(), part.health),
|
||||
WarnIfErr: part.WarnIfErr,
|
||||
later: nil,
|
||||
@@ -231,11 +233,11 @@ func (p *mainPackage) initStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
ptn = append(ptn, part)
|
||||
cpt = append(cpt, part)
|
||||
}
|
||||
|
||||
p.init = true
|
||||
p.ptn = ptn
|
||||
p.cpt = cpt
|
||||
}
|
||||
|
||||
func (p *mainPackage) cleanPrefix(prefix string) string {
|
||||
@@ -302,20 +304,20 @@ func (p *mainPackage) Get(c *gin.Context) {
|
||||
make([]StatusItemResponse, 0),
|
||||
}
|
||||
|
||||
for _, pkg := range p.ptn {
|
||||
for _, pkg := range p.cpt {
|
||||
pres := pkg.GetStatusResponse(c)
|
||||
if res.Status == statusOK && pres.Status == statusKO && !pkg.WarnIfErr {
|
||||
res.Status = statusKO
|
||||
} else if pres.Status == statusKO {
|
||||
hasError = true
|
||||
}
|
||||
res.Partner = append(res.Partner, pres)
|
||||
res.Component = append(res.Component, pres)
|
||||
}
|
||||
|
||||
if res.Status != statusOK {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, &res)
|
||||
} else if hasError {
|
||||
c.JSON(http.StatusMultiStatus, &res)
|
||||
c.JSON(http.StatusAccepted, &res)
|
||||
} else {
|
||||
c.JSON(http.StatusOK, &res)
|
||||
}
|
@@ -30,16 +30,16 @@ import (
|
||||
"io/ioutil"
|
||||
"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
|
||||
//const fileName = "./git.tar"
|
||||
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 regex = ""
|
||||
@@ -57,13 +57,17 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer src.Close()
|
||||
defer func() {
|
||||
_ = src.Close()
|
||||
}()
|
||||
|
||||
if tmp, err = iou.NewTempFile(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer iou.DelTempFile(tmp, true)
|
||||
defer func() {
|
||||
_ = iou.DelTempFile(tmp)
|
||||
}()
|
||||
|
||||
if _, err = io.Copy(tmp, src); err != nil {
|
||||
panic(err)
|
||||
@@ -73,7 +77,9 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer rio.Close()
|
||||
defer func() {
|
||||
_ = rio.Close()
|
||||
}()
|
||||
|
||||
if _, err = rio.Seek(0, 0); err != nil {
|
||||
panic(err)
|
||||
|
@@ -29,21 +29,21 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
njs_progress "github.com/nabbar/golib/njs-progress"
|
||||
npb "github.com/nabbar/golib/progress"
|
||||
"github.com/vbauerster/mpb/v5"
|
||||
)
|
||||
|
||||
var (
|
||||
pb njs_progress.ProgressBar
|
||||
br njs_progress.Bar
|
||||
pb npb.ProgressBar
|
||||
br npb.Bar
|
||||
)
|
||||
|
||||
func main() {
|
||||
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)
|
||||
br = pb.NewBarSimple("test bar")
|
||||
br = pb.NewBarSimpleETA("test bar")
|
||||
|
||||
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"
|
||||
"os"
|
||||
|
||||
njs_ioutils "github.com/nabbar/golib/njs-ioutils"
|
||||
njs_ioutils "github.com/nabbar/golib/ioutils"
|
||||
)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
import "fmt"
|
||||
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func licence_agpl_v3() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func licence_apache2() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func license_cc_by_4() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func license_cc_sa_4() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func licence_cc0_v1() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func licence_gpl_v3() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func licence_lgpl_v3() string {
|
||||
return `
|
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package njs_version
|
||||
package version
|
||||
|
||||
func license_mit() string {
|
||||
return `
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user