github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/types.go (about) 1 // Copyright 2017-present Kirill Danshin and Gramework contributors 2 // Copyright 2019-present Highload LTD (UK CN: 11893420) 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 11 package gramework 12 13 import ( 14 "fmt" 15 "sync" 16 "time" 17 18 "github.com/microcosm-cc/bluemonday" 19 20 "github.com/apex/log" 21 "github.com/gramework/utils/nocopy" 22 "github.com/valyala/fasthttp" 23 ) 24 25 type ( 26 ipList struct { 27 list map[string]struct{} 28 mu *sync.RWMutex 29 } 30 31 suspect struct { 32 hackAttempts int32 33 } 34 35 suspectsList struct { 36 list map[string]*suspect 37 mu *sync.RWMutex 38 } 39 40 // App represents a gramework app 41 App struct { 42 defaultRouter *Router 43 domains map[string]*Router 44 _ [8]byte // callback 45 firewall *firewall 46 firewallInit *sync.Once 47 Flags *Flags 48 flagsQueue []Flag 49 Logger log.Interface 50 name string 51 Settings Settings 52 TLSEmails []string 53 TLSPort uint16 54 middlewares []func(*Context) 55 middlewaresAfterRequest []func(*Context) 56 preMiddlewares []func(*Context) 57 domainListLock *sync.RWMutex 58 middlewaresAfterRequestMu *sync.RWMutex 59 middlewaresMu *sync.RWMutex 60 preMiddlewaresMu *sync.RWMutex 61 EnableFirewall bool 62 flagsRegistered bool 63 HandleUnknownDomains bool 64 seed uintptr 65 cookieDomain string 66 cookiePath string 67 NoDefaultPanicHandler bool 68 PanicHandlerNoPoweredBy bool 69 PanicHandlerCustomLayout string 70 internalLog *log.Entry 71 72 cookieExpire time.Duration 73 74 // Gramework Protection's max detections of suspect before ban 75 maxHackAttempts *int32 76 // Gramework Protection's protected endpoint prefixes 77 protectedPrefixes map[string]struct{} 78 // Gramework Protection's protected paths of endpoints 79 protectedEndpoints map[string]struct{} 80 // Gramework Protection's trusted ip list 81 trustedIP *ipList 82 // Gramework Protection's untrusted (banned) ip list 83 untrustedIP *ipList 84 // Gramework Protection's suspects ip list 85 suspectedIP *suspectsList 86 87 serverBase *fasthttp.Server 88 runningServers []runningServerInfo 89 runningServersMu *sync.Mutex 90 91 behind Behind 92 93 sanitizerPolicy *bluemonday.Policy 94 95 DefaultCacheOptions *CacheOptions 96 } 97 98 // CacheOptions is a handler cache configuration structure. 99 CacheOptions struct { 100 // TTL is the time that cached response is valid 101 TTL time.Duration 102 // Cacheable function returns if current request is cacheable. 103 // By deafult, any request with Authentication header or any Cookies will not be cached for security reasons. 104 // If you want to cache responses for authorized users, please replace both Cacheable and CacheKey functions 105 // to make sure that CacheKey includes something like session id. 106 Cacheable func(ctx *Context) bool 107 // CacheKey function returns the cache key for current request 108 CacheKey func(ctx *Context) []byte 109 110 // ReadCache allows for cache engine replacement. By default, gramework uses github.com/VictoriaMetrics/fastcache. 111 // ReadCache returns the value and boolean if the value was found and still valid. 112 ReadCache func(ctx *Context, key []byte) ([]byte, bool) 113 // StoreCache allows for cache engine replacement. By default, gramework uses github.com/VictoriaMetrics/fastcache. 114 StoreCache func(ctx *Context, key, value []byte, ttl time.Duration) 115 116 // CacheableHeaders is a list of headers that gramework can cache. 117 // Note, that if X-ABC is present both in cacheable and noncacheable header lists, 118 // it will not be cached. 119 CacheableHeaders []string // slice of canonical header names 120 // NonCacheableHeaders is a list of headers that gramework can not cache. 121 // Note, that if X-ABC is present both in cacheable and noncacheable header lists, 122 // it will not be cached. 123 NonCacheableHeaders []string 124 } 125 126 runningServerInfo struct { 127 bind string 128 srv *fasthttp.Server 129 } 130 131 contextKey string 132 133 // Context is a gramework request context 134 Context struct { 135 *fasthttp.RequestCtx 136 nocopy nocopy.NoCopy 137 Logger log.Interface 138 App *App 139 auth *Auth 140 Cookies Cookies 141 requestID string 142 143 middlewaresShouldStopProcessing bool 144 subPrefixes []string 145 middlewareKilledReq bool 146 writer func(p []byte) (int, error) 147 } 148 149 // GQLRequest is a GraphQL request structure 150 GQLRequest struct { 151 Query string `json:"query"` 152 OperationName string `json:"operationName"` 153 Variables map[string]interface{} `json:"variables"` 154 } 155 156 // Cookies handles a typical cookie storage 157 Cookies struct { 158 Storage map[string]string 159 Mu sync.RWMutex 160 } 161 162 // Settings for an App instance 163 Settings struct { 164 Firewall FirewallSettings 165 } 166 167 // FirewallSettings represents a new firewall settings. 168 // Internal firewall representation copies this settings 169 // atomically. 170 FirewallSettings struct { 171 // MaxReqPerMin is a max request per minute count 172 MaxReqPerMin int64 173 // BlockTimeout in seconds 174 BlockTimeout int64 175 } 176 177 firewall struct { 178 // Store a copy of current settings 179 MaxReqPerMin *int64 180 BlockTimeout *int64 181 blockListMutex sync.Mutex 182 requestCounterMutex sync.Mutex 183 blockList map[string]int64 184 requestCounter map[string]int64 185 } 186 187 // Flags is a flags storage 188 Flags struct { 189 values map[string]Flag 190 } 191 192 // Flag is a flag representation 193 Flag struct { 194 Name string 195 Description string 196 Default string 197 Value *string 198 } 199 200 // Router handles internal handler conversion etc. 201 Router struct { 202 router *router 203 httprouter *Router 204 httpsrouter *Router 205 root *Router 206 app *App 207 mu sync.RWMutex 208 209 rootHandler []staticHandler 210 } 211 212 // SubRouter handles subs registration 213 // like app.Sub("v1").GET("someRoute", "hi") 214 SubRouter struct { 215 parent routerable 216 prefix string 217 prefixes []string 218 } 219 220 routerable interface { 221 handleReg(method, route string, handler interface{}, prefixes []string) 222 determineHandler(handler interface{}) func(*Context) 223 } 224 225 // RequestHandler describes a standard request handler type 226 RequestHandler func(*Context) 227 228 // RequestHandlerErr describes a standard request handler with error returned type 229 RequestHandlerErr func(*Context) error 230 231 // Auth is a struct that handles 232 // context's basic auth features 233 Auth struct { 234 login string 235 pass string 236 237 parsed bool 238 // if error occurred during parsing, 239 // it will be always returned for current 240 // context 241 err error 242 243 ctx *Context 244 } 245 246 // HTML type used to determine prerendered strings 247 // as an HTML and give proper content-type 248 HTML string 249 250 // JSON type used to determine prerendered strings 251 // as an JSON and give proper content-type 252 JSON string 253 ) 254 255 // crazy hack to solve nocopy false positive 256 var _ = fmt.Sprintf("%v", func() interface{} { 257 ctx := Context{} 258 return &ctx.nocopy 259 }())