...
1
2
3
4
5 package gin
6
7 import (
8 "encoding/xml"
9 "net/http"
10 "os"
11 "path"
12 "reflect"
13 "runtime"
14 "strings"
15 "unicode"
16 )
17
18
19 const BindKey = "_gin-gonic/gin/bindkey"
20
21
22 func Bind(val any) HandlerFunc {
23 value := reflect.ValueOf(val)
24 if value.Kind() == reflect.Ptr {
25 panic(`Bind struct can not be a pointer. Example:
26 Use: gin.Bind(Struct{}) instead of gin.Bind(&Struct{})
27 `)
28 }
29 typ := value.Type()
30
31 return func(c *Context) {
32 obj := reflect.New(typ).Interface()
33 if c.Bind(obj) == nil {
34 c.Set(BindKey, obj)
35 }
36 }
37 }
38
39
40 func WrapF(f http.HandlerFunc) HandlerFunc {
41 return func(c *Context) {
42 f(c.Writer, c.Request)
43 }
44 }
45
46
47 func WrapH(h http.Handler) HandlerFunc {
48 return func(c *Context) {
49 h.ServeHTTP(c.Writer, c.Request)
50 }
51 }
52
53
54 type H map[string]any
55
56
57 func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
58 start.Name = xml.Name{
59 Space: "",
60 Local: "map",
61 }
62 if err := e.EncodeToken(start); err != nil {
63 return err
64 }
65 for key, value := range h {
66 elem := xml.StartElement{
67 Name: xml.Name{Space: "", Local: key},
68 Attr: []xml.Attr{},
69 }
70 if err := e.EncodeElement(value, elem); err != nil {
71 return err
72 }
73 }
74
75 return e.EncodeToken(xml.EndElement{Name: start.Name})
76 }
77
78 func assert1(guard bool, text string) {
79 if !guard {
80 panic(text)
81 }
82 }
83
84 func filterFlags(content string) string {
85 for i, char := range content {
86 if char == ' ' || char == ';' {
87 return content[:i]
88 }
89 }
90 return content
91 }
92
93 func chooseData(custom, wildcard any) any {
94 if custom != nil {
95 return custom
96 }
97 if wildcard != nil {
98 return wildcard
99 }
100 panic("negotiation config is invalid")
101 }
102
103 func parseAccept(acceptHeader string) []string {
104 parts := strings.Split(acceptHeader, ",")
105 out := make([]string, 0, len(parts))
106 for _, part := range parts {
107 if i := strings.IndexByte(part, ';'); i > 0 {
108 part = part[:i]
109 }
110 if part = strings.TrimSpace(part); part != "" {
111 out = append(out, part)
112 }
113 }
114 return out
115 }
116
117 func lastChar(str string) uint8 {
118 if str == "" {
119 panic("The length of the string can't be 0")
120 }
121 return str[len(str)-1]
122 }
123
124 func nameOfFunction(f any) string {
125 return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
126 }
127
128 func joinPaths(absolutePath, relativePath string) string {
129 if relativePath == "" {
130 return absolutePath
131 }
132
133 finalPath := path.Join(absolutePath, relativePath)
134 if lastChar(relativePath) == '/' && lastChar(finalPath) != '/' {
135 return finalPath + "/"
136 }
137 return finalPath
138 }
139
140 func resolveAddress(addr []string) string {
141 switch len(addr) {
142 case 0:
143 if port := os.Getenv("PORT"); port != "" {
144 debugPrint("Environment variable PORT=\"%s\"", port)
145 return ":" + port
146 }
147 debugPrint("Environment variable PORT is undefined. Using port :8080 by default")
148 return ":8080"
149 case 1:
150 return addr[0]
151 default:
152 panic("too many parameters")
153 }
154 }
155
156
157 func isASCII(s string) bool {
158 for i := 0; i < len(s); i++ {
159 if s[i] > unicode.MaxASCII {
160 return false
161 }
162 }
163 return true
164 }
165
View as plain text