Skip to content

Commit

Permalink
init impl
Browse files Browse the repository at this point in the history
Signed-off-by: gang.liu <gang.liu@daocloud.io>
  • Loading branch information
izturn committed Apr 10, 2024
1 parent 0a81b90 commit c28a3bd
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 126 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ jobs:
uses: docker/build-push-action@v4
with:
push: true
tags: release.daocloud.io/skoala/envoy-extproc-payloadlimit-demo-go:${{ github.sha }}
tags: release.daocloud.io/skoala/envoy-extproc-crc32-check-demo-go:${{ github.sha }}
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ FROM busybox
COPY --from=0 /extproc /bin/extproc
RUN chmod +x /bin/extproc

ARG EXAMPLE=payload-limit
ARG EXAMPLE=crc32-check

EXPOSE 50051

ENTRYPOINT [ "/bin/extproc" ]
CMD [ "payload-limit", "--log-stream", "--log-phases", "payload-limit", "32" ]
CMD [ "crc32-check", "--log-stream", "--log-phases", "poly", "0x82f63b78" ]
40 changes: 36 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# envoy-extproc-payloadlimit-demo-go
# envoy-extproc-crc32-check-demo-go

This repository contains a demo application written in Go that demonstrates the usage of Envoy's External Processor (ExtProc) filter to do `payload limit` for POST request.
This repository contains a demo application written in Go that demonstrates the usage of Envoy's External Processor (ExtProc) filter to do `crc(32) check` for HTTP request.

## Overview

Expand All @@ -19,7 +19,7 @@ To get started with the demo application, follow these steps:

1. Clone the repository:
```
git clone https://github.com/projectsesame/envoy-extproc-payloadlimit-demo-go.git
git clone https://github.com/projectsesame/envoy-extproc-crc32-check-demo-go.git
```

2. Build the Go application:
Expand All @@ -29,9 +29,41 @@ To get started with the demo application, follow these steps:

3. Run the application:
```
./envoy-extproc-payloadlimit-demo-go payload-limit --log-stream --log-phases payload-limit 32
./envoy-extproc-crc32-check-demo-go crc32-check --log-stream --log-phases poly "0x82f63b78"
```

4. Do request:
```
curl --request POST \
--url http://127.0.0.1:8080/post \
--data '{
"data": "123456789",
"crc32": "E7C41C6B",
}'
```

Field Description:

+ **data**: the content.
+ **crc32**: crc for the data.

PS:

The example crc is calculated using the following settings, which are the same configuration as the standard package of go.

+ **Bit Width**: 32
+ **REFIN**: true
+ **REFOUT**: true
+ **XOROUT (HEX)**: 0xFFFFFFFF
+ **Initial Value (HEX)**: 0xFFFFFFFF
+ **Polynomial Formula (HEX)**: 0x82F63B78








## Usage

Expand Down
124 changes: 124 additions & 0 deletions crc32-check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"encoding/json"
"hash/crc32"
"log"
"math/bits"
"strconv"
"strings"

typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
ep "github.com/wrossmorrow/envoy-extproc-sdk-go"
)

const (
kCRC = "crc32"
kData = "data"
kPoly = "poly"
)

type crc32CheckRequestProcessor struct {
opts *ep.ProcessingOptions
poly uint32
}

func (s *crc32CheckRequestProcessor) GetName() string {
return "crc32-check"
}

func (s *crc32CheckRequestProcessor) GetOptions() *ep.ProcessingOptions {
return s.opts
}

func (s *crc32CheckRequestProcessor) ProcessRequestHeaders(ctx *ep.RequestContext, headers ep.AllHeaders) error {
return ctx.ContinueRequest()
}

func extract(m map[string]any, k string) string {
vv, ok := m[k]
if ok {
return vv.(string)
}
return ""
}

func (s *crc32CheckRequestProcessor) crc(input []byte) uint32 {
revPoly := bits.Reverse32(s.poly)
t := crc32.MakeTable(revPoly)
return crc32.Checksum(input, t)
}

func (s *crc32CheckRequestProcessor) ProcessRequestBody(ctx *ep.RequestContext, body []byte) error {
cancel := func(code int32) error {
return ctx.CancelRequest(code, map[string]ep.HeaderValue{}, typev3.StatusCode_name[code])
}

var unstructure map[string]any

err := json.Unmarshal(body, &unstructure)
if err != nil {
log.Printf("parse the request is failed: %v", err.Error())
return cancel(400)
}

actual, _ := strconv.ParseUint(extract(unstructure, kCRC), 16, 32)

want := s.crc([]byte(extract(unstructure, kData)))
if want != uint32(actual) {
log.Printf("verify the checksum is failed, want=0x%0x actual=0x%0x", want, actual)
return cancel(403)
}

return ctx.ContinueRequest()
}

