Skip to content
Snippets Groups Projects
Verified Commit 29a54dc7 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

chore: commit save point

parent 39b83893
No related branches found
No related tags found
No related merge requests found
Showing
with 1280 additions and 0 deletions
package error
import (
"embed"
"encoding/json"
"gitlab.schukai.com/oss/utilities/conan/header"
"gitlab.schukai.com/oss/utilities/conan/negotiator"
"go.uber.org/zap"
"net/http"
"os"
"path/filepath"
"reflect"
"strconv"
"strings"
)
type configAccess interface {
GetResourcePath() string
IsResourcePathSet() bool
}
func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}
type ErrorResponse struct {
Status int
Hint string
ValidationErrors ValidationErrors
}
func NewErrorResponse(status int, hint string) ErrorResponse {
return ErrorResponse{
Status: status,
Hint: hint,
ValidationErrors: []ValidationError{},
}
}
func (e ErrorResponse) Error() string {
return "Status " + string(e.Status) + " " + e.Hint
}
func (e *ErrorResponse) AppendValidationError(err ValidationError) {
e.ValidationErrors = append(e.ValidationErrors, err)
}
func (e *ErrorResponse) GetValidationErrors() ValidationErrors {
return e.ValidationErrors
}
type ValidationError struct {
Message string
Namespace string
Field string
StructField string
Tag string
ActualTag string
Kind reflect.Kind
Type reflect.Type
Value interface{}
Param string
}
type validationDetails struct {
// the field affected by the review
Message string `json:"message,omitempty"`
Field string `json:"field,omitempty"`
Tag string `json:"rules,omitempty"`
ActualTag string `json:"broken-rule,omitempty"`
Value interface{} `json:"value,omitempty"`
Param string `json:"param,omitempty"`
}
type ValidationErrors []ValidationError
func StandardErrorResponse(w http.ResponseWriter, r *http.Request, errorResponse ErrorResponse) {
cfg := r.Context().Value("config")
emd := r.Context().Value("embed")
neg := negotiator.New(r.Header)
if neg.Type("text/html") != "" {
w.Header().Set("X-Alvine-Hint", errorResponse.Hint)
w.WriteHeader(errorResponse.Status)
var i interface{} = cfg
v, ok := i.(configAccess)
if ok == true {
if v.IsResourcePathSet() {
wp := v.GetResourcePath()
fp := filepath.Join(wp, "error/"+strconv.Itoa(errorResponse.Status)+".html")
if fileExists(fp) {
http.ServeFile(w, r, filepath.Join(wp, "error/"+strconv.Itoa(errorResponse.Status)+".html"))
return
}
}
}
if emd != nil {
resources := emd.(embed.FS)
fp := filepath.Join("web/resource/error/", ""+strconv.Itoa(errorResponse.Status)+".html")
content, err := resources.ReadFile(fp)
if err == nil {
w.Write(content)
return
}
}
w.Write([]byte("" + strconv.Itoa(errorResponse.Status)))
return
} else if neg.Type("application/json", "text/json") != "" {
writeJsonError(w, errorResponse)
} else {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
w.Header().Set("X-Alvine-Hint", errorResponse.Hint)
w.WriteHeader(http.StatusNotAcceptable)
}
}
type internalErrorResponseSys struct {
Error string `json:"error,omitempty"`
Code int `json:"code"`
// a more detailed explanation of the error
Hint string `json:"hint,omitempty"`
// An optional field name to which this validation applies
Validation []validationDetails `json:"validation,omitempty"`
}
type internalErrorResponse struct {
Sys internalErrorResponseSys `json:"sys"`
}
func writeJsonError(w http.ResponseWriter, data ErrorResponse) {
o := []validationDetails{}
for _, a := range data.ValidationErrors {
var rules string
if a.Tag != a.ActualTag {
rules = a.Tag
}
o = append(o, validationDetails{
//Message: a.Tr
Message: a.Message,
Field: strings.ToLower(strings.ReplaceAll(a.Namespace, "CreateOptions.", "")),
Tag: rules,
ActualTag: a.ActualTag,
Value: a.Value,
Param: a.Param,
})
}
response := internalErrorResponse{
Sys: internalErrorResponseSys{
Error: http.StatusText(data.Status),
Code: data.Status,
Hint: data.Hint,
Validation: o,
},
}
b, err := json.Marshal(response)
if err != nil {
zap.S().Error("json.Marshal fail: %s", err)
}
header.ApplicationJsonHeader(w)
w.WriteHeader(data.Status)
_, _ = w.Write(b)
}
package error
import (
"errors"
)
var ErrPropertyNotFound = errors.New("property not found")
package files
//
//func handler404(w http.ResponseWriter, r *http.Request) {
// error2.StandardErrorResponse(w, r,
// error2.ErrorResponse{
// Status: http.StatusNotFound,
// Hint: "check your url",
// })
//
//}
//
//func ServeAppFiles(webPath string) http.HandlerFunc {
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// appID := chi.RouteContext(r.Context()).URLParam("appID")
// watch.WriteApp(w, r, appID)
//
// })
//}
//
//func isSlashRune(r rune) bool { return r == '/' || r == '\\' }
//
//func ServeResourceFiles(webPath string) http.HandlerFunc {
//
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// //make sure the url path starts with /
// upath := r.URL.Path
// if !strings.HasPrefix(upath, "/") {
// upath = "/" + upath
// r.URL.Path = upath
// }
//
// upath = path.Clean(upath)
//
// regex := regexp.MustCompile(`(?m)(?P<uuid>/[a-f0-9]{32})(?P<path>/.*\.(js|css))$`)
// upath = regex.ReplaceAllString(upath, "$path")
//
// p := path.Join(webPath, upath)
//
// if strings.Contains(p, "..") {
// handler404(w, r)
// return
// }
//
// for _, ent := range strings.FieldsFunc(p, isSlashRune) {
// if ent == ".." {
// handler404(w, r)
// return
// }
// }
//
// // attempt to open the file via the http.FileSystem
// f, err := os.Open(p)
// //close if successfully opened
// if f != nil {
// defer f.Close()
// }
//
// if err != nil {
// if os.IsNotExist(err) {
// handler404(w, r)
// return
// }
// }
//
// s, err := f.Stat()
//
// if err != nil {
// if os.IsNotExist(err) {
// // call handler
// handler404(w, r)
// return
// }
// }
//
// if s.IsDir() {
// error2.StandardErrorResponse(w, r,
// error2.ErrorResponse{
// Status: http.StatusForbidden,
// Hint: "this is a directory",
// })
// return
// }
//
// http.ServeContent(w, r, p, s.ModTime(), f)
//
// })
//}
module gitlab.schukai.com/oss/utilities/conan
go 1.19
require (
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8
github.com/fsnotify/fsnotify v1.5.4
github.com/go-chi/chi/v5 v5.0.7
github.com/google/uuid v1.3.0
github.com/gookit/color v1.5.1
github.com/gorilla/websocket v1.5.0
github.com/jessevdk/go-flags v1.5.0
github.com/pkg/errors v0.9.1
github.com/sethvargo/go-envconfig v0.8.2
go.uber.org/zap v1.23.0
gopkg.in/yaml.v3 v3.0.1
)
require (
bitbucket.org/creachadair/shell v0.0.7 // indirect
github.com/bitfield/script v0.20.2 // indirect
github.com/itchyny/gojq v0.12.7 // indirect
github.com/itchyny/timefmt-go v0.1.3 // indirect
github.com/unknwon/com v1.0.1 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
)
bitbucket.org/creachadair/shell v0.0.7 h1:Z96pB6DkSb7F3Y3BBnJeOZH2gazyMTWlvecSD4vDqfk=
bitbucket.org/creachadair/shell v0.0.7/go.mod h1:oqtXSSvSYr4624lnnabXHaBsYW6RD80caLi2b3hJk0U=
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8 h1:tJQRXgZigkLeeW9LPlps9G9aMoE6LAmqigLA+wxmd1Q=
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8/go.mod h1:fc/pjt5EqNKgqQXYzcas1Z5L5whkZHyOvTA7OzWVJck=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/bitfield/script v0.20.2 h1:4DexsRtBILVMEn3EZwHbtJdDqdk43sXI8gM3F04JXgs=
github.com/bitfield/script v0.20.2/go.mod h1:l3AZPVAtKQrL03bwh7nlNTUtgrgSWurpJSbtqspYrOA=
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
github.com/couchbase/gomemcached v0.1.1/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo=
github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ=
github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw=
github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sethvargo/go-envconfig v0.8.2 h1:DDUVuG21RMgeB/bn4leclUI/837y6cQCD4w8hb5797k=
github.com/sethvargo/go-envconfig v0.8.2/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
package header
import (
"context"
"net/http"
"net/textproto"
)
// "sync/atomic"
const (
Accept = "Accept"
AcceptCharset = "Accept-Charset"
AcceptEncoding = "Accept-Encoding"
AcceptLanguage = "Accept-Language"
Authorization = "Authorization"
CacheControl = "Cache-Control"
ContentLength = "Content-Length"
ContentMD5 = "Content-MD5"
ContentType = "Content-Type"
DoNotTrack = "DNT"
IfMatch = "If-Match"
IfModifiedSince = "If-Modified-Since"
IfNoneMatch = "If-None-Match"
IfRange = "If-Range"
IfUnmodifiedSince = "If-Unmodified-Since"
MaxForwards = "Max-Forwards"
ProxyAuthorization = "Proxy-Authorization"
Pragma = "Pragma"
Range = "Range"
Referer = "Referer"
UserAgent = "User-Agent"
TE = "TE"
Via = "Via"
Warning = "Warning"
Cookie = "Cookie"
Origin = "Origin"
AcceptDatetime = "Accept-Datetime"
XRequestedWith = "X-Requested-With"
AccessControlAllowOrigin = "Access-Control-Allow-Origin"
AccessControlAllowMethods = "Access-Control-Allow-Methods"
AccessControlAllowHeaders = "Access-Control-Allow-Headers"
AccessControlAllowCredentials = "Access-Control-Allow-Credentials"
AccessControlExposeHeaders = "Access-Control-Expose-Headers"
AccessControlMaxAge = "Access-Control-Max-Age"
AccessControlRequestMethod = "Access-Control-Request-Method"
AccessControlRequestHeaders = "Access-Control-Request-Headers"
AcceptPatch = "Accept-Patch"
AcceptRanges = "Accept-Ranges"
Allow = "Allow"
ContentEncoding = "Content-Encoding"
ContentLanguage = "Content-Language"
ContentLocation = "Content-Location"
ContentDisposition = "Content-Disposition"
ContentRange = "Content-Range"
ETag = "ETag"
Expires = "Expires"
LastModified = "Last-Modified"
Link = "Link"
Location = "Location"
P3P = "P3P"
ProxyAuthenticate = "Proxy-Authenticate"
Refresh = "Refresh"
RetryAfter = "Retry-After"
Server = "Server"
SetCookie = "Set-Cookie"
StrictTransportSecurity = "Strict-Transport-Security"
TransferEncoding = "Transfer-Encoding"
Upgrade = "Upgrade"
Vary = "Vary"
WWWAuthenticate = "WWW-Authenticate"
// Non-Standard
XFrameOptions = "X-Frame-Options"
XXSSProtection = "X-XSS-Protection"
ContentSecurityPolicy = "Content-Security-Policy"
XContentSecurityPolicy = "X-Content-Security-Policy"
XWebKitCSP = "X-WebKit-CSP"
XContentTypeOptions = "X-Content-Type-Options"
XPoweredBy = "X-Powered-By"
XUACompatible = "X-UA-Compatible"
XForwardedProto = "X-Forwarded-Proto"
XHTTPMethodOverride = "X-HTTP-Method-Override"
XForwardedFor = "X-Forwarded-For"
XRealIP = "X-Real-IP"
XCSRFToken = "X-CSRF-Token"
XRatelimitLimit = "X-Ratelimit-Limit"
XRatelimitRemaining = "X-Ratelimit-Remaining"
XRatelimitReset = "X-Ratelimit-Reset"
XConanRequestID = "X-Conan-Request-Id"
)
// Normalize formats the input header to the formation of "Xxx-Xxx".
func Normalize(header string) string {
return textproto.CanonicalMIMEHeaderKey(header)
}
func ApplicationJsonHeader(w http.ResponseWriter) {
w.Header().Set(ContentType, "application/json")
}
///**
//Über `println(w.Header().Get("X-Alvine-Request-Id"))` kann
//die ID in den Handler ausgelesen werden.
// */
//func RequestIDHeader(w http.ResponseWriter) {
// w.Header().Set(XConanRequestID, )
//}
// RequestID is a middleware that injects a request ID into the context of each
// request. A request ID is a uuid-string.
func RequestID(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
//var requestID RequestUUID
ctx := r.Context()
requestID := NewRequestUUID()
//currentUUID := r.Header.Get(XConanRequestID)
//if currentUUID == "" {
// requestID= NewRequestUUID()
//} else {
// requestID,err:=uuid.Parse(currentUUID).(RequestUUID)
// if err!=nil {
// requestID= NewRequestUUID()
// }
// }
w.Header().Set(XConanRequestID, requestID.String())
ctx = context.WithValue(ctx, XConanRequestID, &requestID)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
package header
import (
"context"
"database/sql/driver"
"github.com/google/uuid"
"net/http"
)
type RequestUUID uuid.UUID
func NewRequestUUID() RequestUUID {
return RequestUUID(uuid.New())
}
func (r RequestUUID) UUID() uuid.UUID {
return uuid.UUID(r)
}
func (r RequestUUID) String() string {
return r.UUID().String()
}
// GormDataType -> sets type to binary(16)
func (r RequestUUID) GormDataType() string {
return "binary(16)"
}
// Scan --> tells GORM how to receive from the database
func (r *RequestUUID) Scan(value interface{}) error {
bytes, _ := value.([]byte)
parseByte, err := uuid.FromBytes(bytes)
*r = RequestUUID(parseByte)
return err
}
// Value -> tells GORM how to save into the database
func (r *RequestUUID) Value() (driver.Value, error) {
return uuid.UUID(*r).MarshalBinary()
}
// RequestIDMiddleware is a middleware that injects a request ID into the context of each
// request. A request ID is a uuid-string.
func RequestIDMiddleware(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
requestID := NewRequestUUID()
w.Header().Set(XConanRequestID, requestID.String())
ctx = context.WithValue(ctx, XConanRequestID, &requestID)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
package logging
import (
"github.com/go-chi/chi/v5/middleware"
"gitlab.schukai.com/oss/utilities/conan/header"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"net/http"
"time"
)
var logger *zap.Logger
var sugaredLogger *zap.SugaredLogger
func InitLogger() {
if logger != nil && sugaredLogger != nil {
return
}
var mode string
logger, _ = zap.NewDevelopment()
defer logger.Sync() // flushes buffer, if any
sugaredLogger = logger.Sugar()
sugaredLogger.Infof("init %s logger", mode)
}
func LogInfo(template string, args ...interface{}) {
if sugaredLogger == nil {
InitLogger()
}
sugaredLogger.Infof(template, args)
}
func LogDebug(template string, args ...interface{}) {
if sugaredLogger == nil {
InitLogger()
}
sugaredLogger.Debugf(template, args)
}
func LogError(template string, args ...interface{}) {
if sugaredLogger == nil {
InitLogger()
}
sugaredLogger.Errorf(template, args)
}
func LoggerMiddleware(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
next.ServeHTTP(ww, r)
ctx := r.Context()
requestIDString := ""
requestID, ok := ctx.Value(header.XConanRequestID).(header.RequestUUID)
if ok {
requestIDString = requestID.String()
}
latency := time.Since(start)
fields := []zapcore.Field{
zap.Int("status", ww.Status()),
zap.String("request-id", requestIDString),
zap.Duration("took", latency),
zap.Int64("measure.latency", latency.Nanoseconds()),
zap.String("remote", r.RemoteAddr),
zap.String("request", r.RequestURI),
zap.String("method", r.Method),
}
if logger == nil {
InitLogger()
}
logger.Info("request completed", fields...)
}
return http.HandlerFunc(fn)
}
package main
import "gitlab.schukai.com/oss/utilities/conan/command"
func main() {
command.Execute()
}
package negotiator
import (
"net/http"
"strings"
)
const (
headerAccept = "Accept"
headerAcceptLanguage = "Accept-Language"
headerAcceptEncoding = "Accept-Encoding"
headerAcceptCharset = "Accept-Charset"
)
type spec struct {
val string
q float64
}
// Specs represents []Spec.
type specs []spec
// Len is to impelement sort.Interface for Specs.
func (ss specs) Len() int {
return len(ss)
}
// Swap is to impelement sort.Interface for Specs.
func (ss specs) Swap(i, j int) {
ss[i], ss[j] = ss[j], ss[i]
}
// Less is to impelement sort.Interface for Specs.
func (ss specs) Less(i, j int) bool {
if ss[i].q > ss[j].q {
return true
}
if ss[i].q == ss[j].q {
if ss[i].val == "*" || strings.HasSuffix(ss[i].val, "/*") {
return true
}
if ss[j].val == "*" || strings.HasSuffix(ss[j].val, "/*") {
return false
}
return i < j
}
return false
}
func (ss specs) hasVal(val string) bool {
for _, spec := range ss {
if spec.val == val {
return true
}
}
return false
}
// Negotiator repensents the HTTP negotiator.
type Negotiator struct {
header http.Header
}
// New creates an instance of Negotiator.
func New(header http.Header) *Negotiator {
return &Negotiator{header}
}
// Type returns the most preferred content type from the HTTP Accept header.
// If nothing accepted, then empty string is returned.
func (n *Negotiator) Type(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, true)
return parser.selectOffer(offers, parser.parse(headerAccept))
}
// Language returns the most preferred language from the HTTP Accept-Language
// header. If nothing accepted, then empty string is returned.
func (n *Negotiator) Language(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, false)
return parser.selectOffer(offers, parser.parse(headerAcceptLanguage))
}
// Encoding returns the most preferred encoding from the HTTP Accept-Encoding
// header. If nothing accepted, then empty string is returned.
func (n *Negotiator) Encoding(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, false)
return parser.selectOffer(offers, parser.parse(headerAcceptEncoding))
}
// Charset returns the most preferred charset from the HTTP Accept-Charset
// header. If nothing accepted, then empty string is returned.
func (n *Negotiator) Charset(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, false)
return parser.selectOffer(offers, parser.parse(headerAcceptCharset))
}
package negotiator
import (
"net/http"
"sort"
"strconv"
"strings"
)
type headerParser struct {
header http.Header
hasSlashVal bool
defaultQ float64
wildCard string
}
func newHeaderParser(header http.Header, hasSlashVal bool) *headerParser {
hp := &headerParser{header: header, hasSlashVal: hasSlashVal, defaultQ: 1.0}
if hp.hasSlashVal {
hp.wildCard = "*/*"
} else {
hp.wildCard = "*"
}
return hp
}
func (p headerParser) parse(headerName string) (specs specs) {
headerVal := formatHeaderVal(p.header.Get(headerName))
if headerVal == "" {
specs = []spec{spec{val: p.wildCard, q: p.defaultQ}}
return
}
for _, accept := range strings.Split(headerVal, ",") {
pair := strings.Split(strings.TrimSpace(accept), ";")
if len(pair) < 1 || len(pair) > 2 {
if p.hasSlashVal {
if strings.Index(pair[0], "/") == -1 {
continue
}
} else {
continue
}
}
spec := spec{val: pair[0], q: p.defaultQ}
if len(pair) == 2 {
var i int
if strings.HasPrefix(pair[1], "q=") {
i = 2
} else if strings.HasPrefix(pair[1], "level=") {
i = 6
} else {
continue
}
if q, err := strconv.ParseFloat(pair[1][i:], 64); err == nil && q != 0.0 {
if q > p.defaultQ {
q = p.defaultQ
}
spec.q = q
} else {
continue
}
}
specs = append(specs, spec)
}
sort.Sort(specs)
return
}
func (p headerParser) selectOffer(offers []string, specs specs) (bestOffer string) {
bestQ := 0.0
var bestWild, totalWild int
if p.hasSlashVal {
bestWild, totalWild = 3, 3
} else {
bestWild, totalWild = 2, 2
}
if len(specs) == 0 {
return
}
if len(offers) == 0 {
bestOffer = specs[0].val
return
}
for _, offer := range offers {
lowerCaseOffer := strings.ToLower(offer)
for _, spec := range specs {
switch {
case spec.q <= bestQ:
continue
case spec.val == p.wildCard && !specs.hasVal(lowerCaseOffer):
if spec.q > bestQ || bestWild > totalWild-1 {
bestOffer = offer
bestQ, bestWild = spec.q, totalWild-1
}
case p.hasSlashVal && strings.HasSuffix(spec.val, "/*"):
if strings.HasPrefix(lowerCaseOffer, spec.val[:len(spec.val)-1]) &&
(spec.q > bestQ || bestWild > totalWild-2) {
bestOffer = offer
bestQ, bestWild = spec.q, totalWild-2
}
case spec.val == lowerCaseOffer:
if spec.q > bestQ || bestWild > 0 {
bestOffer = offer
bestQ, bestWild = spec.q, 0
}
}
}
}
return
}
func formatHeaderVal(val string) string {
return strings.ToLower(strings.Replace(val, " ", "", -1))
}
package release
type ReleaseAccessor interface {
GetVersion() string
GetBuild() string
GetMnemonic() string
}
package release
type ReleaseStruct struct {
Version string
Build string
Mnemonic string
}
var release ReleaseStruct
func init() {
InitRelease(version, build, mnemonic)
}
func InitRelease(version, build, mnemonic string) {
release = ReleaseStruct{
Version: version,
Build: build,
Mnemonic: mnemonic,
}
}
func GetVersion() string {
return release.Version
}
func GetBuild() string {
return release.Build
}
func GetMnemonic() string {
return release.Mnemonic
}
package release
// Used when building per
// -ldflags "-X release.version=$version -X release.build=$(due --iso-8601 | tr -d "-" )"
var (
version string = "dev"
build string = "dev"
mnemonic string = "conan"
)
package response
import (
"encoding/json"
"gitlab.schukai.com/oss/utilities/conan/header"
"gitlab.schukai.com/oss/utilities/conan/negotiator"
"go.uber.org/zap"
"net/http"
)
func WriteStandardResponse[D any](w http.ResponseWriter, r *http.Request, data StandardResponse[D]) {
neg := negotiator.New(r.Header)
if neg.Type("text/html") != "" {
w.WriteHeader(data.Status)
} else if neg.Type("application/json", "text/json") != "" {
WriteStandardJson(w, data)
} else {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
w.Header().Set("X-Alvine-Hint", "Mime type not acceptable")
w.WriteHeader(http.StatusNotAcceptable)
}
}
type StandardResponse[D any] struct {
Status int
Hint string
Data D
}
func WriteStandardJson[D any](w http.ResponseWriter, data StandardResponse[D]) {
response := internalResponse{
Sys: internalResponseSys{
Code: data.Status,
},
Data: data.Data,
}
b, err := json.Marshal(response)
if err != nil {
zap.S().Error("json.Marshal fail: %s", err)
}
header.ApplicationJsonHeader(w)
w.WriteHeader(data.Status)
_, _ = w.Write(b)
}
type internalResponse struct {
Data interface{} `json:"data"`
Sys internalResponseSys `json:"sys"`
}
type internalResponseSys struct {
Code int `json:"code"`
}
package server
package server
import (
"net/http"
)
func reloadMiddleware(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
package server
import (
"crypto/tls"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"gitlab.schukai.com/oss/utilities/conan/configuration"
"gitlab.schukai.com/oss/utilities/conan/header"
"gitlab.schukai.com/oss/utilities/conan/logging"
"net/http"
)
func getRouter() *chi.Mux {
/** x509: certificate signed by unknown authority */
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
router := chi.NewRouter()
router.Use(middleware.RealIP)
router.Use(middleware.Heartbeat("ping"))
router.Use(header.RequestIDMiddleware)
router.Use(middleware.Compress(5))
router.Use(logging.LoggerMiddleware)
router.Use(reloadMiddleware)
router.Handle("/*", http.FileServer(
http.Dir(configuration.GetServerWebPath()+"/")))
return router
}
package server
import (
"gitlab.schukai.com/oss/utilities/conan/configuration"
error2 "gitlab.schukai.com/oss/utilities/conan/error"
"gitlab.schukai.com/oss/utilities/conan/logging"
"gitlab.schukai.com/oss/utilities/conan/watch"
"net/http"
)
func Start() {
address := configuration.GetServerAddress() + ":" + configuration.GetServerPort()
server := http.Server{
Handler: getRouter(),
Addr: address,
}
watch.InitWatch()
logging.LogInfo("Server started on %s", address)
logging.LogInfo("Web path: %s", configuration.GetServerWebPath())
logging.LogInfo("Available at (non-exhaustive list): %s", "http://"+configuration.GetServerHost()+"/")
logging.LogInfo("Press %s to quit.", "Ctrl+C")
watch.StartWatching()
err := server.ListenAndServe()
error2.CheckError(err)
watch.DestroyApps()
}
package server
import (
"encoding/json"
"fmt"
"github.com/go-chi/chi/v5"
"gitlab.schukai.com/oss/utilities/conan/constants"
error2 "gitlab.schukai.com/oss/utilities/conan/error"
"gitlab.schukai.com/oss/utilities/conan/header"
"gitlab.schukai.com/oss/utilities/conan/negotiator"
"go.uber.org/zap"
"net/http"
)
type WebManifest struct {
Name string `json:"name"`
ShortName string `json:"short_name"`
Scope string `json:"scope"`
StartUrl string `json:"start_url"`
Display string `json:"display"`
BackgroundColor string `json:"background_color"`
Description string `json:"description"`
Icons []WebManifestIcons `json:"icons"`
RelatedApplications []WebManifestRelatedApplications `json:"related_applications"`
}
type WebManifestRelatedApplications struct {
Platform string `json:"platform"`
Url string `json:"url,omitempty"`
}
type WebManifestIcons struct {
Src string `json:"src"`
Sizes string `json:"sizes"`
Type string `json:"type"`
}
func GetWebmanifestHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
neg := negotiator.New(r.Header)
a := neg.Type("application/json")
fmt.Println(a)
if neg.Type("application/json") == "" {
error2.StandardErrorResponse(w, r,
error2.ErrorResponse{
Status: http.StatusNotAcceptable,
Hint: "the webmanifest is only available for the app as a json file",
})
return
}
//r, _ = DoCheck(w, r)
//if r == nil {
// return
//}
appID := chi.RouteContext(r.Context()).URLParam("appID")
manifest := WebManifest{
Name: appID,
ShortName: appID,
Scope: "/app/" + appID,
StartUrl: "/app/" + appID,
Display: "standalone", // fullscreen,minimal-ui,standalone,browser
BackgroundColor: "#ffffff",
Description: appID,
Icons: []WebManifestIcons{
{
Src: "/app/" + appID + "/" + constants.AssetsPath + "/android-chrome-192x192.png",
Sizes: "192x192",
Type: "image/png",
},
{
Src: "/app/" + appID + "/" + constants.AssetsPath + "/android-chrome-512x512.png",
Sizes: "512x512",
Type: "image/png",
},
},
RelatedApplications: []WebManifestRelatedApplications{
{
Platform: "android",
Url: "https://play.google.com/store/apps/details?id=com.agenor.app." + appID,
},
{
Platform: "ios",
Url: "https://itunes.apple.com/us/app/agenor-app/" + appID + "?ls=1&mt=8",
},
},
}
b, err := json.Marshal(manifest)
if err != nil {
zap.S().Error("json.Marshal fail: %s", err)
}
w.Header().Set(header.ContentType, "application/manifest+json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write(b)
})
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment