func (a *Language) DetectURI(_ engine.Response, r engine.Request) string { p := strings.TrimPrefix(r.URL().Path(), `/`) s := strings.Index(p, `/`) var lang string if s != -1 { lang = p[0:s] } else { lang = p } if lang != "" { if on, ok := a.List[lang]; ok { r.URL().SetPath(strings.TrimPrefix(p, lang)) if !on { lang = "" } } else { lang = "" } } if lang == "" { lang = a.DetectUA(r) } return lang }
// BuildKeys generates a slice of keys to rate-limit by given config and request structs. func BuildKeys(limiter *config.Limiter, r engine.Request) [][]string { remoteIP := RemoteIP(limiter.IPLookups, r) path := r.URL().Path() sliceKeys := make([][]string, 0) // Don't BuildKeys if remoteIP is blank. if remoteIP == "" { return sliceKeys } if limiter.Methods != nil && limiter.Headers != nil && limiter.BasicAuthUsers != nil { // Limit by HTTP methods and HTTP headers+values and Basic Auth credentials. if StringInSlice(limiter.Methods, r.Method()) { for headerKey, headerValues := range limiter.Headers { if (headerValues == nil || len(headerValues) <= 0) && r.Header().Get(headerKey) != "" { // If header values are empty, rate-limit all request with headerKey. username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey, username}) } } else if len(headerValues) > 0 && r.Header().Get(headerKey) != "" { // If header values are not empty, rate-limit all request with headerKey and headerValues. for _, headerValue := range headerValues { username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey, headerValue, username}) } } } } } } else if limiter.Methods != nil && limiter.Headers != nil { // Limit by HTTP methods and HTTP headers+values. if libstring.StringInSlice(limiter.Methods, r.Method()) { for headerKey, headerValues := range limiter.Headers { if (headerValues == nil || len(headerValues) <= 0) && r.Header().Get(headerKey) != "" { // If header values are empty, rate-limit all request with headerKey. sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey}) } else if len(headerValues) > 0 && r.Header().Get(headerKey) != "" { // If header values are not empty, rate-limit all request with headerKey and headerValues. for _, headerValue := range headerValues { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey, headerValue}) } } } } } else if limiter.Methods != nil && limiter.BasicAuthUsers != nil { // Limit by HTTP methods and Basic Auth credentials. if libstring.StringInSlice(limiter.Methods, r.Method()) { username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), username}) } } } else if limiter.Methods != nil { // Limit by HTTP methods. if libstring.StringInSlice(limiter.Methods, r.Method()) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method()}) } } else if limiter.Headers != nil { // Limit by HTTP headers+values. for headerKey, headerValues := range limiter.Headers { if (headerValues == nil || len(headerValues) <= 0) && r.Header().Get(headerKey) != "" { // If header values are empty, rate-limit all request with headerKey. sliceKeys = append(sliceKeys, []string{remoteIP, path, headerKey}) } else if len(headerValues) > 0 && r.Header().Get(headerKey) != "" { // If header values are not empty, rate-limit all request with headerKey and headerValues. for _, headerValue := range headerValues { sliceKeys = append(sliceKeys, []string{remoteIP, path, headerKey, headerValue}) } } } } else if limiter.BasicAuthUsers != nil { // Limit by Basic Auth credentials. username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, username}) } } else { // Default: Limit by remoteIP and path. sliceKeys = append(sliceKeys, []string{remoteIP, path}) } return sliceKeys }