func (s *crc32CheckRequestProcessor) ProcessRequestTrailers(ctx *ep.RequestContext, trailers ep.AllHeaders) error {
return ctx.ContinueRequest()
}

func (s *crc32CheckRequestProcessor) ProcessResponseHeaders(ctx *ep.RequestContext, headers ep.AllHeaders) error {
return ctx.ContinueRequest()
}

func (s *crc32CheckRequestProcessor) ProcessResponseBody(ctx *ep.RequestContext, body []byte) error {
return ctx.ContinueRequest()
}

func (s *crc32CheckRequestProcessor) ProcessResponseTrailers(ctx *ep.RequestContext, trailers ep.AllHeaders) error {
return ctx.ContinueRequest()
}

func (s *crc32CheckRequestProcessor) Init(opts *ep.ProcessingOptions, nonFlagArgs []string) error {
s.opts = opts
s.poly = crc32.IEEE

var i int
nArgs := len(nonFlagArgs)
for ; i < nArgs-1; i++ {
if nonFlagArgs[i] == kPoly {
break
}
}

if i == nArgs {
log.Printf("the argument: 'poly' is missing, use the IEEE.\n")
} else {
polyStr := strings.ToLower(nonFlagArgs[i+1])

if ok := strings.HasPrefix(polyStr, "0x"); ok && len(polyStr) > 2 {
polyStr = polyStr[2:]
}

poly, _ := strconv.ParseInt(polyStr, 16, 64)
if poly == 0 {
log.Printf("parse the value for parameter: 'poly' is failed, use the IEEE.\n")
} else {
s.poly = uint32(poly)
log.Printf("the poly is: 0x%0x.\n", s.poly)
}
}
return nil
}

func (s *crc32CheckRequestProcessor) Finish() {}
18 changes: 9 additions & 9 deletions deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: payload-limit-demo
namespace: payload-limit-demo
name: crc32-check-demo
namespace: crc32-check-demo
annotations:
spec:
replicas: 1
selector:
matchLabels:
app: payload-limit-demo
app: crc32-check-demo
template:
metadata:
creationTimestamp: null
labels:
app: payload-limit-demo
app: crc32-check-demo
spec:
containers:
- name: payload-limit-demo-container
- name: crc32-check-demo-container
image: >-
release.daocloud.io/skoala/envoy-extproc-payloadlimit-demo-go@sha256:dcc5ba7aa2790e87b0cd46799363367b54202585794ebfe87248264f111e63d8
release.daocloud.io/skoala/envoy-extproc-crc32-check-demo-go@sha256:dcc5ba7aa2790e87b0cd46799363367b54202585794ebfe87248264f111e63d8
ports:
- containerPort: 50051
protocol: TCP
Expand All @@ -44,8 +44,8 @@ spec:
apiVersion: v1
kind: Service
metadata:
name: payload-limit-demo
namespace: payload-limit-demo
name: crc32-check-demo
namespace: crc32-check-demo
annotations:
spec:
ports:
Expand All @@ -54,7 +54,7 @@ spec:
targetPort: 50051
nodePort: 31928
selector:
app: payload-limit-demo
app: crc32-check-demo
type: NodePort
sessionAffinity: None
externalTrafficPolicy: Cluster
Expand Down
10 changes: 5 additions & 5 deletions envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static_resources:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
grpc_service:
envoy_grpc:
cluster_name: payload-limit
cluster_name: crc32-check
timeout: 30s
failure_mode_allow: true
message_timeout: 0.2s
Expand Down Expand Up @@ -70,19 +70,19 @@ static_resources:
socket_address:
address: upstream
port_value: 8000
- name: payload-limit
- name: crc32-check
dns_lookup_family: V4_ONLY
lb_policy: LEAST_REQUEST
load_assignment:
cluster_name: payload-limit
cluster_name: crc32-check
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: payload-limit
address: crc32-check
port_value: 50051
hostname: payload-limit
hostname: crc32-check
type: LOGICAL_DNS
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/projectsesame/envoy-extproc-payloadlimit-demo-go
module github.com/projectsesame/envoy-extproc-crc32-check-demo-go

go 1.21

Expand Down
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type processor interface {
}

var processors = map[string]processor{
"payload-limit": &payloadLimitRequestProcessor{},
"crc32-check": &crc32CheckRequestProcessor{},
}

func parseArgs(args []string) (port *int, opts *ep.ProcessingOptions, nonFlagArgs []string) {
Expand All @@ -36,7 +36,6 @@ func parseArgs(args []string) (port *int, opts *ep.ProcessingOptions, nonFlagArg
}

func main() {

// cmd subCmd arg, arg2,...
args := os.Args
if len(args) < 2 {
Expand Down
Loading

0 comments on commit c28a3bd

Please sign in to comment.