feat: new action process

This commit is contained in:
Roi Feng
2025-02-13 22:20:53 -05:00
parent c7e9a69f8b
commit aea36d463b
7 changed files with 123 additions and 74 deletions

View File

@ -1,26 +1,35 @@
package action
type Action int
type checkState int
const (
Undecided Action = iota // 0Undecided
Allow // 1Pass
Block // 2Deny
Continue checkState = iota
Done
Jump
)
// Decision saves the result of the decision
type Decision struct {
result Action
HTTPCode string
State checkState
JumpIndex int
}
func NewDecision() *Decision {
return &Decision{result: Undecided}
return &Decision{HTTPCode: "200", State: Continue, JumpIndex: -1}
}
func (d *Decision) Get() Action {
return d.result
func (d *Decision) Set(state checkState) {
d.State = state
}
func (d *Decision) Set(new Action) {
d.result = new
func (d *Decision) SetCode(state checkState, httpCode string) {
d.State = state
d.HTTPCode = httpCode
}
func (d *Decision) SetJump(state checkState, httpCode string, jumpIndex int) {
d.State = state
d.HTTPCode = httpCode
d.JumpIndex = jumpIndex
}

23
internal/check/IPAllow.go Normal file
View File

@ -0,0 +1,23 @@
package check
import (
"net"
"server_torii/internal/action"
"server_torii/internal/config"
"server_torii/internal/dataType"
)
func IPAllowList(reqData dataType.UserRequest, ruleSet *config.RuleSet, decision *action.Decision) {
remoteIP := reqData.RemoteIP
trie := ruleSet.IPAllowTrie
ip := net.ParseIP(remoteIP)
if ip == nil {
return
}
if trie.Search(ip) {
decision.SetCode(action.Done, "200")
} else {
decision.Set(action.Continue)
}
}

22
internal/check/IPBlock.go Normal file
View File

@ -0,0 +1,22 @@
package check
import (
"net"
"server_torii/internal/action"
"server_torii/internal/config"
"server_torii/internal/dataType"
)
func IPBlockList(reqData dataType.UserRequest, ruleSet *config.RuleSet, decision *action.Decision) {
remoteIP := reqData.RemoteIP
trie := ruleSet.IPBlockTrie
ip := net.ParseIP(remoteIP)
if ip == nil {
return
}
if trie.Search(ip) {
decision.SetCode(action.Done, "403")
} else {
decision.Set(action.Continue)
}
}

View File

@ -0,0 +1,17 @@
package check
import (
"server_torii/internal/action"
"server_torii/internal/config"
"server_torii/internal/dataType"
)
func URLAllowList(reqData dataType.UserRequest, ruleSet *config.RuleSet, decision *action.Decision) {
url := reqData.Uri
list := ruleSet.URLAllowList
if list.Match(url) {
decision.SetCode(action.Done, "200")
} else {
decision.Set(action.Continue)
}
}

View File

@ -0,0 +1,17 @@
package check
import (
"server_torii/internal/action"
"server_torii/internal/config"
"server_torii/internal/dataType"
)
func URLBlockList(reqData dataType.UserRequest, ruleSet *config.RuleSet, decision *action.Decision) {
url := reqData.Uri
list := ruleSet.URLBlockList
if list.Match(url) {
decision.SetCode(action.Done, "403")
} else {
decision.Set(action.Continue)
}
}

View File

@ -0,0 +1,6 @@
package dataType
type UserRequest struct {
RemoteIP string
Uri string
}

View File

@ -5,15 +5,13 @@ import (
"net"
"net/http"
"server_torii/internal/action"
"server_torii/internal/check"
"server_torii/internal/config"
"server_torii/internal/dataType"
"strings"
)
type userRequest struct {
remoteIP string
uri string
}
type CheckFunc func(dataType.UserRequest, *config.RuleSet, *action.Decision)
// StartServer starts the HTTP server
func StartServer(cfg *config.MainConfig, ruleSet *config.RuleSet) error {
@ -23,22 +21,23 @@ func StartServer(cfg *config.MainConfig, ruleSet *config.RuleSet) error {
decision := action.NewDecision()
// run main check logic
checkIPAllow(userRequestData.remoteIP, ruleSet.IPAllowTrie, decision)
checkIPBlock(userRequestData.remoteIP, ruleSet.IPBlockTrie, decision)
checkURLAllow(userRequestData.uri, ruleSet.URLAllowList, decision)
checkURLBlock(userRequestData.uri, ruleSet.URLBlockList, decision)
checkFuncs := make([]CheckFunc, 0)
checkFuncs = append(checkFuncs, check.IPAllowList)
checkFuncs = append(checkFuncs, check.IPBlockList)
checkFuncs = append(checkFuncs, check.URLAllowList)
checkFuncs = append(checkFuncs, check.URLBlockList)
// if still undecided, allow
if decision.Get() == action.Undecided {
decision.Set(action.Allow)
for _, checkFunc := range checkFuncs {
checkFunc(userRequestData, ruleSet, decision)
if decision.State == action.Done {
break
}
}
log.Printf("clientIP: %s, decision: %s, Headers: %v", userRequestData.remoteIP, decision.Get(), r.Header)
// return response
if decision.Get() == action.Allow {
if decision.HTTPCode == "200" {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Allowed"))
} else if decision.Get() == action.Block {
} else if decision.HTTPCode == "403" {
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Blocked"))
} else {
@ -51,7 +50,7 @@ func StartServer(cfg *config.MainConfig, ruleSet *config.RuleSet) error {
return http.ListenAndServe(":"+cfg.Port, nil)
}
func processRequestData(cfg *config.MainConfig, r *http.Request) userRequest {
func processRequestData(cfg *config.MainConfig, r *http.Request) dataType.UserRequest {
var clientIP string
for _, headerName := range cfg.ConnectingIPHeaders {
@ -87,53 +86,9 @@ func processRequestData(cfg *config.MainConfig, r *http.Request) userRequest {
clientURI = r.RequestURI
}
userRequest := userRequest{
remoteIP: clientIP,
uri: clientURI,
userRequest := dataType.UserRequest{
RemoteIP: clientIP,
Uri: clientURI,
}
return userRequest
}
func checkIPAllow(remoteIP string, trie *dataType.TrieNode, decision *action.Decision) {
if decision.Get() != action.Undecided {
return
}
ip := net.ParseIP(remoteIP)
if ip == nil {
return
}
if trie.Search(ip) {
decision.Set(action.Allow)
}
}
func checkIPBlock(remoteIP string, trie *dataType.TrieNode, decision *action.Decision) {
if decision.Get() != action.Undecided {
return
}
ip := net.ParseIP(remoteIP)
if ip == nil {
return
}
if trie.Search(ip) {
decision.Set(action.Block)
}
}
func checkURLAllow(url string, list *dataType.URLRuleList, decision *action.Decision) {
if decision.Get() != action.Undecided {
return
}
if list.Match(url) {
decision.Set(action.Allow)
}
}
func checkURLBlock(url string, list *dataType.URLRuleList, decision *action.Decision) {
if decision.Get() != action.Undecided {
return
}
if list.Match(url) {
decision.Set(action.Block)
}
}