podman
164 строки · 3.5 Кб
1// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
2// Use of this source code is governed by a MIT style
3// license that can be found in the LICENSE file.
4
5package gin6
7import (8"encoding/xml"9"net/http"10"os"11"path"12"reflect"13"runtime"14"strings"15"unicode"16)
17
18// BindKey indicates a default bind key.
19const BindKey = "_gin-gonic/gin/bindkey"20
21// Bind is a helper function for given interface object and returns a Gin middleware.
22func Bind(val any) HandlerFunc {23value := reflect.ValueOf(val)24if value.Kind() == reflect.Ptr {25panic(`Bind struct can not be a pointer. Example:26Use: gin.Bind(Struct{}) instead of gin.Bind(&Struct{})
27`)28}29typ := value.Type()30
31return func(c *Context) {32obj := reflect.New(typ).Interface()33if c.Bind(obj) == nil {34c.Set(BindKey, obj)35}36}37}
38
39// WrapF is a helper function for wrapping http.HandlerFunc and returns a Gin middleware.
40func WrapF(f http.HandlerFunc) HandlerFunc {41return func(c *Context) {42f(c.Writer, c.Request)43}44}
45
46// WrapH is a helper function for wrapping http.Handler and returns a Gin middleware.
47func WrapH(h http.Handler) HandlerFunc {48return func(c *Context) {49h.ServeHTTP(c.Writer, c.Request)50}51}
52
53// H is a shortcut for map[string]any
54type H map[string]any55
56// MarshalXML allows type H to be used with xml.Marshal.
57func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {58start.Name = xml.Name{59Space: "",60Local: "map",61}62if err := e.EncodeToken(start); err != nil {63return err64}65for key, value := range h {66elem := xml.StartElement{67Name: xml.Name{Space: "", Local: key},68Attr: []xml.Attr{},69}70if err := e.EncodeElement(value, elem); err != nil {71return err72}73}74
75return e.EncodeToken(xml.EndElement{Name: start.Name})76}
77
78func assert1(guard bool, text string) {79if !guard {80panic(text)81}82}
83
84func filterFlags(content string) string {85for i, char := range content {86if char == ' ' || char == ';' {87return content[:i]88}89}90return content91}
92
93func chooseData(custom, wildcard any) any {94if custom != nil {95return custom96}97if wildcard != nil {98return wildcard99}100panic("negotiation config is invalid")101}
102
103func parseAccept(acceptHeader string) []string {104parts := strings.Split(acceptHeader, ",")105out := make([]string, 0, len(parts))106for _, part := range parts {107if i := strings.IndexByte(part, ';'); i > 0 {108part = part[:i]109}110if part = strings.TrimSpace(part); part != "" {111out = append(out, part)112}113}114return out115}
116
117func lastChar(str string) uint8 {118if str == "" {119panic("The length of the string can't be 0")120}121return str[len(str)-1]122}
123
124func nameOfFunction(f any) string {125return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()126}
127
128func joinPaths(absolutePath, relativePath string) string {129if relativePath == "" {130return absolutePath131}132
133finalPath := path.Join(absolutePath, relativePath)134if lastChar(relativePath) == '/' && lastChar(finalPath) != '/' {135return finalPath + "/"136}137return finalPath138}
139
140func resolveAddress(addr []string) string {141switch len(addr) {142case 0:143if port := os.Getenv("PORT"); port != "" {144debugPrint("Environment variable PORT=\"%s\"", port)145return ":" + port146}147debugPrint("Environment variable PORT is undefined. Using port :8080 by default")148return ":8080"149case 1:150return addr[0]151default:152panic("too many parameters")153}154}
155
156// https://stackoverflow.com/questions/53069040/checking-a-string-contains-only-ascii-characters
157func isASCII(s string) bool {158for i := 0; i < len(s); i++ {159if s[i] > unicode.MaxASCII {160return false161}162}163return true164}
165