Skip to content

Commit

Permalink
skeleton
Browse files Browse the repository at this point in the history
Signed-off-by: Eliott Bouhana <[email protected]>
  • Loading branch information
eliottness committed Aug 30, 2024
1 parent 46c03ec commit 6bfaba1
Showing 1 changed file with 123 additions and 4 deletions.
127 changes: 123 additions & 4 deletions contrib/envoyproxy/envoy/cmd/serviceextensions/main.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package main

import (
"net"
"net/http"
"os"
"sync"

extproc "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"

"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec"
"net"
"os"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec/types"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/sharedsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/trace/httptrace"
)

// AppsecCalloutServiceExtensionService defines the struct that follows the ExternalProcessorServer interface.
Expand All @@ -33,6 +40,70 @@ func NewAppsecCalloutServiceExtensionService() *AppsecCalloutServiceExtensionSer
return service
}

type BufferResponseWriter struct {
buffer []byte
statusCode int
headers http.Header
}

func (b *BufferResponseWriter) Header() http.Header {
return b.headers
}

func (b *BufferResponseWriter) Write(data []byte) (int, error) {
b.buffer = append(b.buffer, data...)
return len(data), nil
}

func (b *BufferResponseWriter) WriteHeader(statusCode int) {
b.statusCode = statusCode
}

type OpenedRequest struct {
req *http.Request
respBuffer *BufferResponseWriter
op *types.Operation
blocking bool
}

var (
mu sync.Mutex
openedRequests = make(map[string]*OpenedRequest)
)

func processHTTPResponse(req *extproc.ProcessingRequest) error {
id := ""
mu.Lock()
openedRequest, ok := openedRequests[id]
if !ok {
mu.Unlock()
return nil
}

mu.Unlock()

// Response section
var responseHeaders = req.GetResponseHeaders()
var responseBody = req.GetResponseBody()
var responseTrailers = req.GetResponseTrailers()

res := types.HandlerOperationRes{ // TODO: fill all the fields of this struct
Headers: map[string][]string{},
Status: 200,
}

dyngo.FinishOperation(openedRequest.op, res)

if openedRequest.blocking {
println("Blocking request with this body: ", string(openedRequest.respBuffer.buffer))
println("Blocking request with this status code: ", openedRequest.respBuffer.statusCode)
// TODO: return the good response
return nil
}

return nil
}

func (s *AppsecCalloutServiceExtensionService) Process(stream extproc.ExternalProcessor_ProcessServer) error {
println("Processing request...")

Expand All @@ -43,6 +114,13 @@ func (s *AppsecCalloutServiceExtensionService) Process(stream extproc.ExternalPr
return err
}

if false { // TODO: get response from the stream and finish the request
err := processHTTPResponse(req)
if err != nil {
return err
}
}

// Request section
var requestHeaders = req.GetRequestHeaders()
var requestBody = req.GetRequestBody()
Expand All @@ -63,7 +141,48 @@ func (s *AppsecCalloutServiceExtensionService) Process(stream extproc.ExternalPr
return err
}

httpsec.MakeHandlerOperationArgs(nil, "127.0.0.1", nil)
headers := make(map[string][]string)

_, clientIP := httptrace.ClientIPTags(headers, true, "127.0.0.1")

op := &types.Operation{}
args := types.HandlerOperationArgs{ // TODO: fill all the fields of this struct
ClientIP: clientIP,
Headers: headers,
Cookies: headers,
Method: "GET",
PathParams: map[string]string{},
Query: map[string][]string{},
RequestURI: "/",
}

openedRequest := &OpenedRequest{
req: &http.Request{
Header: map[string][]string{}, // TODO: get the good headers thats the only thing needed here
},
respBuffer: &BufferResponseWriter{
buffer: []byte{},
statusCode: 0,
headers: map[string][]string{},
},
op: op,
blocking: false,
}
dyngo.OnData(op, func(a *sharedsec.HTTPAction) {
openedRequest.blocking = true
a.Handler.ServeHTTP(openedRequest.respBuffer, openedRequest.req)
})

dyngo.StartOperation(op, args)
if openedRequest.blocking {
println("Blocking request")
// TODO: block lol
return nil
}

mu.Lock()
defer mu.Unlock()
openedRequests[""] = openedRequest // TODO: get the good id

println("Response sent")
}
Expand Down

0 comments on commit 6bfaba1

Please sign in to comment.