mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 10:18:59 +02:00
feat(rules): add post-request rules system with response manipulation (#160)
* Add comprehensive post-request rules support for response phase * Enable response body, status, and header manipulation via set commands * Refactor command handlers to support both request and response phases * Implement response modifier system for post-request template execution * Support response-based rule matching with status and header checks * Add comprehensive benchmarks for matcher performance * Refactor authentication and proxying commands for unified error handling * Support negated conditions with ! * Enhance error handling, error formatting and validation * Routes: add `rule_file` field with rule preset support * Environment variable substitution: now supports variables without `GODOXY_` prefix * new conditions: * `on resp_header <key> [<value>]` * `on status <status>` * new commands: * `require_auth` * `set resp_header <key> <template>` * `set resp_body <template>` * `set status <code>` * `log <level> <path> <template>` * `notify <level> <provider> <title_template> <body_template>`
This commit is contained in:
74
internal/route/rules/rules_bench_test.go
Normal file
74
internal/route/rules/rules_bench_test.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkRules(b *testing.B) {
|
||||
var rules Rules
|
||||
err := parseRules(`
|
||||
- name: admin-api
|
||||
on: |
|
||||
path glob(/api/admin/*)
|
||||
header Authorization
|
||||
method POST
|
||||
do: |
|
||||
set resp_header X-Access-Level "admin"
|
||||
set resp_header X-API-Version "v1"
|
||||
- name: user-api
|
||||
on: |
|
||||
path glob(/api/users/*) & method GET
|
||||
do: |
|
||||
set resp_header X-Access-Level "user"
|
||||
set resp_header X-API-Version "v1"
|
||||
- name: public-api
|
||||
on: |
|
||||
path glob(/api/public/*) & method GET
|
||||
do: |
|
||||
set resp_header X-Access-Level "public"
|
||||
`, &rules)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
upstream := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
b.Run("BuildHandler", func(b *testing.B) {
|
||||
for b.Loop() {
|
||||
rules.BuildHandler(upstream)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("RunHandler", func(b *testing.B) {
|
||||
var r = &http.Request{
|
||||
Body: io.NopCloser(bytes.NewReader([]byte(""))),
|
||||
URL: &url.URL{Path: "/api/users/"},
|
||||
}
|
||||
var w noopResponseWriter
|
||||
handler := rules.BuildHandler(upstream)
|
||||
b.ResetTimer()
|
||||
for b.Loop() {
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type noopResponseWriter struct {
|
||||
}
|
||||
|
||||
func (w noopResponseWriter) Header() http.Header {
|
||||
return http.Header{}
|
||||
}
|
||||
|
||||
func (w noopResponseWriter) Write(b []byte) (int, error) {
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (w noopResponseWriter) WriteHeader(int) {
|
||||
}
|
||||
Reference in New Issue
Block a user