Upload Modules
This commit is contained in:
77
ngx_http_limit_req_module/log_zone/logs.go
Normal file
77
ngx_http_limit_req_module/log_zone/logs.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
func logs(zone string) {
|
||||
for {
|
||||
zone, err := handleRequest(zone)
|
||||
if err != nil {
|
||||
logrus.Error("Error handling request", "error", err)
|
||||
return
|
||||
}
|
||||
fmt.Print("\033[H\033[2J")
|
||||
logrus.Infof("Zone: %s, RateLimitHeader: %+v, RateLimitEntries: %d",
|
||||
zone.Name, zone.RateLimitHeader, len(zone.RateLimitEntries))
|
||||
for _, entry := range zone.RateLimitEntries {
|
||||
logrus.Infof("Entry Key: %s, Last: %d, Excess: %d",
|
||||
entry.Key.String(zone.RateLimitHeader), entry.Last, entry.Excess)
|
||||
}
|
||||
fmt.Println("\nPress Ctrl+C to exit")
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func handleRequest(zone string) (Zone, error) {
|
||||
endpoint := fmt.Sprintf("http://localhost:9000/api/%s", zone)
|
||||
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
|
||||
if err != nil {
|
||||
return Zone{}, err
|
||||
}
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return Zone{}, fmt.Errorf("error making request to %s: %w", endpoint, err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
decoder := msgpack.NewDecoder(response.Body)
|
||||
var rateLimitHeader RateLimitHeader
|
||||
rateLimitEntries := []RateLimitEntry{}
|
||||
log := logrus.New()
|
||||
if err := decoder.Decode(&rateLimitHeader); err != nil {
|
||||
if err == io.EOF {
|
||||
return Zone{
|
||||
Name: zone,
|
||||
RateLimitHeader: rateLimitHeader,
|
||||
RateLimitEntries: rateLimitEntries,
|
||||
}, nil
|
||||
}
|
||||
log.Error("Error decoding header", "error", err)
|
||||
return Zone{}, err
|
||||
}
|
||||
for {
|
||||
var message RateLimitEntry
|
||||
if err := decoder.Decode(&message); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
log.Error("Error decoding entry", "error", err)
|
||||
return Zone{}, err
|
||||
}
|
||||
message.Last = toNonMonotonic(message.Last, rateLimitHeader)
|
||||
rateLimitEntries = append(rateLimitEntries, message)
|
||||
}
|
||||
log.Debug("Received rate limit entries", "zone", zone, "entries", len(rateLimitEntries))
|
||||
return Zone{
|
||||
Name: zone,
|
||||
RateLimitHeader: rateLimitHeader,
|
||||
RateLimitEntries: rateLimitEntries,
|
||||
}, nil
|
||||
}
|
||||
64
ngx_http_limit_req_module/log_zone/main.go
Normal file
64
ngx_http_limit_req_module/log_zone/main.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
arg := os.Args[1:]
|
||||
zone := "one"
|
||||
if arg[0] == "log" {
|
||||
if len(arg) >= 2 {
|
||||
zone = arg[1]
|
||||
}
|
||||
logs(zone)
|
||||
return
|
||||
}
|
||||
if arg[0] == "send" {
|
||||
if len(arg) >= 2 {
|
||||
zone = arg[1]
|
||||
}
|
||||
send(zone)
|
||||
}
|
||||
}
|
||||
|
||||
func toNonMonotonic(last int64, header RateLimitHeader) int64 {
|
||||
return header.Now - (header.NowMonotonic - last)
|
||||
}
|
||||
|
||||
type Zone struct {
|
||||
Name string
|
||||
RateLimitHeader RateLimitHeader
|
||||
RateLimitEntries []RateLimitEntry
|
||||
}
|
||||
|
||||
type RateLimitHeader struct {
|
||||
Key string
|
||||
Now int64
|
||||
NowMonotonic int64
|
||||
}
|
||||
|
||||
type RateLimitEntry struct {
|
||||
Key Key
|
||||
Last int64
|
||||
Excess int64
|
||||
}
|
||||
|
||||
const (
|
||||
BinaryRemoteAddress = "$binary_remote_addr"
|
||||
RemoteAddress = "$remote_addr"
|
||||
)
|
||||
|
||||
type Key []byte
|
||||
|
||||
func (r Key) String(header RateLimitHeader) string {
|
||||
switch header.Key {
|
||||
case BinaryRemoteAddress:
|
||||
return net.IP(r).String()
|
||||
case RemoteAddress:
|
||||
fallthrough
|
||||
default:
|
||||
return string(r)
|
||||
}
|
||||
}
|
||||
76
ngx_http_limit_req_module/log_zone/send.go
Normal file
76
ngx_http_limit_req_module/log_zone/send.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
func send(zone string) {
|
||||
err := sendRequest(
|
||||
zone,
|
||||
RateLimitHeader{
|
||||
Key: BinaryRemoteAddress,
|
||||
Now: time.Now().Unix(),
|
||||
NowMonotonic: time.Now().UnixNano() / int64(time.Millisecond),
|
||||
}, []RateLimitEntry{
|
||||
{Key([]byte{127, 0, 0, 0}), 7, 99},
|
||||
{Key([]byte{127, 0, 0, 1}), 7, 12},
|
||||
{Key([]byte{127, 6, 4, 00}), 2, 98},
|
||||
{Key([]byte{127, 0, 0, 99}), 30, 300},
|
||||
{Key([]byte{10, 0, 0, 1}), 444, 21},
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Fatalf("Error sending request: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func sendRequest(zone string, header RateLimitHeader, entries []RateLimitEntry) error {
|
||||
var buf bytes.Buffer
|
||||
encoder := msgpack.NewEncoder(&buf)
|
||||
var values []interface{} = []interface{}{
|
||||
headerToArray(header),
|
||||
}
|
||||
for _, entry := range entries {
|
||||
values = append(values, entryToArray(entry, header))
|
||||
}
|
||||
if err := encoder.Encode(values); err != nil {
|
||||
return fmt.Errorf("error encoding entries: %w", err)
|
||||
}
|
||||
endpoint := fmt.Sprintf("http://localhost:9000/api/%s", zone)
|
||||
req, err := http.NewRequest(http.MethodPost, endpoint, &buf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-msgpack")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error sending request to %s: %w", endpoint, err)
|
||||
}
|
||||
fmt.Println(resp.Status)
|
||||
defer resp.Body.Close()
|
||||
respBody, _ := io.ReadAll(resp.Body)
|
||||
logrus.Infof("response status: %s, body: %s", resp.Status, respBody)
|
||||
return nil
|
||||
}
|
||||
|
||||
func headerToArray(header RateLimitHeader) []interface{} {
|
||||
return []interface{}{
|
||||
header.Key,
|
||||
header.Now,
|
||||
header.NowMonotonic,
|
||||
}
|
||||
}
|
||||
|
||||
func entryToArray(entry RateLimitEntry, header RateLimitHeader) []interface{} {
|
||||
return []interface{}{
|
||||
entry.Key,
|
||||
entry.Last,
|
||||
entry.Excess,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user